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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/dor-services.rb +27 -12
  3. data/lib/dor/config.rb +45 -42
  4. data/lib/dor/datastreams/administrative_metadata_ds.rb +137 -44
  5. data/lib/dor/datastreams/content_metadata_ds.rb +42 -42
  6. data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
  7. data/lib/dor/datastreams/default_object_rights_ds.rb +185 -44
  8. data/lib/dor/datastreams/desc_metadata_ds.rb +36 -28
  9. data/lib/dor/datastreams/embargo_metadata_ds.rb +12 -14
  10. data/lib/dor/datastreams/events_ds.rb +10 -10
  11. data/lib/dor/datastreams/geo_metadata_ds.rb +4 -5
  12. data/lib/dor/datastreams/identity_metadata_ds.rb +14 -14
  13. data/lib/dor/datastreams/rights_metadata_ds.rb +23 -23
  14. data/lib/dor/datastreams/role_metadata_ds.rb +61 -15
  15. data/lib/dor/datastreams/simple_dublin_core_ds.rb +8 -8
  16. data/lib/dor/datastreams/version_metadata_ds.rb +10 -12
  17. data/lib/dor/datastreams/workflow_definition_ds.rb +6 -6
  18. data/lib/dor/datastreams/workflow_ds.rb +13 -13
  19. data/lib/dor/exceptions.rb +2 -2
  20. data/lib/dor/indexers/data_indexer.rb +1 -7
  21. data/lib/dor/indexers/describable_indexer.rb +1 -1
  22. data/lib/dor/indexers/identifiable_indexer.rb +0 -2
  23. data/lib/dor/indexers/processable_indexer.rb +55 -28
  24. data/lib/dor/indexers/releasable_indexer.rb +2 -2
  25. data/lib/dor/models/admin_policy_object.rb +4 -4
  26. data/lib/dor/models/concerns/assembleable.rb +4 -0
  27. data/lib/dor/models/concerns/contentable.rb +27 -69
  28. data/lib/dor/models/concerns/describable.rb +14 -29
  29. data/lib/dor/models/concerns/editable.rb +20 -334
  30. data/lib/dor/models/concerns/embargoable.rb +7 -11
  31. data/lib/dor/models/concerns/eventable.rb +5 -1
  32. data/lib/dor/models/concerns/geoable.rb +4 -4
  33. data/lib/dor/models/concerns/governable.rb +18 -87
  34. data/lib/dor/models/concerns/identifiable.rb +15 -75
  35. data/lib/dor/models/concerns/itemizable.rb +9 -11
  36. data/lib/dor/models/concerns/preservable.rb +4 -0
  37. data/lib/dor/models/concerns/processable.rb +30 -129
  38. data/lib/dor/models/concerns/publishable.rb +6 -55
  39. data/lib/dor/models/concerns/releaseable.rb +14 -227
  40. data/lib/dor/models/concerns/rightsable.rb +3 -3
  41. data/lib/dor/models/concerns/shelvable.rb +4 -49
  42. data/lib/dor/models/concerns/versionable.rb +21 -44
  43. data/lib/dor/models/set.rb +1 -1
  44. data/lib/dor/models/workflow_object.rb +2 -2
  45. data/lib/dor/services/ability.rb +77 -0
  46. data/lib/dor/services/cleanup_reset_service.rb +1 -3
  47. data/lib/dor/services/create_workflow_service.rb +51 -0
  48. data/lib/dor/services/creative_commons_license_service.rb +31 -0
  49. data/lib/dor/services/datastream_builder.rb +90 -0
  50. data/lib/dor/services/digital_stacks_service.rb +3 -21
  51. data/lib/dor/services/dublin_core_service.rb +40 -0
  52. data/lib/dor/services/file_metadata_merge_service.rb +67 -0
  53. data/lib/dor/services/indexing_service.rb +8 -4
  54. data/lib/dor/services/merge_service.rb +5 -5
  55. data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
  56. data/lib/dor/services/metadata_service.rb +6 -8
  57. data/lib/dor/{models/concerns → services}/mods2dc.xslt +0 -0
  58. data/lib/dor/services/ontology.rb +35 -0
  59. data/lib/dor/services/open_data_license_service.rb +20 -0
  60. data/lib/dor/services/public_desc_metadata_service.rb +21 -14
  61. data/lib/dor/services/public_xml_service.rb +6 -6
  62. data/lib/dor/services/publish_metadata_service.rb +100 -0
  63. data/lib/dor/services/registration_service.rb +43 -46
  64. data/lib/dor/services/release_tag_service.rb +251 -0
  65. data/lib/dor/services/reset_workspace_service.rb +1 -3
  66. data/lib/dor/services/sdr_ingest_service.rb +5 -7
  67. data/lib/dor/services/search_service.rb +10 -10
  68. data/lib/dor/services/secondary_file_name_service.rb +10 -0
  69. data/lib/dor/services/shelving_service.rb +67 -0
  70. data/lib/dor/services/status_service.rb +121 -0
  71. data/lib/dor/services/suri_service.rb +3 -5
  72. data/lib/dor/services/tag_service.rb +100 -0
  73. data/lib/dor/services/technical_metadata_service.rb +5 -4
  74. data/lib/dor/services/version_service.rb +84 -0
  75. data/lib/dor/utils/ng_tidy.rb +1 -1
  76. data/lib/dor/utils/sdr_client.rb +25 -9
  77. data/lib/dor/version.rb +1 -1
  78. data/lib/dor/workflow/document.rb +13 -13
  79. data/lib/dor/workflow/process.rb +71 -26
  80. data/lib/tasks/rdoc.rake +1 -1
  81. metadata +77 -51
  82. data/config/certs/robots-dor-dev.crt +0 -29
  83. data/config/certs/robots-dor-dev.key +0 -27
  84. data/config/dev_console_env.rb +0 -80
