dor-services 5.2.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -13
  2. data/config/certs/robots-dor-dev.crt +29 -0
  3. data/config/certs/robots-dor-dev.key +27 -0
  4. data/config/config_defaults.yml +2 -0
  5. data/config/dev_console_env.rb +77 -0
  6. data/lib/dor-services.rb +31 -27
  7. data/lib/dor/config.rb +25 -19
  8. data/lib/dor/datastreams/administrative_metadata_ds.rb +19 -20
  9. data/lib/dor/datastreams/content_metadata_ds.rb +238 -177
  10. data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
  11. data/lib/dor/datastreams/default_object_rights_ds.rb +99 -16
  12. data/lib/dor/datastreams/desc_metadata_ds.rb +37 -34
  13. data/lib/dor/datastreams/embargo_metadata_ds.rb +16 -16
  14. data/lib/dor/datastreams/events_ds.rb +2 -2
  15. data/lib/dor/datastreams/geo_metadata_ds.rb +5 -10
  16. data/lib/dor/datastreams/identity_metadata_ds.rb +22 -22
  17. data/lib/dor/datastreams/rights_metadata_ds.rb +43 -32
  18. data/lib/dor/datastreams/role_metadata_ds.rb +5 -5
  19. data/lib/dor/datastreams/simple_dublin_core_ds.rb +13 -14
  20. data/lib/dor/datastreams/version_metadata_ds.rb +22 -23
  21. data/lib/dor/datastreams/workflow_definition_ds.rb +15 -15
  22. data/lib/dor/datastreams/workflow_ds.rb +64 -70
  23. data/lib/dor/exceptions.rb +0 -1
  24. data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +4 -4
  25. data/lib/dor/migrations/processable/unify_workflows.rb +1 -1
  26. data/lib/dor/models/admin_policy_object.rb +4 -4
  27. data/lib/dor/models/assembleable.rb +2 -3
  28. data/lib/dor/models/collection.rb +1 -1
  29. data/lib/dor/models/contentable.rb +113 -108
  30. data/lib/dor/models/describable.rb +136 -95
  31. data/lib/dor/models/editable.rb +205 -119
  32. data/lib/dor/models/embargoable.rb +16 -16
  33. data/lib/dor/models/eventable.rb +2 -2
  34. data/lib/dor/models/geoable.rb +3 -3
  35. data/lib/dor/models/governable.rb +25 -26
  36. data/lib/dor/models/identifiable.rb +66 -55
  37. data/lib/dor/models/item.rb +0 -1
  38. data/lib/dor/models/itemizable.rb +7 -8
  39. data/lib/dor/models/preservable.rb +7 -8
  40. data/lib/dor/models/processable.rb +76 -73
  41. data/lib/dor/models/publishable.rb +25 -30
  42. data/lib/dor/models/releaseable.rb +118 -155
  43. data/lib/dor/models/rightsable.rb +2 -3
  44. data/lib/dor/models/set.rb +1 -1
  45. data/lib/dor/models/shelvable.rb +8 -10
  46. data/lib/dor/models/upgradable.rb +5 -6
  47. data/lib/dor/models/versionable.rb +3 -4
  48. data/lib/dor/models/workflow_object.rb +15 -16
  49. data/lib/dor/services/cleanup_reset_service.rb +15 -16
  50. data/lib/dor/services/cleanup_service.rb +2 -4
  51. data/lib/dor/services/digital_stacks_service.rb +10 -13
  52. data/lib/dor/services/merge_service.rb +8 -9
  53. data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
  54. data/lib/dor/services/metadata_handlers/mdtoolkit_handler.rb +3 -3
  55. data/lib/dor/services/metadata_service.rb +19 -20
  56. data/lib/dor/services/registration_service.rb +80 -61
  57. data/lib/dor/services/reset_workspace_service.rb +6 -10
  58. data/lib/dor/services/sdr_ingest_service.rb +15 -16
  59. data/lib/dor/services/search_service.rb +18 -23
  60. data/lib/dor/services/suri_service.rb +6 -6
  61. data/lib/dor/services/technical_metadata_service.rb +27 -44
  62. data/lib/dor/utils/ng_tidy.rb +3 -3
  63. data/lib/dor/utils/sdr_client.rb +2 -3
  64. data/lib/dor/utils/solr_doc_helper.rb +1 -3
  65. data/lib/dor/version.rb +1 -1
  66. data/lib/dor/workflow/document.rb +43 -40
  67. data/lib/dor/workflow/graph.rb +26 -26
  68. data/lib/dor/workflow/process.rb +34 -35
  69. data/lib/tasks/rdoc.rake +5 -5
  70. metadata +129 -111
  71. data/lib/dor/models/presentable.rb +0 -146
