dor-services 5.18.0 → 5.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dor-services.rb +3 -1
- data/lib/dor/datastreams/rights_metadata_ds.rb +7 -4
- data/lib/dor/models/concerns/describable.rb +8 -153
- data/lib/dor/models/concerns/embargoable.rb +2 -2
- data/lib/dor/models/concerns/geoable.rb +0 -2
- data/lib/dor/models/concerns/governable.rb +1 -2
- data/lib/dor/models/concerns/itemizable.rb +1 -1
- data/lib/dor/models/concerns/publishable.rb +1 -24
- data/lib/dor/models/concerns/releaseable.rb +0 -13
- data/lib/dor/models/concerns/versionable.rb +1 -1
- data/lib/dor/models/workflow_object.rb +2 -2
- data/lib/dor/services/public_desc_metadata_service.rb +174 -0
- data/lib/dor/services/public_xml_service.rb +52 -0
- data/lib/dor/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dc1bf75851ebaf4b19feb92a2f1acf584dd6855
|
4
|
+
data.tar.gz: 0e075b4ab4cdb029fe3165d6612d51212586012d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45a77bd472e8fa469edada87a30d474aecb5a895978545d271236be31b69da2016726c732fad2d827e45b49bf04cb976e27f118502f196d6de40789f2ac9f55d
|
7
|
+
data.tar.gz: 1805fcdcdd30cc35a2321c00b2a07fd8ecf506ef369fcf762ebcf2a625729b1f4d0a27b269ca005b9125a1a76f658b441e11bb26fca9aa7d4e31ac26db415d57
|
data/lib/dor-services.rb
CHANGED
@@ -37,7 +37,7 @@ module Dor
|
|
37
37
|
# TODO: return enumerable and lazy load_instance
|
38
38
|
# TODO: restrict fieldlist (fl) for non-:lightweight queries
|
39
39
|
def find_all(query, opts = {})
|
40
|
-
ActiveSupport::Deprecation.warn 'Dor.
|
40
|
+
ActiveSupport::Deprecation.warn 'Dor.find_all is deprecated; use activefedora finders instead'
|
41
41
|
|
42
42
|
resp = SearchService.query query, opts
|
43
43
|
resp['response']['docs'].collect do |solr_doc|
|
@@ -144,6 +144,8 @@ module Dor
|
|
144
144
|
autoload :MergeService, 'dor/services/merge_service'
|
145
145
|
autoload :ResetWorkspaceService, 'dor/services/reset_workspace_service'
|
146
146
|
autoload :CleanupResetService, 'dor/services/cleanup_reset_service'
|
147
|
+
autoload :PublicDescMetadataService, 'dor/services/public_desc_metadata_service'
|
148
|
+
autoload :PublicXmlService, 'dor/services/public_xml_service'
|
147
149
|
|
148
150
|
# Workflow Classes
|
149
151
|
module Workflow
|
@@ -195,15 +195,18 @@ module Dor
|
|
195
195
|
%w(use_statement_ssim copyright_ssim).each do |key|
|
196
196
|
solr_doc[key] = solr_doc[key].reject(&:blank?).flatten unless solr_doc[key].nil?
|
197
197
|
end
|
198
|
-
add_solr_value(solr_doc, 'use_license_machine', use_license, :string, [:stored_sortable])
|
198
|
+
add_solr_value(solr_doc, 'use_license_machine', use_license.first, :string, [:stored_sortable])
|
199
|
+
add_solr_value(solr_doc, 'use_licenses_machine', use_license, :symbol, [:stored_searchable])
|
199
200
|
|
200
201
|
solr_doc
|
201
202
|
end
|
202
203
|
|
203
204
|
def use_license
|
204
|
-
|
205
|
-
|
206
|
-
|
205
|
+
use_license = []
|
206
|
+
use_license += Array(creative_commons)
|
207
|
+
use_license += Array(open_data_commons)
|
208
|
+
|
209
|
+
use_license.reject(&:blank?)
|
207
210
|
end
|
208
211
|
|
209
212
|
# maintain AF < 8 indexing behavior
|
@@ -46,8 +46,12 @@ module Dor
|
|
46
46
|
# @raise [CrosswalkError] Raises an Exception if the generated DC is empty or has no children
|
47
47
|
# @return [Nokogiri::Doc] the DublinCore XML document object
|
48
48
|
def generate_dublin_core(include_collection_as_related_item: true)
|
49
|
-
desc_md =
|
50
|
-
|
49
|
+
desc_md = if include_collection_as_related_item
|
50
|
+
Nokogiri::XML(generate_public_desc_md(include_access_conditions: false))
|
51
|
+
else
|
52
|
+
descMetadata.ng_xml
|
53
|
+
end
|
54
|
+
|
51
55
|
dc_doc = MODS_TO_DC_XSLT.transform(desc_md)
|
52
56
|
dc_doc.xpath('/oai_dc:dc/*[count(text()) = 0]', oai_dc: XMLNS_OAI_DC).remove # Remove empty nodes
|
53
57
|
raise CrosswalkError, "Dor::Item#generate_dublin_core produced incorrect xml (no root):\n#{dc_doc.to_xml}" if dc_doc.root.nil?
|
@@ -56,146 +60,8 @@ module Dor
|
|
56
60
|
end
|
57
61
|
|
58
62
|
# @return [String] Public descriptive medatada XML
|
59
|
-
def generate_public_desc_md
|
60
|
-
|
61
|
-
add_collection_reference(doc)
|
62
|
-
add_access_conditions(doc)
|
63
|
-
add_constituent_relations(doc)
|
64
|
-
doc.xpath('//comment()').remove
|
65
|
-
new_doc = Nokogiri::XML(doc.to_xml) { |x| x.noblanks }
|
66
|
-
new_doc.encoding = 'UTF-8'
|
67
|
-
new_doc.to_xml
|
68
|
-
end
|
69
|
-
|
70
|
-
# Create MODS accessCondition statements from rightsMetadata
|
71
|
-
# @param [Nokogiri::XML::Document] doc Document representing the descriptiveMetadata of the object
|
72
|
-
# @note this method modifies the passed in doc
|
73
|
-
def add_access_conditions(doc)
|
74
|
-
# clear out any existing accessConditions
|
75
|
-
doc.xpath('//mods:accessCondition', 'mods' => 'http://www.loc.gov/mods/v3').each {|n| n.remove}
|
76
|
-
rights = datastreams['rightsMetadata'].ng_xml
|
77
|
-
|
78
|
-
rights.xpath('//use/human[@type="useAndReproduction"]').each do |use|
|
79
|
-
txt = use.text.strip
|
80
|
-
next if txt.empty?
|
81
|
-
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', txt, :type => 'useAndReproduction')
|
82
|
-
end
|
83
|
-
rights.xpath('//copyright/human[@type="copyright"]').each do |cr|
|
84
|
-
txt = cr.text.strip
|
85
|
-
next if txt.empty?
|
86
|
-
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', txt, :type => 'copyright')
|
87
|
-
end
|
88
|
-
rights.xpath("//use/machine[#{ci_compare('type', 'creativecommons')}]").each do |lic_type|
|
89
|
-
next if lic_type.text =~ /none/i
|
90
|
-
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'creativecommons')}]").text.strip
|
91
|
-
next if lic_text.empty?
|
92
|
-
new_text = "CC #{lic_type.text}: #{lic_text}"
|
93
|
-
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', new_text, :type => 'license')
|
94
|
-
end
|
95
|
-
rights.xpath("//use/machine[#{ci_compare('type', 'opendatacommons')}]").each do |lic_type|
|
96
|
-
next if lic_type.text =~ /none/i
|
97
|
-
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'opendatacommons')}]").text.strip
|
98
|
-
next if lic_text.empty?
|
99
|
-
new_text = "ODC #{lic_type.text}: #{lic_text}"
|
100
|
-
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', new_text, :type => 'license')
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Remove existing relatedItem entries for collections from descMetadata
|
105
|
-
def remove_related_item_nodes_for_collections(doc)
|
106
|
-
doc.search('/mods:mods/mods:relatedItem[@type="host"]/mods:typeOfResource[@collection=\'yes\']', 'mods' => 'http://www.loc.gov/mods/v3').each do |node|
|
107
|
-
node.parent.remove
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def add_related_item_node_for_collection(doc, collection_druid)
|
112
|
-
begin
|
113
|
-
collection_obj = Dor.find(collection_druid)
|
114
|
-
rescue ActiveFedora::ObjectNotFoundError
|
115
|
-
return nil
|
116
|
-
end
|
117
|
-
|
118
|
-
title_node = Nokogiri::XML::Node.new('title', doc)
|
119
|
-
title_node.content = Dor::Describable.get_collection_title(collection_obj)
|
120
|
-
|
121
|
-
title_info_node = Nokogiri::XML::Node.new('titleInfo', doc)
|
122
|
-
title_info_node.add_child(title_node)
|
123
|
-
|
124
|
-
# e.g.:
|
125
|
-
# <location>
|
126
|
-
# <url>http://purl.stanford.edu/rh056sr3313</url>
|
127
|
-
# </location>
|
128
|
-
loc_node = doc.create_element('location')
|
129
|
-
url_node = doc.create_element('url')
|
130
|
-
url_node.content = "https://#{Dor::Config.stacks.document_cache_host}/#{collection_druid.split(':').last}"
|
131
|
-
loc_node << url_node
|
132
|
-
|
133
|
-
type_node = Nokogiri::XML::Node.new('typeOfResource', doc)
|
134
|
-
type_node['collection'] = 'yes'
|
135
|
-
|
136
|
-
related_item_node = Nokogiri::XML::Node.new('relatedItem', doc)
|
137
|
-
related_item_node['type'] = 'host'
|
138
|
-
|
139
|
-
related_item_node.add_child(title_info_node)
|
140
|
-
related_item_node.add_child(loc_node)
|
141
|
-
related_item_node.add_child(type_node)
|
142
|
-
|
143
|
-
doc.root.add_child(related_item_node)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Adds to desc metadata a relatedItem with information about the collection this object belongs to.
|
147
|
-
# For use in published mods and mods-to-DC conversion.
|
148
|
-
# @param [Nokogiri::XML::Document] doc A copy of the descriptiveMetadata of the object, to be modified
|
149
|
-
# @return [Void]
|
150
|
-
# @note this method modifies the passed in doc
|
151
|
-
def add_collection_reference(doc)
|
152
|
-
return unless methods.include? :public_relationships
|
153
|
-
collections = public_relationships.search('//rdf:RDF/rdf:Description/fedora:isMemberOfCollection',
|
154
|
-
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
155
|
-
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
|
156
|
-
return if collections.empty?
|
157
|
-
|
158
|
-
remove_related_item_nodes_for_collections(doc)
|
159
|
-
|
160
|
-
collections.each do |collection_node|
|
161
|
-
collection_druid = collection_node['rdf:resource'].gsub('info:fedora/', '')
|
162
|
-
add_related_item_node_for_collection(doc, collection_druid)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
# expand constituent relations into relatedItem references -- see JUMBO-18
|
167
|
-
# @param [Nokogiri::XML] doc public MODS XML being built
|
168
|
-
# @return [Void]
|
169
|
-
def add_constituent_relations(doc)
|
170
|
-
public_relationships.search('//rdf:RDF/rdf:Description/fedora:isConstituentOf',
|
171
|
-
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
172
|
-
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' ).each do |parent|
|
173
|
-
# fetch the parent object to get title
|
174
|
-
druid = parent['rdf:resource'].gsub(/^info:fedora\//, '')
|
175
|
-
parent_item = Dor.find(druid)
|
176
|
-
|
177
|
-
# create the MODS relation
|
178
|
-
relatedItem = doc.create_element 'relatedItem'
|
179
|
-
relatedItem['type'] = 'host'
|
180
|
-
relatedItem['displayLabel'] = 'Appears in'
|
181
|
-
|
182
|
-
# load the title from the parent's DC.title
|
183
|
-
titleInfo = doc.create_element 'titleInfo'
|
184
|
-
title = doc.create_element 'title'
|
185
|
-
title.content = Dor::Describable.get_collection_title(parent_item)
|
186
|
-
titleInfo << title
|
187
|
-
relatedItem << titleInfo
|
188
|
-
|
189
|
-
# point to the PURL for the parent
|
190
|
-
location = doc.create_element 'location'
|
191
|
-
url = doc.create_element 'url'
|
192
|
-
url.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
|
193
|
-
location << url
|
194
|
-
relatedItem << location
|
195
|
-
|
196
|
-
# finish up by adding relation to public MODS
|
197
|
-
doc.root << relatedItem
|
198
|
-
end
|
63
|
+
def generate_public_desc_md(**options)
|
64
|
+
PublicDescMetadataService.new(self).to_xml(**options)
|
199
65
|
end
|
200
66
|
|
201
67
|
def to_solr(solr_doc = {}, *args)
|
@@ -297,16 +163,5 @@ module Dor
|
|
297
163
|
def full_title
|
298
164
|
stanford_mods.sw_title_display
|
299
165
|
end
|
300
|
-
|
301
|
-
private
|
302
|
-
|
303
|
-
# Builds case-insensitive xpath translate function call that will match the attribute to a value
|
304
|
-
def ci_compare(attribute, value)
|
305
|
-
"translate(
|
306
|
-
@#{attribute},
|
307
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
308
|
-
'abcdefghijklmnopqrstuvwxyz'
|
309
|
-
) = '#{value}' "
|
310
|
-
end
|
311
166
|
end
|
312
167
|
end
|
@@ -36,7 +36,7 @@ module Dor
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
add_event('embargo', release_agent, 'Embargo released')
|
40
40
|
end
|
41
41
|
|
42
42
|
def release_20_pct_vis_embargo(release_agent = 'unknown')
|
@@ -58,7 +58,7 @@ module Dor
|
|
58
58
|
rights_xml.root.add_child(world_doc.root.clone)
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
add_event('embargo', release_agent, '20% Visibility Embargo released')
|
62
62
|
end
|
63
63
|
|
64
64
|
def update_embargo(new_date)
|
@@ -19,9 +19,8 @@ module Dor
|
|
19
19
|
return 'default' if admin_policy_object.nil? # TODO: log warning?
|
20
20
|
|
21
21
|
admin_md = admin_policy_object.datastreams['administrativeMetadata']
|
22
|
-
return 'default' unless admin_md.respond_to? :default_workflow_lane
|
23
22
|
lane = admin_md.default_workflow_lane
|
24
|
-
return 'default' if lane.
|
23
|
+
return 'default' if lane.blank?
|
25
24
|
lane
|
26
25
|
end
|
27
26
|
|
@@ -31,7 +31,7 @@ module Dor
|
|
31
31
|
raise Dor::ParameterError, 'Missing Dor::Config.stacks.local_workspace_root'
|
32
32
|
end
|
33
33
|
|
34
|
-
if contentMetadata.nil?
|
34
|
+
if !respond_to?(:contentMetadata) || contentMetadata.nil?
|
35
35
|
raise Dor::Exception, 'Missing contentMetadata datastream'
|
36
36
|
end
|
37
37
|
|
@@ -73,30 +73,7 @@ module Dor
|
|
73
73
|
# Generate the public .xml for a PURL page.
|
74
74
|
# @return [xml] The public xml for the item
|
75
75
|
def public_xml
|
76
|
-
|
77
|
-
pub['id'] = pid
|
78
|
-
pub['published'] = Time.now.utc.xmlschema
|
79
|
-
pub['publishVersion'] = 'dor-services/' + Dor::VERSION
|
80
|
-
release_xml = Nokogiri(generate_release_xml).xpath('//release')
|
81
|
-
|
82
|
-
im = datastreams['identityMetadata'].ng_xml.clone
|
83
|
-
im.search('//release').each(&:remove) # remove any <release> tags from public xml which have full history
|
84
|
-
|
85
|
-
pub.add_child(im.root) # add in modified identityMetadata datastream
|
86
|
-
pub.add_child(datastreams['contentMetadata'].public_xml.root.clone)
|
87
|
-
pub.add_child(datastreams['rightsMetadata'].ng_xml.root.clone)
|
88
|
-
|
89
|
-
rels = public_relationships.root
|
90
|
-
pub.add_child(rels.clone) unless rels.nil? # TODO: Should never be nil in practice; working around an ActiveFedora quirk for testing
|
91
|
-
pub.add_child(generate_dublin_core.root.clone)
|
92
|
-
pub.add_child(Nokogiri::XML(generate_public_desc_md).root.clone)
|
93
|
-
pub.add_child(Nokogiri(generate_release_xml).root.clone) unless release_xml.children.size == 0 # If there are no release_tags, this prevents an empty <releaseData/> from being added
|
94
|
-
# Note we cannot base this on if an individual object has release tags or not, because the collection may cause one to be generated for an item,
|
95
|
-
# so we need to calculate it and then look at the final result.s
|
96
|
-
pub.add_child(Nokogiri("<thumb>#{thumb}</thumb>").root.clone) unless thumb.nil?
|
97
|
-
new_pub = Nokogiri::XML(pub.to_xml) { |x| x.noblanks }
|
98
|
-
new_pub.encoding = 'UTF-8'
|
99
|
-
new_pub.to_xml
|
76
|
+
PublicXmlService.new(self).to_xml
|
100
77
|
end
|
101
78
|
|
102
79
|
# Copies this object's public_xml to the Purl document cache if it is world discoverable
|
@@ -22,19 +22,6 @@ module Dor
|
|
22
22
|
create_workflow('releaseWF')
|
23
23
|
end
|
24
24
|
|
25
|
-
# Generate XML structure for inclusion to Purl
|
26
|
-
# @return [String] The XML release node as a string, with ReleaseDigest as the root document
|
27
|
-
def generate_release_xml
|
28
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
29
|
-
xml.releaseData {
|
30
|
-
released_for.each do |project, released_value|
|
31
|
-
xml.release(released_value['release'], :to => project)
|
32
|
-
end
|
33
|
-
}
|
34
|
-
end
|
35
|
-
builder.to_xml
|
36
|
-
end
|
37
|
-
|
38
25
|
# Determine projects in which an item is released
|
39
26
|
# @param [Boolean] skip_live_purl set true to skip requesting from purl backend
|
40
27
|
# @return [Hash{String => Boolean}] all namespaces, keys are Project name Strings, values are Boolean
|
@@ -35,7 +35,7 @@ module Dor
|
|
35
35
|
|
36
36
|
vmd_upd_info = opts[:vers_md_upd_info]
|
37
37
|
return unless vmd_upd_info
|
38
|
-
|
38
|
+
add_event('open', vmd_upd_info[:opening_user_name], "Version #{vmd_ds.current_version_id} opened")
|
39
39
|
vmd_ds.update_current_version({:description => vmd_upd_info[:description], :significance => vmd_upd_info[:significance].to_sym})
|
40
40
|
save
|
41
41
|
end
|
@@ -8,8 +8,8 @@ module Dor
|
|
8
8
|
has_object_type 'workflow'
|
9
9
|
has_metadata :name => 'workflowDefinition', :type => Dor::WorkflowDefinitionDs, :label => 'Workflow Definition'
|
10
10
|
|
11
|
-
def self.find_by_name(name
|
12
|
-
Dor.
|
11
|
+
def self.find_by_name(name)
|
12
|
+
Dor::WorkflowObject.where(Solrizer.solr_name('workflow_name', :symbol) => name).first
|
13
13
|
end
|
14
14
|
|
15
15
|
# Searches for the workflow definition object in DOR, then
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Dor
|
2
|
+
class PublicDescMetadataService
|
3
|
+
attr_reader :object
|
4
|
+
|
5
|
+
NOKOGIRI_DEEP_COPY = 1
|
6
|
+
|
7
|
+
def initialize(object)
|
8
|
+
@object = object
|
9
|
+
end
|
10
|
+
|
11
|
+
def doc
|
12
|
+
@doc ||= object.descMetadata.ng_xml.dup(NOKOGIRI_DEEP_COPY)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] Public descriptive medatada XML
|
16
|
+
def to_xml(include_access_conditions: true)
|
17
|
+
add_collection_reference!
|
18
|
+
add_access_conditions! if include_access_conditions
|
19
|
+
add_constituent_relations!
|
20
|
+
strip_comments!
|
21
|
+
|
22
|
+
new_doc = Nokogiri::XML(doc.to_xml) { |x| x.noblanks }
|
23
|
+
new_doc.encoding = 'UTF-8'
|
24
|
+
new_doc.to_xml
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def strip_comments!
|
30
|
+
doc.xpath('//comment()').remove
|
31
|
+
end
|
32
|
+
|
33
|
+
# Create MODS accessCondition statements from rightsMetadata
|
34
|
+
# @param [Nokogiri::XML::Document] doc Document representing the descriptiveMetadata of the object
|
35
|
+
# @note this method modifies the passed in doc
|
36
|
+
def add_access_conditions!
|
37
|
+
# clear out any existing accessConditions
|
38
|
+
doc.xpath('//mods:accessCondition', 'mods' => 'http://www.loc.gov/mods/v3').each {|n| n.remove}
|
39
|
+
rights = object.datastreams['rightsMetadata'].ng_xml
|
40
|
+
|
41
|
+
rights.xpath('//use/human[@type="useAndReproduction"]').each do |use|
|
42
|
+
txt = use.text.strip
|
43
|
+
next if txt.empty?
|
44
|
+
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', txt, :type => 'useAndReproduction')
|
45
|
+
end
|
46
|
+
rights.xpath('//copyright/human[@type="copyright"]').each do |cr|
|
47
|
+
txt = cr.text.strip
|
48
|
+
next if txt.empty?
|
49
|
+
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', txt, :type => 'copyright')
|
50
|
+
end
|
51
|
+
rights.xpath("//use/machine[#{ci_compare('type', 'creativecommons')}]").each do |lic_type|
|
52
|
+
next if lic_type.text =~ /none/i
|
53
|
+
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'creativecommons')}]").text.strip
|
54
|
+
next if lic_text.empty?
|
55
|
+
new_text = "CC #{lic_type.text}: #{lic_text}"
|
56
|
+
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', new_text, :type => 'license')
|
57
|
+
end
|
58
|
+
rights.xpath("//use/machine[#{ci_compare('type', 'opendatacommons')}]").each do |lic_type|
|
59
|
+
next if lic_type.text =~ /none/i
|
60
|
+
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'opendatacommons')}]").text.strip
|
61
|
+
next if lic_text.empty?
|
62
|
+
new_text = "ODC #{lic_type.text}: #{lic_text}"
|
63
|
+
doc.root.element_children.last.add_next_sibling doc.create_element('accessCondition', new_text, :type => 'license')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# expand constituent relations into relatedItem references -- see JUMBO-18
|
68
|
+
# @param [Nokogiri::XML] doc public MODS XML being built
|
69
|
+
# @return [Void]
|
70
|
+
def add_constituent_relations!
|
71
|
+
object.public_relationships.search('//rdf:RDF/rdf:Description/fedora:isConstituentOf',
|
72
|
+
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
73
|
+
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' ).each do |parent|
|
74
|
+
# fetch the parent object to get title
|
75
|
+
druid = parent['rdf:resource'].gsub(/^info:fedora\//, '')
|
76
|
+
parent_item = Dor.find(druid)
|
77
|
+
|
78
|
+
# create the MODS relation
|
79
|
+
relatedItem = doc.create_element 'relatedItem'
|
80
|
+
relatedItem['type'] = 'host'
|
81
|
+
relatedItem['displayLabel'] = 'Appears in'
|
82
|
+
|
83
|
+
# load the title from the parent's DC.title
|
84
|
+
titleInfo = doc.create_element 'titleInfo'
|
85
|
+
title = doc.create_element 'title'
|
86
|
+
title.content = Dor::Describable.get_collection_title(parent_item)
|
87
|
+
titleInfo << title
|
88
|
+
relatedItem << titleInfo
|
89
|
+
|
90
|
+
# point to the PURL for the parent
|
91
|
+
location = doc.create_element 'location'
|
92
|
+
url = doc.create_element 'url'
|
93
|
+
url.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
|
94
|
+
location << url
|
95
|
+
relatedItem << location
|
96
|
+
|
97
|
+
# finish up by adding relation to public MODS
|
98
|
+
doc.root << relatedItem
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Adds to desc metadata a relatedItem with information about the collection this object belongs to.
|
103
|
+
# For use in published mods and mods-to-DC conversion.
|
104
|
+
# @param [Nokogiri::XML::Document] doc A copy of the descriptiveMetadata of the object, to be modified
|
105
|
+
# @return [Void]
|
106
|
+
# @note this method modifies the passed in doc
|
107
|
+
def add_collection_reference!
|
108
|
+
collections = object.public_relationships.search('//rdf:RDF/rdf:Description/fedora:isMemberOfCollection',
|
109
|
+
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
110
|
+
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
|
111
|
+
return if collections.empty?
|
112
|
+
|
113
|
+
remove_related_item_nodes_for_collections!
|
114
|
+
|
115
|
+
collections.each do |collection_node|
|
116
|
+
collection_druid = collection_node['rdf:resource'].gsub('info:fedora/', '')
|
117
|
+
add_related_item_node_for_collection! collection_druid
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Remove existing relatedItem entries for collections from descMetadata
|
122
|
+
def remove_related_item_nodes_for_collections!
|
123
|
+
doc.search('/mods:mods/mods:relatedItem[@type="host"]/mods:typeOfResource[@collection=\'yes\']', 'mods' => 'http://www.loc.gov/mods/v3').each do |node|
|
124
|
+
node.parent.remove
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_related_item_node_for_collection! collection_druid
|
129
|
+
begin
|
130
|
+
collection_obj = Dor.find(collection_druid)
|
131
|
+
rescue ActiveFedora::ObjectNotFoundError
|
132
|
+
return nil
|
133
|
+
end
|
134
|
+
|
135
|
+
title_node = Nokogiri::XML::Node.new('title', doc)
|
136
|
+
title_node.content = Dor::Describable.get_collection_title(collection_obj)
|
137
|
+
|
138
|
+
title_info_node = Nokogiri::XML::Node.new('titleInfo', doc)
|
139
|
+
title_info_node.add_child(title_node)
|
140
|
+
|
141
|
+
# e.g.:
|
142
|
+
# <location>
|
143
|
+
# <url>http://purl.stanford.edu/rh056sr3313</url>
|
144
|
+
# </location>
|
145
|
+
loc_node = doc.create_element('location')
|
146
|
+
url_node = doc.create_element('url')
|
147
|
+
url_node.content = "https://#{Dor::Config.stacks.document_cache_host}/#{collection_druid.split(':').last}"
|
148
|
+
loc_node << url_node
|
149
|
+
|
150
|
+
type_node = Nokogiri::XML::Node.new('typeOfResource', doc)
|
151
|
+
type_node['collection'] = 'yes'
|
152
|
+
|
153
|
+
related_item_node = Nokogiri::XML::Node.new('relatedItem', doc)
|
154
|
+
related_item_node['type'] = 'host'
|
155
|
+
|
156
|
+
related_item_node.add_child(title_info_node)
|
157
|
+
related_item_node.add_child(loc_node)
|
158
|
+
related_item_node.add_child(type_node)
|
159
|
+
|
160
|
+
doc.root.add_child(related_item_node)
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
# Builds case-insensitive xpath translate function call that will match the attribute to a value
|
166
|
+
def ci_compare(attribute, value)
|
167
|
+
"translate(
|
168
|
+
@#{attribute},
|
169
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
170
|
+
'abcdefghijklmnopqrstuvwxyz'
|
171
|
+
) = '#{value}' "
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Dor
|
2
|
+
class PublicXmlService
|
3
|
+
attr_reader :object
|
4
|
+
|
5
|
+
def initialize(object)
|
6
|
+
@object = object
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_xml
|
10
|
+
pub = Nokogiri::XML('<publicObject/>').root
|
11
|
+
pub['id'] = object.pid
|
12
|
+
pub['published'] = Time.now.utc.xmlschema
|
13
|
+
pub['publishVersion'] = 'dor-services/' + Dor::VERSION
|
14
|
+
release_xml = Nokogiri(generate_release_xml)
|
15
|
+
|
16
|
+
im = object.datastreams['identityMetadata'].ng_xml.clone
|
17
|
+
im.search('//release').each(&:remove) # remove any <release> tags from public xml which have full history
|
18
|
+
|
19
|
+
pub.add_child(im.root) # add in modified identityMetadata datastream
|
20
|
+
public_content_metadata = object.datastreams['contentMetadata'].public_xml
|
21
|
+
pub.add_child(public_content_metadata.root.clone) if public_content_metadata.xpath('//resource').any?
|
22
|
+
pub.add_child(object.datastreams['rightsMetadata'].ng_xml.root.clone)
|
23
|
+
|
24
|
+
rels = object.public_relationships.root
|
25
|
+
pub.add_child(rels.clone) unless rels.nil? # TODO: Should never be nil in practice; working around an ActiveFedora quirk for testing
|
26
|
+
pub.add_child(object.generate_dublin_core.root.clone)
|
27
|
+
pub.add_child(Nokogiri::XML(object.generate_public_desc_md).root.clone)
|
28
|
+
pub.add_child(release_xml.root.clone) unless release_xml.xpath('//release').children.size == 0 # If there are no release_tags, this prevents an empty <releaseData/> from being added
|
29
|
+
# Note we cannot base this on if an individual object has release tags or not, because the collection may cause one to be generated for an item,
|
30
|
+
# so we need to calculate it and then look at the final result.s
|
31
|
+
pub.add_child(Nokogiri("<thumb>#{object.thumb}</thumb>").root.clone) unless object.thumb.nil?
|
32
|
+
|
33
|
+
new_pub = Nokogiri::XML(pub.to_xml) { |x| x.noblanks }
|
34
|
+
new_pub.encoding = 'UTF-8'
|
35
|
+
new_pub.to_xml
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Generate XML structure for inclusion to Purl
|
40
|
+
# @return [String] The XML release node as a string, with ReleaseDigest as the root document
|
41
|
+
def generate_release_xml
|
42
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
43
|
+
xml.releaseData {
|
44
|
+
object.released_for.each do |project, released_value|
|
45
|
+
xml.release(released_value['release'], :to => project)
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
builder.to_xml
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/dor/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Klein
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2016-
|
17
|
+
date: 2016-12-06 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: active-fedora
|
@@ -643,6 +643,8 @@ files:
|
|
643
643
|
- lib/dor/services/merge_service.rb
|
644
644
|
- lib/dor/services/metadata_handlers/catalog_handler.rb
|
645
645
|
- lib/dor/services/metadata_service.rb
|
646
|
+
- lib/dor/services/public_desc_metadata_service.rb
|
647
|
+
- lib/dor/services/public_xml_service.rb
|
646
648
|
- lib/dor/services/registration_service.rb
|
647
649
|
- lib/dor/services/reset_workspace_service.rb
|
648
650
|
- lib/dor/services/sdr_ingest_service.rb
|
@@ -679,7 +681,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
679
681
|
version: 1.3.6
|
680
682
|
requirements: []
|
681
683
|
rubyforge_project:
|
682
|
-
rubygems_version: 2.5.
|
684
|
+
rubygems_version: 2.5.2
|
683
685
|
signing_key:
|
684
686
|
specification_version: 4
|
685
687
|
summary: Ruby implmentation of DOR services used by the SULAIR Digital Library
|