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.
- checksums.yaml +5 -13
- data/config/certs/robots-dor-dev.crt +29 -0
- data/config/certs/robots-dor-dev.key +27 -0
- data/config/config_defaults.yml +2 -0
- data/config/dev_console_env.rb +77 -0
- data/lib/dor-services.rb +31 -27
- data/lib/dor/config.rb +25 -19
- data/lib/dor/datastreams/administrative_metadata_ds.rb +19 -20
- data/lib/dor/datastreams/content_metadata_ds.rb +238 -177
- data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
- data/lib/dor/datastreams/default_object_rights_ds.rb +99 -16
- data/lib/dor/datastreams/desc_metadata_ds.rb +37 -34
- data/lib/dor/datastreams/embargo_metadata_ds.rb +16 -16
- data/lib/dor/datastreams/events_ds.rb +2 -2
- data/lib/dor/datastreams/geo_metadata_ds.rb +5 -10
- data/lib/dor/datastreams/identity_metadata_ds.rb +22 -22
- data/lib/dor/datastreams/rights_metadata_ds.rb +43 -32
- data/lib/dor/datastreams/role_metadata_ds.rb +5 -5
- data/lib/dor/datastreams/simple_dublin_core_ds.rb +13 -14
- data/lib/dor/datastreams/version_metadata_ds.rb +22 -23
- data/lib/dor/datastreams/workflow_definition_ds.rb +15 -15
- data/lib/dor/datastreams/workflow_ds.rb +64 -70
- data/lib/dor/exceptions.rb +0 -1
- data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +4 -4
- data/lib/dor/migrations/processable/unify_workflows.rb +1 -1
- data/lib/dor/models/admin_policy_object.rb +4 -4
- data/lib/dor/models/assembleable.rb +2 -3
- data/lib/dor/models/collection.rb +1 -1
- data/lib/dor/models/contentable.rb +113 -108
- data/lib/dor/models/describable.rb +136 -95
- data/lib/dor/models/editable.rb +205 -119
- data/lib/dor/models/embargoable.rb +16 -16
- data/lib/dor/models/eventable.rb +2 -2
- data/lib/dor/models/geoable.rb +3 -3
- data/lib/dor/models/governable.rb +25 -26
- data/lib/dor/models/identifiable.rb +66 -55
- data/lib/dor/models/item.rb +0 -1
- data/lib/dor/models/itemizable.rb +7 -8
- data/lib/dor/models/preservable.rb +7 -8
- data/lib/dor/models/processable.rb +76 -73
- data/lib/dor/models/publishable.rb +25 -30
- data/lib/dor/models/releaseable.rb +118 -155
- data/lib/dor/models/rightsable.rb +2 -3
- data/lib/dor/models/set.rb +1 -1
- data/lib/dor/models/shelvable.rb +8 -10
- data/lib/dor/models/upgradable.rb +5 -6
- data/lib/dor/models/versionable.rb +3 -4
- data/lib/dor/models/workflow_object.rb +15 -16
- data/lib/dor/services/cleanup_reset_service.rb +15 -16
- data/lib/dor/services/cleanup_service.rb +2 -4
- data/lib/dor/services/digital_stacks_service.rb +10 -13
- data/lib/dor/services/merge_service.rb +8 -9
- data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
- data/lib/dor/services/metadata_handlers/mdtoolkit_handler.rb +3 -3
- data/lib/dor/services/metadata_service.rb +19 -20
- data/lib/dor/services/registration_service.rb +80 -61
- data/lib/dor/services/reset_workspace_service.rb +6 -10
- data/lib/dor/services/sdr_ingest_service.rb +15 -16
- data/lib/dor/services/search_service.rb +18 -23
- data/lib/dor/services/suri_service.rb +6 -6
- data/lib/dor/services/technical_metadata_service.rb +27 -44
- data/lib/dor/utils/ng_tidy.rb +3 -3
- data/lib/dor/utils/sdr_client.rb +2 -3
- data/lib/dor/utils/solr_doc_helper.rb +1 -3
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +43 -40
- data/lib/dor/workflow/graph.rb +26 -26
- data/lib/dor/workflow/process.rb +34 -35
- data/lib/tasks/rdoc.rake +5 -5
- metadata +129 -111
- data/lib/dor/models/presentable.rb +0 -146
@@ -8,7 +8,7 @@ handler = Class.new do
|
|
8
8
|
|
9
9
|
def label(metadata)
|
10
10
|
mods = Nokogiri::XML(metadata)
|
11
|
-
mods.root.add_namespace_definition('mods','http://www.loc.gov/mods/v3')
|
11
|
+
mods.root.add_namespace_definition('mods', 'http://www.loc.gov/mods/v3')
|
12
12
|
mods.xpath('/mods:mods/mods:titleInfo[1]').xpath('mods:title|mods:nonSort').collect { |n| n.text }.join(' ').strip
|
13
13
|
end
|
14
14
|
|
@@ -14,18 +14,18 @@ handler = Class.new do
|
|
14
14
|
client = RestClient::Resource.new(Dor::Config.metadata.exist.url)
|
15
15
|
response = client['db'].post(query, :content_type => 'application/xquery')
|
16
16
|
doc = Nokogiri::XML(response)
|
17
|
-
doc.root.add_namespace_definition('exist','http://exist.sourceforge.net/NS/exist')
|
17
|
+
doc.root.add_namespace_definition('exist', 'http://exist.sourceforge.net/NS/exist')
|
18
18
|
result = doc.xpath('/exist:result/*[1]').first
|
19
19
|
result.nil? ? nil : result.to_s
|
20
20
|
end
|
21
21
|
|
22
22
|
def label(metadata)
|
23
23
|
xml = Nokogiri::XML(metadata)
|
24
|
-
return
|
24
|
+
return '' if xml.root.nil?
|
25
25
|
case xml.root.name
|
26
26
|
when 'msDesc' then xml.xpath('/msDesc/msIdentifier/collection').text
|
27
27
|
when 'mods' then
|
28
|
-
xml.root.add_namespace_definition('mods','http://www.loc.gov/mods/v3')
|
28
|
+
xml.root.add_namespace_definition('mods', 'http://www.loc.gov/mods/v3')
|
29
29
|
xml.xpath('/mods:mods/mods:titleInfo[1]').xpath('mods:title|mods:nonSort').collect { |n| n.text }.join(' ').strip
|
30
30
|
end
|
31
31
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
require 'cache'
|
2
2
|
|
3
3
|
module Dor
|
4
|
-
|
5
4
|
class MetadataError < Exception ; end
|
6
5
|
|
7
|
-
# class MetadataHandler
|
8
|
-
#
|
9
|
-
# def fetch(prefix, identifier)
|
10
|
-
# ### Return metadata for prefix/identifier combo
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# def label(metadata)
|
14
|
-
# ### Return a Fedora-compatible label from the metadata format returned by #fetch
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# end
|
6
|
+
# class MetadataHandler
|
7
|
+
#
|
8
|
+
# def fetch(prefix, identifier)
|
9
|
+
# ### Return metadata for prefix/identifier combo
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def label(metadata)
|
13
|
+
# ### Return a Fedora-compatible label from the metadata format returned by #fetch
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# end
|
18
17
|
|
19
18
|
class MetadataService
|
20
19
|
|
@@ -31,15 +30,15 @@ module Dor
|
|
31
30
|
handler.prefixes.each do |prefix|
|
32
31
|
handlers[prefix.to_sym] = handler
|
33
32
|
end
|
34
|
-
|
33
|
+
handler
|
35
34
|
end
|
36
35
|
|
37
36
|
def known_prefixes
|
38
|
-
|
37
|
+
handlers.keys
|
39
38
|
end
|
40
39
|
|
41
40
|
def can_resolve?(identifier)
|
42
|
-
(prefix,
|
41
|
+
(prefix, _identifier) = identifier.split(/:/, 2)
|
43
42
|
handlers.keys.include?(prefix.to_sym)
|
44
43
|
end
|
45
44
|
|
@@ -50,14 +49,14 @@ module Dor
|
|
50
49
|
|
51
50
|
def fetch(identifier)
|
52
51
|
@@cache.fetch(identifier) do
|
53
|
-
(prefix, identifier) = identifier.split(/:/,2)
|
52
|
+
(prefix, identifier) = identifier.split(/:/, 2)
|
54
53
|
handler = handler_for(prefix)
|
55
54
|
handler.fetch(prefix, identifier)
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
59
58
|
def label_for(identifier)
|
60
|
-
(prefix, identifier) = identifier.split(/:/,2)
|
59
|
+
(prefix, identifier) = identifier.split(/:/, 2)
|
61
60
|
handler = handler_for(prefix)
|
62
61
|
handler.label(handler.fetch(prefix, identifier))
|
63
62
|
end
|
@@ -65,10 +64,11 @@ module Dor
|
|
65
64
|
def handler_for(prefix)
|
66
65
|
handler = handlers[prefix.to_sym]
|
67
66
|
raise MetadataError, "Unkown metadata prefix: #{prefix}" if handler.nil?
|
68
|
-
|
67
|
+
handler
|
69
68
|
end
|
70
69
|
|
71
70
|
private
|
71
|
+
|
72
72
|
def handlers
|
73
73
|
@handlers ||= {}
|
74
74
|
end
|
@@ -76,9 +76,8 @@ module Dor
|
|
76
76
|
end
|
77
77
|
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
|
82
|
-
Dir[File.join(File.dirname(__FILE__),'metadata_handlers','*.rb')].each { |handler_file|
|
81
|
+
Dir[File.join(File.dirname(__FILE__), 'metadata_handlers', '*.rb')].each { |handler_file|
|
83
82
|
load handler_file
|
84
83
|
}
|
@@ -4,75 +4,100 @@ module Dor
|
|
4
4
|
class RegistrationService
|
5
5
|
|
6
6
|
class << self
|
7
|
+
|
8
|
+
# @TODO: Why isn't all this logic in, for example, Dor::Item.create? or Dor::Base.create? or Dor::Creatable.create?
|
9
|
+
# @TODO: these duplicate checks could be combined into 1 query
|
10
|
+
|
11
|
+
# @param [String] pid an ID to check, if desired. If not passed (or nil), a new ID is minted
|
12
|
+
# @return [String] a pid you can use immidately, either freshly minted or your checked value
|
13
|
+
# @raise [Dor::DuplicateIdError]
|
14
|
+
def unduplicated_pid(pid = nil)
|
15
|
+
return Dor::SuriService.mint_id unless pid
|
16
|
+
existing_pid = SearchService.query_by_id(pid).first
|
17
|
+
unless existing_pid.nil?
|
18
|
+
raise Dor::DuplicateIdError.new(existing_pid), "An object with the PID #{pid} has already been registered."
|
19
|
+
end
|
20
|
+
pid
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param [String] source_id_string a fully qualified source:val or empty string
|
24
|
+
# @return [String] the same qualified source:id for immediate use
|
25
|
+
# @raise [Dor::DuplicateIdError]
|
26
|
+
def check_source_id(source_id_string)
|
27
|
+
return '' if source_id_string == ''
|
28
|
+
unless SearchService.query_by_id("#{source_id_string}").first.nil?
|
29
|
+
raise Dor::DuplicateIdError.new(source_id_string), "An object with the source ID '#{source_id_string}' has already been registered."
|
30
|
+
end
|
31
|
+
source_id_string
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [Hash{Symbol => various}] params
|
35
|
+
# @option params [String] :object_type required
|
36
|
+
# @option params [String] :label required
|
37
|
+
# @option params [String] :admin_policy required
|
38
|
+
# @option params [String] :metadata_source
|
39
|
+
# @option params [String] :rights
|
40
|
+
# @option params [String] :collection
|
41
|
+
# @option params [Hash{String => String}] :source_id Primary ID from another system, max one key/value pair!
|
42
|
+
# @option params [Hash] :other_ids including :uuid if known
|
43
|
+
# @option params [String] :pid Fully qualified PID if you don't want one generated for you
|
44
|
+
# @option params [Integer] :workflow_priority]
|
45
|
+
# @option params [Array<String>] :seed_datastream datastream_names
|
46
|
+
# @option params [Array<String>] :initiate_workflow workflow_ids
|
47
|
+
# @option params [Array] :tags
|
7
48
|
def register_object(params = {})
|
8
49
|
Dor.ensure_models_loaded!
|
9
50
|
[:object_type, :label].each do |required_param|
|
10
|
-
raise Dor::ParameterError, "#{required_param.inspect} must be specified in call to #{
|
51
|
+
raise Dor::ParameterError, "#{required_param.inspect} must be specified in call to #{name}.register_object" unless params[required_param]
|
11
52
|
end
|
12
53
|
metadata_source = params[:metadata_source]
|
13
|
-
if params[:label].length<1 && (metadata_source=='label' || metadata_source=='none')
|
14
|
-
raise Dor::ParameterError, "label cannot be empty to call #{
|
54
|
+
if params[:label].length < 1 && (metadata_source == 'label' || metadata_source == 'none')
|
55
|
+
raise Dor::ParameterError, "label cannot be empty to call #{name}.register_object"
|
15
56
|
end
|
16
57
|
object_type = params[:object_type]
|
17
58
|
item_class = Dor.registered_classes[object_type]
|
18
59
|
raise Dor::ParameterError, "Unknown item type: '#{object_type}'" if item_class.nil?
|
19
60
|
|
20
|
-
content_model = params[:content_model]
|
21
|
-
|
61
|
+
# content_model = params[:content_model]
|
62
|
+
# parent = params[:parent]
|
22
63
|
label = params[:label]
|
23
64
|
source_id = params[:source_id] || {}
|
24
65
|
other_ids = params[:other_ids] || {}
|
25
66
|
tags = params[:tags] || []
|
26
|
-
parent = params[:parent]
|
27
67
|
collection = params[:collection]
|
28
|
-
pid = nil
|
29
|
-
if params[:pid]
|
30
|
-
pid = params[:pid]
|
31
|
-
existing_pid = SearchService.query_by_id(pid).first
|
32
|
-
unless existing_pid.nil?
|
33
|
-
raise Dor::DuplicateIdError.new(existing_pid), "An object with the PID #{pid} has already been registered."
|
34
|
-
end
|
35
|
-
else
|
36
|
-
pid = Dor::SuriService.mint_id
|
37
|
-
end
|
38
68
|
|
39
|
-
|
69
|
+
# Check for sourceId conflict *before* potentially minting PID
|
70
|
+
source_id_string = check_source_id [source_id.keys.first, source_id[source_id.keys.first]].compact.join(':')
|
71
|
+
pid = unduplicated_pid(params[:pid])
|
72
|
+
|
73
|
+
raise ArgumentError, ":source_id Hash can contain at most 1 pair: recieved #{source_id.size}" if source_id.size > 1
|
74
|
+
|
75
|
+
rights = nil
|
40
76
|
if params[:rights]
|
41
|
-
rights=params[:rights]
|
77
|
+
rights = params[:rights]
|
42
78
|
unless %w(world stanford dark default none).include? rights
|
43
|
-
raise Dor::ParameterError, "Unknown rights setting '#{rights}' when calling #{
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
source_id_string = [source_id.keys.first,source_id[source_id.keys.first]].compact.join(':')
|
48
|
-
unless source_id.empty?
|
49
|
-
existing_pid = SearchService.query_by_id("#{source_id_string}").first
|
50
|
-
unless existing_pid.nil?
|
51
|
-
raise Dor::DuplicateIdError.new(existing_pid), "An object with the source ID '#{source_id_string}' has already been registered."
|
79
|
+
raise Dor::ParameterError, "Unknown rights setting '#{rights}' when calling #{name}.register_object"
|
52
80
|
end
|
53
81
|
end
|
54
82
|
|
55
83
|
if (other_ids.key?(:uuid) || other_ids.key?('uuid')) == false
|
56
84
|
other_ids[:uuid] = UUIDTools::UUID.timestamp_create.to_s
|
57
85
|
end
|
58
|
-
|
59
|
-
apo_object = Dor.find(admin_policy, :lightweight => true)
|
60
|
-
adm_xml = apo_object.administrativeMetadata.ng_xml
|
61
|
-
|
86
|
+
apo_object = Dor.find(params[:admin_policy])
|
62
87
|
new_item = item_class.new(:pid => pid)
|
63
|
-
new_item.label =
|
88
|
+
new_item.label = label.length > 254 ? label[0, 254] : label
|
64
89
|
idmd = new_item.identityMetadata
|
65
90
|
idmd.sourceId = source_id_string
|
66
91
|
idmd.add_value(:objectId, pid)
|
67
92
|
idmd.add_value(:objectCreator, 'DOR')
|
68
93
|
idmd.add_value(:objectLabel, label)
|
69
94
|
idmd.add_value(:objectType, object_type)
|
70
|
-
other_ids.each_pair { |name,value| idmd.add_otherId("#{name}:#{value}") }
|
95
|
+
other_ids.each_pair { |name, value| idmd.add_otherId("#{name}:#{value}") }
|
71
96
|
tags.each { |tag| idmd.add_value(:tag, tag) }
|
72
97
|
new_item.admin_policy_object = apo_object
|
73
98
|
|
74
|
-
|
75
|
-
short_predicate = ActiveFedora::RelsExtDatastream.short_predicate rel.namespace.href+rel.name
|
99
|
+
apo_object.administrativeMetadata.ng_xml.xpath('/administrativeMetadata/relationships/*').each do |rel|
|
100
|
+
short_predicate = ActiveFedora::RelsExtDatastream.short_predicate rel.namespace.href + rel.name
|
76
101
|
if short_predicate.nil?
|
77
102
|
ix = 0
|
78
103
|
ix += 1 while ActiveFedora::Predicates.predicate_mappings[rel.namespace.href].key?(short_predicate = :"extra_predicate_#{ix}")
|
@@ -82,21 +107,21 @@ module Dor
|
|
82
107
|
end
|
83
108
|
new_item.add_collection(collection) if collection
|
84
109
|
if rights && %w(item collection).include?(object_type)
|
85
|
-
rights_xml=apo_object.defaultObjectRights.ng_xml
|
86
|
-
new_item.datastreams['rightsMetadata'].content=rights_xml.to_s
|
110
|
+
rights_xml = apo_object.defaultObjectRights.ng_xml
|
111
|
+
new_item.datastreams['rightsMetadata'].content = rights_xml.to_s
|
87
112
|
new_item.set_read_rights(rights) unless rights == 'default' # already defaulted to default!
|
88
113
|
end
|
89
|
-
#create basic mods from the label
|
90
|
-
if
|
91
|
-
ds=new_item.build_datastream('descMetadata')
|
114
|
+
# create basic mods from the label
|
115
|
+
if metadata_source == 'label'
|
116
|
+
ds = new_item.build_datastream('descMetadata')
|
92
117
|
builder = Nokogiri::XML::Builder.new { |xml|
|
93
|
-
xml.mods( 'xmlns' => 'http://www.loc.gov/mods/v3', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
94
|
-
xml.titleInfo{
|
118
|
+
xml.mods( 'xmlns' => 'http://www.loc.gov/mods/v3', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', :version => '3.3', 'xsi:schemaLocation' => 'http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd') {
|
119
|
+
xml.titleInfo {
|
95
120
|
xml.title label
|
96
121
|
}
|
97
122
|
}
|
98
123
|
}
|
99
|
-
ds.content=builder.to_xml
|
124
|
+
ds.content = builder.to_xml
|
100
125
|
end
|
101
126
|
|
102
127
|
workflow_priority = params[:workflow_priority] ? params[:workflow_priority].to_i : 0
|
@@ -106,22 +131,18 @@ module Dor
|
|
106
131
|
|
107
132
|
new_item.assert_content_model
|
108
133
|
|
109
|
-
new_item.class.ancestors.select { |x| x.respond_to?
|
110
|
-
next if parent_class == ActiveFedora::Base
|
134
|
+
new_item.class.ancestors.select { |x| x.respond_to?(:to_class_uri) && x != ActiveFedora::Base }.each do |parent_class|
|
111
135
|
new_item.add_relationship(:has_model, parent_class.to_class_uri)
|
112
136
|
end
|
113
137
|
|
114
138
|
new_item.save
|
115
|
-
|
116
|
-
new_item.update_index if ::ENABLE_SOLR_UPDATES
|
117
|
-
rescue StandardError => e
|
118
|
-
Dor.logger.warn "Dor::RegistrationService.register_object failed to update solr index for #{new_item.pid}: #<#{e.class.name}: #{e.message}>"
|
119
|
-
end
|
120
|
-
return(new_item)
|
139
|
+
new_item
|
121
140
|
end
|
122
141
|
|
142
|
+
# @param [Hash] params
|
143
|
+
# @see register_object similar but different
|
123
144
|
def create_from_request(params)
|
124
|
-
other_ids = Array(params[:other_id]).
|
145
|
+
other_ids = Array(params[:other_id]).map do |id|
|
125
146
|
if id =~ /^symphony:(.+)$/
|
126
147
|
"#{$1.length < 14 ? 'catkey' : 'barcode'}:#{$1}"
|
127
148
|
else
|
@@ -153,21 +174,19 @@ module Dor
|
|
153
174
|
:collection => params[:collection],
|
154
175
|
:workflow_priority => params[:workflow_priority]
|
155
176
|
}
|
156
|
-
dor_params.delete_if { |k,v| v.nil? }
|
177
|
+
dor_params.delete_if { |k, v| v.nil? }
|
157
178
|
|
158
|
-
dor_obj =
|
179
|
+
dor_obj = register_object(dor_params)
|
159
180
|
pid = dor_obj.pid
|
160
|
-
location = URI.parse(Dor::Config.fedora.safeurl.sub(/\/*$/,'/')).merge("objects/#{pid}").to_s
|
161
|
-
|
181
|
+
location = URI.parse(Dor::Config.fedora.safeurl.sub(/\/*$/, '/')).merge("objects/#{pid}").to_s
|
182
|
+
dor_params.dup.merge({ :location => location, :pid => pid })
|
162
183
|
end
|
163
184
|
|
164
185
|
private
|
186
|
+
|
165
187
|
def ids_to_hash(ids)
|
166
|
-
if ids.nil?
|
167
|
-
|
168
|
-
else
|
169
|
-
Hash[Array(ids).collect { |id| id.split(/:/) }]
|
170
|
-
end
|
188
|
+
return nil if ids.nil?
|
189
|
+
Hash[Array(ids).map { |id| id.split(/:/) }]
|
171
190
|
end
|
172
191
|
end
|
173
192
|
end
|
@@ -1,30 +1,26 @@
|
|
1
1
|
module Dor
|
2
|
-
|
3
2
|
# Rename the druid trees at the end of the accessionWF in order to be cleaned/deleted later.
|
4
3
|
class ResetWorkspaceService
|
5
4
|
|
6
5
|
def self.reset_workspace_druid_tree(druid, version, workspace_root)
|
7
|
-
|
8
6
|
druid_tree_path = DruidTools::Druid.new(druid, workspace_root).pathname.to_s
|
9
7
|
|
10
|
-
raise "The archived directory #{druid_tree_path}_v#{version} already existed." if File.
|
8
|
+
raise "The archived directory #{druid_tree_path}_v#{version} already existed." if File.exist?("#{druid_tree_path}_v#{version}")
|
11
9
|
|
12
|
-
if File.
|
10
|
+
if File.exist?(druid_tree_path)
|
13
11
|
FileUtils.mv(druid_tree_path, "#{druid_tree_path}_v#{version}")
|
14
|
-
end #Else is a truncated tree where we shouldn't do anything
|
15
|
-
|
12
|
+
end # Else is a truncated tree where we shouldn't do anything
|
16
13
|
end
|
17
14
|
|
18
15
|
def self.reset_export_bag(druid, version, export_root)
|
19
|
-
|
20
16
|
id = druid.split(':').last
|
21
17
|
bag_dir = File.join(export_root, id)
|
22
18
|
|
23
|
-
raise "The archived bag #{bag_dir}_v#{version} already existed." if File.
|
19
|
+
raise "The archived bag #{bag_dir}_v#{version} already existed." if File.exist?("#{bag_dir}_v#{version}")
|
24
20
|
|
25
|
-
FileUtils.mv(bag_dir, "#{bag_dir}_v#{version}") if File.
|
21
|
+
FileUtils.mv(bag_dir, "#{bag_dir}_v#{version}") if File.exist?(bag_dir)
|
26
22
|
|
27
|
-
if File.
|
23
|
+
if File.exist?("#{bag_dir}.tar")
|
28
24
|
FileUtils.mv("#{bag_dir}.tar", "#{bag_dir}_v#{version}.tar")
|
29
25
|
end
|
30
26
|
end
|
@@ -6,9 +6,9 @@ module Dor
|
|
6
6
|
# @param [Dor::Item] dor_item The representation of the digital object
|
7
7
|
# @param [String] agreement_id depreciated, included for backward compatability with common-accessoning
|
8
8
|
# @return [void] Create the moab manifests, export data to a BagIt bag, kick off the SDR ingest workflow
|
9
|
-
def self.transfer(dor_item, agreement_id=nil)
|
9
|
+
def self.transfer(dor_item, agreement_id = nil)
|
10
10
|
druid = dor_item.pid
|
11
|
-
workspace = DruidTools::Druid.new(druid,Dor::Config.sdr.local_workspace_root)
|
11
|
+
workspace = DruidTools::Druid.new(druid, Dor::Config.sdr.local_workspace_root)
|
12
12
|
signature_catalog = get_signature_catalog(druid)
|
13
13
|
new_version_id = signature_catalog.version_id + 1
|
14
14
|
metadata_dir = extract_datastreams(dor_item, workspace)
|
@@ -20,14 +20,14 @@ module Dor
|
|
20
20
|
content_dir = nil
|
21
21
|
else
|
22
22
|
new_file_list = content_addtions.path_list
|
23
|
-
content_dir = workspace.find_filelist_parent('content',new_file_list)
|
23
|
+
content_dir = workspace.find_filelist_parent('content', new_file_list)
|
24
24
|
end
|
25
25
|
content_group = version_inventory.group('content')
|
26
26
|
unless content_group.nil? || content_group.files.empty?
|
27
27
|
signature_catalog.normalize_group_signatures(content_group, content_dir)
|
28
28
|
end
|
29
29
|
# export the bag (in tar format)
|
30
|
-
bag_dir = Pathname(Dor::Config.sdr.local_export_home).join(druid.sub('druid:',''))
|
30
|
+
bag_dir = Pathname(Dor::Config.sdr.local_export_home).join(druid.sub('druid:', ''))
|
31
31
|
bagger = Moab::Bagger.new(version_inventory, signature_catalog, bag_dir)
|
32
32
|
bagger.reset_bag
|
33
33
|
bagger.create_bag_inventory(:depositor)
|
@@ -38,7 +38,7 @@ module Dor
|
|
38
38
|
# Now bootstrap SDR workflow. but do not create the workflows datastream
|
39
39
|
dor_item.initialize_workflow('sdrIngestWF', false)
|
40
40
|
rescue Exception => e
|
41
|
-
raise LyberCore::Exceptions::ItemError.new(druid,
|
41
|
+
raise LyberCore::Exceptions::ItemError.new(druid, 'Export failure', e)
|
42
42
|
end
|
43
43
|
|
44
44
|
# @param [String] druid The object identifier
|
@@ -57,11 +57,11 @@ module Dor
|
|
57
57
|
# @return [Pathname] Pull all the datastreams specified in the configuration file
|
58
58
|
# into the workspace's metadata directory, overwriting existing file if present
|
59
59
|
def self.extract_datastreams(dor_item, workspace)
|
60
|
-
metadata_dir = Pathname.new(workspace.path('metadata',
|
60
|
+
metadata_dir = Pathname.new(workspace.path('metadata', true))
|
61
61
|
Config.sdr.datastreams.to_hash.each_pair do |ds_name, required|
|
62
62
|
ds_name = ds_name.to_s
|
63
63
|
metadata_file = metadata_dir.join("#{ds_name}.xml")
|
64
|
-
metadata_string =
|
64
|
+
metadata_string = get_datastream_content(dor_item, ds_name, required)
|
65
65
|
metadata_file.open('w') { |f| f << metadata_string } if metadata_string
|
66
66
|
end
|
67
67
|
metadata_dir
|
@@ -76,7 +76,7 @@ module Dor
|
|
76
76
|
ds = (ds_name == 'relationshipMetadata' ? 'RELS-EXT' : ds_name)
|
77
77
|
if dor_item.datastreams.keys.include?(ds) && !dor_item.datastreams[ds].new?
|
78
78
|
return dor_item.datastreams[ds].content
|
79
|
-
elsif
|
79
|
+
elsif required == 'optional'
|
80
80
|
return nil
|
81
81
|
else
|
82
82
|
raise "required datastream #{ds_name} not found in DOR"
|
@@ -86,7 +86,7 @@ module Dor
|
|
86
86
|
# @param [Pathname] metadata_dir the location of the metadata directory in the workspace
|
87
87
|
# @param [Integer] expected the version identifer expected to be used in the versionMetadata
|
88
88
|
def self.verify_version_metadata(metadata_dir, expected)
|
89
|
-
vmfile = metadata_dir.join(
|
89
|
+
vmfile = metadata_dir.join('versionMetadata.xml')
|
90
90
|
verify_version_id(vmfile, expected, vmfile_version_id(vmfile))
|
91
91
|
true
|
92
92
|
end
|
@@ -95,7 +95,7 @@ module Dor
|
|
95
95
|
# @param [Integer] expected The version number that should be in the file
|
96
96
|
# @param [Integer] found The version number that is actually in the file
|
97
97
|
def self.verify_version_id(pathname, expected, found)
|
98
|
-
raise "Version mismatch in #{pathname}, expected #{expected}, found #{found}" unless
|
98
|
+
raise "Version mismatch in #{pathname}, expected #{expected}, found #{found}" unless expected == found
|
99
99
|
true
|
100
100
|
end
|
101
101
|
|
@@ -104,7 +104,7 @@ module Dor
|
|
104
104
|
def self.vmfile_version_id(pathname)
|
105
105
|
verify_pathname(pathname)
|
106
106
|
doc = Nokogiri::XML(File.open(pathname.to_s))
|
107
|
-
nodeset = doc.xpath(
|
107
|
+
nodeset = doc.xpath('/versionMetadata/version')
|
108
108
|
version_id = nodeset.last['versionId']
|
109
109
|
version_id.nil? ? nil : version_id.to_i
|
110
110
|
end
|
@@ -127,9 +127,9 @@ module Dor
|
|
127
127
|
def self.get_content_inventory(metadata_dir, druid, version_id)
|
128
128
|
content_metadata = get_content_metadata(metadata_dir)
|
129
129
|
if content_metadata
|
130
|
-
Stanford::ContentInventory.new.inventory_from_cm(content_metadata, druid,
|
130
|
+
Stanford::ContentInventory.new.inventory_from_cm(content_metadata, druid, 'preserve', version_id)
|
131
131
|
else
|
132
|
-
FileInventory.new(:type=>
|
132
|
+
FileInventory.new(:type => 'version', :digital_object_id => druid, :version_id => version_id)
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
@@ -143,7 +143,7 @@ module Dor
|
|
143
143
|
# @param [Pathname] metadata_dir The location of the the object's metadata files
|
144
144
|
# @return [Moab::FileGroup] Traverse the metadata directory and generate a metadata group
|
145
145
|
def self.get_metadata_file_group(metadata_dir)
|
146
|
-
file_group = FileGroup.new(:group_id=>'metadata').group_from_directory(metadata_dir)
|
146
|
+
file_group = FileGroup.new(:group_id => 'metadata').group_from_directory(metadata_dir)
|
147
147
|
file_group
|
148
148
|
end
|
149
149
|
|
@@ -158,7 +158,7 @@ module Dor
|
|
158
158
|
verify_pathname(bag_dir.join('tagmanifest-sha256.txt'))
|
159
159
|
verify_pathname(bag_dir.join('versionAdditions.xml'))
|
160
160
|
verify_pathname(bag_dir.join('versionInventory.xml'))
|
161
|
-
verify_pathname(bag_dir.join('data','metadata','versionMetadata.xml'))
|
161
|
+
verify_pathname(bag_dir.join('data', 'metadata', 'versionMetadata.xml'))
|
162
162
|
true
|
163
163
|
end
|
164
164
|
|
@@ -170,5 +170,4 @@ module Dor
|
|
170
170
|
end
|
171
171
|
|
172
172
|
end
|
173
|
-
|
174
173
|
end
|