moab-versioning 4.2.0 → 4.2.1

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.
@@ -1,5 +1,4 @@
1
1
  module Serializer
2
-
3
2
  # Subclass of {Serializable} that adds methods for marshalling/unmarshalling data
4
3
  # to a persistent XML file format.
5
4
  #
@@ -11,13 +10,12 @@ module Serializer
11
10
  # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
12
11
  # All rights reserved. See {file:LICENSE.rdoc} for details.
13
12
  class Manifest < Serializer::Serializable
14
-
15
13
  include HappyMapper
16
14
 
17
15
  # @api internal
18
16
  # @param filename [String] Optional filename if one wishes to override the default filename
19
17
  # @return [String] Returns the standard filename (derived from the class name) to be used for serializing an object
20
- def self.xml_filename(filename=nil)
18
+ def self.xml_filename(filename = nil)
21
19
  if filename
22
20
  filename
23
21
  else
@@ -30,7 +28,7 @@ module Serializer
30
28
  # @param parent_dir [Pathname,String] The location of the directory in which the xml file is located
31
29
  # @param filename [String] Optional filename if one wishes to override the default filename
32
30
  # @return [Pathname] The location of the xml file
33
- def self.xml_pathname(parent_dir, filename=nil)
31
+ def self.xml_pathname(parent_dir, filename = nil)
34
32
  Pathname.new(parent_dir).join(self.xml_filename(filename))
35
33
  end
36
34
 
@@ -38,7 +36,7 @@ module Serializer
38
36
  # @param parent_dir [Pathname,String] The location of the directory in which the xml file is located
39
37
  # @param filename [String] Optional filename if one wishes to override the default filename
40
38
  # @return [Boolean] Returns true if the xml file exists
41
- def self.xml_pathname_exist?(parent_dir, filename=nil)
39
+ def self.xml_pathname_exist?(parent_dir, filename = nil)
42
40
  self.xml_pathname(parent_dir, filename).exist?
43
41
  end
44
42
 
@@ -47,7 +45,7 @@ module Serializer
47
45
  # @param filename [String] Optional filename if one wishes to override the default filename
48
46
  # @return [Serializable] Read the xml file and return the parsed XML
49
47
  # @example {include:file:spec/features/serializer/read_xml_spec.rb}
50
- def self.read_xml_file(parent_dir, filename=nil)
48
+ def self.read_xml_file(parent_dir, filename = nil)
51
49
  self.parse(self.xml_pathname(parent_dir, filename).read)
52
50
  end
53
51
 
@@ -56,7 +54,7 @@ module Serializer
56
54
  # @param parent_dir [Pathname,String] The location of the directory in which the xml file is located
57
55
  # @param filename [String] Optional filename if one wishes to override the default filename
58
56
  # @return [void] Serializize the in-memory object to a xml file instance
59
- def self.write_xml_file(xml_object, parent_dir, filename=nil)
57
+ def self.write_xml_file(xml_object, parent_dir, filename = nil)
60
58
  parent_dir.mkpath
61
59
  self.xml_pathname(parent_dir, filename).open('w') do |f|
62
60
  xmlBuilder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8')
@@ -71,10 +69,8 @@ module Serializer
71
69
  # @param filename [String] Optional filename if one wishes to override the default filename
72
70
  # @return [void] Serializize the in-memory object to a xml file instance
73
71
  # @example {include:file:spec/features/serializer/write_xml_spec.rb}
74
- def write_xml_file(parent_dir, filename=nil)
72
+ def write_xml_file(parent_dir, filename = nil)
75
73
  self.class.write_xml_file(self, parent_dir, filename)
76
74
  end
77
-
78
75
  end
79
-
80
76
  end
@@ -1,5 +1,4 @@
1
1
  module Serializer
2
-
3
2
  # Some utility methods to faciliate serialization of data fields to Hash, JSON, or YAML shared by all subclasses.
4
3
  # This class assumes that HappyMapper is used for declaration of fields to be serialized.
5
4
  #
@@ -11,7 +10,6 @@ module Serializer
11
10
  # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
12
11
  # All rights reserved. See {file:LICENSE.rdoc} for details.
13
12
  class Serializable
14
-
15
13
  include HappyMapper
16
14
 
17
15
  # A flexible initializer based on the DataMapper "create factory" design pattern.
@@ -19,7 +17,7 @@ module Serializer
19
17
  # @see Serializable#initialize
20
18
  # @param opts [Hash<Symbol,Object>] a hash containing any number of symbol => value pairs.
21
19
  # The symbols should correspond to attributes declared using HappyMapper syntax
