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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2d0fea02b55ee4906b57a7f1ec29d281cd4441a
4
- data.tar.gz: 87963a5b75e157f4bb9bfd3aadefaf77b1945707
3
+ metadata.gz: 0dc1bf75851ebaf4b19feb92a2f1acf584dd6855
4
+ data.tar.gz: 0e075b4ab4cdb029fe3165d6612d51212586012d
5
5
  SHA512:
6
- metadata.gz: 3d97aa054071249c9980d50c382823395a8b1deaa0a76241166bb5d0c1d903e5a6b6d0cd619a6bb881d64907ac07ef7beba7f6efda267dc1d55c852a62099d6b
7
- data.tar.gz: f5c4680e39daa95b119771e1c6c0006b7e3189552637d4b20650008b2e5697d4b2c179f2ca85f6f518cb25532226b828e0fcf1039518e9546324c79ee70d9b4c
6
+ metadata.gz: 45a77bd472e8fa469edada87a30d474aecb5a895978545d271236be31b69da2016726c732fad2d827e45b49bf04cb976e27f118502f196d6de40789f2ac9f55d
7
+ data.tar.gz: 1805fcdcdd30cc35a2321c00b2a07fd8ecf506ef369fcf762ebcf2a625729b1f4d0a27b269ca005b9125a1a76f658b441e11bb26fca9aa7d4e31ac26db415d57
@@ -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.ensure_models_loaded! is unnecessary and has been deprecated.'
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
- return creative_commons unless creative_commons.blank?
205
- return open_data_commons unless open_data_commons.blank?
206
- nil
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 = descMetadata.ng_xml.dup(1)
50
- add_collection_reference(desc_md) if include_collection_as_related_item
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
- doc = descMetadata.ng_xml.dup(1)
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
- datastreams['events'].add_event('embargo', release_agent, 'Embargo released')
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
- datastreams['events'].add_event('embargo', release_agent, '20% Visibility Embargo released')
61
+ add_event('embargo', release_agent, '20% Visibility Embargo released')
62
62
  end
63
63
 
64
64
  def update_embargo(new_date)
@@ -2,8 +2,6 @@ module Dor
2
2
  module Geoable
3
3
  extend ActiveSupport::Concern
4
4
 
5
- class CrosswalkError < Exception; end
6
-
7
5
  included do
8
6
  has_metadata :name => 'geoMetadata',
9
7
  :type => Dor::GeoMetadataDS,
@@ -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.nil? || lane.strip == ''
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
- pub = Nokogiri::XML('<publicObject/>').root
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
- datastreams['events'].add_event('open', vmd_upd_info[:opening_user_name], "Version #{vmd_ds.current_version_id} opened")
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, opts = {})
12
- Dor.find_all(%(#{Solrizer.solr_name 'objectType', :symbol}:"#{object_type}" #{Solrizer.solr_name 'workflow_name', :symbol}:"#{name}"), opts).first
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
@@ -1,3 +1,3 @@
1
1
  module Dor
2
- VERSION = '5.18.0'.freeze
2
+ VERSION = '5.19.0'.freeze
3
3
  end
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.18.0
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-11-30 00:00:00.000000000 Z
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.1
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