active-fedora 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +30 -0
- data/.gitmodules +3 -0
- data/.rvmrc +33 -0
- data/CONSOLE_GETTING_STARTED.textile +337 -0
- data/Gemfile +6 -1
- data/Gemfile.lock +39 -23
- data/NOKOGIRI_DATASTREAMS.textile +107 -0
- data/README.textile +41 -17
- data/Rakefile +5 -30
- data/active-fedora.gemspec +34 -496
- data/lib/active_fedora.rb +6 -1
- data/lib/active_fedora/base.rb +7 -5
- data/lib/active_fedora/datastream.rb +9 -8
- data/lib/active_fedora/metadata_datastream.rb +10 -3
- data/lib/active_fedora/model.rb +8 -4
- data/lib/active_fedora/nokogiri_datastream.rb +30 -24
- data/lib/active_fedora/qualified_dublin_core_datastream.rb +3 -2
- data/lib/active_fedora/rels_ext_datastream.rb +14 -5
- data/lib/active_fedora/samples.rb +3 -0
- data/lib/active_fedora/samples/hydra-mods_article_datastream.rb +517 -0
- data/lib/active_fedora/samples/hydra-rights_metadata_datastream.rb +206 -0
- data/lib/active_fedora/samples/marpa-dc_datastream.rb +97 -0
- data/lib/active_fedora/samples/special_thing.rb +45 -0
- data/lib/active_fedora/semantic_node.rb +16 -13
- data/lib/active_fedora/version.rb +3 -0
- data/lib/fedora/base.rb +5 -5
- data/lib/fedora/datastream.rb +1 -1
- data/lib/fedora/fedora_object.rb +1 -1
- data/lib/fedora/repository.rb +4 -0
- data/lib/tasks/active_fedora.rake +126 -0
- data/lib/tasks/active_fedora_dev.rake +127 -0
- data/solr/conf/schema.xml +278 -0
- data/solr/conf/solrconfig.xml +840 -0
- data/spec/integration/full_featured_model_spec.rb +2 -2
- data/spec/integration/mods_article_integration_spec.rb +2 -2
- data/spec/integration/nokogiri_datastream_spec.rb +2 -2
- data/spec/rcov.opts +2 -0
- data/spec/samples/models/hydrangea_article.rb +12 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/nokogiri_datastream_spec.rb +10 -7
- metadata +189 -886
- data/NG_XML_DATASTREAM.textile +0 -25
- data/USING_OM_DATASTREAMS.textile +0 -60
- data/VERSION +0 -1
- data/lib/hydra.rb +0 -2
- data/lib/hydra/sample_mods_datastream.rb +0 -63
- data/tasks/hoe.rake +0 -0
- data/tasks/rspec.rake +0 -29
@@ -0,0 +1,206 @@
|
|
1
|
+
module Hydra
|
2
|
+
# This is an example of a NokogiriDatastream that defines a terminology for Hydra rightsMetadata xml
|
3
|
+
# The documentation for Hydra rightsMetadata is on the Hydra wiki at https://wiki.duraspace.org/display/hydra/Hydra+rights+metadata
|
4
|
+
# The real version of this Terminology is part of the hydra-head plugin. See https://github.com/projecthydra/hydra-head/blob/master/lib/hydra/rights_metadata.rb
|
5
|
+
#
|
6
|
+
# The purpose of rightsMetadata is to store information about access controls and licensing for the object that the rightsMetadata is attached to
|
7
|
+
#
|
8
|
+
# The most interesting thing going on in this Class is the use of custom methods to access and update permissions in intuitive ways.
|
9
|
+
# These methods allow you to do things like
|
10
|
+
# * Get reports on which groups & individuals have which permissions
|
11
|
+
# * Update permissions for individuals & groups with straightforward syntax
|
12
|
+
#
|
13
|
+
# Another interesting thing in this Class: it extends to_solr, first calling "super" (the default to_solr behavior) and then inserting an additional embargo_release_date_dt field
|
14
|
+
# It uses Solrizer::Extractor.insert_solr_field_value to do this. That method handles inserting new values into a Hash while ensuring that you don't destroy or overwrite any existing values in the hash.
|
15
|
+
class RightsMetadataDatastream < ActiveFedora::NokogiriDatastream
|
16
|
+
|
17
|
+
set_terminology do |t|
|
18
|
+
t.root(:path=>"rightsMetadata", :xmlns=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1", :schema=>"http://github.com/projecthydra/schemas/tree/v1/rightsMetadata.xsd")
|
19
|
+
t.copyright {
|
20
|
+
t.machine {
|
21
|
+
t.cclicense
|
22
|
+
}
|
23
|
+
t.human_readable(:path=>"human")
|
24
|
+
t.cclicense(:proxy=>[:machine, :cclicense ])
|
25
|
+
}
|
26
|
+
t.access {
|
27
|
+
t.human_readable(:path=>"human")
|
28
|
+
t.machine {
|
29
|
+
t.group
|
30
|
+
t.person
|
31
|
+
}
|
32
|
+
t.person(:proxy=>[:machine, :person])
|
33
|
+
t.group(:proxy=>[:machine, :group])
|
34
|
+
# accessor :access_person, :term=>[:access, :machine, :person]
|
35
|
+
}
|
36
|
+
t.discover_access(:ref=>[:access], :attributes=>{:type=>"discover"})
|
37
|
+
t.read_access(:ref=>[:access], :attributes=>{:type=>"read"})
|
38
|
+
t.edit_access(:ref=>[:access], :attributes=>{:type=>"edit"})
|
39
|
+
# A bug in OM prevnts us from declaring proxy terms at the root of a Terminology
|
40
|
+
# t.access_person(:proxy=>[:access,:machine,:person])
|
41
|
+
# t.access_group(:proxy=>[:access,:machine,:group])
|
42
|
+
|
43
|
+
t.embargo {
|
44
|
+
t.human_readable(:path=>"human")
|
45
|
+
t.machine{
|
46
|
+
t.date(:type =>"release")
|
47
|
+
}
|
48
|
+
t.embargo_release_date(:proxy => [:machine, :date])
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Generates an empty Mods Article (used when you call ModsArticle.new without passing in existing xml)
|
53
|
+
def self.xml_template
|
54
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
55
|
+
xml.rightsMetadata(:version=>"0.1", "xmlns"=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1") {
|
56
|
+
xml.copyright {
|
57
|
+
xml.human
|
58
|
+
xml.machine {
|
59
|
+
xml.uvalicense "no"
|
60
|
+
}
|
61
|
+
}
|
62
|
+
xml.access(:type=>"discover") {
|
63
|
+
xml.human
|
64
|
+
xml.machine
|
65
|
+
}
|
66
|
+
xml.access(:type=>"read") {
|
67
|
+
xml.human
|
68
|
+
xml.machine
|
69
|
+
}
|
70
|
+
xml.access(:type=>"edit") {
|
71
|
+
xml.human
|
72
|
+
xml.machine
|
73
|
+
}
|
74
|
+
xml.embargo{
|
75
|
+
xml.human
|
76
|
+
xml.machine
|
77
|
+
}
|
78
|
+
}
|
79
|
+
end
|
80
|
+
return builder.doc
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the permissions for the selected person/group
|
84
|
+
# If new_access_level is provided, updates the selected person/group access_level to the one specified
|
85
|
+
# A new_access_level of "none" will remove all access_levels for the selected person/group
|
86
|
+
# @param [Hash] selector
|
87
|
+
# @param [String] new_access_level (default nil)
|
88
|
+
# @return [Hash]
|
89
|
+
#
|
90
|
+
# @example Query permissions for person123, Set the permissions to "read", then query again to see that they have changed.
|
91
|
+
# permissions({:person=>"person123"})
|
92
|
+
# => {"person123"=>"edit"}
|
93
|
+
# permissions({:person=>"person123"}, "read")
|
94
|
+
# => {"person123"=>"read"}
|
95
|
+
# permissions({:person=>"person123"})
|
96
|
+
# => {"person123"=>"read"}
|
97
|
+
def permissions(selector, new_access_level=nil)
|
98
|
+
|
99
|
+
type = selector.keys.first.to_sym
|
100
|
+
actor = selector.values.first
|
101
|
+
if new_access_level.nil?
|
102
|
+
xpath = self.class.terminology.xpath_for(:access, type, actor)
|
103
|
+
nodeset = self.find_by_terms(xpath)
|
104
|
+
if nodeset.empty?
|
105
|
+
return "none"
|
106
|
+
else
|
107
|
+
return nodeset.first.ancestors("access").first.attributes["type"].text
|
108
|
+
end
|
109
|
+
else
|
110
|
+
remove_all_permissions(selector)
|
111
|
+
unless new_access_level == "none"
|
112
|
+
access_type_symbol = "#{new_access_level}_access".to_sym
|
113
|
+
result = self.update_values([access_type_symbol, type] => {"-1"=>actor})
|
114
|
+
end
|
115
|
+
self.dirty = true
|
116
|
+
return new_access_level
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
# Reports on which groups have which permissions
|
122
|
+
# @return [Hash]
|
123
|
+
# @example
|
124
|
+
# sample_ds.permissions({"group"=>"group_zzz"}, "edit")
|
125
|
+
# sample_ds.permissions({"group"=>"public"}, "discover")
|
126
|
+
# sample_ds.groups #=> {"public"=>"discover", "group_zzz"=>"edit"}
|
127
|
+
def groups
|
128
|
+
return quick_search_by_type(:group)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Reports on which groups have which permissions
|
132
|
+
# @return [Hash]
|
133
|
+
# @example
|
134
|
+
# sample_ds.permissions({"person"=>"person_123"}, "read")
|
135
|
+
# sample_ds.permissions({""person"=>"person_456"}, "edit")
|
136
|
+
# sample_ds.individuals #=> {"person_123"=>"read", "person_456"=>"edit"}
|
137
|
+
def individuals
|
138
|
+
return quick_search_by_type(:person)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Updates permissions for all of the persons and groups in a hash
|
142
|
+
# @param [Hash] params example: {"group"=>{"group1"=>"discover","group2"=>"edit"}, "person"=>{"person1"=>"read","person2"=>"discover"}}
|
143
|
+
# Currently restricts actor type to group or person. Any others will be ignored
|
144
|
+
def update_permissions(params)
|
145
|
+
params.fetch("group", {}).each_pair {|group_id, access_level| self.permissions({"group"=>group_id}, access_level)}
|
146
|
+
params.fetch("person", {}).each_pair {|group_id, access_level| self.permissions({"person"=>group_id}, access_level)}
|
147
|
+
end
|
148
|
+
|
149
|
+
# This method limits the response to known access levels (:discover, :read, :edit). Probably runs a bit faster than {#permissions}.
|
150
|
+
# @param [:group,:person] type
|
151
|
+
# @return [Hash]
|
152
|
+
def quick_search_by_type(type)
|
153
|
+
result = {}
|
154
|
+
[{:discover_access=>"discover"},{:read_access=>"read"},{:edit_access=>"edit"}].each do |access_levels_hash|
|
155
|
+
access_level = access_levels_hash.keys.first
|
156
|
+
access_level_name = access_levels_hash.values.first
|
157
|
+
self.find_by_terms(*[access_level, type]).each do |entry|
|
158
|
+
result[entry.text] = access_level_name
|
159
|
+
end
|
160
|
+
end
|
161
|
+
return result
|
162
|
+
end
|
163
|
+
|
164
|
+
attr_reader :embargo_release_date
|
165
|
+
def embargo_release_date=(release_date)
|
166
|
+
release_date = release_date.to_s if release_date.is_a? Date
|
167
|
+
begin
|
168
|
+
Date.parse(release_date)
|
169
|
+
rescue
|
170
|
+
return "INVALID DATE"
|
171
|
+
end
|
172
|
+
self.update_values({[:embargo,:machine,:date]=>release_date})
|
173
|
+
end
|
174
|
+
def embargo_release_date(opts={})
|
175
|
+
embargo_release_date = self.find_by_terms(*[:embargo,:machine,:date]).first ? self.find_by_terms(*[:embargo,:machine,:date]).first.text : nil
|
176
|
+
if opts[:format] && opts[:format] == :solr_date
|
177
|
+
embargo_release_date << "T23:59:59Z"
|
178
|
+
end
|
179
|
+
embargo_release_date
|
180
|
+
end
|
181
|
+
def under_embargo?
|
182
|
+
(embargo_release_date && Date.today < embargo_release_date.to_date) ? true : false
|
183
|
+
end
|
184
|
+
|
185
|
+
def to_solr(solr_doc=Hash.new)
|
186
|
+
super(solr_doc)
|
187
|
+
::Solrizer::Extractor.insert_solr_field_value(solr_doc, "embargo_release_date_dt", embargo_release_date(:format=>:solr_date)) if embargo_release_date
|
188
|
+
solr_doc
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
private
|
196
|
+
# Purge all access given group/person
|
197
|
+
def remove_all_permissions(selector)
|
198
|
+
type = selector.keys.first.to_sym
|
199
|
+
actor = selector.values.first
|
200
|
+
xpath = self.class.terminology.xpath_for(:access, type, actor)
|
201
|
+
nodes_to_purge = self.find_by_terms(xpath)
|
202
|
+
nodes_to_purge.each {|node| node.remove}
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "active-fedora"
|
2
|
+
module Marpa
|
3
|
+
|
4
|
+
# This is an example of a NokogiriDatastream that defines a terminology for Dublin Core xml
|
5
|
+
#
|
6
|
+
# Some things to observe about this Class:
|
7
|
+
# * Defines a couple of custom terms, tibetan_title and english_title, that map to dc:title with varying @language attributes
|
8
|
+
# * Indicates which terms should be indexed as facets using :index_as=>[:facetable]
|
9
|
+
# * Defines an xml template that is an empty dublin core xml document with three namespaces set
|
10
|
+
# * Sets the namespace using :xmlns argument on the root term
|
11
|
+
# * Does not override or extend to_solr, so the default solrization approach will be used (Solrizer::XML::TerminologyBasedSolrizer)
|
12
|
+
#
|
13
|
+
class DcDatastream < ActiveFedora::NokogiriDatastream
|
14
|
+
|
15
|
+
set_terminology do |t|
|
16
|
+
t.root(:path=>"dc", :xmlns=>'http://purl.org/dc/terms/')
|
17
|
+
t.tibetan_title(:path=>"title", :attributes=>{:language=>"tibetan"})
|
18
|
+
t.english_title(:path=>"title", :attributes=>{:language=>:none})
|
19
|
+
t.contributor(:index_as=>[:facetable])
|
20
|
+
t.coverage
|
21
|
+
t.creator
|
22
|
+
t.description
|
23
|
+
t.format
|
24
|
+
t.identifier
|
25
|
+
t.language(:index_as=>[:facetable])
|
26
|
+
t.publisher
|
27
|
+
t.relation
|
28
|
+
t.source
|
29
|
+
t.title
|
30
|
+
t.abstract
|
31
|
+
t.accessRights
|
32
|
+
t.accrualMethod
|
33
|
+
t.accrualPeriodicity
|
34
|
+
t.accrualPolicy
|
35
|
+
t.alternative
|
36
|
+
t.audience
|
37
|
+
t.available
|
38
|
+
t.bibliographicCitation
|
39
|
+
t.conformsTo
|
40
|
+
t.contributor
|
41
|
+
t.coverage
|
42
|
+
t.created
|
43
|
+
t.creator
|
44
|
+
t.date(:index_as=>[:facetable])
|
45
|
+
t.dateAccepted
|
46
|
+
t.dateCopyrighted
|
47
|
+
t.dateSubmitted
|
48
|
+
t.description
|
49
|
+
t.educationLevel
|
50
|
+
t.extent
|
51
|
+
t.format
|
52
|
+
t.hasFormat
|
53
|
+
t.hasPart
|
54
|
+
t.hasVersion
|
55
|
+
t.identifier
|
56
|
+
t.instructionalMethod
|
57
|
+
t.isFormatOf
|
58
|
+
t.isPartOf
|
59
|
+
t.isReferencedBy
|
60
|
+
t.isReplacedBy
|
61
|
+
t.isRequiredBy
|
62
|
+
t.issued
|
63
|
+
t.isVersionOf
|
64
|
+
t.language(:index_as=>[:facetable])
|
65
|
+
t.license
|
66
|
+
t.mediator
|
67
|
+
t.medium
|
68
|
+
t.modified
|
69
|
+
t.provenance
|
70
|
+
t.publisher
|
71
|
+
t.references
|
72
|
+
t.relation
|
73
|
+
t.replaces
|
74
|
+
t.requires
|
75
|
+
t.rights
|
76
|
+
t.rightsHolder
|
77
|
+
t.source
|
78
|
+
t.spatial(:index_as=>[:facetable])
|
79
|
+
t.subject(:index_as=>[:facetable])
|
80
|
+
t.tableOfContents
|
81
|
+
t.temporal
|
82
|
+
t.type
|
83
|
+
t.valid
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.xml_template
|
87
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
88
|
+
xml.dc("xmlns"=>'http://purl.org/dc/terms/',
|
89
|
+
"xmlns:dcterms"=>'http://purl.org/dc/terms/',
|
90
|
+
"xmlns:xsi"=>'http://www.w3.org/2001/XMLSchema-instance') {
|
91
|
+
}
|
92
|
+
end
|
93
|
+
return builder.doc
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "active-fedora"
|
2
|
+
require "active_fedora/samples/hydra-mods_article_datastream.rb"
|
3
|
+
require "active_fedora/samples/hydra-rights_metadata_datastream.rb"
|
4
|
+
require "active_fedora/samples/marpa-dc_datastream.rb"
|
5
|
+
|
6
|
+
# This is an example of an ActiveFedora Model
|
7
|
+
#
|
8
|
+
# Some of the datastream ids were chosen based on the Hydra modeling conventions. You don't have to follow them in your work. ActiveFedora itself has no notion of those conventions, but we do encourage you to use them.
|
9
|
+
#
|
10
|
+
# The Hydra conventions encourage you to have a datastream with this dsid whose contents are descriptive metadata like MODS or Dublin Core. They especially encourage MODS.
|
11
|
+
# The rightsMetadata datastream is also a convention provided by the Hydra Common Metadata "content model"
|
12
|
+
#
|
13
|
+
# For more info on the Hydra conventions, see the documentation on "Common Metadata content model" in https://wiki.duraspace.org/display/hydra/Hydra+content+models+and+disseminators
|
14
|
+
# Note that on the wiki, "content model" is often used to refer to Fedora CModels and/or abstract/notional models. The Common Metadata content model is an example of this.
|
15
|
+
# The wiki includes a page that attempts to shed some light on the question of "What is a content model?" https://wiki.duraspace.org/display/hydra/Don't+call+it+a+'content+model'!
|
16
|
+
class SpecialThing < ActiveFedora::Base
|
17
|
+
|
18
|
+
#
|
19
|
+
# DATASTREAMS
|
20
|
+
#
|
21
|
+
|
22
|
+
# This declares a datastream with Datastream ID (dsid) of "descMetadata"
|
23
|
+
# The descMetadata datastream is bound to the Hydra::ModsArticleDatastream class that's defined in lib/active_fedora/samples
|
24
|
+
# Any time you load a Fedora object using an instance of SampleModel, the instance will assume its descMetadata datastream conforms to the assumptions in Hydra::ModsArticleDatastream class
|
25
|
+
has_metadata :name => "descMetadata", :type=> Hydra::ModsArticleDatastream
|
26
|
+
|
27
|
+
# This declares a datastream with Datastream ID (dsid) of "rightsMetadata"
|
28
|
+
# Like the descMetadata datastream, any time you load a Fedora object using an instance of SampleModel, the instance will assume its descMetadata datastream conforms to the assumptions in Hydra::RightsMetadataDatastream class
|
29
|
+
has_metadata :name => "rightsMetadata", :type => Hydra::RightsMetadataDatastream
|
30
|
+
|
31
|
+
# This is not part of the Hydra conventions
|
32
|
+
# Adding an extra datastream called "extraMetadataForFun" that is bound to the Marpa::DcDatastream class
|
33
|
+
has_metadata :name => "extraMetadataForFun", :type => Marpa::DcDatastream
|
34
|
+
|
35
|
+
#
|
36
|
+
# RELATIONSHIPS
|
37
|
+
#
|
38
|
+
|
39
|
+
# This is an example of how you can add a custom relationship to a model
|
40
|
+
# This will allow you to call .derivations on instances of the model to get a list of all of the _outbound_ "hasDerivation" relationships in the RELS-EXT datastream
|
41
|
+
has_relationship "derivations", :has_derivation
|
42
|
+
|
43
|
+
# This will allow you to call .inspirations on instances of the model to get a list of all of the objects that assert "hasDerivation" relationships pointing at this object
|
44
|
+
has_relationship "inspirations", :has_derivation, :inbound => true
|
45
|
+
end
|
@@ -394,7 +394,8 @@ module ActiveFedora
|
|
394
394
|
end
|
395
395
|
|
396
396
|
# Creates a RELS-EXT datastream for insertion into a Fedora Object
|
397
|
-
# @pid
|
397
|
+
# @param [String] pid
|
398
|
+
# @param [Hash] relationships (optional) @default self.relationships
|
398
399
|
# Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
|
399
400
|
def to_rels_ext(pid, relationships=self.relationships)
|
400
401
|
starter_xml = <<-EOL
|
@@ -480,10 +481,10 @@ module ActiveFedora
|
|
480
481
|
|
481
482
|
# Generates relationship finders for predicates that point in both directions
|
482
483
|
#
|
483
|
-
# @name
|
484
|
-
# @outbound_predicate Predicate used in outbound relationships
|
485
|
-
# @inbound_predicate Predicate used in inbound relationships
|
486
|
-
# @opts
|
484
|
+
# @param [String] name of the relationship method(s) to create
|
485
|
+
# @param [Symbol] outbound_predicate Predicate used in outbound relationships
|
486
|
+
# @param [Symbol] inbound_predicate Predicate used in inbound relationships
|
487
|
+
# @param [Hash] opts
|
487
488
|
#
|
488
489
|
# Example:
|
489
490
|
# has_bidirectional_relationship("parts", :has_part, :is_part_of)
|
@@ -646,11 +647,10 @@ module ActiveFedora
|
|
646
647
|
# Generates relationship finders for predicates that point in both directions
|
647
648
|
# and registers predicate relationships for each direction.
|
648
649
|
#
|
649
|
-
# @name Name of the relationship method(s) to create
|
650
|
-
# @outbound_predicate Predicate used in outbound relationships
|
651
|
-
# @inbound_predicate Predicate used in inbound relationships
|
652
|
-
# @opts
|
653
|
-
#
|
650
|
+
# @param [String] name Name of the relationship method(s) to create
|
651
|
+
# @param [Symbol] outbound_predicate Predicate used in outbound relationships
|
652
|
+
# @param [Symbol] inbound_predicate Predicate used in inbound relationships
|
653
|
+
# @param [Hash] opts (optional)
|
654
654
|
def create_bidirectional_relationship_finders(name, outbound_predicate, inbound_predicate, opts={})
|
655
655
|
inbound_method_name = name.to_s+"_inbound"
|
656
656
|
outbound_method_name = name.to_s+"_outbound"
|
@@ -693,7 +693,9 @@ module ActiveFedora
|
|
693
693
|
END
|
694
694
|
end
|
695
695
|
|
696
|
-
# relationships are tracked as a hash of structure
|
696
|
+
# relationships are tracked as a hash of structure
|
697
|
+
# @example
|
698
|
+
# ds.relationships # => {:self=>{:has_model=>["afmodel:SimpleThing"],:has_part=>["demo:20"]},:inbound=>{:is_part_of=>["demo:6"]}
|
697
699
|
def relationships
|
698
700
|
@class_relationships ||= Hash[:self => {}]
|
699
701
|
end
|
@@ -715,7 +717,8 @@ module ActiveFedora
|
|
715
717
|
#alias_method :register_target, :register_object
|
716
718
|
|
717
719
|
# Creates a RELS-EXT datastream for insertion into a Fedora Object
|
718
|
-
# @pid
|
720
|
+
# @param [String] pid of the object that the RELS-EXT datastream belongs to
|
721
|
+
# @param [Hash] relationships the relationships hash to transform into RELS-EXT RDF. @default the object's relationships hash
|
719
722
|
# Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
|
720
723
|
def relationships_to_rels_ext(pid, relationships=self.relationships)
|
721
724
|
starter_xml = <<-EOL
|
@@ -738,7 +741,7 @@ module ActiveFedora
|
|
738
741
|
|
739
742
|
# If predicate is a symbol, looks up the predicate in the predicate_mappings
|
740
743
|
# If predicate is not a Symbol, returns the predicate untouched
|
741
|
-
# @
|
744
|
+
# @raise UnregisteredPredicateError if the predicate is a symbol but is not found in the predicate_mappings
|
742
745
|
def predicate_lookup(predicate,namespace="info:fedora/fedora-system:def/relations-external#")
|
743
746
|
if predicate.class == Symbol
|
744
747
|
if predicate_mappings[namespace].has_key?(predicate)
|
data/lib/fedora/base.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'xmlsimple'
|
2
2
|
|
3
3
|
class Hash
|
4
|
-
|
5
|
-
#
|
4
|
+
|
5
|
+
# Produces a valid Fedora query based on the current hash
|
6
|
+
# @example
|
7
|
+
# {:q => 'test', :num => 5}.to_fedora_query # => 'q=test&num=5'
|
6
8
|
def to_fedora_query
|
7
9
|
self.collect { |key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}" }.sort * '&'
|
8
10
|
end
|
@@ -17,9 +19,7 @@ class Fedora::BaseObject
|
|
17
19
|
attr_reader :errors, :uri
|
18
20
|
attr_writer :new_object
|
19
21
|
|
20
|
-
#
|
21
|
-
# attrs<Hash>:: object attributes
|
22
|
-
#-
|
22
|
+
# @param [Hash] attrs object attributes
|
23
23
|
def initialize(attrs = {})
|
24
24
|
@new_object = true
|
25
25
|
@attributes = attrs || {}
|
data/lib/fedora/datastream.rb
CHANGED
@@ -49,7 +49,7 @@ class Fedora::Datastream < Fedora::BaseObject
|
|
49
49
|
"fedora:info/#{pid}/datastreams/#{dsid}"
|
50
50
|
end
|
51
51
|
|
52
|
-
# @
|
52
|
+
# @return [String] url of the datastream in Fedora, without the repository userinfo
|
53
53
|
def url
|
54
54
|
return "#{Fedora::Repository.instance.base_url}/objects/#{pid}/datastreams/#{dsid}"
|
55
55
|
end
|