dor-services 5.2.0 → 5.3.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.
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