22
- def initialize(opts={})
20
+ def initialize(opts = {})
23
21
  opts.each do |key, value|
24
22
  if variable_names.include?(key.to_s) || key == :test
25
23
  instance_variable_set("@#{key}", value)
@@ -47,7 +45,7 @@ module Serializer
47
45
  # @api internal
48
46
  # @return [Array] Extract the names of the variables
49
47
  def variable_names
50
- variables.collect { |variable| variable.name}
48
+ variables.collect { |variable| variable.name }
51
49
  end
52
50
 
53
51
  # @api internal
@@ -80,12 +78,12 @@ module Serializer
80
78
  # @return [Hash] Generate a hash from an array of objects.
81
79
  # If the array member has a field tagged as a key, that field will be used as the hash.key.
82
80
  # Otherwise the index position of the array member will be used as the key
83
- def array_to_hash(array,summary=false)
81
+ def array_to_hash(array, summary = false)
84
82
  item_hash = Hash.new
85
83
  array.each_index do |index|
86
84
  item = array[index]
87
- ikey = (item.respond_to?(:key) && item.key) ? item.key : index
88
- item_hash[ikey] = item.respond_to?(:to_hash) ? item.to_hash(summary) : item
85
+ ikey = (item.respond_to?(:key) && item.key) ? item.key : index
86
+ item_hash[ikey] = item.respond_to?(:to_hash) ? item.to_hash(summary) : item
89
87
  end
90
88
  item_hash
91
89
  end
@@ -93,19 +91,19 @@ module Serializer
93
91
  # @api internal
94
92
  # @return [Hash] Recursively generate an Hash containing the object's properties
95
93
  # @param summary [Boolean] Controls the depth and detail of recursion
96
- def to_hash(summary=false)
94
+ def to_hash(summary = false)
97
95
  oh = Hash.new
98
- vars = summary ? variables.select{|v| summary_fields.include?(v.name)} : variables
96
+ vars = summary ? variables.select { |v| summary_fields.include?(v.name) } : variables
99
97
  vars.each do |variable|
100
98
  key = variable.name.to_s
101
99
  value = self.send(variable.name)
102
100
  case value
103
- when Array
104
- oh[key] = array_to_hash(value,summary)
105
- when Serializable
106
- oh[key] = value.to_hash
107
- else
108
- oh[key] = value
101
+ when Array
102
+ oh[key] = array_to_hash(value, summary)
103
+ when Serializable
104
+ oh[key] = value.to_hash
105
+ else
106
+ oh[key] = value
109
107
  end
110
108
  end
111
109
  oh
@@ -113,7 +111,7 @@ module Serializer
113
111
 
114
112
  # @return [Hash] Calls to_hash(summary=true)
115
113
  def summary
116
- self.to_hash(summary=true)
114
+ self.to_hash(summary = true)
117
115
  end
118
116
 
119
117
  # @api internal
@@ -141,12 +139,12 @@ module Serializer
141
139
  def Serializable.deep_diff(*hashes)
142
140
  diff = Hash.new
143
141
  case hashes.length
144
- when 4
145
- ltag, left, rtag, right = hashes
146
- when 2
147
- ltag, left, rtag, right = :left, hashes[0], :right, hashes[1]
148
- else
149
- raise ArgumentError, "wrong number of arguments (#{hashes.length} for 2 or 4)"
142
+ when 4
143
+ ltag, left, rtag, right = hashes
144
+ when 2
145
+ ltag, left, rtag, right = :left, hashes[0], :right, hashes[1]
146
+ else
147
+ raise ArgumentError, "wrong number of arguments (#{hashes.length} for 2 or 4)"
150
148
  end
151
149
  (left.keys | right.keys).each do |k|
152
150
  if left[k] != right[k]
@@ -162,17 +160,15 @@ module Serializer
162
160
 
163
161
  # @api internal
164
162
  # @return [String] Generate JSON output from a hash of the object's variables
165
- def to_json(summary=false)
166
- hash=self.to_hash(summary)
163
+ def to_json(summary = false)
164
+ hash = self.to_hash(summary)
167
165
  JSON.pretty_generate(hash)
168
166
  end
169
167
 
170
168
  # @api internal
171
169
  # @return [String] Generate YAML output from a hash of the object's variables
172
- def to_yaml(summary=false)
170
+ def to_yaml(summary = false)
173
171
  self.to_hash(summary).to_yaml
174
172
  end
175
-
176
173
  end
177
-
178
174
  end
@@ -1,7 +1,6 @@
1
1
  require 'moab/stanford'