@@ -5,29 +5,15 @@ module Dor
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- belongs_to :admin_policy_object, :property => :is_governed_by, :class_name => 'Dor::AdminPolicyObject'
9
- has_and_belongs_to_many :collections, :property => :is_member_of_collection, :class_name => 'Dor::Collection'
10
- has_and_belongs_to_many :sets, :property => :is_member_of, :class_name => 'Dor::Collection'
8
+ belongs_to :admin_policy_object, property: :is_governed_by, class_name: 'Dor::AdminPolicyObject'
9
+ has_and_belongs_to_many :collections, property: :is_member_of_collection, class_name: 'Dor::Collection'
10
+ has_and_belongs_to_many :sets, property: :is_member_of, class_name: 'Dor::Collection'
11
11
  end
12
12
 
13
13
  def initiate_apo_workflow(name)
14
- create_workflow(name, !self.new_record?)
15
- end
16
-
17
- # Returns the default lane_id from the item's APO. Will return 'default' if the item does not have
18
- # and APO, or if the APO does not have a default_lane
19
- # @return [String] the lane id
20
- def default_workflow_lane
21
- return 'default' if admin_policy_object.nil? # TODO: log warning?
22
-
23
- admin_md = admin_policy_object.datastreams['administrativeMetadata']
24
- return 'default' unless admin_md.respond_to?(:default_workflow_lane) # Some APOs don't have this datastream
25
-
26
- lane = admin_md.default_workflow_lane
27
- return 'default' if lane.blank?
28
-
29
- lane
14
+ CreateWorkflowService.create_workflow(self, name: name, create_ds: !new_record?)
30
15
  end
16
+ deprecation_deprecate initiate_apo_workflow: 'Use Dor::CreateWorkflowService.create_workflow instead'
31
17
 
32
18
  def reset_to_apo_default
33
19
  rightsMetadata.content = admin_policy_object.rightsMetadata.ng_xml
@@ -39,7 +25,7 @@ module Dor
39
25
  end
40
26
 
41
27
  def unshelve_and_unpublish
42
- if self.respond_to? :contentMetadata
28
+ if respond_to? :contentMetadata
43
29
  content_ds = datastreams['contentMetadata']