@@ -1,7 +1,6 @@
1
1
  module Dor
2
2
  class ContentMetadataDS < ActiveFedora::OmDatastream
3
3
  include Upgradable
4
- include SolrDocHelper
5
4
 
6
5
  set_terminology do |t|
7
6
  t.root :path => 'contentMetadata', :index_as => [:not_searchable]
@@ -9,7 +8,7 @@ module Dor
9
8
  t.stacks :path => '/contentMetadata/@stacks', :index_as => [:not_searchable]
10
9
  t.resource(:index_as => [:not_searchable]) do
11
10
  t.id_ :path => { :attribute => 'id' }
12
- t.sequence :path => { :attribute => 'sequence' } #, :data_type => :integer
11
+ t.sequence :path => { :attribute => 'sequence' } # , :data_type => :integer
13
12
  t.type_ :path => { :attribute => 'type' }, :index_as => [:displayable]
14
13
  t.attribute(:path => 'attr', :index_as => [:not_searchable]) do
15
14
  t.name :path => { :attribute => 'name' }, :index_as => [:not_searchable]
@@ -18,36 +17,121 @@ module Dor
18
17
  t.id_ :path => { :attribute => 'id' }
19
18
  t.mimeType :path => { :attribute => 'mimeType' }, :index_as => [:displayable]
20
19
  t.dataType :path => { :attribute => 'dataType' }, :index_as => [:displayable]
21
- t.size :path => { :attribute => 'size' }, :index_as => [:displayable] #, :data_type => :long
22
- t.shelve :path => { :attribute => 'shelve' }, :index_as => [:not_searchable] #, :data_type => :boolean
23
- t.publish :path => { :attribute => 'publish' }, :index_as => [:not_searchable] #, :data_type => :boolean
24
- t.preserve :path => { :attribute => 'preserve' }, :index_as => [:not_searchable] #, :data_type => :boolean
20
+ t.size :path => { :attribute => 'size' }, :index_as => [:displayable] # , :data_type => :long
21
+ t.shelve :path => { :attribute => 'shelve' }, :index_as => [:not_searchable] # , :data_type => :boolean
22
+ t.publish :path => { :attribute => 'publish' }, :index_as => [:not_searchable] # , :data_type => :boolean
23
+ t.preserve :path => { :attribute => 'preserve' }, :index_as => [:not_searchable] # , :data_type => :boolean
25
24
  t.checksum do
26
25
  t.type_ :path => { :attribute => 'type' }
27
26
  end
28
27
  end
29
- t.shelved_file(:path => 'file', :attributes => {:shelve=>'yes'}, :index_as => [:not_searchable]) do
28
+ t.shelved_file(:path => 'file', :attributes => {:shelve => 'yes'}, :index_as => [:not_searchable]) do
30
29
  t.id_ :path => { :attribute => 'id' }, :index_as => [:displayable, :stored_searchable]
31
30
  end
32
31
  end
33
32
  t.shelved_file_id :proxy => [:resource, :shelved_file, :id], :index_as => [:displayable, :stored_searchable]
34
33
  end
35
34
 
35
+ ### READ ONLY METHODS
36
+
37
+ # @return [Nokogiri::XML::Document] sanitized for public consumption
36
38
  def public_xml