2
2
 
3
3
  module Stanford
4
-
5
4
  # Utility Class for extracting content or other information from a Fedora Instance
6
5
  #
7
6
  # ====Data Model
@@ -12,7 +11,6 @@ module Stanford
12
11
  # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
13
12
  # All rights reserved. See {file:LICENSE.rdoc} for details.
14
13
  class ActiveFedoraObject
15
-
16
14
  # @param fedora_object [Object] The Active Fedora representation of the Fedora Object
17
15
  # @return [Stanford::ActiveFedoraObject] Create a u
18
16
  def initialize(fedora_object)
@@ -28,7 +26,5 @@ module Stanford
28
26
  def get_datastream_content(ds_id)
29
27
  @fedora_object.datastreams[ds_id].content
30
28
  end
31
-
32
29
  end
33
-
34
30
  end
@@ -1,7 +1,6 @@
1
1
  require 'moab/stanford'
2
2
 
3
3
  module Stanford
4
-
5
4
  # Stanford-specific utility methods for transforming contentMetadata to versionInventory and doing comparisons
6
5
  #
7
6
  # ====Data Model
@@ -12,20 +11,19 @@ module Stanford
12
11
  # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
13
12
  # All rights reserved. See {file:LICENSE.rdoc} for details.
14
13
  class ContentInventory
15
-
16
14
  # @param content_metadata [String] The content metadata to be transformed into a versionInventory
17
15
  # @param object_id [String] The identifier of the digital object
18
16
  # @param subset [String] Speciifes which subset of files to list (all|preserve|publish|shelve)
19
17
  # @param version_id [Integer] The ID of the version whosen content metadata is to be transformed
20
18
  # @return [FileInventory] The versionInventory equivalent of the contentMetadata
21
19
  # if the supplied content_metadata is blank or empty, then a skeletal FileInventory will be returned
22
- def inventory_from_cm(content_metadata, object_id, subset, version_id=nil)
20
+ def inventory_from_cm(content_metadata, object_id, subset, version_id = nil)
23
21
  # The contentMetadata datastream is not required for ingest, since some object types, such as collection
24
22
  # or APO do not require one.
25
23
  # Many of these objects have contentMetadata with no child elements, such as this:
26
24
  # <contentMetadata objectId="bd608mj3166" type="file"/>
27
25
  # but there are also objects that have no datasteam of this name at all
28
- cm_inventory = Moab::FileInventory.new(:type=>"version",:digital_object_id=>object_id, :version_id=>version_id)
26
+ cm_inventory = Moab::FileInventory.new(:type => "version", :digital_object_id => object_id, :version_id => version_id)
29
27
  content_group = group_from_cm(content_metadata, subset)
30
28
  cm_inventory.groups << content_group
31
29
  cm_inventory
@@ -40,18 +38,18 @@ module Stanford
40
38
  ng_doc = Nokogiri::XML(content_metadata)
41
39
  validate_content_metadata(ng_doc)
42
40
  nodeset = case subset.to_s.downcase
43
- when 'preserve'
44
- ng_doc.xpath("//file[@preserve='yes']")
45
- when 'publish'
46
- ng_doc.xpath("//file[@publish='yes']")
47
- when 'shelve'
48
- ng_doc.xpath("//file[@shelve='yes']")
49
- when 'all'
50
- ng_doc.xpath("//file")
51
- else
52
- raise "Unknown disposition subset (#{subset})"
53
- end
54
- content_group = Moab::FileGroup.new(:group_id=>'content', :data_source => "contentMetadata-#{subset}")
41
+ when 'preserve'
42
+ ng_doc.xpath("//file[@preserve='yes']")
43
+ when 'publish'
44
+ ng_doc.xpath("//file[@publish='yes']")
45
+ when 'shelve'
46
+ ng_doc.xpath("//file[@shelve='yes']")
47
+ when 'all'
48
+ ng_doc.xpath("//file")
49
+ else
50
+ raise "Unknown disposition subset (#{subset})"
51
+ end
52
+ content_group = Moab::FileGroup.new(:group_id => 'content', :data_source => "contentMetadata-#{subset}")
55
53
  nodeset.each do |file_node|
56
54
  signature = generate_signature(file_node)
57
55
  instance = generate_instance(file_node)
@@ -69,12 +67,12 @@ module Stanford
69
67
  checksum_nodes = node.xpath('checksum')
70
68
  checksum_nodes.each do |checksum_node|
71
69
  case checksum_node.attributes['type'].content.upcase
