dor-services 5.1.1 → 5.2.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 +8 -8
- data/lib/dor-services.rb +1 -2
- data/lib/dor/config.rb +5 -6
- data/lib/dor/datastreams/content_metadata_ds.rb +17 -20
- data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
- data/lib/dor/datastreams/desc_metadata_ds.rb +7 -7
- data/lib/dor/datastreams/embargo_metadata_ds.rb +2 -7
- data/lib/dor/datastreams/events_ds.rb +9 -9
- data/lib/dor/datastreams/identity_metadata_ds.rb +29 -34
- data/lib/dor/datastreams/rights_metadata_ds.rb +1 -1
- data/lib/dor/datastreams/role_metadata_ds.rb +0 -1
- data/lib/dor/datastreams/simple_dublin_core_ds.rb +12 -13
- data/lib/dor/datastreams/version_metadata_ds.rb +11 -15
- data/lib/dor/datastreams/workflow_definition_ds.rb +18 -22
- data/lib/dor/datastreams/workflow_ds.rb +24 -36
- data/lib/dor/migrations/identifiable/assert_adminPolicy.rb +1 -1
- data/lib/dor/migrations/identifiable/fix_model_assertions.rb +1 -1
- data/lib/dor/migrations/identifiable/record_remediation.rb +2 -2
- data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +1 -1
- data/lib/dor/migrations/identifiable/uriify_contentlocation_refs.rb +1 -1
- data/lib/dor/migrations/processable/unify_workflows.rb +4 -4
- data/lib/dor/migrations/versionable/add_missing_version_md.rb +2 -2
- data/lib/dor/models/assembleable.rb +2 -2
- data/lib/dor/models/collection.rb +1 -0
- data/lib/dor/models/contentable.rb +3 -3
- data/lib/dor/models/describable.rb +16 -13
- data/lib/dor/models/editable.rb +3 -3
- data/lib/dor/models/embargoable.rb +2 -2
- data/lib/dor/models/eventable.rb +2 -2
- data/lib/dor/models/geoable.rb +14 -18
- data/lib/dor/models/governable.rb +1 -1
- data/lib/dor/models/identifiable.rb +36 -57
- data/lib/dor/models/itemizable.rb +6 -6
- data/lib/dor/models/presentable.rb +12 -12
- data/lib/dor/models/preservable.rb +2 -5
- data/lib/dor/models/processable.rb +19 -25
- data/lib/dor/models/publishable.rb +2 -2
- data/lib/dor/models/releaseable.rb +165 -212
- data/lib/dor/models/shelvable.rb +10 -14
- data/lib/dor/models/upgradable.rb +11 -11
- data/lib/dor/models/versionable.rb +16 -21
- data/lib/dor/models/workflow_object.rb +3 -3
- data/lib/dor/services/cleanup_reset_service.rb +32 -27
- data/lib/dor/services/digital_stacks_service.rb +3 -3
- data/lib/dor/services/merge_service.rb +4 -8
- data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
- data/lib/dor/services/metadata_handlers/mdtoolkit_handler.rb +4 -6
- data/lib/dor/services/metadata_service.rb +20 -22
- data/lib/dor/services/registration_service.rb +6 -8
- data/lib/dor/services/reset_workspace_service.rb +14 -16
- data/lib/dor/services/sdr_ingest_service.rb +2 -6
- data/lib/dor/services/search_service.rb +3 -3
- data/lib/dor/services/suri_service.rb +2 -3
- data/lib/dor/services/technical_metadata_service.rb +2 -3
- data/lib/dor/utils/ng_tidy.rb +6 -6
- data/lib/dor/utils/predicate_patch.rb +1 -1
- data/lib/dor/utils/solr_doc_helper.rb +2 -2
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +27 -33
- data/lib/dor/workflow/graph.rb +34 -37
- data/lib/dor/workflow/process.rb +8 -8
- data/lib/tasks/rdoc.rake +5 -5
- metadata +4 -11
- data/bin/dor-indexer +0 -108
- data/bin/dor-indexerd +0 -73
- data/config/certs/robots-dor-dev.crt +0 -29
- data/config/certs/robots-dor-dev.key +0 -27
- data/config/dev_console_env.rb +0 -78
data/lib/dor/models/shelvable.rb
CHANGED
@@ -35,30 +35,26 @@ module Dor
|
|
35
35
|
# @param [Moab::FileGroupDifference] content_diff The differences between the current contentMetadata and the previously ingested version
|
36
36
|
# @param [DruidTools::Druid] workspace_druid the location of the object's files in the workspace area
|
37
37
|
# @return [Pathname] The location of the object's content files in the workspace area
|
38
|
-
def workspace_content_dir
|
38
|
+
def workspace_content_dir(content_diff, workspace_druid)
|
39
39
|
deltas = content_diff.file_deltas
|
40
40
|
filelist = deltas[:modified] + deltas[:added] + deltas[:copyadded].collect{|old,new| new}
|
41
41
|
return nil if filelist.empty?
|
42
42
|
content_pathname = Pathname(workspace_druid.find_filelist_parent('content', filelist))
|
43
43
|
content_pathname
|
44
44
|
end
|
45
|
-
|
46
|
-
|
47
|
-
# get the stack location based on the contentMetadata stacks attribute
|
45
|
+
|
46
|
+
# get the stack location based on the contentMetadata stacks attribute
|
48
47
|
# or using the default value from the config file if it doesn't exist
|
49
48
|
def get_stacks_location
|
50
|
-
|
49
|
+
|
51
50
|
contentMetadataDS = self.datastreams['contentMetadata']
|
52
|
-
unless contentMetadataDS.nil?
|
53
|
-
stacks_location = contentMetadataDS.stacks[0]
|
54
|
-
if stacks_location.start_with?"/" #Absolute stacks path
|
55
|
-
|
56
|
-
|
57
|
-
raise "stacks attribute for item: "+self.id+ " contentMetadata should start with /. The current value is "+stacks_location
|
58
|
-
end
|
59
|
-
end
|
51
|
+
unless contentMetadataDS.nil? || contentMetadataDS.stacks.length == 0
|
52
|
+
stacks_location = contentMetadataDS.stacks[0]
|
53
|
+
return stacks_location if stacks_location.start_with? "/" #Absolute stacks path
|
54
|
+
raise "stacks attribute for item: "+self.id+ " contentMetadata should start with /. The current value is "+stacks_location
|
55
|
+
end
|
60
56
|
return Config.stacks.local_stacks_root #Default stacks
|
61
|
-
|
57
|
+
|
62
58
|
end
|
63
59
|
end
|
64
60
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module Dor
|
2
2
|
module Upgradable
|
3
3
|
|
4
|
-
# The Upgradable mixin is responsible for making sure all DOR objects,
|
5
|
-
# concerns, and datastreams know how to upgrade themselves to the latest
|
4
|
+
# The Upgradable mixin is responsible for making sure all DOR objects,
|
5
|
+
# concerns, and datastreams know how to upgrade themselves to the latest
|
6
6
|
# Chimera/DOR content standards.
|
7
7
|
#
|
8
8
|
# To add a new upgrade:
|
9
9
|
# 1) include Dor::Upgradable within whatever model, datastream, or mixin
|
10
10
|
# you want to make upgradable.
|
11
11
|
# 2) Add a block to the model, datastream, or mixin as follows:
|
12
|
-
#
|
13
|
-
# on_upgrade(v) do |obj|
|
12
|
+
#
|
13
|
+
# on_upgrade(v) do |obj|
|
14
14
|
# # Do whatever needs to be done to obj
|
15
15
|
# end
|
16
16
|
#
|
@@ -20,7 +20,7 @@ module Dor
|
|
20
20
|
# The block can either be defined on the model itself, or in a file
|
21
21
|
# in the dor/migrations/[model] directory. See Dor::Identifiable and
|
22
22
|
# dor/migrations/identifiable/* for an example.
|
23
|
-
|
23
|
+
|
24
24
|
Callback = Struct.new :module, :version, :description, :block
|
25
25
|
|
26
26
|
mattr_accessor :__upgrade_callbacks
|
@@ -28,12 +28,12 @@ module Dor
|
|
28
28
|
def self.add_upgrade_callback c, v, d, &b
|
29
29
|
@@__upgrade_callbacks << Callback.new(c, Gem::Version.new(v), d, b)
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def self.run_upgrade_callbacks(obj, event_handler)
|
33
33
|
relevant = @@__upgrade_callbacks.select { |c| obj.is_a?(c.module) }.sort_by(&:version)
|
34
|
-
results = relevant.collect do |c|
|
34
|
+
results = relevant.collect do |c|
|
35
35
|
result = c.block.call(obj)
|
36
|
-
if result
|
36
|
+
if result && event_handler.respond_to?(:add_event)
|
37
37
|
event_handler.add_event 'remediation', "#{c.module.name} #{c.version}", c.description
|
38
38
|
end
|
39
39
|
if result
|
@@ -43,19 +43,19 @@ module Dor
|
|
43
43
|
end
|
44
44
|
results.any?
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def self.included(base)
|
48
48
|
base.instance_eval do
|
49
49
|
def self.on_upgrade version, desc, &block
|
50
50
|
Dor::Upgradable.add_upgrade_callback self, version, desc, &block
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
Dir[File.join(Dor.root,'dor','migrations',base.name.split(/::/).last.underscore,'*.rb')].each do |migration|
|
54
54
|
require migration
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def upgrade!
|
60
60
|
results = [Dor::Upgradable.run_upgrade_callbacks(self, self)]
|
61
61
|
if self.respond_to?(:datastreams)
|
@@ -16,14 +16,11 @@ module Dor
|
|
16
16
|
# @option opts [Hash] :vers_md_upd_info If present, used to add to the events datastream and set the desc and significance on the versionMetadata datastream
|
17
17
|
# @raise [Dor::Exception] if the object hasn't been accessioned, or if a version is already opened
|
18
18
|
def open_new_version(opts = {})
|
19
|
-
# During local development, we need a way to open a new version
|
20
|
-
# even if the object has not been accessioned.
|
19
|
+
# During local development, we need a way to open a new version even if the object has not been accessioned.
|
21
20
|
raise(Dor::Exception, 'Object net yet accessioned') unless
|
22
|
-
opts[:assume_accessioned] ||
|
23
|
-
|
24
|
-
|
25
|
-
raise Dor::Exception, 'Object already opened for versioning' if(new_version_open?)
|
26
|
-
raise Dor::Exception, 'Object currently being accessioned' if(Dor::WorkflowService.get_active_lifecycle('dor', pid, 'submitted'))
|
21
|
+
opts[:assume_accessioned] || Dor::WorkflowService.get_lifecycle('dor', pid, 'accessioned')
|
22
|
+
raise Dor::Exception, 'Object already opened for versioning' if new_version_open?
|
23
|
+
raise Dor::Exception, 'Object currently being accessioned' if Dor::WorkflowService.get_active_lifecycle('dor', pid, 'submitted')
|
27
24
|
|
28
25
|
sdr_version = Sdr::Client.current_version pid
|
29
26
|
|
@@ -33,20 +30,18 @@ module Dor
|
|
33
30
|
vmd_ds.save unless self.new_object?
|
34
31
|
|
35
32
|
k = :create_workflows_ds
|
36
|
-
if opts.
|
37
|
-
# During local development, Hydrus (or
|
38
|
-
# does not want this call to initialize the workflows datastream.
|
33
|
+
if opts.key?(k)
|
34
|
+
# During local development, Hydrus (or another app w/ local Fedora) does not want to initialize workflows datastream.
|
39
35
|
initialize_workflow('versioningWF', opts[k])
|
40
36
|
else
|
41
37
|
initialize_workflow('versioningWF')
|
42
38
|
end
|
43
39
|
|
44
40
|
vmd_upd_info = opts[:vers_md_upd_info]
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
41
|
+
return unless vmd_upd_info
|
42
|
+
datastreams['events'].add_event("open", vmd_upd_info[:opening_user_name], "Version #{vmd_ds.current_version_id} opened")
|
43
|
+
vmd_ds.update_current_version({:description => vmd_upd_info[:description], :significance => vmd_upd_info[:significance].to_sym})
|
44
|
+
save
|
50
45
|
end
|
51
46
|
|
52
47
|
def current_version
|
@@ -63,27 +58,27 @@ module Dor
|
|
63
58
|
# @raise [Dor::Exception] if the object hasn't been opened for versioning, or if accessionWF has
|
64
59
|
# already been instantiated or the current version is missing a tag or description
|
65
60
|
def close_version(opts={})
|
66
|
-
unless
|
61
|
+
unless opts.empty?
|
67
62
|
datastreams['versionMetadata'].update_current_version opts
|
68
63
|
datastreams['versionMetadata'].save
|
69
64
|
end
|
70
65
|
|
71
|
-
raise Dor::Exception, 'latest version in versionMetadata requires tag and description before it can be closed' unless
|
72
|
-
raise Dor::Exception, 'Trying to close version on an object not opened for versioning' unless
|
73
|
-
raise Dor::Exception, 'accessionWF already created for versioned object' if
|
66
|
+
raise Dor::Exception, 'latest version in versionMetadata requires tag and description before it can be closed' unless datastreams['versionMetadata'].current_version_closeable?
|
67
|
+
raise Dor::Exception, 'Trying to close version on an object not opened for versioning' unless new_version_open?
|
68
|
+
raise Dor::Exception, 'accessionWF already created for versioned object' if Dor::WorkflowService.get_active_lifecycle('dor', pid, 'submitted')
|
74
69
|
|
75
70
|
Dor::WorkflowService.close_version 'dor', pid, opts.fetch(:start_accession, true) # Default to creating accessionWF when calling close_version
|
76
71
|
end
|
77
72
|
|
78
73
|
# @return [Boolean] true if 'opened' lifecycle is active, false otherwise
|
79
74
|
def new_version_open?
|
80
|
-
return true if
|
75
|
+
return true if Dor::WorkflowService.get_active_lifecycle('dor', pid, 'opened')
|
81
76
|
false
|
82
77
|
end
|
83
78
|
|
84
79
|
# @return [Boolean] true if the object is in a state that allows it to be modified. States that will allow modification are: has not been submitted for accessioning, has an open version or has sdr-ingest set to hold
|
85
80
|
def allows_modification?
|
86
|
-
if Dor::WorkflowService.get_lifecycle('dor', pid, 'submitted') && !
|
81
|
+
if Dor::WorkflowService.get_lifecycle('dor', pid, 'submitted') && !new_version_open? && Dor::WorkflowService.get_workflow_status('dor', pid, 'accessionWF', 'sdr-ingest-transfer')!='hold'
|
87
82
|
false
|
88
83
|
else
|
89
84
|
true
|
@@ -12,7 +12,7 @@ module Dor
|
|
12
12
|
has_metadata :name => "workflowDefinition", :type => Dor::WorkflowDefinitionDs, :label => 'Workflow Definition'
|
13
13
|
|
14
14
|
def self.find_by_name(name, opts={})
|
15
|
-
Dor.find_all(%{#{Solrizer.solr_name
|
15
|
+
Dor.find_all(%{#{Solrizer.solr_name 'objectType', :symbol}:"#{self.object_type}" #{Solrizer.solr_name 'workflow_name', :symbol}:"#{name}"}, opts).first
|
16
16
|
end
|
17
17
|
|
18
18
|
# Searches for the workflow definition object in DOR, then
|
@@ -21,7 +21,7 @@ module Dor
|
|
21
21
|
# @param [String] name the name of the workflow
|
22
22
|
# @return [String] the initial workflow xml
|
23
23
|
def self.initial_workflow(name)
|
24
|
-
return @@xml_cache[name] if
|
24
|
+
return @@xml_cache[name] if @@xml_cache.include?(name)
|
25
25
|
|
26
26
|
self.find_and_cache_workflow_xml_and_repo name
|
27
27
|
@@xml_cache[name]
|
@@ -32,7 +32,7 @@ module Dor
|
|
32
32
|
# @param [String] name the name of the workflow
|
33
33
|
# @return [String] the initial workflow xml
|
34
34
|
def self.initial_repo(name)
|
35
|
-
return @@repo_cache[name] if
|
35
|
+
return @@repo_cache[name] if @@repo_cache.include?(name)
|
36
36
|
|
37
37
|
self.find_and_cache_workflow_xml_and_repo name
|
38
38
|
@@repo_cache[name]
|
@@ -4,27 +4,27 @@ module Dor
|
|
4
4
|
|
5
5
|
# Remove all traces of the object's data files from the workspace and export areas
|
6
6
|
class CleanupResetService
|
7
|
-
|
7
|
+
|
8
8
|
# @param [String] druid The identifier for the object whose reset data is to be removed
|
9
9
|
# @return [void] remove copy of the reset data that was exported to preservation core
|
10
10
|
def self.cleanup_by_reset_druid(druid)
|
11
|
-
last_version = get_druid_last_version(druid)
|
11
|
+
last_version = get_druid_last_version(druid)
|
12
12
|
cleanup_reset_workspace_content(druid, last_version, Config.cleanup.local_workspace_root)
|
13
|
-
|
13
|
+
cleanup_assembly_content(druid, Config.cleanup.local_assembly_root)
|
14
14
|
cleanup_reset_export(druid, last_version)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def self.get_druid_last_version(druid)
|
18
18
|
druid_obj = Dor::Item.find(druid)
|
19
19
|
last_version = druid_obj.current_version.to_i
|
20
|
-
|
20
|
+
|
21
21
|
#if the current version is still open, avoid this versioned directory
|
22
|
-
if Dor::WorkflowService.get_lifecycle('dor', druid, 'accessioned').nil? then
|
23
|
-
last_version
|
22
|
+
if Dor::WorkflowService.get_lifecycle('dor', druid, 'accessioned').nil? then
|
23
|
+
last_version -= 1
|
24
24
|
end
|
25
25
|
return last_version
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# @param [String] druid The identifier for the object whose reset data is to be removed
|
29
29
|
# @param [String] base The base directory to delete from
|
30
30
|
# @param [Integer] last_version The last version that the data should be removed until version 1
|
@@ -32,27 +32,26 @@ module Dor
|
|
32
32
|
def self.cleanup_reset_workspace_content(druid,last_version, base)
|
33
33
|
base_druid = DruidTools::Druid.new(druid, base)
|
34
34
|
base_druid_tree = base_druid.pathname.to_s
|
35
|
-
#if it is truncated tree /aa/111/aaa/1111/content,
|
35
|
+
#if it is truncated tree /aa/111/aaa/1111/content,
|
36
36
|
#we should follow the regular cleanup technique
|
37
37
|
|
38
38
|
reset_directories = get_reset_dir_list(last_version, base_druid_tree)
|
39
|
-
reset_directories.each do |path|
|
39
|
+
reset_directories.each do |path|
|
40
40
|
FileUtils.rm_rf(path)
|
41
41
|
end
|
42
42
|
base_druid.prune_ancestors(base_druid.pathname.parent)
|
43
43
|
end
|
44
|
-
|
45
|
-
|
44
|
+
|
46
45
|
# @param [String] base_druid_tree The base directory to delete from
|
47
46
|
# @param [Integer] last_version The last version that the data should be removed until version 1
|
48
47
|
# @return [void] prepares a list of reset directories that should be removed
|
49
48
|
def self.get_reset_dir_list(last_version, base_druid_tree)
|
50
|
-
reset_directories = []
|
51
|
-
for i in 1..last_version
|
49
|
+
reset_directories = []
|
50
|
+
for i in 1..last_version
|
52
51
|
reset_path = "#{base_druid_tree}_v#{i}"
|
53
|
-
reset_directories.append(reset_path) if File.exists?(reset_path)
|
52
|
+
reset_directories.append(reset_path) if File.exists?(reset_path)
|
54
53
|
end
|
55
|
-
return reset_directories
|
54
|
+
return reset_directories
|
56
55
|
end
|
57
56
|
|
58
57
|
# @param [String] druid The identifier for the object whose reset bags data is to be removed
|
@@ -60,41 +59,47 @@ module Dor
|
|
60
59
|
def self.cleanup_reset_export(druid, last_version)
|
61
60
|
id = druid.split(':').last
|
62
61
|
base_bag_directory = File.join(Config.cleanup.local_export_home, id)
|
63
|
-
|
62
|
+
|
64
63
|
bag_dir_list = get_reset_bag_dir_list(last_version, base_bag_directory)
|
65
|
-
bag_dir_list.each do |bag_dir|
|
64
|
+
bag_dir_list.each do |bag_dir|
|
66
65
|
Pathname(bag_dir).rmtree
|
67
66
|
end
|
68
|
-
|
67
|
+
|
69
68
|
bag_tar_list = get_reset_bag_tar_list(last_version, base_bag_directory)
|
70
|
-
bag_tar_list.each do |bag_tar|
|
69
|
+
bag_tar_list.each do |bag_tar|
|
71
70
|
Pathname(bag_tar).rmtree
|
72
71
|
end
|
73
72
|
end
|
74
|
-
|
73
|
+
|
75
74
|
# @param [Integer] last_version The last version that the data should be removed until version 1
|
76
75
|
# @param [String] base_bag_directory The base bag directory including the export home and druid id
|
77
76
|
# @return [void] prepares a list of reset bag directories that should be removed
|
78
77
|
def self.get_reset_bag_dir_list(last_version, base_bag_directory)
|
79
|
-
reset_bags = []
|
78
|
+
reset_bags = []
|
80
79
|
for i in 1..last_version do
|
81
80
|
reset_path = "#{base_bag_directory}_v#{i}"
|
82
|
-
reset_bags.append(reset_path) if File.exists?(reset_path)
|
81
|
+
reset_bags.append(reset_path) if File.exists?(reset_path)
|
83
82
|
end
|
84
|
-
return reset_bags
|
83
|
+
return reset_bags
|
85
84
|
end
|
86
85
|
|
87
86
|
# @param [String] base_bag_directory The base bag directory including the export home and druid id
|
88
87
|
# @param [Integer] last_version The last version that the data should be removed until version 1
|
89
88
|
# @return [void] prepares a list of reset bag tars that should be removed
|
90
89
|
def self.get_reset_bag_tar_list(last_version, base_bag_directory)
|
91
|
-
reset_bags = []
|
90
|
+
reset_bags = []
|
92
91
|
for i in 1..last_version do
|
93
92
|
reset_path = "#{base_bag_directory}_v#{i}.tar"
|
94
|
-
reset_bags.append(reset_path) if File.exists?(reset_path)
|
93
|
+
reset_bags.append(reset_path) if File.exists?(reset_path)
|
95
94
|
end
|
96
|
-
return reset_bags
|
95
|
+
return reset_bags
|
97
96
|
end
|
98
97
|
|
98
|
+
# @param [String] druid The identifier for the object whose data is to be removed
|
99
|
+
# @param [String] base The base directory to delete from
|
100
|
+
# @return [void] remove the object's data files from the assembly area
|
101
|
+
def self.cleanup_assembly_content(druid, base)
|
102
|
+
DruidTools::Druid.new(druid, base).prune!
|
103
|
+
end
|
99
104
|
end
|
100
105
|
end
|
@@ -24,7 +24,7 @@ module Dor
|
|
24
24
|
# @param [Moab::FileSignature] moab_signature The fixity values of the file
|
25
25
|
# @return [Boolean] true if file deleted, false otherwise
|
26
26
|
def self.delete_file(file_pathname, moab_signature)
|
27
|
-
if file_pathname.exist?
|
27
|
+
if file_pathname.exist? && (file_pathname.size == moab_signature.size)
|
28
28
|
file_signature = Moab::FileSignature.new.signature_from_file(file_pathname)
|
29
29
|
if (file_signature == moab_signature)
|
30
30
|
file_pathname.delete
|
@@ -65,7 +65,7 @@ module Dor
|
|
65
65
|
# @param [Moab::FileSignature] moab_signature The fixity values of the file
|
66
66
|
# @return [Boolean] true if file renamed, false otherwise
|
67
67
|
def self.rename_file(old_pathname, new_pathname, moab_signature)
|
68
|
-
if old_pathname.exist?
|
68
|
+
if old_pathname.exist? && (old_pathname.size == moab_signature.size)
|
69
69
|
file_signature = Moab::FileSignature.new.signature_from_file(old_pathname)
|
70
70
|
if (file_signature == moab_signature)
|
71
71
|
new_pathname.parent.mkpath
|
@@ -82,7 +82,7 @@ module Dor
|
|
82
82
|
# @param [Moab::FileGroupDifference] content_diff the content file version differences report
|
83
83
|
def self.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff)
|
84
84
|
return false if workspace_content_pathname.nil?
|
85
|
-
[:added, :copyadded, :modified
|
85
|
+
[:added, :copyadded, :modified].each do |change_type|
|
86
86
|
subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset
|
87
87
|
subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
|
88
88
|
moab_signature = moab_file.signatures.last # {Moab::FileSignature}
|
@@ -2,7 +2,7 @@ module Dor
|
|
2
2
|
|
3
3
|
class MergeService
|
4
4
|
|
5
|
-
def
|
5
|
+
def self.merge_into_primary primary_druid, secondary_druids, tag, logger = nil
|
6
6
|
# TODO test the secondary_obj to see if we've processed it already
|
7
7
|
merge_service = Dor::MergeService.new primary_druid, secondary_druids, tag, logger
|
8
8
|
merge_service.check_objects_editable
|
@@ -24,12 +24,9 @@ module Dor
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def check_objects_editable
|
27
|
-
unless @primary.allows_modification?
|
28
|
-
|
29
|
-
|
30
|
-
if ( non_editable = (@secondary_objs.detect {|obj| ! obj.allows_modification? } ))
|
31
|
-
raise Dor::Exception.new "Secondary object is not editable: #{non_editable.pid}"
|
32
|
-
end
|
27
|
+
raise Dor::Exception.new("Primary object is not editable: #{@primary.pid}") unless @primary.allows_modification?
|
28
|
+
non_editable = @secondary_objs.detect {|obj| !obj.allows_modification? }
|
29
|
+
raise Dor::Exception.new "Secondary object is not editable: #{non_editable.pid}" if non_editable
|
33
30
|
end
|
34
31
|
|
35
32
|
def move_metadata_and_content
|
@@ -47,7 +44,6 @@ module Dor
|
|
47
44
|
primary_cm = @primary.contentMetadata.ng_xml
|
48
45
|
|
49
46
|
@secondary_objs.each do |secondary|
|
50
|
-
|
51
47
|
sec_druid = DruidTools::Druid.new secondary.pid, Dor::Config.stacks.local_workspace_root
|
52
48
|
secondary.contentMetadata.ng_xml.xpath("//resource").each do |src_resource|
|
53
49
|
primary_resource = primary_cm.at_xpath "//resource[attr[@name = 'mergedFromPid']/text() = '#{secondary.pid}' and
|
@@ -21,20 +21,18 @@ handler = Class.new do
|
|
21
21
|
|
22
22
|
def label(metadata)
|
23
23
|
xml = Nokogiri::XML(metadata)
|
24
|
-
if xml.root.nil?
|
25
|
-
return ""
|
26
|
-
end
|
24
|
+
return "" if xml.root.nil?
|
27
25
|
case xml.root.name
|
28
26
|
when 'msDesc' then xml.xpath('/msDesc/msIdentifier/collection').text
|
29
|
-
when 'mods' then
|
27
|
+
when 'mods' then
|
30
28
|
xml.root.add_namespace_definition('mods','http://www.loc.gov/mods/v3')
|
31
29
|
xml.xpath('/mods:mods/mods:titleInfo[1]').xpath('mods:title|mods:nonSort').collect { |n| n.text }.join(' ').strip
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
35
33
|
def prefixes
|
36
|
-
|
34
|
+
%w(mdtoolkit druid)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
|
-
Dor::MetadataService.register(handler)
|
38
|
+
Dor::MetadataService.register(handler)
|
@@ -3,28 +3,28 @@ require 'cache'
|
|
3
3
|
module Dor
|
4
4
|
|
5
5
|
class MetadataError < Exception ; end
|
6
|
-
|
6
|
+
|
7
7
|
# class MetadataHandler
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# def fetch(prefix, identifier)
|
10
10
|
# ### Return metadata for prefix/identifier combo
|
11
11
|
# end
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# def label(metadata)
|
14
14
|
# ### Return a Fedora-compatible label from the metadata format returned by #fetch
|
15
15
|
# end
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# end
|
18
|
-
|
18
|
+
|
19
19
|
class MetadataService
|
20
|
-
|
20
|
+
|
21
21
|
class << self
|
22
22
|
@@cache = Cache.new(nil, nil, 250, 300)
|
23
|
-
|
23
|
+
|
24
24
|
def register(handler_class)
|
25
|
-
|
26
|
-
unless handler_class.instance_methods.include?(method) || handler_class.instance_methods.include?(method.to_sym)
|
27
|
-
raise TypeError, "Metadata handlers must define ##{method
|
25
|
+
%w(fetch label prefixes).each do |method|
|
26
|
+
unless handler_class.instance_methods.include?(method) || handler_class.instance_methods.include?(method.to_sym)
|
27
|
+
raise TypeError, "Metadata handlers must define ##{method}"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
handler = handler_class.new
|
@@ -33,21 +33,21 @@ module Dor
|
|
33
33
|
end
|
34
34
|
return handler
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def known_prefixes
|
38
38
|
return handlers.keys
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def can_resolve?(identifier)
|
42
42
|
(prefix, identifier) = identifier.split(/:/,2)
|
43
43
|
handlers.keys.include?(prefix.to_sym)
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# TODO: Return a prioritized list
|
47
47
|
def resolvable(identifiers)
|
48
48
|
identifiers.select { |identifier| self.can_resolve?(identifier) }
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def fetch(identifier)
|
52
52
|
@@cache.fetch(identifier) do
|
53
53
|
(prefix, identifier) = identifier.split(/:/,2)
|
@@ -61,24 +61,22 @@ module Dor
|
|
61
61
|
handler = handler_for(prefix)
|
62
62
|
handler.label(handler.fetch(prefix, identifier))
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def handler_for(prefix)
|
66
66
|
handler = handlers[prefix.to_sym]
|
67
|
-
if handler.nil?
|
68
|
-
raise MetadataError, "Unkown metadata prefix: #{prefix}"
|
69
|
-
end
|
67
|
+
raise MetadataError, "Unkown metadata prefix: #{prefix}" if handler.nil?
|
70
68
|
return handler
|
71
69
|
end
|
72
|
-
|
70
|
+
|
73
71
|
private
|
74
72
|
def handlers
|
75
73
|
@handlers ||= {}
|
76
74
|
end
|
77
|
-
|
75
|
+
|
78
76
|
end
|
79
|
-
|
77
|
+
|
80
78
|
end
|
81
|
-
|
79
|
+
|
82
80
|
end
|
83
81
|
|
84
82
|
Dir[File.join(File.dirname(__FILE__),'metadata_handlers','*.rb')].each { |handler_file|
|