dor-services 6.0.0 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/dor-services.rb +7 -6
  3. data/lib/dor/certificate_authenticated_rest_resource_factory.rb +2 -1
  4. data/lib/dor/config.rb +38 -37
  5. data/lib/dor/datastreams/administrative_metadata_ds.rb +98 -98
  6. data/lib/dor/datastreams/content_metadata_ds.rb +26 -17
  7. data/lib/dor/datastreams/datastream_spec_solrizer.rb +4 -2
  8. data/lib/dor/datastreams/default_object_rights_ds.rb +10 -7
  9. data/lib/dor/datastreams/desc_metadata_ds.rb +6 -6
  10. data/lib/dor/datastreams/embargo_metadata_ds.rb +94 -94
  11. data/lib/dor/datastreams/events_ds.rb +55 -54
  12. data/lib/dor/datastreams/geo_metadata_ds.rb +7 -6
  13. data/lib/dor/datastreams/identity_metadata_ds.rb +128 -125
  14. data/lib/dor/datastreams/provenance_metadata_ds.rb +3 -1
  15. data/lib/dor/datastreams/rights_metadata_ds.rb +4 -4
  16. data/lib/dor/datastreams/role_metadata_ds.rb +42 -42
  17. data/lib/dor/datastreams/simple_dublin_core_ds.rb +45 -43
  18. data/lib/dor/datastreams/technical_metadata_ds.rb +3 -1
  19. data/lib/dor/datastreams/version_metadata_ds.rb +12 -5
  20. data/lib/dor/datastreams/workflow_definition_ds.rb +74 -73
  21. data/lib/dor/datastreams/workflow_ds.rb +12 -7
  22. data/lib/dor/exceptions.rb +2 -0
  23. data/lib/dor/indexers/data_indexer.rb +16 -0
  24. data/lib/dor/indexers/describable_indexer.rb +2 -0
  25. data/lib/dor/indexers/editable_indexer.rb +2 -0
  26. data/lib/dor/indexers/identifiable_indexer.rb +23 -8
  27. data/lib/dor/indexers/processable_indexer.rb +2 -0
  28. data/lib/dor/indexers/releasable_indexer.rb +2 -0
  29. data/lib/dor/models/abstract.rb +2 -0
  30. data/lib/dor/models/admin_policy_object.rb +2 -0
  31. data/lib/dor/models/agreement.rb +2 -0
  32. data/lib/dor/models/collection.rb +3 -0
  33. data/lib/dor/models/concerns/assembleable.rb +2 -0
  34. data/lib/dor/models/concerns/contentable.rb +5 -2
  35. data/lib/dor/models/concerns/describable.rb +7 -2
  36. data/lib/dor/models/concerns/editable.rb +28 -21
  37. data/lib/dor/models/concerns/embargoable.rb +4 -0
  38. data/lib/dor/models/concerns/eventable.rb +2 -0
  39. data/lib/dor/models/concerns/geoable.rb +2 -0
  40. data/lib/dor/models/concerns/governable.rb +7 -2
  41. data/lib/dor/models/concerns/identifiable.rb +33 -34
  42. data/lib/dor/models/concerns/itemizable.rb +4 -1
  43. data/lib/dor/models/concerns/preservable.rb +2 -0
  44. data/lib/dor/models/concerns/processable.rb +15 -9
  45. data/lib/dor/models/concerns/publishable.rb +9 -4
  46. data/lib/dor/models/concerns/releaseable.rb +21 -11
  47. data/lib/dor/models/concerns/rightsable.rb +2 -0
  48. data/lib/dor/models/concerns/shelvable.rb +6 -2
  49. data/lib/dor/models/concerns/versionable.rb +8 -4
  50. data/lib/dor/models/item.rb +2 -0
  51. data/lib/dor/models/set.rb +2 -0
  52. data/lib/dor/models/workflow_object.rb +5 -1
  53. data/lib/dor/rest_resource_factory.rb +2 -0
  54. data/lib/dor/services/cleanup_reset_service.rb +2 -1
  55. data/lib/dor/services/cleanup_service.rb +2 -1
  56. data/lib/dor/services/digital_stacks_service.rb +3 -1
  57. data/lib/dor/services/indexing_service.rb +3 -1
  58. data/lib/dor/services/merge_service.rb +6 -4
  59. data/lib/dor/services/metadata_handlers/catalog_handler.rb +2 -0
  60. data/lib/dor/services/metadata_service.rb +4 -4
  61. data/lib/dor/services/public_desc_metadata_service.rb +16 -8
  62. data/lib/dor/services/public_xml_service.rb +7 -4
  63. data/lib/dor/services/registration_service.rb +25 -20
  64. data/lib/dor/services/reset_workspace_service.rb +4 -4
  65. data/lib/dor/services/sdr_ingest_service.rb +4 -2
  66. data/lib/dor/services/search_service.rb +8 -9
  67. data/lib/dor/services/suri_service.rb +3 -2
  68. data/lib/dor/services/technical_metadata_service.rb +15 -9
  69. data/lib/dor/services/thumbnail_service.rb +14 -10
  70. data/lib/dor/utils/hydrus_shims.rb +2 -0
  71. data/lib/dor/utils/ng_tidy.rb +3 -7
  72. data/lib/dor/utils/predicate_patch.rb +2 -0
  73. data/lib/dor/utils/sdr_client.rb +3 -0
  74. data/lib/dor/utils/solr_doc_helper.rb +4 -2
  75. data/lib/dor/version.rb +3 -1
  76. data/lib/dor/workflow/document.rb +113 -108
  77. data/lib/dor/workflow/process.rb +90 -87
  78. data/lib/tasks/rdoc.rake +4 -3
  79. metadata +4 -4
