dor-services 6.0.5 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dor-services.rb +27 -12
- data/lib/dor/config.rb +45 -42
- data/lib/dor/datastreams/administrative_metadata_ds.rb +137 -44
- data/lib/dor/datastreams/content_metadata_ds.rb +42 -42
- data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
- data/lib/dor/datastreams/default_object_rights_ds.rb +185 -44
- data/lib/dor/datastreams/desc_metadata_ds.rb +36 -28
- data/lib/dor/datastreams/embargo_metadata_ds.rb +12 -14
- data/lib/dor/datastreams/events_ds.rb +10 -10
- data/lib/dor/datastreams/geo_metadata_ds.rb +4 -5
- data/lib/dor/datastreams/identity_metadata_ds.rb +14 -14
- data/lib/dor/datastreams/rights_metadata_ds.rb +23 -23
- data/lib/dor/datastreams/role_metadata_ds.rb +61 -15
- data/lib/dor/datastreams/simple_dublin_core_ds.rb +8 -8
- data/lib/dor/datastreams/version_metadata_ds.rb +10 -12
- data/lib/dor/datastreams/workflow_definition_ds.rb +6 -6
- data/lib/dor/datastreams/workflow_ds.rb +13 -13
- data/lib/dor/exceptions.rb +2 -2
- data/lib/dor/indexers/data_indexer.rb +1 -7
- data/lib/dor/indexers/describable_indexer.rb +1 -1
- data/lib/dor/indexers/identifiable_indexer.rb +0 -2
- data/lib/dor/indexers/processable_indexer.rb +55 -28
- data/lib/dor/indexers/releasable_indexer.rb +2 -2
- data/lib/dor/models/admin_policy_object.rb +4 -4
- data/lib/dor/models/concerns/assembleable.rb +4 -0
- data/lib/dor/models/concerns/contentable.rb +27 -69
- data/lib/dor/models/concerns/describable.rb +14 -29
- data/lib/dor/models/concerns/editable.rb +20 -334
- data/lib/dor/models/concerns/embargoable.rb +7 -11
- data/lib/dor/models/concerns/eventable.rb +5 -1
- data/lib/dor/models/concerns/geoable.rb +4 -4
- data/lib/dor/models/concerns/governable.rb +18 -87
- data/lib/dor/models/concerns/identifiable.rb +15 -75
- data/lib/dor/models/concerns/itemizable.rb +9 -11
- data/lib/dor/models/concerns/preservable.rb +4 -0
- data/lib/dor/models/concerns/processable.rb +30 -129
- data/lib/dor/models/concerns/publishable.rb +6 -55
- data/lib/dor/models/concerns/releaseable.rb +14 -227
- data/lib/dor/models/concerns/rightsable.rb +3 -3
- data/lib/dor/models/concerns/shelvable.rb +4 -49
- data/lib/dor/models/concerns/versionable.rb +21 -44
- data/lib/dor/models/set.rb +1 -1
- data/lib/dor/models/workflow_object.rb +2 -2
- data/lib/dor/services/ability.rb +77 -0
- data/lib/dor/services/cleanup_reset_service.rb +1 -3
- data/lib/dor/services/create_workflow_service.rb +51 -0
- data/lib/dor/services/creative_commons_license_service.rb +31 -0
- data/lib/dor/services/datastream_builder.rb +90 -0
- data/lib/dor/services/digital_stacks_service.rb +3 -21
- data/lib/dor/services/dublin_core_service.rb +40 -0
- data/lib/dor/services/file_metadata_merge_service.rb +67 -0
- data/lib/dor/services/indexing_service.rb +8 -4
- data/lib/dor/services/merge_service.rb +5 -5
- data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
- data/lib/dor/services/metadata_service.rb +6 -8
- data/lib/dor/{models/concerns → services}/mods2dc.xslt +0 -0
- data/lib/dor/services/ontology.rb +35 -0
- data/lib/dor/services/open_data_license_service.rb +20 -0
- data/lib/dor/services/public_desc_metadata_service.rb +21 -14
- data/lib/dor/services/public_xml_service.rb +6 -6
- data/lib/dor/services/publish_metadata_service.rb +100 -0
- data/lib/dor/services/registration_service.rb +43 -46
- data/lib/dor/services/release_tag_service.rb +251 -0
- data/lib/dor/services/reset_workspace_service.rb +1 -3
- data/lib/dor/services/sdr_ingest_service.rb +5 -7
- data/lib/dor/services/search_service.rb +10 -10
- data/lib/dor/services/secondary_file_name_service.rb +10 -0
- data/lib/dor/services/shelving_service.rb +67 -0
- data/lib/dor/services/status_service.rb +121 -0
- data/lib/dor/services/suri_service.rb +3 -5
- data/lib/dor/services/tag_service.rb +100 -0
- data/lib/dor/services/technical_metadata_service.rb +5 -4
- data/lib/dor/services/version_service.rb +84 -0
- data/lib/dor/utils/ng_tidy.rb +1 -1
- data/lib/dor/utils/sdr_client.rb +25 -9
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +13 -13
- data/lib/dor/workflow/process.rb +71 -26
- data/lib/tasks/rdoc.rake +1 -1
- metadata +77 -51
- 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 -80
@@ -3,9 +3,11 @@
|
|
3
3
|
module Dor
|
4
4
|
module Versionable
|
5
5
|
extend ActiveSupport::Concern
|
6
|
+
extend Deprecation
|
7
|
+
self.deprecation_horizon = 'dor-services version 7.0.0'
|
6
8
|
|
7
9
|
included do
|
8
|
-
has_metadata :
|
10
|
+
has_metadata name: 'versionMetadata', type: Dor::VersionMetadataDS, label: 'Version Metadata', autocreate: true
|
9
11
|
end
|
10
12
|
|
11
13
|
# Increments the version number and initializes versioningWF for the object
|
@@ -15,36 +17,12 @@ module Dor
|
|
15
17
|
# @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
|
16
18
|
# @raise [Dor::Exception] if the object hasn't been accessioned, or if a version is already opened
|
17
19
|
def open_new_version(opts = {})
|
18
|
-
|
19
|
-
raise(Dor::Exception, 'Object net yet accessioned') unless
|
20
|
-
opts[:assume_accessioned] || Dor::Config.workflow.client.get_lifecycle('dor', pid, 'accessioned')
|
21
|
-
raise Dor::Exception, 'Object already opened for versioning' if new_version_open?
|
22
|
-
raise Dor::Exception, 'Object currently being accessioned' if Dor::Config.workflow.client.get_active_lifecycle('dor', pid, 'submitted')
|
23
|
-
|
24
|
-
sdr_version = Sdr::Client.current_version pid
|
25
|
-
|
26
|
-
vmd_ds = datastreams['versionMetadata']
|
27
|
-
vmd_ds.sync_then_increment_version sdr_version
|
28
|
-
vmd_ds.save unless self.new_record?
|
29
|
-
|
30
|
-
k = :create_workflows_ds
|
31
|
-
if opts.key?(k)
|
32
|
-
# During local development, Hydrus (or another app w/ local Fedora) does not want to initialize workflows datastream.
|
33
|
-
create_workflow('versioningWF', opts[k])
|
34
|
-
else
|
35
|
-
create_workflow('versioningWF')
|
36
|
-
end
|
37
|
-
|
38
|
-
vmd_upd_info = opts[:vers_md_upd_info]
|
39
|
-
return unless vmd_upd_info
|
40
|
-
|
41
|
-
add_event('open', vmd_upd_info[:opening_user_name], "Version #{vmd_ds.current_version_id} opened")
|
42
|
-
vmd_ds.update_current_version({ :description => vmd_upd_info[:description], :significance => vmd_upd_info[:significance].to_sym })
|
43
|
-
save
|
20
|
+
VersionService.open(self, opts)
|
44
21
|
end
|
22
|
+
deprecation_deprecate open_new_version: 'Use VersionService.open instead'
|
45
23
|
|
46
24
|
def current_version
|
47
|
-
|
25
|
+
versionMetadata.current_version_id
|
48
26
|
end
|
49
27
|
|
50
28
|
# Sets versioningWF:submit-version to completed and initiates accessionWF for the object
|
@@ -57,30 +35,22 @@ module Dor
|
|
57
35
|
# @raise [Dor::Exception] if the object hasn't been opened for versioning, or if accessionWF has
|
58
36
|
# already been instantiated or the current version is missing a tag or description
|
59
37
|
def close_version(opts = {})
|
60
|
-
|
61
|
-
datastreams['versionMetadata'].update_current_version opts
|
62
|
-
datastreams['versionMetadata'].save
|
63
|
-
end
|
64
|
-
|
65
|
-
raise Dor::Exception, 'latest version in versionMetadata requires tag and description before it can be closed' unless datastreams['versionMetadata'].current_version_closeable?
|
66
|
-
raise Dor::Exception, 'Trying to close version on an object not opened for versioning' unless new_version_open?
|
67
|
-
raise Dor::Exception, 'accessionWF already created for versioned object' if Dor::Config.workflow.client.get_active_lifecycle('dor', pid, 'submitted')
|
68
|
-
|
69
|
-
Dor::Config.workflow.client.close_version 'dor', pid, opts.fetch(:start_accession, true) # Default to creating accessionWF when calling close_version
|
38
|
+
VersionService.close(self, opts)
|
70
39
|
end
|
40
|
+
deprecation_deprecate close_version: 'Use VersionService.close instead'
|
71
41
|
|
72
42
|
# @return [Boolean] true if 'opened' lifecycle is active, false otherwise
|
73
43
|
def new_version_open?
|
74
|
-
|
75
|
-
|
76
|
-
false
|
44
|
+
VersionService.new(self).open?
|
77
45
|
end
|
46
|
+
deprecation_deprecate new_version_open?: 'Use VersionService.open? instead'
|
78
47
|
|
48
|
+
# This is used by Argo and the MergeService
|
79
49
|
# @return [Boolean] true if the object is in a state that allows it to be modified.
|
80
50
|
# States that will allow modification are: has not been submitted for accessioning, has an open version or has sdr-ingest set to hold
|
81
51
|
def allows_modification?
|
82
52
|
if Dor::Config.workflow.client.get_lifecycle('dor', pid, 'submitted') &&
|
83
|
-
!
|
53
|
+
!VersionService.new(self).open? &&
|
84
54
|
Dor::Config.workflow.client.get_workflow_status('dor', pid, 'accessionWF', 'sdr-ingest-transfer') != 'hold'
|
85
55
|
false
|
86
56
|
else
|
@@ -89,7 +59,14 @@ module Dor
|
|
89
59
|
end
|
90
60
|
|
91
61
|
# Following chart of processes on this consul page: https://consul.stanford.edu/display/chimera/Versioning+workflows
|
92
|
-
|
93
|
-
|
62
|
+
def start_version
|
63
|
+
open_new_version
|
64
|
+
end
|
65
|
+
deprecation_deprecate start_version: 'use VersionService.open'
|
66
|
+
|
67
|
+
def submit_version
|
68
|
+
close_version
|
69
|
+
end
|
70
|
+
deprecation_deprecate submit_version: 'use VersionService.close'
|
94
71
|
end
|
95
72
|
end
|
data/lib/dor/models/set.rb
CHANGED
@@ -4,7 +4,7 @@ module Dor
|
|
4
4
|
class Set < Dor::Abstract
|
5
5
|
include Publishable
|
6
6
|
|
7
|
-
has_many :members, :
|
7
|
+
has_many :members, property: :is_member_of_collection, class_name: 'ActiveFedora::Base'
|
8
8
|
has_object_type 'set'
|
9
9
|
|
10
10
|
self.resource_indexer = CompositeIndexer.new(
|
@@ -8,7 +8,7 @@ module Dor
|
|
8
8
|
@@repo_cache = {}
|
9
9
|
|
10
10
|
has_object_type 'workflow'
|
11
|
-
has_metadata :
|
11
|
+
has_metadata name: 'workflowDefinition', type: Dor::WorkflowDefinitionDs, label: 'Workflow Definition'
|
12
12
|
|
13
13
|
self.resource_indexer = CompositeIndexer.new(
|
14
14
|
DataIndexer,
|
@@ -53,7 +53,7 @@ module Dor
|
|
53
53
|
datastreams['workflowDefinition'].initial_workflow
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
alias generate_intial_workflow generate_initial_workflow
|
57
57
|
|
58
58
|
# Searches DOR for the workflow definition object. It then caches the workflow repository and xml
|
59
59
|
# @param [String] name the name of the workflow
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
class Ability
|
5
|
+
class << self
|
6
|
+
def can_manage_item?(roles)
|
7
|
+
intersect roles, groups_which_manage_item
|
8
|
+
end
|
9
|
+
|
10
|
+
def can_manage_desc_metadata?(roles)
|
11
|
+
intersect roles, groups_which_manage_desc_metadata
|
12
|
+
end
|
13
|
+
|
14
|
+
def can_manage_system_metadata?(roles)
|
15
|
+
intersect roles, groups_which_manage_system_metadata
|
16
|
+
end
|
17
|
+
|
18
|
+
def can_manage_content?(roles)
|
19
|
+
intersect roles, groups_which_manage_content
|
20
|
+
end
|
21
|
+
|
22
|
+
def can_manage_rights?(roles)
|
23
|
+
intersect roles, groups_which_manage_rights
|
24
|
+
end
|
25
|
+
|
26
|
+
def can_manage_embargo?(roles)
|
27
|
+
intersect roles, groups_which_manage_embargo
|
28
|
+
end
|
29
|
+
|
30
|
+
def can_view_content?(roles)
|
31
|
+
intersect roles, groups_which_view_content
|
32
|
+
end
|
33
|
+
|
34
|
+
def can_view_metadata?(roles)
|
35
|
+
intersect roles, groups_which_view_metadata
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def groups_which_manage_item
|
41
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
|
42
|
+
end
|
43
|
+
|
44
|
+
def groups_which_manage_desc_metadata
|
45
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-apo-metadata']
|
46
|
+
end
|
47
|
+
|
48
|
+
def groups_which_manage_system_metadata
|
49
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
|
50
|
+
end
|
51
|
+
|
52
|
+
def groups_which_manage_content
|
53
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
|
54
|
+
end
|
55
|
+
|
56
|
+
def groups_which_manage_rights
|
57
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
|
58
|
+
end
|
59
|
+
|
60
|
+
def groups_which_manage_embargo
|
61
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
|
62
|
+
end
|
63
|
+
|
64
|
+
def groups_which_view_content
|
65
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
|
66
|
+
end
|
67
|
+
|
68
|
+
def groups_which_view_metadata
|
69
|
+
['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
|
70
|
+
end
|
71
|
+
|
72
|
+
def intersect(arr1, arr2)
|
73
|
+
(arr1 & arr2).length > 0
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -19,9 +19,7 @@ module Dor
|
|
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::Config.workflow.client.get_lifecycle('dor', druid, 'accessioned').nil?
|
23
|
-
last_version -= 1
|
24
|
-
end
|
22
|
+
last_version -= 1 if Dor::Config.workflow.client.get_lifecycle('dor', druid, 'accessioned').nil?
|
25
23
|
last_version
|
26
24
|
end
|
27
25
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
class CreateWorkflowService
|
5
|
+
# Initilizes workflow for the object in the workflow service
|
6
|
+
# It will set the priorty of the new workflow to the current_priority if it is > 0
|
7
|
+
# It will set lane_id from the item's APO default workflow lane
|
8
|
+
# @param [String] name of the workflow to be initialized
|
9
|
+
# @param [Boolean] create_ds create a 'workflows' datastream in Fedora for the object
|
10
|
+
# @param [Integer] priority the workflow's priority level
|
11
|
+
def self.create_workflow(item, name:, create_ds: true, priority: 0)
|
12
|
+
new(item).create_workflow(name: name, create_ds: create_ds, priority: priority)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(item)
|
16
|
+
@item = item
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_workflow(name:, create_ds: true, priority: 0)
|
20
|
+
priority = item.workflows.current_priority if priority == 0
|
21
|
+
opts = { create_ds: create_ds, lane_id: default_workflow_lane }
|
22
|
+
opts[:priority] = priority if priority > 0
|
23
|
+
Dor::Config.workflow.client.create_workflow(Dor::WorkflowObject.initial_repo(name),
|
24
|
+
item.pid,
|
25
|
+
name,
|
26
|
+
Dor::WorkflowObject.initial_workflow(name),
|
27
|
+
opts)
|
28
|
+
item.workflows.content(true) # refresh the copy of the workflows datastream
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :item
|
34
|
+
delegate :admin_policy_object, to: :item
|
35
|
+
|
36
|
+
# Returns the default lane_id from the item's APO. Will return 'default' if the item does not have
|
37
|
+
# and APO, or if the APO does not have a default_lane
|
38
|
+
# @return [String] the lane id
|
39
|
+
def default_workflow_lane
|
40
|
+
return 'default' if admin_policy_object.nil? # TODO: log warning?
|
41
|
+
|
42
|
+
admin_md = admin_policy_object.administrativeMetadata
|
43
|
+
return 'default' unless admin_md.respond_to?(:default_workflow_lane) # Some APOs don't have this datastream
|
44
|
+
|
45
|
+
lane = admin_md.default_workflow_lane
|
46
|
+
return lane unless lane.blank?
|
47
|
+
|
48
|
+
'default'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
class CreativeCommonsLicenseService < Ontology
|
5
|
+
# these hashes map short ("machine") license codes to their corresponding URIs and human readable titles. they
|
6
|
+
# also allow for deprecated entries (via optional :deprecation_warning). clients that use these maps are advised to
|
7
|
+
# only display undeprecated entries, except where a deprecated entry is already in use by an object. e.g., an APO
|
8
|
+
# that already specifies "by_sa" for its default license code could continue displaying that in a list of license options
|
9
|
+
# for editing, preferably with the deprecation warning. but other deprecated entries would be omitted in such a
|
10
|
+
# selectbox.
|
11
|
+
@data = {
|
12
|
+
'by' => { human_readable: 'Attribution 3.0 Unported',
|
13
|
+
uri: 'https://creativecommons.org/licenses/by/3.0/' },
|
14
|
+
'by-sa' => { human_readable: 'Attribution Share Alike 3.0 Unported',
|
15
|
+
uri: 'https://creativecommons.org/licenses/by-sa/3.0/' },
|
16
|
+
'by_sa' => { human_readable: 'Attribution Share Alike 3.0 Unported',
|
17
|
+
uri: 'https://creativecommons.org/licenses/by-sa/3.0/',
|
18
|
+
deprecation_warning: 'license code "by_sa" was a typo in argo, prefer "by-sa"' },
|
19
|
+
'by-nd' => { human_readable: 'Attribution No Derivatives 3.0 Unported',
|
20
|
+
uri: 'https://creativecommons.org/licenses/by-nd/3.0/' },
|
21
|
+
'by-nc' => { human_readable: 'Attribution Non-Commercial 3.0 Unported',
|
22
|
+
uri: 'https://creativecommons.org/licenses/by-nc/3.0/' },
|
23
|
+
'by-nc-sa' => { human_readable: 'Attribution Non-Commercial Share Alike 3.0 Unported',
|
24
|
+
uri: 'https://creativecommons.org/licenses/by-nc-sa/3.0/' },
|
25
|
+
'by-nc-nd' => { human_readable: 'Attribution Non-Commercial, No Derivatives 3.0 Unported',
|
26
|
+
uri: 'https://creativecommons.org/licenses/by-nc-nd/3.0/' },
|
27
|
+
'pdm' => { human_readable: 'Public Domain Mark 1.0',
|
28
|
+
uri: 'https://creativecommons.org/publicdomain/mark/1.0/' }
|
29
|
+
}.freeze
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
# The ContentMetadata and DescMetadata robot are allowed to build the
|
5
|
+
# datastream by reading a file from the /dor/workspace that matches the
|
6
|
+
# datastream name. This allows assembly or pre-assembly to prebuild the
|
7
|
+
# datastreams from templates or using other means
|
8
|
+
# (like the assembly-objectfile gem) and then have those datastreams picked
|
9
|
+
# up and added to the object during accessionWF.
|
10
|
+
#
|
11
|
+
# This class builds that datastream using the content of a file if such a file
|
12
|
+
# exists and is newer than the object's current datastream (see above); otherwise,
|
13
|
+
# builds the datastream by calling build_fooMetadata_datastream.
|
14
|
+
class DatastreamBuilder
|
15
|
+
# @param [ActiveFedora::Base] object The object that contains the datastream
|
16
|
+
# @param [ActiveFedora::Datastream] datastream The datastream object
|
17
|
+
# @param [Boolean] force Should we overwrite existing datastream?
|
18
|
+
# @param [Boolean] required If set to true, raise an error if we can't build the datastream
|
19
|
+
# @return [ActiveFedora::Datastream]
|
20
|
+
def initialize(object:, datastream:, force: false, required: false)
|
21
|
+
@object = object
|
22
|
+
@datastream = datastream
|
23
|
+
@force = force
|
24
|
+
@required = required
|
25
|
+
@filename = find_metadata_file
|
26
|
+
end
|
27
|
+
|
28
|
+
def build
|
29
|
+
# See if datastream exists as a file and if the file's timestamp is newer than datastream's timestamp.
|
30
|
+
if file_newer_than_datastream?
|
31
|
+
create_from_file(filename)
|
32
|
+
elsif force || empty_datastream?
|
33
|
+
create_default
|
34
|
+
end
|
35
|
+
# Check for success.
|
36
|
+
raise "Required datastream #{datastream_name} could not be populated!" if required && empty_datastream?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :datastream, :force, :object, :required, :filename
|
42
|
+
|
43
|
+
def datastream_name
|
44
|
+
datastream.dsid
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_newer_than_datastream?
|
48
|
+
filename && (!datastream_date || file_date > datastream_date)
|
49
|
+
end
|
50
|
+
|
51
|
+
def file_date
|
52
|
+
File.mtime(filename)
|
53
|
+
end
|
54
|
+
|
55
|
+
def datastream_date
|
56
|
+
datastream.createDate
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_from_file(filename)
|
60
|
+
content = File.read(filename)
|
61
|
+
datastream.content = content
|
62
|
+
datastream.ng_xml = Nokogiri::XML(content) if datastream.respond_to?(:ng_xml)
|
63
|
+
datastream.save unless datastream.digital_object.new?
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_default
|
67
|
+
meth = "build_#{datastream_name}_datastream".to_sym
|
68
|
+
return unless object.respond_to?(meth)
|
69
|
+
|
70
|
+
object.public_send(meth, datastream)
|
71
|
+
datastream.save unless datastream.digital_object.new?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Tries to find a file for the datastream.
|
75
|
+
# @param [String] datastream name of a datastream
|
76
|
+
# @return [String, nil] path to datastream or nil
|
77
|
+
def find_metadata_file
|
78
|
+
druid = DruidTools::Druid.new(object.pid, Dor::Config.stacks.local_workspace_root)
|
79
|
+
druid.find_metadata("#{datastream_name}.xml")
|
80
|
+
end
|
81
|
+
|
82
|
+
def empty_datastream?
|
83
|
+
return true if datastream.new?
|
84
|
+
|
85
|
+
return datastream.content.to_s.empty? unless datastream.class.respond_to?(:xml_template)
|
86
|
+
|
87
|
+
datastream.content.to_s.empty? || EquivalentXml.equivalent?(datastream.content, datastream.class.xml_template)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -9,7 +9,7 @@ module Dor
|
|
9
9
|
# @param [Pathname] stacks_object_pathname the stacks location of the digital object
|
10
10
|
# @param [Moab::FileGroupDifference] content_diff the content file version differences report
|
11
11
|
def self.remove_from_stacks(stacks_object_pathname, content_diff)
|
12
|
-
[
|
12
|
+
%i[deleted copydeleted modified].each do |change_type|
|
13
13
|
subset = content_diff.subset(change_type) # {Moab::FileGroupDifferenceSubset}
|
14
14
|
subset.files.each do |moab_file| # {Moab::FileInstanceDifference}
|
15
15
|
moab_signature = moab_file.signatures.first # {Moab::FileSignature}
|
@@ -82,11 +82,11 @@ module Dor
|
|
82
82
|
def self.shelve_to_stacks(workspace_content_pathname, stacks_object_pathname, content_diff)
|
83
83
|
return false if workspace_content_pathname.nil?
|
84
84
|
|
85
|
-
[
|
85
|
+
%i[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}
|
89
|
-
filename =
|
89
|
+
filename = change_type == :modified ? moab_file.basis_path : moab_file.other_path
|
90
90
|
workspace_pathname = workspace_content_pathname.join(filename)
|
91
91
|
stacks_pathname = stacks_object_pathname.join(filename)
|
92
92
|
copy_file(workspace_pathname, stacks_pathname, moab_signature)
|
@@ -115,29 +115,11 @@ module Dor
|
|
115
115
|
false
|
116
116
|
end
|
117
117
|
|
118
|
-
### depricated ???
|
119
|
-
|
120
|
-
# Create a file inside the content directory under the stacks.local_document_cache_root
|
121
|
-
# @param [String] id The druid identifier for the object
|
122
|
-
# @param [String] content The contents of the file to be created
|
123
|
-
# @param [String] filename The name of the file to be created
|
124
|
-
# @return [void]
|
125
|
-
def self.transfer_to_document_store(id, content, filename)
|
126
|
-
druid = DruidTools::PurlDruid.new id, Config.stacks.local_document_cache_root
|
127
|
-
druid.content_dir # create the druid tree if it doesn't exist yet
|
128
|
-
File.open(File.join(druid.content_dir, filename), 'w') { |f| f.write content }
|
129
|
-
end
|
130
|
-
|
131
118
|
# Assumes the digital stacks storage root is mounted to the local file system
|
132
119
|
# TODO: since this is delegating to the Druid, this method may not be necessary
|
133
120
|
def self.prune_stacks_dir(id)
|
134
121
|
stacks_druid_tree = DruidTools::StacksDruid.new(id, Config.stacks.local_stacks_root)
|
135
122
|
stacks_druid_tree.prune!
|
136
123
|
end
|
137
|
-
|
138
|
-
def self.prune_purl_dir(id)
|
139
|
-
druid = DruidTools::PurlDruid.new(id, Dor::Config.stacks.local_document_cache_root)
|
140
|
-
druid.prune!
|
141
|
-
end
|
142
124
|
end
|
143
125
|
end
|