37
- result = self.ng_xml.clone
38
- result.xpath('/contentMetadata/resource[not(file[(@deliver="yes" or @publish="yes")])]' ).each { |n| n.remove }
39
- result.xpath('/contentMetadata/resource/file[not(@deliver="yes" or @publish="yes")]' ).each { |n| n.remove }
40
- result.xpath('/contentMetadata/resource/file').xpath('@preserve|@shelve|@publish|@deliver').each { |n| n.remove }
41
- result.xpath('/contentMetadata/resource/file/checksum' ).each { |n| n.remove }
39
+ result = ng_xml.clone
40
+ result.xpath('/contentMetadata/resource[not(file[(@deliver="yes" or @publish="yes")])]' ).each(&:remove)
41
+ result.xpath('/contentMetadata/resource/file[not(@deliver="yes" or @publish="yes")]' ).each(&:remove)
42
+ result.xpath('/contentMetadata/resource/file').xpath('@preserve|@shelve|@publish|@deliver').each(&:remove)
43
+ result.xpath('/contentMetadata/resource/file/checksum' ).each(&:remove)
42
44
  result
43
45
  end
46
+
47
+ # Only use this when you want the behavior of raising an exception if anything besides exactly one matching node
48
+ # is found. Otherwise just use .xpath, .at_xpath or .search.
49
+ # @param xpath [String] accessor invocation for Nokogiri xpath
50
+ # @return [Nokogiri::XML::Element] the matched element
51
+ def singular_node(xpath)
52
+ node = ng_xml.search(xpath)
53
+ len = node.length
54
+ raise "#{xpath} not found" if len < 1
55
+ raise "#{xpath} duplicated: #{len} found" if len != 1
56
+ node.first
57
+ end
58
+
59
+ # Generates the XML tree for externalFile references. For example:
60
+ # <externalFile objectId="druid:mn123pq4567" resourceId="Image01" fileId="image_01.jp2000" mimetype="image/jp2" />
61
+ # @param [String] objectId the linked druid
62
+ # @param [String] resourceId the linked druid's resource identifier
63
+ # @param [String] fileId the linked druid's resource's file identifier
64
+ # @param [String] mimetype the file's MIME type
65
+ # @return [Nokogiri::XML::Element]
66
+ def generate_external_file_node(objectId, resourceId, fileId, mimetype)
67
+ externalFile = ng_xml.create_element 'externalFile'
68
+ externalFile[:objectId] = objectId
69
+ externalFile[:resourceId] = resourceId
70
+ externalFile[:fileId] = fileId
71
+ externalFile[:mimetype] = mimetype
72
+ externalFile
73
+ end
74
+
75
+ # Generates the XML tree for virtual resource relationship reference. For example:
76
+ # <relationship type="alsoAvailableAs" objectId="druid:mn123pq4567" />
77
+ # @param [String] objectId the linked druid
78
+ # @return [Nokogiri::XML::Element]
79
+ def generate_also_available_as_node(objectId)
80
+ relationship = ng_xml.create_element 'relationship'
81
+ relationship[:type] = 'alsoAvailableAs'
82
+ relationship[:objectId] = objectId
83
+ relationship
84
+ end
85
+
86
+ # Terminology-based solrization is going to be painfully slow for large
87
+ # contentMetadata streams. Just select the relevant elements instead.
88
+ # TODO: Call super()?
89
+ def to_solr(solr_doc = {}, *args)
90
+ doc = ng_xml
91
+ return solr_doc unless doc.root['type']
92
+
93
+ preserved_size = 0
94
+ counts = Hash.new(0) # default count is zero
95
+ resource_type_counts = Hash.new(0) # default count is zero
96
+ first_shelved_image = nil
97
+
98
+ doc.xpath('contentMetadata/resource').sort { |a, b| a['sequence'].to_i <=> b['sequence'].to_i }.each do |resource|
99
+ counts['resource'] += 1
100
+ resource_type_counts[resource['type']] += 1 if resource['type']
101
+ resource.xpath('file').each do |file|
102
+ counts['content_file'] += 1
103
+ preserved_size += file['size'].to_i if file['preserve'] == 'yes'
104
+ next unless file['shelve'] == 'yes'
105
+ counts['shelved_file'] += 1
106
+ first_shelved_image ||= file['id'] if file['id'].match(/jp2$/)
107
+ end
108
+ end
109
+ solr_doc['content_type_ssim' ] = doc.root['type']
110
+ solr_doc['content_file_count_itsi' ] = counts['content_file']
111
+ solr_doc['shelved_content_file_count_itsi'] = counts['shelved_file']
112
+ solr_doc['resource_count_itsi' ] = counts['resource']
113
+ solr_doc['preserved_size_dbtsi' ] = preserved_size # double (trie) to support very large sizes
114
+ solr_doc['resource_types_ssim' ] = resource_type_counts.keys if resource_type_counts.size > 0
115
+ resource_type_counts.each do |key, count|
116
+ solr_doc["#{key}_resource_count_itsi"] = count
117
+ end
118
+ # first_shelved_image is neither indexed nor multiple
119
+ solr_doc['first_shelved_image_ss'] = first_shelved_image unless first_shelved_image.nil?
120
+ solr_doc
121
+ end
122
+
123
+ ### END: READ ONLY METHODS
124
+ ### DATSTREAM WRITING METHODS
125
+
126
+ # @param [Object] file
127
+ # @param [String] resource_name
128
+ # @return [Nokogiri::XML::Node] the added XML node
44
129
  def add_file(file, resource_name)