44
30
  unless content_ds.nil?
45
31
  content_ds.ng_xml.xpath('/contentMetadata/resource//file').each_with_index do |file_node, index|
@@ -82,7 +68,7 @@ module Dor
82
68
  end
83
69
 
84
70
  def rights
85
- return nil unless self.respond_to? :rightsMetadata
71
+ return nil unless respond_to? :rightsMetadata
86
72
  return nil if rightsMetadata.nil?
87
73
 
88
74
  xml = rightsMetadata.ng_xml
@@ -99,72 +85,17 @@ module Dor
99
85
  end
100
86
  end
101
87
 
102
- def groups_which_manage_item
103
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
104
- end
105
-
106
- def groups_which_manage_desc_metadata
107
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-apo-metadata']
108
- end
109
-
110
- def groups_which_manage_system_metadata
111
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
112
- end
88
+ delegate :can_manage_item?, :can_manage_desc_metadata?, :can_manage_system_metadata?,
89
+ :can_manage_content?, :can_manage_rights?, :can_manage_embargo?,
90
+ :can_view_content?, :can_view_metadata?, to: Dor::Ability
113
91
 
114
- def groups_which_manage_content
115
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
116
- end
117
-
118
- def groups_which_manage_rights
119
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
120
- end
121
-
122
- def groups_which_manage_embargo
123
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
124
- end
125
-
126
- def groups_which_view_content
127
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
128
- end
129
-
130
- def groups_which_view_metadata
131
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
132
- end
133
-
134
- def intersect(arr1, arr2)
135
- (arr1 & arr2).length > 0
136
- end
137
-
138
- def can_manage_item?(roles)
139
- intersect roles, groups_which_manage_item
140
- end
141
-
142
- def can_manage_desc_metadata?(roles)
143
- intersect roles, groups_which_manage_desc_metadata
144
- end
145
-
146
- def can_manage_system_metadata?(roles)
147
- intersect roles, groups_which_manage_system_metadata
148
- end
149
-
150
- def can_manage_content?(roles)
151
- intersect roles, groups_which_manage_content
152
- end
153
-
154
- def can_manage_rights?(roles)
155
- intersect roles, groups_which_manage_rights
156
- end
157
-
158
- def can_manage_embargo?(roles)
159
- intersect roles, groups_which_manage_embargo
160
- end
161
-
162
- def can_view_content?(roles)
163
- intersect roles, groups_which_view_content
164
- end
165
-
166
- def can_view_metadata?(roles)
167
- intersect roles, groups_which_view_metadata
168
- end
92
+ deprecation_deprecate can_manage_item?: 'Use Dor::Ability.can_manage_item? instead'
93
+ deprecation_deprecate can_manage_desc_metadata?: 'Use Dor::Ability.can_manage_desc_metadata? instead'
94
+ deprecation_deprecate can_manage_system_metadata?: 'Use Dor::Ability.can_manage_system_metadata? instead'
95
+ deprecation_deprecate can_manage_content?: 'Use Dor::Ability.can_manage_content? instead'
96
+ deprecation_deprecate can_manage_rights?: 'Use Dor::Ability.can_manage_rights? instead'
97
+ deprecation_deprecate can_manage_embargo?: 'Use Dor::Ability.can_manage_embargo? instead'
98
+ deprecation_deprecate can_view_content?: 'Use Dor::Ability.can_view_content? instead'
99
+ deprecation_deprecate can_view_metadata?: 'Use Dor::Ability.can_view_metadata? instead'
169
100
  end
170
101
  end
@@ -9,8 +9,8 @@ module Dor
9
9
  PREVIOUS_CATKEY_TYPE_ID = 'previous_catkey'
10
10
 
11
11
  included do
12
- has_metadata :name => 'DC', :type => SimpleDublinCoreDs, :label => 'Dublin Core Record for self object'
13
- has_metadata :name => 'identityMetadata', :type => Dor::IdentityMetadataDS, :label => 'Identity Metadata'
12
+ has_metadata name: 'DC', type: SimpleDublinCoreDs, label: 'Dublin Core Record for self object'
13
+ has_metadata name: 'identityMetadata', type: Dor::IdentityMetadataDS, label: 'Identity Metadata'
14
14
  end