@@ -1,27 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dor
2
4
  # Responsible for finding a path to a thumbnail based on the contentMetadata of an object
3
5
  class ThumbnailService
4
6
  # allow the mimetype attribute to be lower or camelcase when searching to make it more robust
5
- MIME_TYPE_FINDER = "@mimetype='image/jp2' or @mimeType='image/jp2'".freeze
7
+ MIME_TYPE_FINDER = "@mimetype='image/jp2' or @mimeType='image/jp2'"
6
8
 
7
9
  # these are the finders we will use to search for a thumb resource in contentMetadata, they will be searched in the order provided, stopping when one is reached
8
10
  THUMB_XPATH_FINDERS = [
9
11
  # first find a file of mimetype jp2 explicitly marked as a thumb in the resource type and with a thumb=yes attribute
10
- { image_type: 'local', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/file[#{MIME_TYPE_FINDER}]"},
12
+ { image_type: 'local', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/file[#{MIME_TYPE_FINDER}]" },
11
13
  # same thing for external files
12
- { image_type: 'external', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/externalFile[#{MIME_TYPE_FINDER}]"},
14
+ { image_type: 'external', finder: "/contentMetadata/resource[@type='thumb' and @thumb='yes']/externalFile[#{MIME_TYPE_FINDER}]" },
13
15
  # next find any image or page resource types with the thumb=yes attribute of mimetype jp2
14
- { image_type: 'local', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/file[#{MIME_TYPE_FINDER}]"},
16
+ { image_type: 'local', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/file[#{MIME_TYPE_FINDER}]" },
15
17
  # same thing for external file
16
- { image_type: 'external', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/externalFile[#{MIME_TYPE_FINDER}]"},
18
+ { image_type: 'external', finder: "/contentMetadata/resource[(@type='page' or @type='image') and @thumb='yes']/externalFile[#{MIME_TYPE_FINDER}]" },
17
19
  # next find a file of mimetype jp2 and resource type=thumb but not marked with the thumb directive
18
- { image_type: 'local', finder: "/contentMetadata/resource[@type='thumb']/file[#{MIME_TYPE_FINDER}]"},
20
+ { image_type: 'local', finder: "/contentMetadata/resource[@type='thumb']/file[#{MIME_TYPE_FINDER}]" },
19
21
  # same thing for external file
20
- { image_type: 'external', finder: "/contentMetadata/resource[@type='thumb']/externalFile[#{MIME_TYPE_FINDER}]"},
22
+ { image_type: 'external', finder: "/contentMetadata/resource[@type='thumb']/externalFile[#{MIME_TYPE_FINDER}]" },
21
23
  # finally find the first page or image resource of mimetype jp2
22
- { image_type: 'local', finder: "/contentMetadata/resource[@type='page' or @type='image']/file[#{MIME_TYPE_FINDER}]"},
24
+ { image_type: 'local', finder: "/contentMetadata/resource[@type='page' or @type='image']/file[#{MIME_TYPE_FINDER}]" },
23
25
  # same thing for external file
24
- { image_type: 'external', finder: "/contentMetadata/resource[@type='page' or @type='image']/externalFile[#{MIME_TYPE_FINDER}]"}
26
+ { image_type: 'external', finder: "/contentMetadata/resource[@type='page' or @type='image']/externalFile[#{MIME_TYPE_FINDER}]" }
25
27
  ].freeze
26
28
 
27
29
  # @params [Dor::Item] object
@@ -34,19 +36,21 @@ module Dor
34
36
  # @return [String] the computed thumb filename, with the druid prefix and a slash in front of it, e.g. oo000oo0001/filenamewith space.jp2
35
37
  def thumb
36
38
  return unless object.respond_to?(:contentMetadata) && object.contentMetadata.present?
39
+
37
40
  cm = object.contentMetadata.ng_xml
38
41
  thumb_image = nil
39
42
 
40
43
  THUMB_XPATH_FINDERS.each do |search_path|
41
44
  thumb_files = cm.xpath(search_path[:finder]) # look for a thumb
42
45
  next if thumb_files.empty?
46
+
43
47
  # if we find one, return the filename based on whether it is a local file or external file
44
48
  thumb_image = if search_path[:image_type] == 'local'
45
49
  "#{object.remove_druid_prefix}/#{thumb_files[0]['id']}"
46
50
  else
47
51
  "#{object.remove_druid_prefix(thumb_files[0]['objectId'])}/#{thumb_files[0]['fileId']}"
48
52
  end
49
- break # break out of the loop so we stop searching
53
+ break # break out of the loop so we stop searching
50
54
  end
51
55
 
52
56
  thumb_image
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hydrus
2
4
  # These shims allow DOR to interact seamlessly with Hydrus' custom models
3
5
  class Item < Dor::Item
@@ -1,5 +1,6 @@
1
- class Nokogiri::XML::Text
1
+ # frozen_string_literal: true
2
2
 
3
+ class Nokogiri::XML::Text
3
4
  def normalize
4
5
  content =~ /\S/ ? content.gsub(/\s+/, ' ').strip : content
5
6
  end
@@ -7,19 +8,15 @@ class Nokogiri::XML::Text
7
8
  def normalize!
8
9
  self.content = normalize
9
10
  end
10
-
11
11
  end
12
12
 
13
13
  class Nokogiri::XML::Node
14
-
15
14
  def normalize_text!
16
15
  xpath('//text()').each { |t| t.normalize! }
17
16
  end
18
-
19
17
  end
20
18
 
21
19
  class Nokogiri::XML::Document
22
-
23
20
  PRETTIFY_XSLT = Nokogiri::XSLT <<-EOC
24
21
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
25
22
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
@@ -29,10 +26,9 @@ class Nokogiri::XML::Document
29
26
  </xsl:copy>
30
27
  </xsl:template>
31
28
  </xsl:stylesheet>
32
- EOC
29
+ EOC
33
30
 
34
31
  def prettify
35
32
  PRETTIFY_XSLT.transform(self).to_xml
36
33
  end
37
-
38
34
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Monkey patch ActiveFedora::RelsExtDatastream.short_predicate to
2
4
  # create missing mappings on the fly.
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'moab'
2
4
  module Sdr
3
5
  class Client
@@ -10,6 +12,7 @@ module Sdr
10
12
  begin
11
13
  doc = Nokogiri::XML xml
12
14
  raise if doc.root.name != 'currentVersion'
15
+
13
16
  return Integer(doc.text)
14
17
  rescue
15
18
  raise "Unable to parse XML from SDR current_version API call: #{xml}"
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SolrDocHelper
2
4
  def add_solr_value(solr_doc, field_name, value, field_type = :default, index_types = [:searchable])
3
5
  case field_type
4
- when :symbol
5
- index_types << field_type
6
+ when :symbol
7
+ index_types << field_type
6
8
  end
7
9
  ::Solrizer.insert_field(solr_doc, field_name, value, *index_types)
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dor
2
- VERSION = '6.0.0'.freeze
4
+ VERSION = '6.0.1'
3
5
  end
@@ -1,130 +1,135 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dor
2
- module Workflow
3
- class Document
4
- include SolrDocHelper
5
- include ::OM::XML::Document
6
-
7
- set_terminology do |t|
8
- t.root(:path => 'workflow')
9
- t.repository(:path => {:attribute => 'repository'})
10
- t.workflowId(:path => {:attribute => 'id'})
11
- t.process do
12
- t.name_(:path => {:attribute => 'name'})
13
- t.status(:path => {:attribute => 'status'})
14
- t.timestamp(:path => {:attribute => 'datetime'}) # , :data_type => :date)
15
- t.elapsed(:path => {:attribute => 'elapsed'})
16
- t.lifecycle(:path => {:attribute => 'lifecycle'})
17
- t.attempts(:path => {:attribute => 'attempts'}, :index_as => [:not_searchable])
18
- t.version(:path => {:attribute => 'version'})
4
+ module Workflow
5
+ class Document
6
+ include SolrDocHelper
7
+ include ::OM::XML::Document
8
+
9
+ set_terminology do |t|
10
+ t.root(:path => 'workflow')
11
+ t.repository(:path => { :attribute => 'repository' })
12
+ t.workflowId(:path => { :attribute => 'id' })
13
+ t.process do
14
+ t.name_(:path => { :attribute => 'name' })
15
+ t.status(:path => { :attribute => 'status' })
16
+ t.timestamp(:path => { :attribute => 'datetime' }) # , :data_type => :date)
17
+ t.elapsed(:path => { :attribute => 'elapsed' })
18
+ t.lifecycle(:path => { :attribute => 'lifecycle' })
19
+ t.attempts(:path => { :attribute => 'attempts' }, :index_as => [:not_searchable])
20
+ t.version(:path => { :attribute => 'version' })
21
+ end
19
22
  end
20
- end
21
23
 
22
- @@definitions = {}
24
+ @@definitions = {}
23
25
 
24
- def initialize(node)
25
- self.ng_xml = Nokogiri::XML(node)
26
- end
26
+ def initialize(node)
27
+ self.ng_xml = Nokogiri::XML(node)
28
+ end
27
29
 
28
- # is this an incomplete workflow with steps that have a priority > 0
29
- def expedited?
30
- processes.any? { |proc| !proc.completed? && proc.priority.to_i > 0 }
31
- end
30
+ # is this an incomplete workflow with steps that have a priority > 0
31
+ def expedited?
32
+ processes.any? { |proc| !proc.completed? && proc.priority.to_i > 0 }
33
+ end
32
34
 
33
- # @return [Integer] value of the first > 0 priority. Defaults to 0
34
- def priority
35
- processes.map {|proc| proc.priority.to_i }.detect(0) {|p| p > 0}
36
- end
35
+ # @return [Integer] value of the first > 0 priority. Defaults to 0
36
+ def priority
37
+ processes.map { |proc| proc.priority.to_i }.detect(0) { |p| p > 0 }
38
+ end
37
39
 
38
- # @return [Boolean] if any process node does not have version, returns true, false otherwise (all processes have version)
39
- def active?
40
- ng_xml.at_xpath('/workflow/process[not(@version)]') ? true : false
41
- end
40
+ # @return [Boolean] if any process node does not have version, returns true, false otherwise (all processes have version)
41
+ def active?
42
+ ng_xml.at_xpath('/workflow/process[not(@version)]') ? true : false
43
+ end
42
44
 
43
- # @return [Dor::WorkflowDefinitionDs]
44
- def definition
45
- @definition ||= begin
46
- if @@definitions.key? workflowId.first
47
- @@definitions[workflowId.first]
48
- else
49
- wfo = Dor::WorkflowObject.find_by_name(workflowId.first)
50
- wf_def = wfo ? wfo.definition : nil
51
- @@definitions[workflowId.first] = wf_def
52
- wf_def
45
+ # @return [Dor::WorkflowDefinitionDs]
46
+ def definition
47
+ @definition ||= begin
48
+ if @@definitions.key? workflowId.first
49
+ @@definitions[workflowId.first]
50
+ else
51
+ wfo = Dor::WorkflowObject.find_by_name(workflowId.first)
52
+ wf_def = wfo ? wfo.definition : nil
53
+ @@definitions[workflowId.first] = wf_def
54
+ wf_def
55
+ end
53
56
  end
54
57
  end
55
- end
56
58
 
57
- def [](value)
58
- processes.find { |p| p.name == value }
59
- end
59
+ def [](value)
60
+ processes.find { |p| p.name == value }
61
+ end
60
62
 
61
- def processes
62
- # if the workflow service didnt return any processes, dont return any processes from the reified wf
63
- return [] if ng_xml.search('/workflow/process').length == 0
64
- @processes ||=
65
- if definition
66
- definition.processes.collect do |process|
67
- node = ng_xml.at("/workflow/process[@name = '#{process.name}']")
68
- process.update!(node, self)
69
- end
70
- else
71
- find_by_terms(:workflow, :process).collect do |x|
72
- pnode = Dor::Workflow::Process.new(repository, workflowId, {})
73
- pnode.update!(x, self)
74
- end.sort_by(&:datetime)
63
+ def processes
64
+ # if the workflow service didnt return any processes, dont return any processes from the reified wf
65
+ return [] if ng_xml.search('/workflow/process').length == 0
66
+
67
+ @processes ||=
68
+ if definition
69
+ definition.processes.collect do |process|
70
+ node = ng_xml.at("/workflow/process[@name = '#{process.name}']")
71
+ process.update!(node, self)
72
+ end
73
+ else
74
+ find_by_terms(:workflow, :process).collect do |x|
75
+ pnode = Dor::Workflow::Process.new(repository, workflowId, {})
76
+ pnode.update!(x, self)
77
+ end.sort_by(&:datetime)
78
+ end
75
79
  end
76
- end
77
80
 
78
- def workflow_should_show_completed?(processes)
79
- processes.all? {|p| ['skipped', 'completed', '', nil].include?(p.status)}
80
- end
81
+ def workflow_should_show_completed?(processes)
82
+ processes.all? { |p| ['skipped', 'completed', '', nil].include?(p.status) }
83
+ end
84
+
85
+ def to_solr(solr_doc = {}, *args)
86
+ wf_name = workflowId.first
87
+ repo = repository.first
88
+ wf_solr_type = :string
89
+ wf_solr_attrs = [:symbol]
90
+ add_solr_value(solr_doc, 'wf', wf_name, wf_solr_type, wf_solr_attrs)
91
+ add_solr_value(solr_doc, 'wf_wps', wf_name, wf_solr_type, wf_solr_attrs)
92
+ add_solr_value(solr_doc, 'wf_wsp', wf_name, wf_solr_type, wf_solr_attrs)
93
+ status = processes.empty? ? 'empty' : (workflow_should_show_completed?(processes) ? 'completed' : 'active')
94
+ errors = processes.count(&:error?)
95
+ add_solr_value(solr_doc, 'workflow_status', [wf_name, status, errors, repo].join('|'), wf_solr_type, wf_solr_attrs)
81
96
 
82
- def to_solr(solr_doc = {}, *args)
83
- wf_name = workflowId.first
84
- repo = repository.first
85
- wf_solr_type = :string
86
- wf_solr_attrs = [:symbol]
87
- add_solr_value(solr_doc, 'wf', wf_name, wf_solr_type, wf_solr_attrs)
88
- add_solr_value(solr_doc, 'wf_wps', wf_name, wf_solr_type, wf_solr_attrs)
89
- add_solr_value(solr_doc, 'wf_wsp', wf_name, wf_solr_type, wf_solr_attrs)
90
- status = processes.empty? ? 'empty' : (workflow_should_show_completed?(processes) ? 'completed' : 'active')
91
- errors = processes.count(&:error?)
92
- add_solr_value(solr_doc, 'workflow_status', [wf_name, status, errors, repo].join('|'), wf_solr_type, wf_solr_attrs)
93
-
94
- processes.each do |process|
95
- next unless process.status.present?
96
- # add a record of the robot having operated on this item, so we can track robot activity
97
- if !process.date_time.blank? && process.status && (process.status == 'completed' || process.status == 'error')
98
- solr_doc["wf_#{wf_name}_#{process.name}_dttsi"] = Time.parse(process.date_time).utc.iso8601
97
+ processes.each do |process|
98
+ next unless process.status.present?
99
+
100
+ # add a record of the robot having operated on this item, so we can track robot activity
101
+ if !process.date_time.blank? && process.status && (process.status == 'completed' || process.status == 'error')
102
+ solr_doc["wf_#{wf_name}_#{process.name}_dttsi"] = Time.parse(process.date_time).utc.iso8601
103
+ end
104
+ # index the error message without the druid so we hopefully get some overlap
105
+ add_solr_value(solr_doc, 'wf_error', "#{wf_name}:#{process.name}:#{process.error_message}", wf_solr_type, wf_solr_attrs) if process.error_message
106
+ add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}", wf_solr_type, wf_solr_attrs)
107
+ add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}:#{process.name}", wf_solr_type, wf_solr_attrs)
108
+ add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
109
+ add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.status}", wf_solr_type, wf_solr_attrs)
110
+ add_solr_value(solr_doc, 'wf_swp', "#{process.status}", wf_solr_type, wf_solr_attrs)
111
+ add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}", wf_solr_type, wf_solr_attrs)
112
+ add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
113
+ next unless process.state != process.status
114
+
115
+ add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.state}:#{process.name}", wf_solr_type, wf_solr_attrs)
116
+ add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.state}", wf_solr_type, wf_solr_attrs)
117
+ add_solr_value(solr_doc, 'wf_swp', "#{process.state}", wf_solr_type, wf_solr_attrs)
118
+ add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}", wf_solr_type, wf_solr_attrs)
119
+ add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
99
120
  end
100
- # index the error message without the druid so we hopefully get some overlap
101
- add_solr_value(solr_doc, 'wf_error', "#{wf_name}:#{process.name}:#{process.error_message}", wf_solr_type, wf_solr_attrs) if process.error_message
102
- add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}", wf_solr_type, wf_solr_attrs)
103
- add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}:#{process.name}", wf_solr_type, wf_solr_attrs)
104
- add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
105
- add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.status}", wf_solr_type, wf_solr_attrs)
106
- add_solr_value(solr_doc, 'wf_swp', "#{process.status}", wf_solr_type, wf_solr_attrs)
107
- add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}", wf_solr_type, wf_solr_attrs)
108
- add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
109
- next unless process.state != process.status
110
- add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.state}:#{process.name}", wf_solr_type, wf_solr_attrs)
111
- add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.state}", wf_solr_type, wf_solr_attrs)
112
- add_solr_value(solr_doc, 'wf_swp', "#{process.state}", wf_solr_type, wf_solr_attrs)
113
- add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}", wf_solr_type, wf_solr_attrs)
114
- add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}:#{process.name}", wf_solr_type, wf_solr_attrs)
115
- end
116
121
 