45
- xml=self.ng_xml
46
- resource_nodes = xml.search('//resource[@id=\''+resource_name+'\']')
47
- raise 'resource doesnt exist.' if resource_nodes.length==0
48
- node=resource_nodes.first
49
- file_node=Nokogiri::XML::Node.new('file',xml)
50
- file_node['id']=file[:name]
130
+ resource_nodes = ng_xml.search('//resource[@id=\'' + resource_name + '\']')
131
+ raise 'resource doesnt exist.' if resource_nodes.length == 0
132
+ node = resource_nodes.first
133
+ file_node = Nokogiri::XML::Node.new('file', ng_xml)
134
+ file_node['id'] = file[:name]
51
135
  file_node['shelve' ] = file[:shelve ] ? file[:shelve ] : ''
52
136
  file_node['publish' ] = file[:publish ] ? file[:publish ] : ''
53
137
  file_node['preserve'] = file[:preserve] ? file[:preserve] : ''
@@ -55,227 +139,204 @@ module Dor
55
139
 
56
140
  [:md5, :sha1].each do |algo|
57
141
  next unless file[algo]
58
- checksum_node = Nokogiri::XML::Node.new('checksum',xml)
142
+ checksum_node = Nokogiri::XML::Node.new('checksum', ng_xml)
59
143
  checksum_node['type'] = algo.to_s
60
144
  checksum_node.content = file[algo]
61
145
  file_node.add_child(checksum_node)
62
146
  end
63
147
  file_node['size' ] = file[:size ] if file[:size ]
64
148
  file_node['mimetype'] = file[:mime_type] if file[:mime_type]
65
- self.content=xml.to_s
66
- self.save
149
+ self.content = ng_xml.to_s
150
+ file_node
67
151
  end
68
152
 
69
- def add_resource(files,resource_name, position,type="file")
70
- xml=self.ng_xml
71
- if xml.search('//resource[@id=\''+resource_name+'\']').length>0
72
- raise 'resource '+resource_name+' already exists'
153
+ # Copies the child's resource into the parent (self) as a virtual resource.
154
+ # Assumes the resource isn't a duplicate of an existing virtual or real resource.
155
+ # @param [String] child_druid druid
156
+ # @param [Nokogiri::XML::Element] child_resource
157
+ # @return [Nokogiri::XML::Element] the new resource that was added to the contentMetadata
158
+ def add_virtual_resource(child_druid, child_resource)
159
+ # create a virtual resource element with attributes linked to the child and omit label
160
+ sequence_max = ng_xml.search('//resource').map { |node| node[:sequence].to_i }.max
161
+ resource = Nokogiri::XML::Element.new('resource', ng_xml)
162
+ resource[:sequence] = sequence_max + 1
163
+ resource[:id] = "#{pid.gsub(/^druid:/, '')}_#{resource[:sequence]}"
164
+ resource[:type] = child_resource[:type]
165
+
166
+ # iterate over all the published files and link to them
167
+ child_resource.search('file[@publish=\'yes\']').each do |file|
168
+ resource << generate_external_file_node(child_druid, child_resource[:id], file[:id], file[:mimetype])
73
169
  end
