dor-services 5.18.0 → 5.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|