117
- solr_doc[Solrizer.solr_name('wf_wps', :symbol)].uniq! if solr_doc[Solrizer.solr_name('wf_wps', :symbol)]
118
- solr_doc[Solrizer.solr_name('wf_wsp', :symbol)].uniq! if solr_doc[Solrizer.solr_name('wf_wsp', :symbol)]
119
- solr_doc[Solrizer.solr_name('wf_swp', :symbol)].uniq! if solr_doc[Solrizer.solr_name('wf_swp', :symbol)]
120
- solr_doc['workflow_status'].uniq! if solr_doc['workflow_status']
122
+ solr_doc[Solrizer.solr_name('wf_wps', :symbol)]&.uniq!
123
+ solr_doc[Solrizer.solr_name('wf_wsp', :symbol)]&.uniq!
124
+ solr_doc[Solrizer.solr_name('wf_swp', :symbol)]&.uniq!
125
+ solr_doc['workflow_status']&.uniq!
121
126
 
122
- solr_doc
123
- end
127
+ solr_doc
128
+ end
124
129
 
125
- def inspect
126
- "#<#{self.class.name}:#{object_id}>"
130
+ def inspect
131
+ "#<#{self.class.name}:#{object_id}>"
132
+ end
127
133
  end
128
134
  end
129
135
  end