74
- node=nil
170
+ resource << generate_also_available_as_node(child_druid)
171
+
172
+ # attach the virtual resource as a sibling and return
173
+ ng_xml.root << resource
174
+ self.content = ng_xml.to_s
175
+ resource
176
+ end
75
177
 
76
- max = xml.search('//resource').map{ |node| node['sequence'].to_i }.max
77
- #renumber all of the resources that will come after the newly added one
78
- while max>position
79
- node=xml.search('//resource[@sequence=\'' + position + '\']')
80
- node.first[sequence]=max+1 if node.length>0
81
- max-=1
178
+ # @param [Array] files
179
+ # @param [String] resource_name ID of the resource
180
+ # @param [Integer] position
181
+ # @param [String] type Resource type
182
+ # @return [Nokogiri::XML::Node] the new resource that was added to the contentMetadata
183
+ def add_resource(files, resource_name, position, type = 'file')
184
+ raise "resource #{resource_name} already exists" if ng_xml.search('//resource[@id=\'' + resource_name + '\']').length > 0
185
+ max = ng_xml.search('//resource').map { |node| node['sequence'].to_i }.max
186
+ # renumber all of the resources that will come after the newly added one
187
+ while max > position
188
+ node = ng_xml.search('//resource[@sequence=\'' + position + '\']')
189
+ node.first[sequence] = max + 1 if node.length > 0
190
+ max -= 1
82
191
  end
83
- node=Nokogiri::XML::Node.new('resource',xml)
84
- node['sequence']=position.to_s
85
- node['id']=resource_name
86
- node['type']=type
192
+ node = Nokogiri::XML::Node.new('resource', ng_xml)
193
+ node['sequence'] = position.to_s
194
+ node['id'] = resource_name
195
+ node['type'] = type
87
196
  files.each do |file|
88
- file_node=Nokogiri::XML::Node.new('file',xml)
89
- %w[shelve publish preserve].each {|x| file_node[x] = file[x.to_sym] ? file[x.to_sym] : '' }
197
+ file_node = Nokogiri::XML::Node.new('file', ng_xml)
198
+ %w(shelve publish preserve).each {|x| file_node[x] = file[x.to_sym] ? file[x.to_sym] : '' }
90
199
  file_node['id'] = file[:name]
91
200
  node.add_child(file_node)
92
201
 
93
202
  [:md5, :sha1].each { |algo|
94
203
  next if file[algo].nil?
95
- checksum_node = Nokogiri::XML::Node.new('checksum',xml)
204
+ checksum_node = Nokogiri::XML::Node.new('checksum', ng_xml)
96
205
  checksum_node['type'] = algo.to_s
97
206
  checksum_node.content = file[algo]
98
207
  file_node.add_child(checksum_node)
99
208
  }
100
209
  file_node['size'] = file[:size] if file[:size]
101
210
  end
102
- xml.search('//contentMetadata').first.add_child(node)
103
- self.content=xml.to_s
104
- self.save
211
+ ng_xml.search('//contentMetadata').first.add_child(node)
212
+ self.content = ng_xml.to_s
213
+ node
105
214
  end
106
215
 
107
- def remove_resource resource_name
108
- xml=self.ng_xml
109
- node = singular_node('//resource[@id=\''+resource_name+'\']')
110
- position = node['sequence'].to_i+1
216
+ # @param [String] resource_name ID of the resource
217
+ def remove_resource(resource_name)
218
+ node = singular_node('//resource[@id=\'' + resource_name + '\']')
219
+ position = node['sequence'].to_i + 1
111
220
  node.remove
112
- while true
113
- res=xml.search('//resource[@sequence=\''+position.to_s+'\']')
114
- break if res.length==0
115
- res['sequence']=position.to_s
116
- position+=1
221
+ loop do
222
+ res = ng_xml.search('//resource[@sequence=\'' + position.to_s + '\']')
223
+ break if res.length == 0
224
+ res['sequence'] = position.to_s
225
+ position += 1
117
226
  end