72
- when 'MD5'
73
- signature.md5 = checksum_node.text
74
- when 'SHA1', 'SHA-1'
75
- signature.sha1 = checksum_node.text
76
- when 'SHA256', 'SHA-256'
77
- signature.sha256 = checksum_node.text
70
+ when 'MD5'
71
+ signature.md5 = checksum_node.text
72
+ when 'SHA1', 'SHA-1'
73
+ signature.sha1 = checksum_node.text
74
+ when 'SHA256', 'SHA-256'
75
+ signature.sha256 = checksum_node.text
78
76
  end
79
77
  end
80
78
  signature
@@ -96,22 +94,23 @@ module Stanford
96
94
  # @example {include:file:spec/features/stanford/content_metadata_write_spec.rb}
97
95
  def generate_content_metadata(file_group, object_id, version_id)
98
96
  cm = Nokogiri::XML::Builder.new do |xml|
99
- xml.contentMetadata(:type=>"sample", :objectId=>object_id) {
100
- xml.resource(:type=>"version", :sequence=>"1", :id=>"version-#{version_id}") {
97
+ xml.contentMetadata(:type => "sample", :objectId => object_id) {
98
+ xml.resource(:type => "version", :sequence => "1", :id => "version-#{version_id}") {
101
99
  file_group.files.each do |file_manifestation|
102
100
  signature = file_manifestation.signature
103
101
  file_manifestation.instances.each do |instance|
104
102
  xml.file(
105
- :id=>instance.path,
106
- :size=>signature.size,
107
- :datetime=>instance.datetime,
108
- :shelve=>'yes',
109
- :publish=>'yes',
110
- :preserve=>'yes') {
103
+ :id => instance.path,
104
+ :size => signature.size,
105
+ :datetime => instance.datetime,
106
+ :shelve => 'yes',
107
+ :publish => 'yes',
108
+ :preserve => 'yes'
109
+ ) {
111
110
  fixity = signature.fixity
112
- xml.checksum(:type=>"MD5") {xml.text signature.md5 } if fixity[:md5]
113
- xml.checksum(:type=>"SHA-1") {xml.text signature.sha1} if fixity[:sha1]
114
- xml.checksum(:type=>"SHA-256") {xml.text signature.sha256} if fixity[:sha256]
111
+ xml.checksum(:type => "MD5") { xml.text signature.md5 } if fixity[:md5]
112
+ xml.checksum(:type => "SHA-1") { xml.text signature.sha1 } if fixity[:sha1]
113
+ xml.checksum(:type => "SHA-256") { xml.text signature.sha256 } if fixity[:sha256]
115
114
  }
116
115
  end
117
116
  end
@@ -125,7 +124,7 @@ module Stanford
125
124
  # @return [Boolean] True if contentMetadata has essential file attributes, else raise exception
126
125
  def validate_content_metadata(content_metadata)
127
126
  result = validate_content_metadata_details(content_metadata)
128
- raise Moab::InvalidMetadataException, result[0]+" ..." if result.size > 0
127
+ raise Moab::InvalidMetadataException, result[0] + " ..." if result.size > 0
129
128
  true
130
129
  end
131
130
 
@@ -135,27 +134,27 @@ module Stanford
135
134
  result = []
136
135
  content_metadata_doc =
137
136
  case content_metadata.class.name
138
- when "String"
139
- Nokogiri::XML(content_metadata)
140
- when "Pathname"
141
- Nokogiri::XML(content_metadata.read)
142
- when "Nokogiri::XML::Document"
143
- content_metadata
144
- else
145
- raise Moab::InvalidMetadataException, "Content Metadata is in unrecognized format"
146
- end
137
+ when "String"
138
+ Nokogiri::XML(content_metadata)
139
+ when "Pathname"
140
+ Nokogiri::XML(content_metadata.read)
141
+ when "Nokogiri::XML::Document"
142
+ content_metadata
143
+ else
144
+ raise Moab::InvalidMetadataException, "Content Metadata is in unrecognized format"
145
+ end
147
146
  nodeset = content_metadata_doc.xpath("//file")
148
147
  nodeset.each do |file_node|
149
- missing = ['id', 'size','md5','sha1']
148
+ missing = ['id', 'size', 'md5', 'sha1']
150
149
  missing.delete('id') if file_node.has_attribute?('id')
151
150
  missing.delete('size') if file_node.has_attribute?('size')
152
151
  checksum_nodes = file_node.xpath('checksum')
153
152
  checksum_nodes.each do |checksum_node|
154
153
  case checksum_node.attributes['type'].content.upcase
155
- when 'MD5'
156
- missing.delete('md5')
157
- when 'SHA1', 'SHA-1'
158
- missing.delete('sha1')
154
+ when 'MD5'
155
+ missing.delete('md5')
156
+ when 'SHA1', 'SHA-1'
157
+ missing.delete('sha1')
159
158
  end
160
159
  end
161
160
  if missing.include?('id')
@@ -214,14 +213,14 @@ module Stanford
214
213
  # add new <checksum> elements for the other checksum types that were missing
215
214
  @names_for_type.each do |type, names|
216
215
  unless checksum_nodes.has_key?(type)
217
- checksum_node = Nokogiri::XML::Element.new('checksum',file_node.document)
216
+ checksum_node = Nokogiri::XML::Element.new('checksum', file_node.document)
218
217
  checksum_node['type'] = names[0]
219
218
  file_node << checksum_node
220
219
  checksum_nodes[type] = checksum_node
221
220
  end
222
221
  end
223
222
  # make sure the <checksum> element has a content value
224
- checksum_nodes.each do |type,checksum_node|
223
+ checksum_nodes.each do |type, checksum_node|
225
224
  cm_checksum = checksum_node.content
226
225
  sig_checksum = signature.checksums[type]
227
226
  if cm_checksum.nil? or cm_checksum.empty?
@@ -231,7 +230,5 @@ module Stanford
231
230
  end
232
231
  end
233
232
  end
234
-
235
233
  end
236
-
237
234
  end
@@ -1,7 +1,6 @@
1
1
  require 'moab/stanford'
2
2
 
3
3
  module Stanford
4
-
5
4
  # Stanford-specific utility methods for interfacing with DOR metadata files
6
5
  #
7
6
  # ====Data Model
@@ -12,7 +11,6 @@ module Stanford
12
11
  # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
13
12
  # All rights reserved. See {file:LICENSE.rdoc} for details.
14
13
  class DorMetadata
15
-
16
14
  # @return [String] The digital object identifier (druid)
17
15
  attr_accessor :digital_object_id
18
16
 
@@ -22,7 +20,7 @@ module Stanford
22
20
  # @param digital_object_id [String] The digital object identifier
23
21
  # @param version_id [Integer] The ordinal version number
24
22
  # @return [Stanford::DorMetadata]
25
- def initialize(digital_object_id, version_id=nil)
23
+ def initialize(digital_object_id, version_id = nil)
26
24
  @digital_object_id = digital_object_id
27
25
  @version_id = version_id
28
26
  end
@@ -31,16 +29,15 @@ module Stanford
31
29
  # @param directory [String] The location of the directory to be inventoried
32
30
  # @param version_id (see #initialize)
33
31
  # @return [FileInventory] Inventory of the files under the specified directory
34
- def inventory_from_directory(directory, version_id=nil)
32
+ def inventory_from_directory(directory, version_id = nil)
35
33
  version_id ||= @version_id
36
34
  version_inventory = Moab::FileInventory.new(type: 'version', digital_object_id: @digital_object_id, version_id: version_id)
37
- content_metadata = IO.read(File.join(directory,'contentMetadata.xml'))
38
- content_group = Stanford::ContentInventory.new.group_from_cm(content_metadata, 'preserve' )
35
+ content_metadata = IO.read(File.join(directory, 'contentMetadata.xml'))
36
+ content_group = Stanford::ContentInventory.new.group_from_cm(content_metadata, 'preserve')
39
37
  version_inventory.groups << content_group
40
- metadata_group = Moab::FileGroup.new(:group_id=>'metadata').group_from_directory(directory)
38
+ metadata_group = Moab::FileGroup.new(:group_id => 'metadata').group_from_directory(directory)
41
39
  version_inventory.groups << metadata_group
42
40
  version_inventory
43
41
  end
44
42
  end
45
-
46
43
  end
@@ -3,12 +3,11 @@ require 'moab'
3
3
  module Stanford
4
4
  # druids are Stanford specific entities
5
5
  class StorageObjectValidator < Moab::StorageObjectValidator
6
-
7
6
  # TODO: test to make sure constants don't collide on underlying int vals?
8
7
  # keep from stepping on previously defined error code constants.
9
8
  DRUID_MISMATCH = superclass.error_code_to_messages.keys.max + 1
10
9
 
11
- def validation_errors(allow_content_subdirs=true)
10
+ def validation_errors(allow_content_subdirs = true)
12
11
  errors = []
13
12
  errors.concat super(allow_content_subdirs)
14
13
  errors.concat(identify_druid) if errors.empty?