libis-tools 1.0.5-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +40 -0
- data/Gemfile +7 -0
- data/README.md +202 -0
- data/Rakefile +11 -0
- data/bin/libis_tool +5 -0
- data/lib/libis-tools.rb +1 -0
- data/lib/libis/tools.rb +25 -0
- data/lib/libis/tools/assert.rb +52 -0
- data/lib/libis/tools/checksum.rb +106 -0
- data/lib/libis/tools/cli/cli_helper.rb +189 -0
- data/lib/libis/tools/cli/reorg.rb +416 -0
- data/lib/libis/tools/command.rb +133 -0
- data/lib/libis/tools/command_line.rb +23 -0
- data/lib/libis/tools/config.rb +147 -0
- data/lib/libis/tools/config_file.rb +85 -0
- data/lib/libis/tools/csv.rb +38 -0
- data/lib/libis/tools/deep_struct.rb +71 -0
- data/lib/libis/tools/extend/array.rb +16 -0
- data/lib/libis/tools/extend/empty.rb +7 -0
- data/lib/libis/tools/extend/hash.rb +147 -0
- data/lib/libis/tools/extend/kernel.rb +25 -0
- data/lib/libis/tools/extend/ostruct.rb +3 -0
- data/lib/libis/tools/extend/roo.rb +91 -0
- data/lib/libis/tools/extend/string.rb +94 -0
- data/lib/libis/tools/extend/struct.rb +29 -0
- data/lib/libis/tools/extend/symbol.rb +8 -0
- data/lib/libis/tools/logger.rb +130 -0
- data/lib/libis/tools/mets_dnx.rb +61 -0
- data/lib/libis/tools/mets_file.rb +504 -0
- data/lib/libis/tools/mets_objects.rb +547 -0
- data/lib/libis/tools/parameter.rb +372 -0
- data/lib/libis/tools/spreadsheet.rb +196 -0
- data/lib/libis/tools/temp_file.rb +42 -0
- data/lib/libis/tools/thread_safe.rb +31 -0
- data/lib/libis/tools/version.rb +5 -0
- data/lib/libis/tools/xml_document.rb +583 -0
- data/libis-tools.gemspec +55 -0
- data/spec/assert_spec.rb +65 -0
- data/spec/checksum_spec.rb +68 -0
- data/spec/command_spec.rb +90 -0
- data/spec/config_file_spec.rb +83 -0
- data/spec/config_spec.rb +113 -0
- data/spec/csv_spec.rb +159 -0
- data/spec/data/test-headers.csv +2 -0
- data/spec/data/test-headers.tsv +2 -0
- data/spec/data/test-noheaders.csv +1 -0
- data/spec/data/test-noheaders.tsv +1 -0
- data/spec/data/test.data +9 -0
- data/spec/data/test.xlsx +0 -0
- data/spec/data/test.xml +8 -0
- data/spec/data/test.yml +2 -0
- data/spec/data/test_config.yml +15 -0
- data/spec/deep_struct_spec.rb +138 -0
- data/spec/logger_spec.rb +165 -0
- data/spec/mets_file_spec.rb +223 -0
- data/spec/parameter_container_spec.rb +152 -0
- data/spec/parameter_spec.rb +148 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/spreadsheet_spec.rb +1820 -0
- data/spec/temp_file_spec.rb +76 -0
- data/spec/test.xsd +20 -0
- data/spec/thread_safe_spec.rb +64 -0
- data/spec/xmldocument_spec.rb +421 -0
- data/test/test_helper.rb +7 -0
- data/test/webservices/test_ca_item_info.rb +59 -0
- data/test/webservices/test_ca_search.rb +35 -0
- metadata +437 -0
@@ -0,0 +1,547 @@
|
|
1
|
+
require 'libis/tools/thread_safe'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module Libis
|
5
|
+
module Tools
|
6
|
+
# noinspection RubyResolve
|
7
|
+
class MetsFile
|
8
|
+
|
9
|
+
# Generic module that provides code shortcuts for the {Representation}, {Div} and {File} classes.
|
10
|
+
module MetsObject
|
11
|
+
|
12
|
+
# Take a hash and set class instance attributes.
|
13
|
+
# @param [Hash] hash Hash with <attribute_name>, <attribute_value> pairs.
|
14
|
+
def set_from_hash(hash)
|
15
|
+
hash.each { |key, value| send "#{key}=", value if respond_to?(key) }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Default initializer
|
19
|
+
def initialize
|
20
|
+
@id = 0
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sets the unique id for the instance
|
24
|
+
def set_id(id)
|
25
|
+
@id = id
|
26
|
+
end
|
27
|
+
|
28
|
+
def id
|
29
|
+
@id
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert structure to String. Can be used for debugging to show what is stored.
|
33
|
+
def to_s
|
34
|
+
"#{self.class}:\n" +
|
35
|
+
self.instance_variables.map do |var|
|
36
|
+
v = self.instance_variable_get(var)
|
37
|
+
v = "#{v.class}-#{v.id}" if v.is_a? MetsObject
|
38
|
+
v = v.map do |x|
|
39
|
+
x.is_a?(MetsObject) ? "#{x.class}-#{x.id}" : x.to_s
|
40
|
+
end.join(',') if v.is_a? Array
|
41
|
+
" - #{var.to_s.gsub(/^@/, '')}: #{v}"
|
42
|
+
end.join("\n")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# Container class for creating a representation in the METS.
|
48
|
+
class Representation
|
49
|
+
include MetsObject
|
50
|
+
|
51
|
+
# The currently allowed attributes on this class. The attributes will typically be used in {DnxSection}s.
|
52
|
+
attr_accessor :label, :preservation_type, :usage_type, :representation_code, :entity_type, :access_right_id,
|
53
|
+
:user_a, :user_b, :user_c,
|
54
|
+
:group_id, :priority, :order,
|
55
|
+
:digital_original, :content, :context, :hardware, :carrier, :original_name,
|
56
|
+
:preservation_levels, :env_dependencies, :hardware_ids, :software_ids,
|
57
|
+
:hardware_infos, :software_infos, :relationship_infos, :environments,
|
58
|
+
:dc_record, :source_metadata
|
59
|
+
|
60
|
+
# The id that will be used in the XML file to reference this representation.
|
61
|
+
def xml_id
|
62
|
+
"rep#{@id}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# This method creates the appropriate {DnxSection}s based on what attributes are filled in.
|
66
|
+
def amd
|
67
|
+
dnx = {}
|
68
|
+
tech_data = []
|
69
|
+
# General characteristics
|
70
|
+
data = {
|
71
|
+
preservationType: preservation_type,
|
72
|
+
usageType: usage_type,
|
73
|
+
DigitalOriginal: digital_original,
|
74
|
+
label: label,
|
75
|
+
representationEntityType: entity_type,
|
76
|
+
contentType: content,
|
77
|
+
contextType: context,
|
78
|
+
hardwareUsed: hardware,
|
79
|
+
physicalCarrierMedia: carrier,
|
80
|
+
deliveryPriority: priority,
|
81
|
+
orderingSequence: order,
|
82
|
+
RepresentationCode: representation_code,
|
83
|
+
RepresentationOriginalName: original_name,
|
84
|
+
UserDefinedA: user_a,
|
85
|
+
UserDefinedB: user_b,
|
86
|
+
UserDefinedC: user_c,
|
87
|
+
}.cleanup
|
88
|
+
tech_data << GeneralRepCharacteristics.new(data) unless data.empty?
|
89
|
+
# Object characteristics
|
90
|
+
data = {
|
91
|
+
groupID: group_id
|
92
|
+
}.cleanup
|
93
|
+
tech_data << ObjectCharacteristics.new(data) unless data.empty?
|
94
|
+
# Preservation level
|
95
|
+
if preservation_levels
|
96
|
+
data_list = []
|
97
|
+
preservation_levels.each do |preservation_level|
|
98
|
+
data = {
|
99
|
+
preservationLevelValue: preservation_level[:value],
|
100
|
+
preservationLevelRole: preservation_level[:role],
|
101
|
+
preservationLevelRationale: preservation_level[:rationale],
|
102
|
+
preservationLevelDateAssigned: preservation_level[:date],
|
103
|
+
}.cleanup
|
104
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
105
|
+
end
|
106
|
+
tech_data << PreservationLevel.new(array: data_list) unless data_list.empty?
|
107
|
+
end
|
108
|
+
# Dependencies
|
109
|
+
if env_dependencies
|
110
|
+
data_list = []
|
111
|
+
env_dependencies.each do |dependency|
|
112
|
+
data = {
|
113
|
+
dependencyName: dependency[:name],
|
114
|
+
dependencyIdentifierType1: dependency[:type1],
|
115
|
+
dependencyIdentifierValue1: dependency[:value1],
|
116
|
+
dependencyIdentifierType2: dependency[:type2],
|
117
|
+
dependencyIdentifierValue2: dependency[:value2],
|
118
|
+
dependencyIdentifierType3: dependency[:type3],
|
119
|
+
dependencyIdentifierValue3: dependency[:value3],
|
120
|
+
}.cleanup
|
121
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
122
|
+
end
|
123
|
+
tech_data << EnvironmentDependencies.new(array: data_list) unless data_list.empty?
|
124
|
+
end
|
125
|
+
# Hardware registry id
|
126
|
+
if hardware_ids
|
127
|
+
data_list = []
|
128
|
+
hardware_ids.each do |id|
|
129
|
+
data = {
|
130
|
+
registryId: id
|
131
|
+
}.cleanup
|
132
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
133
|
+
end
|
134
|
+
tech_data << EnvHardwareRegistry.new(array: data_list) unless data_list.empty?
|
135
|
+
end
|
136
|
+
# Software registry id
|
137
|
+
if software_ids
|
138
|
+
data_list = []
|
139
|
+
software_ids.each do |id|
|
140
|
+
data = {
|
141
|
+
registryId: id
|
142
|
+
}.cleanup
|
143
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
144
|
+
end
|
145
|
+
tech_data << EnvSoftwareRegistry.new(array: data_list) unless data_list.empty?
|
146
|
+
end
|
147
|
+
# Hardware
|
148
|
+
if hardware_infos
|
149
|
+
data_list = []
|
150
|
+
hardware_infos.each do |hardware|
|
151
|
+
data = {
|
152
|
+
hardwareName: hardware[:name],
|
153
|
+
hardwareType: hardware[:type],
|
154
|
+
hardwareOtherInformation: hardware[:info],
|
155
|
+
}.cleanup
|
156
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
157
|
+
end
|
158
|
+
tech_data << EnvironmentHardware.new(array: data_list) unless data_list.empty?
|
159
|
+
end
|
160
|
+
# Software
|
161
|
+
if software_infos
|
162
|
+
data_list = []
|
163
|
+
software_infos.each do |software|
|
164
|
+
data = {
|
165
|
+
softwareName: software[:name],
|
166
|
+
softwareVersion: software[:version],
|
167
|
+
softwareType: software[:type],
|
168
|
+
softwareOtherInformation: software[:info],
|
169
|
+
softwareDependancy: software[:dependency],
|
170
|
+
}.cleanup
|
171
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
172
|
+
end
|
173
|
+
tech_data << EnvironmentSoftware.new(array: data_list) unless data_list.empty?
|
174
|
+
end
|
175
|
+
# Relationship
|
176
|
+
if relationship_infos
|
177
|
+
data_list = []
|
178
|
+
relationship_infos.each do |relationship|
|
179
|
+
data = {
|
180
|
+
relationshipType: relationship[:type],
|
181
|
+
relationshipSubType: relationship[:subtype],
|
182
|
+
relatedObjectIdentifierType1: relationship[:type1],
|
183
|
+
relatedObjectIdentifierValue1: relationship[:id1],
|
184
|
+
relatedObjectSequence1: relationship[:seq1],
|
185
|
+
relatedObjectIdentifierType2: relationship[:type2],
|
186
|
+
relatedObjectIdentifierValue2: relationship[:id2],
|
187
|
+
relatedObjectSequence2: relationship[:seq2],
|
188
|
+
relatedObjectIdentifierType3: relationship[:type3],
|
189
|
+
relatedObjectIdentifierValue3: relationship[:id3],
|
190
|
+
relatedObjectSequence3: relationship[:seq3],
|
191
|
+
}.cleanup
|
192
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
193
|
+
end
|
194
|
+
tech_data << RelationShip.new(array: data_list) unless data_list.empty?
|
195
|
+
end
|
196
|
+
# Environment
|
197
|
+
if environments
|
198
|
+
data_list = []
|
199
|
+
environments.each do |environment|
|
200
|
+
data = {
|
201
|
+
environmentCharacteristic: environment[:characteristic],
|
202
|
+
environmentPurpose: environment[:purpose],
|
203
|
+
environmentNote: environment[:note],
|
204
|
+
}.cleanup
|
205
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
206
|
+
end
|
207
|
+
tech_data << Environment.new(array: data_list) unless data_list.empty?
|
208
|
+
end
|
209
|
+
# Finally assemble technical section
|
210
|
+
dnx[:tech] = tech_data unless tech_data.empty?
|
211
|
+
# Rights section
|
212
|
+
rights_data = []
|
213
|
+
data = {
|
214
|
+
policyId: access_right_id
|
215
|
+
}.cleanup
|
216
|
+
rights_data << AccessRightsPolicy.new(data) unless data.empty?
|
217
|
+
dnx[:rights] = rights_data unless rights_data.empty?
|
218
|
+
# Source metadata
|
219
|
+
if source_metadata
|
220
|
+
source_metadata.each_with_index do |metadata, i|
|
221
|
+
dnx["source-#{metadata[:type].to_s.upcase}-#{i}"] = metadata[:data]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
dnx
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
# Container class for creating a file in the METS.
|
230
|
+
class File
|
231
|
+
include MetsObject
|
232
|
+
|
233
|
+
# The currently allowed attributes on this class. The attributes will typically be used in {DnxSection}s.
|
234
|
+
attr_accessor :label, :note, :location, :target_location, :original, :mimetype, :puid, :size, :entity_type,
|
235
|
+
:creation_date, :modification_date, :composition_level, :group_id,
|
236
|
+
:checksum_MD5, :checksum_SHA1, :checksum_SHA256,:checksum_SHA384,:checksum_SHA512,
|
237
|
+
:fixity_type, :fixity_value,
|
238
|
+
:preservation_levels, :inhibitors, :env_dependencies, :hardware_ids, :software_ids,
|
239
|
+
:signatures, :hardware_infos, :software_infos, :relationship_infos, :environments, :applications,
|
240
|
+
:dc_record, :source_metadata, :representation
|
241
|
+
|
242
|
+
# The id that will be used in the XML file to reference this file.
|
243
|
+
def xml_id
|
244
|
+
"fid#{@id}"
|
245
|
+
end
|
246
|
+
|
247
|
+
# The id that will be used for the group in the XML file.
|
248
|
+
def make_group_id
|
249
|
+
"grp#{group_id rescue @id}"
|
250
|
+
end
|
251
|
+
|
252
|
+
# The file's name as it was originally.
|
253
|
+
def orig_name
|
254
|
+
::File.basename(location)
|
255
|
+
end
|
256
|
+
|
257
|
+
# The file's original directory.
|
258
|
+
def orig_path
|
259
|
+
::File.dirname(location)
|
260
|
+
end
|
261
|
+
|
262
|
+
# The full path where the file is copied
|
263
|
+
def target
|
264
|
+
if target_location.nil?
|
265
|
+
return "#{xml_id}#{::File.extname(location)}"
|
266
|
+
end
|
267
|
+
target_location
|
268
|
+
end
|
269
|
+
|
270
|
+
def target_name
|
271
|
+
::File.basename(target)
|
272
|
+
end
|
273
|
+
|
274
|
+
def target_path
|
275
|
+
::File.dirname(target)
|
276
|
+
end
|
277
|
+
|
278
|
+
# This method creates the appropriate {DnxSection}s based on what attributes are filled in.
|
279
|
+
def amd
|
280
|
+
dnx = {}
|
281
|
+
tech_data = []
|
282
|
+
# General File charateristics
|
283
|
+
data = {
|
284
|
+
label: label,
|
285
|
+
note: note,
|
286
|
+
fileCreationDate: creation_date,
|
287
|
+
fileModificationDate: modification_date,
|
288
|
+
FileEntityType: entity_type,
|
289
|
+
compositionLevel: composition_level,
|
290
|
+
# fileLocationType: 'FILE',
|
291
|
+
fileLocation: location,
|
292
|
+
fileOriginalName: CGI.escape(original || target_name).gsub('+', '%20'),
|
293
|
+
fileOriginalPath: target_path,
|
294
|
+
# fileOriginalID: URI.encode(location),
|
295
|
+
# fileExtension: ::File.extname(orig_name),
|
296
|
+
fileMIMEType: mimetype,
|
297
|
+
fileSizeBytes: size,
|
298
|
+
# formatLibraryId: puid
|
299
|
+
}.cleanup
|
300
|
+
tech_data << GeneralFileCharacteristics.new(data) unless data.empty?
|
301
|
+
# Fixity
|
302
|
+
%w'MD5 SHA1 SHA256 SHA384 SHA512'.each do |checksum_type|
|
303
|
+
if (checksum = self.send("checksum_#{checksum_type}"))
|
304
|
+
data = {
|
305
|
+
fixityType: checksum_type,
|
306
|
+
fixityValue: checksum,
|
307
|
+
}.cleanup
|
308
|
+
tech_data << FileFixity.new(data) unless data.empty?
|
309
|
+
end
|
310
|
+
end
|
311
|
+
# Object characteristics
|
312
|
+
data = {
|
313
|
+
groupID: make_group_id
|
314
|
+
}.cleanup
|
315
|
+
tech_data << ObjectCharacteristics.new(data) unless data.empty?
|
316
|
+
# Preservation level
|
317
|
+
if preservation_levels
|
318
|
+
data_list = []
|
319
|
+
preservation_levels.each do |preservation_level|
|
320
|
+
data = {
|
321
|
+
preservationLevelValue: preservation_level[:value],
|
322
|
+
preservationLevelRole: preservation_level[:role],
|
323
|
+
preservationLevelRationale: preservation_level[:rationale],
|
324
|
+
preservationLevelDateAssigned: preservation_level[:date],
|
325
|
+
}.cleanup
|
326
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
327
|
+
end
|
328
|
+
tech_data << PreservationLevel.new(array: data_list) unless data_list.empty?
|
329
|
+
end
|
330
|
+
# Inhibitor
|
331
|
+
if inhibitors
|
332
|
+
data_list = []
|
333
|
+
inhibitors.each do |inhibitor|
|
334
|
+
data = {
|
335
|
+
inhibitorType: inhibitor[:type],
|
336
|
+
inhibitorTarget: inhibitor[:target],
|
337
|
+
inhibitorKey: inhibitor[:key],
|
338
|
+
}.cleanup
|
339
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
340
|
+
end
|
341
|
+
tech_data << Inhibitors.new(array: data_list) unless data_list.empty?
|
342
|
+
end
|
343
|
+
# Dependencies
|
344
|
+
if env_dependencies
|
345
|
+
data_list = []
|
346
|
+
env_dependencies.each do |dependency|
|
347
|
+
data = {
|
348
|
+
dependencyName: dependency[:name],
|
349
|
+
dependencyIdentifierType1: dependency[:type1],
|
350
|
+
dependencyIdentifierValue1: dependency[:value1],
|
351
|
+
dependencyIdentifierType2: dependency[:type2],
|
352
|
+
dependencyIdentifierValue2: dependency[:value2],
|
353
|
+
dependencyIdentifierType3: dependency[:type3],
|
354
|
+
dependencyIdentifierValue3: dependency[:value3],
|
355
|
+
}.cleanup
|
356
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
357
|
+
end
|
358
|
+
tech_data << EnvironmentDependencies.new(array: data_list) unless data_list.empty?
|
359
|
+
end
|
360
|
+
# Hardware registry id
|
361
|
+
if hardware_ids
|
362
|
+
data_list = []
|
363
|
+
hardware_ids.each do |id|
|
364
|
+
data = {
|
365
|
+
registryId: id
|
366
|
+
}.cleanup
|
367
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
368
|
+
end
|
369
|
+
tech_data << EnvHardwareRegistry.new(array: data_list) unless data_list.empty?
|
370
|
+
end
|
371
|
+
# Software registry id
|
372
|
+
if software_ids
|
373
|
+
data_list = []
|
374
|
+
software_ids.each do |id|
|
375
|
+
data = {
|
376
|
+
registryId: id
|
377
|
+
}.cleanup
|
378
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
379
|
+
end
|
380
|
+
tech_data << EnvSoftwareRegistry.new(array: data_list) unless data_list.empty?
|
381
|
+
end
|
382
|
+
# Singatures
|
383
|
+
if signatures
|
384
|
+
data_list = []
|
385
|
+
signatures.each do |signature|
|
386
|
+
data = {
|
387
|
+
signatureInformationEncoding: signature[:encoding],
|
388
|
+
signer: signature[:signer],
|
389
|
+
signatureMethod: signature[:method],
|
390
|
+
signatureValue: signature[:value],
|
391
|
+
signatureValidationRules: signature[:rules],
|
392
|
+
signatureProperties: signature[:properties],
|
393
|
+
}.cleanup
|
394
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
395
|
+
end
|
396
|
+
tech_data << SignatureInformation.new(array: data_list) unless data_list.empty?
|
397
|
+
end
|
398
|
+
# Hardware
|
399
|
+
if hardware_infos
|
400
|
+
data_list = []
|
401
|
+
hardware_infos.each do |hardware|
|
402
|
+
data = {
|
403
|
+
hardwareName: hardware[:name],
|
404
|
+
hardwareType: hardware[:type],
|
405
|
+
hardwareOtherInformation: hardware[:info],
|
406
|
+
}.cleanup
|
407
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
408
|
+
end
|
409
|
+
tech_data << EnvironmentHardware.new(array: data_list) unless data_list.empty?
|
410
|
+
end
|
411
|
+
# Software
|
412
|
+
if software_infos
|
413
|
+
data_list = []
|
414
|
+
software_infos.each do |software|
|
415
|
+
data = {
|
416
|
+
softwareName: software[:name],
|
417
|
+
softwareVersion: software[:version],
|
418
|
+
softwareType: software[:type],
|
419
|
+
softwareOtherInformation: software[:info],
|
420
|
+
softwareDependancy: software[:dependency],
|
421
|
+
}.cleanup
|
422
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
423
|
+
end
|
424
|
+
tech_data << EnvironmentSoftware.new(array: data_list) unless data_list.empty?
|
425
|
+
end
|
426
|
+
# Relationship
|
427
|
+
if relationship_infos
|
428
|
+
data_list = []
|
429
|
+
relationship_infos.each do |relationship|
|
430
|
+
data = {
|
431
|
+
relationshipType: relationship[:type],
|
432
|
+
relationshipSubType: relationship[:subtype],
|
433
|
+
relatedObjectIdentifierType1: relationship[:type1],
|
434
|
+
relatedObjectIdentifierValue1: relationship[:id1],
|
435
|
+
relatedObjectSequence1: relationship[:seq1],
|
436
|
+
relatedObjectIdentifierType2: relationship[:type2],
|
437
|
+
relatedObjectIdentifierValue2: relationship[:id2],
|
438
|
+
relatedObjectSequence2: relationship[:seq2],
|
439
|
+
relatedObjectIdentifierType3: relationship[:type3],
|
440
|
+
relatedObjectIdentifierValue3: relationship[:id3],
|
441
|
+
relatedObjectSequence3: relationship[:seq3],
|
442
|
+
}.cleanup
|
443
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
444
|
+
end
|
445
|
+
tech_data << RelationShip.new(array: data_list) unless data_list.empty?
|
446
|
+
end
|
447
|
+
# Environment
|
448
|
+
if environments
|
449
|
+
data_list = []
|
450
|
+
environments.each do |environment|
|
451
|
+
data = {
|
452
|
+
environmentCharacteristic: environment[:characteristic],
|
453
|
+
environmentPurpose: environment[:purpose],
|
454
|
+
environmentNote: environment[:note],
|
455
|
+
}.cleanup
|
456
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
457
|
+
end
|
458
|
+
tech_data << Environment.new(array: data_list) unless data_list.empty?
|
459
|
+
end
|
460
|
+
# Application
|
461
|
+
if applications
|
462
|
+
data_list = []
|
463
|
+
applications.each do |application|
|
464
|
+
data = {
|
465
|
+
creatingApplicationName: application[:name],
|
466
|
+
creatingApplicationVersion: application[:version],
|
467
|
+
dateCreatedByApplication: application[:date],
|
468
|
+
}.cleanup
|
469
|
+
data_list << OpenStruct.new(data) unless data.empty?
|
470
|
+
end
|
471
|
+
tech_data << CreatingApplication.new(array: data_list) unless data_list.empty?
|
472
|
+
end
|
473
|
+
# Finally assemble technical section
|
474
|
+
dnx[:tech] = tech_data unless tech_data.empty?
|
475
|
+
dnx
|
476
|
+
end
|
477
|
+
|
478
|
+
end
|
479
|
+
|
480
|
+
# Container class for creating a division in the METS.
|
481
|
+
class Div
|
482
|
+
include MetsObject
|
483
|
+
include Libis::Tools::ThreadSafe
|
484
|
+
|
485
|
+
attr_accessor :label
|
486
|
+
|
487
|
+
# The id that will be used in the XML file to reference this division.
|
488
|
+
def xml_id
|
489
|
+
"div-#{@id}"
|
490
|
+
end
|
491
|
+
|
492
|
+
# All items stored in the current division
|
493
|
+
def children
|
494
|
+
files + divs
|
495
|
+
end
|
496
|
+
|
497
|
+
# All file items stored in the current division
|
498
|
+
def files
|
499
|
+
self.mutex.synchronize do
|
500
|
+
@files ||= Array.new
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# All division items stored in the current division
|
505
|
+
def divs
|
506
|
+
self.mutex.synchronize do
|
507
|
+
@divs ||= Array.new
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
# Add an item ({File} or {Div}) to the current division
|
512
|
+
def <<(obj)
|
513
|
+
self.mutex.synchronize do
|
514
|
+
case obj
|
515
|
+
when File
|
516
|
+
files << obj
|
517
|
+
when Div
|
518
|
+
divs << obj
|
519
|
+
else
|
520
|
+
raise RuntimeError, "Child object type not supported: #{obj.class}"
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
end
|
526
|
+
|
527
|
+
# Container class for creating a structmap in the METS.
|
528
|
+
class Map
|
529
|
+
include MetsObject
|
530
|
+
|
531
|
+
# The representation this structmap is for
|
532
|
+
attr_accessor :representation
|
533
|
+
# The top division in the structmap
|
534
|
+
attr_accessor :div
|
535
|
+
# Is the structmap Logical (true) or Physical(false)?
|
536
|
+
attr_accessor :is_logical
|
537
|
+
|
538
|
+
# The id that will be used in the XML file to reference this structmap.
|
539
|
+
def xml_id
|
540
|
+
"smap-#{@id}"
|
541
|
+
end
|
542
|
+
|
543
|
+
end
|
544
|
+
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|