118
- self.content=xml.to_s
119
- self.save
227
+ self.content = ng_xml.to_s
120
228
  end
121
229
 
122
- def remove_file file_name
123
- xml=self.ng_xml
124
- xml.search('//file[@id=\''+file_name+'\']').each do |node|
125
- node.remove
126
- end
127
- self.content=xml.to_s
128
- self.save
230
+ # @param [String] file_name ID of the file element
231
+ def remove_file(file_name)
232
+ ng_xml.search('//file[@id=\'' + file_name + '\']').each(&:remove)
233
+ self.content = ng_xml.to_s
129
234
  end
130
- def update_attributes file_name, publish, shelve, preserve
131
- xml=self.ng_xml
132
- file_node=xml.search('//file[@id=\''+file_name+'\']').first
133
- file_node['shelve' ]=shelve
134
- file_node['publish' ]=publish
135
- file_node['preserve']=preserve
136
- self.content=xml.to_s
137
- self.save
235
+
236
+ # @param [String] file_name ID of the file element
237
+ # @param [String] publish
238
+ # @param [String] shelve
239
+ # @param [String] preserve
240
+ def update_attributes(file_name, publish, shelve, preserve)
241
+ file_node = ng_xml.search('//file[@id=\'' + file_name + '\']').first
242
+ file_node['publish' ] = publish
243
+ file_node['shelve' ] = shelve
244
+ file_node['preserve'] = preserve
245
+ self.content = ng_xml.to_s
138
246
  end
139
- def update_file file, old_file_id
140
- xml=self.ng_xml
141
- file_node=xml.search('//file[@id=\''+old_file_id+'\']').first
142
- file_node['id']=file[:name]
247
+
248
+ # @param file [Object] some hash-like file
249
+ # @param old_file_id [String] unique id attribute of the file element
250
+ def update_file(file, old_file_id)
251
+ file_node = ng_xml.search('//file[@id=\'' + old_file_id + '\']').first
252
+ file_node['id'] = file[:name]
143
253
  [:md5, :sha1].each { |algo|
144
254
  next if file[algo].nil?
145
- checksum_node = xml.search('//file[@id=\''+old_file_id+'\']/checksum[@type=\'' + algo.to_s + '\']').first
255
+ checksum_node = ng_xml.search('//file[@id=\'' + old_file_id + '\']/checksum[@type=\'' + algo.to_s + '\']').first
146
256
  if checksum_node.nil?
147
- checksum_node = Nokogiri::XML::Node.new('checksum',xml)
257
+ checksum_node = Nokogiri::XML::Node.new('checksum', ng_xml)
148
258
  file_node.add_child(checksum_node)
149
259
  end
150
260
  checksum_node['type'] = algo.to_s
151
261
  checksum_node.content = file[algo]
152
262
  }
153
263
 