15
15
 
16
16
  module ClassMethods
@@ -52,7 +52,7 @@ module Dor
52
52
  def source_id=(source_id)
53
53
  identityMetadata.sourceId = source_id
54
54
  end
55
- alias_method :set_source_id, :source_id=
55
+ alias set_source_id source_id=
56
56
  deprecate set_source_id: 'Use source_id= instead'
57
57
 
58
58
  # Convenience method to get the current catkey
@@ -65,9 +65,8 @@ module Dor
65
65
  # @param [String] catkey the new source identifier
66
66
  # @return [String] same value, as per Ruby assignment convention
67
67
  def catkey=(val)
68
- if val != catkey && !catkey.blank? # if there was already a catkey in the record, store that in the "previous" spot (assuming there is no change)
69
- identityMetadata.add_otherId("#{PREVIOUS_CATKEY_TYPE_ID}:#{catkey}")
70
- end
68
+ # if there was already a catkey in the record, store that in the "previous" spot (assuming there is no change)
69
+ identityMetadata.add_otherId("#{PREVIOUS_CATKEY_TYPE_ID}:#{catkey}") if val != catkey && !catkey.blank?
71
70
 
72
71
  if val.blank? # if we are setting the catkey to blank, remove the node from XML
73
72
  remove_other_Id(CATKEY_TYPE_ID)
@@ -87,9 +86,7 @@ module Dor
87
86
  end
88
87
 
89
88
  def add_other_Id(type, val)
90
- if identityMetadata.otherId(type).length > 0
91
- raise 'There is an existing entry for ' + type + ', consider using update_other_Id().'
92
- end
89
+ raise 'There is an existing entry for ' + type + ', consider using update_other_Id().' if identityMetadata.otherId(type).length > 0
93
90
 
94
91
  identityMetadata.add_otherId(type + ':' + val)
95
92
  end
@@ -110,79 +107,22 @@ module Dor
110
107
  .any?
111
108
  end
112
109
 
113
- # turns a tag string into an array with one element per tag part.
114
- # split on ":", disregard leading and trailing whitespace on tokens.
115
- def split_tag_to_arr(tag_str)
116
- tag_str.split(':').map { |str| str.strip }
117
- end
118
-
119
- # turn a tag array back into a tag string with a standard format
120
- def normalize_tag_arr(tag_arr)
121
- tag_arr.join(' : ')
122
- end
123
-
124
- # take a tag string and return a normalized tag string
125
- def normalize_tag(tag_str)
126
- normalize_tag_arr(split_tag_to_arr(tag_str))
127
- end
128
-
129
- # take a proposed tag string and a list of the existing tags for the object being edited. if
130
- # the proposed tag is valid, return it in normalized form. if not, raise an exception with an
131
- # explanatory message.
132
- def validate_and_normalize_tag(tag_str, existing_tag_list)
133
- tag_arr = validate_tag_format(tag_str)
134
-
135
- # note that the comparison for duplicate tags is case-insensitive, but we don't change case as part of the normalized version
136
- # we return, because we want to preserve the user's intended case.
137
- normalized_tag = normalize_tag_arr(tag_arr)
138
- dupe_existing_tag = existing_tag_list.detect { |existing_tag| normalize_tag(existing_tag).casecmp(normalized_tag) == 0 }
139
- if dupe_existing_tag
140
- raise "An existing tag (#{dupe_existing_tag}) is the same, consider using update_tag?"
141
- end
142
-
143
- normalized_tag
144
- end
145
-
146
- # Ensure that an administrative tag meets the proper mininum format
147
- # @param tag_str [String] the tag
148
- # @return [Array] the tag split into an array via ':'
149
- def validate_tag_format(tag_str)
150
- tag_arr = split_tag_to_arr(tag_str)
151
- if tag_arr.length < 2
152
- raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' must have at least 2 elements"
153
- end
154
- if tag_arr.detect { |str| str.empty? }
155
- raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' contains empty elements"
156
- end
157
-
158
- tag_arr
159
- end
160
-
161
110
  # Add an administrative tag to an item, you will need to seperately save the item to write it to fedora
