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 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