154
- [:size, :shelve, :preserve, :publish].each{ |x|
264
+ [:size, :shelve, :preserve, :publish].each { |x|
155
265
  file_node[x.to_s] = file[x] if file[x]
156
266
  }
157
- self.content=xml.to_s
158
- self.save
267
+ self.content = ng_xml.to_s
159
268
  end
160
269
 
161
- # Terminology-based solrization is going to be painfully slow for large
162
- # contentMetadata streams. Just select the relevant elements instead.
163
- # TODO: Call super()?
164
- def to_solr(solr_doc=Hash.new, *args)
165
- doc = self.ng_xml
166
- return solr_doc unless doc.root['type']
167
-
168
- preserved_size=0
169
- counts = Hash.new(0) # default count is zero
170
- resource_type_counts = Hash.new(0) # default count is zero
171
- first_shelved_image = nil
172
-
173
- doc.xpath('contentMetadata/resource').sort { |a,b| a['sequence'].to_i <=> b['sequence'].to_i }.each do |resource|
174
- counts['resource'] += 1
175
- resource_type_counts[resource['type']] += 1 if resource['type']
176
- resource.xpath('file').each do |file|
177
- counts['content_file'] += 1
178
- preserved_size += file['size'].to_i if file['preserve'] == 'yes'
179
- next unless file['shelve'] == 'yes'
180
- counts['shelved_file'] += 1
181
- first_shelved_image ||= file['id'] if file['id'].match(/jp2$/)
182
- end
183
- end
184
- solr_doc["content_type_ssim" ] = doc.root['type']
185
- solr_doc["content_file_count_itsi" ] = counts['content_file']
186
- solr_doc["shelved_content_file_count_itsi"] = counts['shelved_file']
187
- solr_doc["resource_count_itsi" ] = counts['resource']
188
- solr_doc["preserved_size_dbtsi" ] = preserved_size # double (trie) to support very large sizes
189
- solr_doc["resource_types_ssim" ] = resource_type_counts.keys if resource_type_counts.size > 0
190
- resource_type_counts.each do |key, count|
191
- solr_doc["#{key}_resource_count_itsi"] = count
192
- end
193
- # first_shelved_image is neither indexed nor multiple
194
- solr_doc["first_shelved_image_ss"] = first_shelved_image unless first_shelved_image.nil?
195
- solr_doc
196
- end
197
-
198
- #@param old_name [String] unique id attribute of the file element
199
- #@param new_name [String] new unique id value being assigned
200
- #@return [Nokogiri::XML::Element] the file node
201
- def rename_file old_name, new_name
202
- xml=self.ng_xml
203
- file_node=xml.search('//file[@id=\''+old_name+'\']').first
204
- file_node['id']=new_name
205
- self.content=xml.to_s
206
- self.save
270
+ # @param old_name [String] unique id attribute of the file element
271
+ # @param new_name [String] new unique id value being assigned
272
+ # @return [Nokogiri::XML::Element] the file node
273
+ def rename_file(old_name, new_name)
274
+ file_node = ng_xml.search('//file[@id=\'' + old_name + '\']').first
275
+ file_node['id'] = new_name
276
+ self.content = ng_xml.to_s
277
+ file_node
207
278
  end
208
279
 
209
- #Updates old label OR creates a new one if necessary
210
- #@param resource_name [String] unique id attribute of the resource
211
- #@param new_label [String] label value being assigned
212
- #@return [Nokogiri::XML::Element] the resource node
213
- def update_resource_label resource_name, new_label
214
- node = singular_node('//resource[@id=\''+resource_name+'\']')
280
+ # Updates old label OR creates a new one if necessary
281
+ # @param resource_name [String] unique id attribute of the resource
282
+ # @param new_label [String] label value being assigned
283
+ # @return [Nokogiri::XML::Element] the resource node
284
+ def update_resource_label(resource_name, new_label)
285
+ node = singular_node('//resource[@id=\'' + resource_name + '\']')
215
286
  labels = node.xpath('./label')
216
- if (labels.length==0)
217
- #create a label
218
- label_node = Nokogiri::XML::Node.new('label',self.ng_xml)
219
- label_node.content=new_label
287
+ if labels.length == 0
288
+ label_node = Nokogiri::XML::Node.new('label', ng_xml) # create a label
289
+ label_node.content = new_label
220
290
  node.add_child(label_node)
221
291
  else
222
- labels.first.content=new_label
292
+ labels.first.content = new_label
223
293
  end
224
- return node
294
+ self.content = ng_xml.to_s
295
+ node
225
296
  end
226
297
 
227
- #@param resource_name [String] unique id attribute of the resource
228
- #@param new_type [String] type value being assigned
229
- def update_resource_type resource_name, new_type
230
- singular_node('//resource[@id=\''+resource_name+'\']')['type']=new_type
298
+ # @param resource_name [String] unique id attribute of the resource
299
+ # @param new_type [String] type value being assigned
300
+ def update_resource_type(resource_name, new_type)
301
+ singular_node('//resource[@id=\'' + resource_name + '\']')['type'] = new_type
302
+ self.content = ng_xml.to_s
231
303
  end
232
304
 
233
- #You just *had* to have ordered lists in XML, didn't you?
234
- #Re-enumerate the sequence numbers affected
235
- #@param resource_name [String] unique id attribute of the resource
236
- #@param new_position [Integer, String] new sequence number of the resource, or a string that looks like one
237
- #@return [Nokogiri::XML::Element] the resource node
238
- def move_resource resource_name, new_position
239
- node = singular_node('//resource[@id=\''+resource_name+'\']')
305
+ # You just *had* to have ordered lists in XML, didn't you?
306
+ # Re-enumerate the sequence numbers affected
307
+ # @param resource_name [String] unique id attribute of the resource
308
+ # @param new_position [Integer, String] new sequence number of the resource, or a string that looks like one
309
+ # @return [Nokogiri::XML::Element] the resource node
310
+ def move_resource(resource_name, new_position)
311
+ node = singular_node('//resource[@id=\'' + resource_name + '\']')
240
312
  position = node['sequence'].to_i
241
- new_position = new_position.to_i # tolerate strings as a Legacy behavior
313
+ new_position = new_position.to_i # tolerate strings as a Legacy behavior
242
314
  return node if position == new_position
243
- #otherwise, is the resource being moved earlier in the sequence or later?
244
- up = new_position>position
245
- others = new_position..(up ? position-1 : position+1) # a range
315
+ # otherwise, is the resource being moved earlier in the sequence or later?
316
+ up = new_position > position
317
+ others = new_position..(up ? position - 1 : position + 1) # a range
246
318
  others.each do |i|
247
- item = self.ng_xml.at_xpath('/resource[@sequence=\''+i.to_s+'\']')
248
- item['sequence'] = (up ? i-1 : i+1).to_s # if you're going up, everything else comes down and vice versa
319
+ item = ng_xml.at_xpath('/resource[@sequence=\'' + i.to_s + '\']')
320
+ item['sequence'] = (up ? i - 1 : i + 1).to_s # if you're going up, everything else comes down and vice versa
249
321
  end
250
- node['sequence'] = new_position.to_s # set the node we already had last, so we don't hit it twice!
251
- return node
322
+ node['sequence'] = new_position.to_s # set the node we already had last, so we don't hit it twice!
323
+ self.content = ng_xml.to_s
324
+ node
252
325
  end
253
326
 
254
- #Set the content type and the resource types for all resources
255
- #@param new_type [String] the new content type, ex book
256
- #@param new_resource_type [String] the new type for all resources, ex book
257
- def set_content_type old_type, old_resource_type, new_type, new_resource_type
258
- xml=self.ng_xml
259
- xml.search('/contentMetadata[@type=\''+old_type+'\']').each do |node|
260
- node['type']=new_type
261
- xml.search('//resource[@type=\''+old_resource_type+'\']').each do |resource|
262
- resource['type']=new_resource_type
327
+ # Set the content type (e.g. "book") and the resource type (e.g. "book") for all resources
328
+ # @param [String] old_type the old content type
329
+ # @param [String] old_resource_type the old type for all resources
330
+ # @param [String] new_type the new content type
331
+ # @param [String] new_resource_type the new type for all resources
332
+ def set_content_type(old_type, old_resource_type, new_type, new_resource_type)
333
+ ng_xml.search('/contentMetadata[@type=\'' + old_type + '\']').each do |node|
334
+ node['type'] = new_type
335
+ ng_xml.search('//resource[@type=\'' + old_resource_type + '\']').each do |resource|
336
+ resource['type'] = new_resource_type
263
337
  end
264
338
  end
265
- self.content=xml.to_s
266
- end
267
-
268
- # Only use this when you want the behavior of raising an exception if anything besides exactly one matching node
269
- # is found. Otherwise just use .xpath, .at_xpath or .search.
270
- #@param xpath [String] accessor invocation for Nokogiri xpath
271
- #@return [Nokogiri::XML::Element] the matched element
272
- def singular_node xpath
273
- node = self.ng_xml.search(xpath)
274
- len = node.length
275
- raise "#{xpath} not found" if len < 1
276
- raise "#{xpath} duplicated: #{len} found" if len != 1
277
- node.first
339
+ self.content = ng_xml.to_s
278
340
  end
279
341
  end
280
-
281
342
  end