162
111
  # @param tag [string] The tag you wish to add
163
112
  def add_tag(tag)
164
- identity_metadata_ds = identityMetadata
165
- normalized_tag = validate_and_normalize_tag(tag, identity_metadata_ds.tags)
166
- identity_metadata_ds.add_value(:tag, normalized_tag)
113
+ TagService.add(self, tag)
167
114
  end
115
+ deprecation_deprecate add_tag: 'Call TagService.add instead'
168
116
 
169
117
  def remove_tag(tag)
170
- normtag = normalize_tag(tag)
171
- identityMetadata.ng_xml.search('//tag')
172
- .select { |node| normalize_tag(node.content) == normtag }
173
- .each { identityMetadata.ng_xml_will_change! }
174
- .each(&:remove)
175
- .any?
118
+ TagService.remove(self, tag)
176
119
  end
120
+ deprecation_deprecate remove_tag: 'Call TagService.remove instead'
177
121
 
178
122
  def update_tag(old_tag, new_tag)
179
- normtag = normalize_tag(old_tag)
180
- identityMetadata.ng_xml.search('//tag')
181
- .select { |node| normalize_tag(node.content) == normtag }
182
- .each { identityMetadata.ng_xml_will_change! }
183
- .each { |node| node.content = normalize_tag(new_tag) }
184
- .any?
123
+ TagService.update(self, old_tag, new_tag)
185
124
  end
125
+ deprecation_deprecate update_tag: 'Call TagService.update instead'
186
126
 
187
127
  # a regex that can be used to identify the last part of a druid (e.g. oo000oo0001)
188
128
  # @return [Regex] a regular expression to identify the ID part of the druid
@@ -210,12 +150,12 @@ module Dor
210
150
  object_class = Dor.registered_classes[object_type]
211
151
 
212
152
  if object_class
213
- self.instance_of?(object_class) ? self : self.adapt_to(object_class)
153
+ instance_of?(object_class) ? self : adapt_to(object_class)
214
154
  else
215
155
  if ActiveFedora::VERSION < '8'
216
156
  result = super
217
157
  if result.class == Dor::Abstract
218
- self.adapt_to(Dor::Item)
158
+ adapt_to(Dor::Item)
219
159
  else
220
160
  result
221
161
  end
@@ -223,7 +163,7 @@ module Dor
223
163
  begin
224
164
  super
225
165
  rescue ActiveFedora::ModelNotAsserted
226
- self.adapt_to(Dor::Item)
166
+ adapt_to(Dor::Item)
227
167
  end
228
168
  end
229
169
  end
@@ -6,23 +6,24 @@ require 'uri'
6
6
  module Dor
7
7
  module Itemizable
8
8
  extend ActiveSupport::Concern
9
+ extend Deprecation
10
+ self.deprecation_horizon = 'dor-services version 7.0.0'
9
11
 
10
12
  included do
11
- has_metadata :name => 'contentMetadata', :type => Dor::ContentMetadataDS, :label => 'Content Metadata', :control_group => 'M'
13
+ has_metadata name: 'contentMetadata', type: Dor::ContentMetadataDS, label: 'Content Metadata', control_group: 'M'
12
14
  end
13
15
 
14
16
  DIFF_FILENAME = 'cm_inv_diff'
15
17
 
16
18
  # Deletes all cm_inv_diff files in the workspace for the Item
17
19
  def clear_diff_cache
18
- if Dor::Config.stacks.local_workspace_root.nil?
19
- raise ArgumentError, 'Missing Dor::Config.stacks.local_workspace_root'
20
- end
20
+ raise ArgumentError, 'Missing Dor::Config.stacks.local_workspace_root' if Dor::Config.stacks.local_workspace_root.nil?
21
21
 
22
22
  druid = DruidTools::Druid.new(pid, Dor::Config.stacks.local_workspace_root)