130
- end
@@ -1,108 +1,111 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dor
2
- module Workflow
3
- class Process
4
- attr_reader :owner, :repo, :workflow
4
+ module Workflow
5
+ class Process
6
+ attr_reader :owner, :repo, :workflow
5
7
 
6
- # @param repo [String] the name of the repository, typically 'dor'
7
- # @param workflow [String] the name of the workflow, e.g. 'assemblyWF'
8
- # @param attrs [Nokogiri::XML::Node, Hash]
9
- def initialize(repo, workflow, attrs)
10
- @workflow = workflow
11
- @repo = repo
12
- if attrs.is_a? Nokogiri::XML::Node
13
- init_from_node(attrs)
14
- else
15
- @attrs = attrs
8
+ # @param repo [String] the name of the repository, typically 'dor'
9
+ # @param workflow [String] the name of the workflow, e.g. 'assemblyWF'
10
+ # @param attrs [Nokogiri::XML::Node, Hash]
11
+ def initialize(repo, workflow, attrs)
12
+ @workflow = workflow
13
+ @repo = repo
14
+ if attrs.is_a? Nokogiri::XML::Node
15
+ init_from_node(attrs)
16
+ else
17
+ @attrs = attrs
18
+ end
16
19
  end
17
- end
18
20
 
19
- def init_from_node(node)
20
- @attrs = {
21
- 'name' => node['name'],
22
- 'sequence' => node['sequence'] ? node['sequence'].to_i : nil,
23
- 'status' => node['status'], # TODO: see how this affects argo
24
- 'lifecycle' => node['lifecycle'],
25
- 'label' => node.at_xpath('label/text()').to_s,
26
- 'batch_limit' => node['batch-limit'] ? node['batch-limit'].to_i : nil,
27
- 'error_limit' => node['error-limit'] ? node['error-limit'].to_i : nil,
28
- 'priority' => node['priority'] ? node['priority'].to_i : 0,
29
- 'prerequisite' => node.xpath('prereq').collect { |p|
30
- repo = (p['repository'].nil? || p['repository'] == @repo ) ? nil : p['repository']
31
- wf = (p['workflow'].nil? || p['workflow'] == @workflow) ? nil : p['workflow']
32
- [repo, wf, p.text.to_s].compact.join(':')
21
+ def init_from_node(node)
22
+ @attrs = {
23
+ 'name' => node['name'],
24
+ 'sequence' => node['sequence'] ? node['sequence'].to_i : nil,
25
+ 'status' => node['status'], # TODO: see how this affects argo
26
+ 'lifecycle' => node['lifecycle'],
27
+ 'label' => node.at_xpath('label/text()').to_s,
28
+ 'batch_limit' => node['batch-limit'] ? node['batch-limit'].to_i : nil,
29
+ 'error_limit' => node['error-limit'] ? node['error-limit'].to_i : nil,
30
+ 'priority' => node['priority'] ? node['priority'].to_i : 0,
31
+ 'prerequisite' => node.xpath('prereq').collect { |p|
32
+ repo = (p['repository'].nil? || p['repository'] == @repo) ? nil : p['repository']
33
+ wf = (p['workflow'].nil? || p['workflow'] == @workflow) ? nil : p['workflow']
34
+ [repo, wf, p.text.to_s].compact.join(':')
35
+ }
33
36
  }
34
- }
35
- end
37
+ end
36
38
 
37
- def name ; @attrs['name'] ; end
38
- def sequence ; @attrs['sequence'] ; end
39
- def lifecycle ; @attrs['lifecycle'] ; end
40
- def label ; @attrs['label'] ; end
41
- def batch_limit ; @attrs['batch_limit'] ; end
42
- def error_limit ; @attrs['error_limit'] ; end
43
- def error_message ; @attrs['errorMessage'] ; end
44
- def prerequisite ; @attrs['prerequisite'] ; end
45
- def status ; @attrs['status'] ; end
46
- def note ; @attrs['note'] ; end
47
- def version ; @attrs['version'] ; end
48
- def priority ; @attrs['priority'] ; end
49
- def completed? ; status == 'completed' ; end
50
- def error? ; status == 'error' ; end
51
- def waiting? ; status == 'waiting' ; end
52
- def date_time ; @attrs['datetime'] ; end
39
+ def name; @attrs['name']; end
40
+ def sequence; @attrs['sequence']; end
41
+ def lifecycle; @attrs['lifecycle']; end
42
+ def label; @attrs['label']; end
43
+ def batch_limit; @attrs['batch_limit']; end
44
+ def error_limit; @attrs['error_limit']; end
45
+ def error_message; @attrs['errorMessage']; end
46
+ def prerequisite; @attrs['prerequisite']; end
47
+ def status; @attrs['status']; end
48
+ def note; @attrs['note']; end
49
+ def version; @attrs['version']; end
50
+ def priority; @attrs['priority']; end
51
+ def completed?; status == 'completed'; end
52
+ def error?; status == 'error'; end
53
+ def waiting?; status == 'waiting'; end
54
+ def date_time; @attrs['datetime']; end
53
55
 
54
- def archived?
55
- @attrs['archived'] =~ /true$/i
56
- end
56
+ def archived?
57
+ @attrs['archived'] =~ /true$/i
58
+ end
57
59
 
58
- def ready?
59
- self.waiting? && !prerequisite.nil? && prerequisite.all? { |pr| (prq = owner[pr]) && prq.completed? }
60
- end
60
+ def ready?
61
+ self.waiting? && !prerequisite.nil? && prerequisite.all? { |pr| (prq = owner[pr]) && prq.completed? }
62
+ end
61
63
 
62
- def blocked?
63
- self.waiting? && !prerequisite.nil? && prerequisite.any? { |pr| (prq = owner[pr]) && (prq.error? || prq.blocked?) }
64
- end
64
+ def blocked?
65
+ self.waiting? && !prerequisite.nil? && prerequisite.any? { |pr| (prq = owner[pr]) && (prq.error? || prq.blocked?) }
66
+ end
65
67
 
66
- def state
67
- if blocked?
68
- 'blocked'
69
- elsif ready?
70
- 'ready'
71
- else
72
- status
68
+ def state
69
+ if blocked?
70
+ 'blocked'
71
+ elsif ready?
72
+ 'ready'
73
+ else
74
+ status
75
+ end
73
76
  end
74
- end
75
77
 
76
- def attempts
77
- @attrs['attempts'].to_i
78
- end
78
+ def attempts
79
+ @attrs['attempts'].to_i
80
+ end
79
81
 
80
- def datetime
81
- @attrs['datetime'] ? Time.parse(@attrs['datetime']) : nil
82
- end
82
+ def datetime
83
+ @attrs['datetime'] ? Time.parse(@attrs['datetime']) : nil
84
+ end
83
85
 
84
- def elapsed
85
- @attrs['elapsed'].nil? ? nil : @attrs['elapsed'].to_f
86
- end
86
+ def elapsed
87
+ @attrs['elapsed'].nil? ? nil : @attrs['elapsed'].to_f
88
+ end
89
+
90
+ # Updates this object with the attributes passed in.
91
+ # @param info [Hash,Nokogiri::XML::Element,NilClass]
92
+ # @param new_owner [Dor::Workflow::Document]
93
+ def update!(info, new_owner)
94
+ raise ArgumentError, 'Owner can not be nil. It must be an instance of Dor::Workflow::Document' unless new_owner
87
95
 
88
- # Updates this object with the attributes passed in.
89
- # @param info [Hash,Nokogiri::XML::Element,NilClass]
90
- # @param new_owner [Dor::Workflow::Document]
91
- def update!(info, new_owner)
92
- raise ArgumentError, 'Owner can not be nil. It must be an instance of Dor::Workflow::Document' unless new_owner
93
- @owner = new_owner
94
- return self if info.nil?
96
+ @owner = new_owner
97
+ return self if info.nil?
95
98
 
96
- if info.is_a? Nokogiri::XML::Node
97
- info = Hash[info.attributes.collect { |k, v| [k, v.value] }]
99
+ if info.is_a? Nokogiri::XML::Node
100
+ info = Hash[info.attributes.collect { |k, v| [k, v.value] }]
101
+ end
102
+ @attrs.merge! info
103
+ self
98
104
  end
99
- @attrs.merge! info
100
- self
101
- end
102
105
 
103
- def to_hash
104
- @attrs.reject { |k, v| v.nil? || v == 0 || (v.respond_to?(:empty?) && v.empty?) }
106
+ def to_hash
107
+ @attrs.reject { |k, v| v.nil? || v == 0 || (v.respond_to?(:empty?) && v.empty?) }
108
+ end
105
109
  end
106
110
  end
107
111
  end
108
- end