23
23
  diff_pattern = File.join(druid.temp_dir, DIFF_FILENAME + '.*')
24
24
  FileUtils.rm_f Dir.glob(diff_pattern)
25
25
  end
26
+ deprecation_deprecate clear_diff_cache: 'No longer used by any DLSS code and will be removed without replacement'
26
27
 
27
28
  # Retrieves file difference manifest for contentMetadata from SDR
28
29
  #
@@ -30,15 +31,12 @@ module Dor
30
31
  # @param [String] version
31
32
  # @return [Moab::FileInventoryDifference] XML contents of cm_inv_diff manifest
32
33
  def get_content_diff(subset = :all, version = nil)
33
- if Dor::Config.stacks.local_workspace_root.nil?
34
- raise Dor::ParameterError, 'Missing Dor::Config.stacks.local_workspace_root'
35
- end
34
+ raise Dor::ParameterError, 'Missing Dor::Config.stacks.local_workspace_root' if Dor::Config.stacks.local_workspace_root.nil?
36
35
 
37
- if !respond_to?(:contentMetadata) || contentMetadata.nil?
38
- raise Dor::Exception, 'Missing contentMetadata datastream'
39
- end
36
+ raise Dor::Exception, 'Missing contentMetadata datastream' if !respond_to?(:contentMetadata) || contentMetadata.nil?
40
37
 
41
- Sdr::Client.get_content_diff(pid, contentMetadata.content, subset, version)
38
+ Sdr::Client.get_content_diff(pid, contentMetadata.content, subset.to_s, version)
42
39
  end
40
+ deprecation_deprecate get_content_diff: 'Use Sdr::Client.get_content_diff instead'
43
41
  end
44
42
  end
@@ -8,6 +8,8 @@ module Dor
8
8
  has_metadata name: 'provenanceMetadata', type: ProvenanceMetadataDS, label: 'Provenance Metadata'
9
9
  end
10
10
 
11
+ # This is invoked by Robots::DorRepo::Accession::ProvenanceMetadata in common-accessioning
12
+ # as well as Argo's ItemsController#fix_missing_provenance
11
13
  def build_provenanceMetadata_datastream(workflow_id, event_text)
12
14
  workflow_provenance = create_workflow_provenance(workflow_id, event_text)
13
15
  ds = datastreams['provenanceMetadata']
@@ -20,6 +22,8 @@ module Dor
20
22
  SdrIngestService.transfer(self, agreement_id)
21
23
  end
22
24
 
25
+ private
26
+
23
27
  # @return [Nokogiri::Document]
24
28
  def create_workflow_provenance(workflow_id, event_text)
25
29
  builder = Nokogiri::XML::Builder.new do |xml|
@@ -5,6 +5,8 @@ require 'equivalent-xml'
5
5
  module Dor
6
6
  module Processable
7
7
  extend ActiveSupport::Concern
8
+ extend Deprecation
9
+ self.deprecation_horizon = 'dor-services version 7.0.0'
8
10
 
9
11
  included do
10
12
  has_metadata name: 'workflows',
@@ -14,135 +16,54 @@ module Dor
14
16
  autocreate: true
15
17
  end
16
18
 
17
- # verbiage we want to use to describe an item when it has completed a particular step
18
- STATUS_CODE_DISP_TXT = {
19
- 0 => 'Unknown Status', # if there are no milestones for the current version, someone likely messed up the versioning process.
20
- 1 => 'Registered',
21
- 2 => 'In accessioning',
22
- 3 => 'In accessioning (described)',
23
- 4 => 'In accessioning (described, published)',
24
- 5 => 'In accessioning (described, published, deposited)',
25
- 6 => 'Accessioned',
26
- 7 => 'Accessioned (indexed)',
27
- 8 => 'Accessioned (indexed, ingested)',
28
- 9 => 'Opened'
29
- }.freeze
30
-
31
- # milestones from accessioning and the order they happen in
32
- STEPS = {
33
- 'registered' => 1,
34
- 'submitted' => 2,
35
- 'described' => 3,
36
- 'published' => 4,
37
- 'deposited' => 5,
38
- 'accessioned' => 6,
39
- 'indexed' => 7,
40
- 'shelved' => 8,
41
- 'opened' => 9
42
- }.freeze
43
-
44
- def empty_datastream?(datastream)
45
- return true if datastream.new?
46
-
47
- if datastream.class.respond_to?(:xml_template)
48
- datastream.content.to_s.empty? || EquivalentXml.equivalent?(datastream.content, datastream.class.xml_template)
49
- else
50
- datastream.content.to_s.empty?
51
- end
52
- end
53
-
54
- # Tries to find a file for the datastream.
55
- # @param [String] datastream name of a datastream
56
- # @return [String, nil] path to datastream or nil
57
- def find_metadata_file(datastream)
58
- druid = DruidTools::Druid.new(pid, Dor::Config.stacks.local_workspace_root)
59
- druid.find_metadata("#{datastream}.xml")
60
- end
61
-
62
- # Builds that datastream using the content of a file if such a file
63
- # exists and is newer than the object's current datastream; otherwise,
19
+ # The ContentMetadata and DescMetadata robot are allowed to build the
20
+ # datastream by reading a file from the /dor/workspace that matches the
21
+ # datastream name. This allows assembly or pre-assembly to prebuild the
22
+ # datastreams from templates or using other means
23
+ # (like the assembly-objectfile gem) and then have those datastreams picked
24
+ # up and added to the object during accessionWF.
25
+ #
26
+ # This method builds that datastream using the content of a file if such a file
27
+ # exists and is newer than the object's current datastream (see above); otherwise,
64
28
  # builds the datastream by calling build_fooMetadata_datastream.
65
29
  # @param [String] datastream name of a datastream (e.g. "fooMetadata")
66
30
  # @param [Boolean] force overwrite existing datastream
67
31
  # @param [Boolean] is_required
68
- # @return [SomeDatastream]
32
+ # @return [ActiveFedora::Datastream]
69
33
  def build_datastream(datastream, force = false, is_required = false)
70
- # See if datastream exists as a file and if the file's timestamp is newer than datastream's timestamp.
71
- ds = datastreams[datastream]
72
- filename = find_metadata_file(datastream)
73
- use_file = filename && (ds.createDate.nil? || File.mtime(filename) >= ds.createDate)
74
- # Build datastream.
75
- if use_file
76
- content = File.read(filename)
77
- ds.content = content
78
- ds.ng_xml = Nokogiri::XML(content) if ds.respond_to?(:ng_xml)
79
- ds.save unless ds.digital_object.new?
80
- elsif force || empty_datastream?(ds)
81
- meth = "build_#{datastream}_datastream".to_sym
82
- if respond_to?(meth)
83
- send(meth, ds)
84
- ds.save unless ds.digital_object.new?
85
- end
86
- end
87
- # Check for success.
88
- raise "Required datastream #{datastream} could not be populated!" if is_required && empty_datastream?(ds)
34
+ ds = datastreams[datastream]
35
+ builder = Dor::DatastreamBuilder.new(object: self,
36
+ datastream: ds,
37
+ force: force,
38
+ required: is_required)
39
+ builder.build
89
40
 
90
41
  ds
91
42
  end
43
+ deprecation_deprecate build_datastream: 'Use Dor::DatastreamBuilder instead'
92
44
 
93
45
  def cleanup
94
46
  CleanupService.cleanup(self)
95
47
  end
96
-
97
- def milestones
98
- @milestones ||= Dor::Config.workflow.client.get_milestones('dor', pid)
99
- end
48
+ deprecation_deprecate cleanup: 'Use CleanupService.cleanup instead'
100
49
 
101
50
  # @return [Hash{Symbol => Object}] including :current_version, :status_code and :status_time
102
51
  def status_info
103
- current_version = '1'
104
- begin
105
- current_version = versionMetadata.current_version_id
106
- rescue
107
- end
108
-
109
- current_milestones = []
110
- # only get steps that are part of accessioning and part of the current version. That can mean they were archived with the current version
111
- # number, or they might be active (no version number).
112
- milestones.each do |m|
113
- if STEPS.keys.include?(m[:milestone]) && (m[:version].nil? || m[:version] == current_version)
114
- current_milestones << m unless m[:milestone] == 'registered' && current_version.to_i > 1
115
- end
116
- end
117
-
118
- status_code = 0
119
- status_time = nil
120
- # for each milestone in the current version, see if it comes after the current 'last' step, if so, make it the last and record the date/time
121
- current_milestones.each do |m|
122
- m_name = m[:milestone]
123
- m_time = m[:at].utc.xmlschema
124
- next unless STEPS.keys.include?(m_name) && (!status_time || m_time > status_time)
125
-
126
- status_code = STEPS[m_name]
127
- status_time = m_time
128
- end
129
-
130
- { :current_version => current_version, :status_code => status_code, :status_time => status_time }
52
+ StatusService.status_info(self)
131
53
  end
54
+ deprecation_deprecate status_info: 'Use StatusService.status_info instead'
132
55
 
133
56
  # @param [Boolean] include_time
134
57
  # @return [String] single composed status from status_info
135
58
  def status(include_time = false)
136
- status_info_hash = status_info
137
- current_version = status_info_hash[:current_version]
138
- status_code = status_info_hash[:status_code]
139
- status_time = status_info_hash[:status_time]
59
+ StatusService.status(self, include_time)
60
+ end
61
+ deprecation_deprecate status: 'Use StatusService.status instead'
140
62
 
141
- # use the translation table to get the appropriate verbage for the latest step
142
- result = "v#{current_version} #{STATUS_CODE_DISP_TXT[status_code]}"
143
- result += " #{format_date(status_time)}" if include_time
144
- result
63
+ def milestones
64
+ StatusService.new(self).milestones
145
65
  end
66
+ deprecation_deprecate status_info: 'Use StatusService#milestones instead'
146
67
 
147
68
  # Initilizes workflow for the object in the workflow service
148
69
  # It will set the priorty of the new workflow to the current_priority if it is > 0
@@ -151,33 +72,13 @@ module Dor
151
72
  # @param [Boolean] create_ds create a 'workflows' datastream in Fedora for the object
152
73
  # @param [Integer] priority the workflow's priority level
153
74
  def create_workflow(name, create_ds = true, priority = 0)
154
- priority = workflows.current_priority if priority == 0
155
- opts = { :create_ds => create_ds, :lane_id => default_workflow_lane }
156
- opts[:priority] = priority if priority > 0
157
- Dor::Config.workflow.client.create_workflow(Dor::WorkflowObject.initial_repo(name), pid, name, Dor::WorkflowObject.initial_workflow(name), opts)
158
- workflows.content(true) # refresh the copy of the workflows datastream
75
+ CreateWorkflowService.create_workflow(self, name: name, create_ds: create_ds, priority: priority)
159
76
  end
77
+ deprecation_deprecate create_workflow: 'Use CreateWorkflowService.create_workflow'
160
78
 
161
79
  def initialize_workflow(name, create_ds = true, priority = 0)
162
80
  warn 'WARNING: initialize_workflow is deprecated, use create_workflow instead'
163
81
  create_workflow(name, create_ds, priority)
164
82
  end
165
-
166
- private
167
-
168
- # handles formating utc date/time to human readable
169
- # XXX: bad form to hardcode TZ here. Code smell abounds.
170
- def format_date(datetime)
171
- d =
172
- if datetime.is_a?(Time)
173
- datetime
174
- else
175
- DateTime.parse(datetime).in_time_zone(ActiveSupport::TimeZone.new('Pacific Time (US & Canada)'))
176
- end
177
- I18n.l(d).strftime('%Y-%m-%d %I:%M%p')
178
- rescue
179
- d = datetime.is_a?(Time) ? datetime : Time.parse(datetime.to_s)
180
- d.strftime('%Y-%m-%d %I:%M%p')
181
- end
182
83
  end
183
84
  end