dor-services 5.2.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/config/certs/robots-dor-dev.crt +29 -0
- data/config/certs/robots-dor-dev.key +27 -0
- data/config/config_defaults.yml +2 -0
- data/config/dev_console_env.rb +77 -0
- data/lib/dor-services.rb +31 -27
- data/lib/dor/config.rb +25 -19
- data/lib/dor/datastreams/administrative_metadata_ds.rb +19 -20
- data/lib/dor/datastreams/content_metadata_ds.rb +238 -177
- data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
- data/lib/dor/datastreams/default_object_rights_ds.rb +99 -16
- data/lib/dor/datastreams/desc_metadata_ds.rb +37 -34
- data/lib/dor/datastreams/embargo_metadata_ds.rb +16 -16
- data/lib/dor/datastreams/events_ds.rb +2 -2
- data/lib/dor/datastreams/geo_metadata_ds.rb +5 -10
- data/lib/dor/datastreams/identity_metadata_ds.rb +22 -22
- data/lib/dor/datastreams/rights_metadata_ds.rb +43 -32
- data/lib/dor/datastreams/role_metadata_ds.rb +5 -5
- data/lib/dor/datastreams/simple_dublin_core_ds.rb +13 -14
- data/lib/dor/datastreams/version_metadata_ds.rb +22 -23
- data/lib/dor/datastreams/workflow_definition_ds.rb +15 -15
- data/lib/dor/datastreams/workflow_ds.rb +64 -70
- data/lib/dor/exceptions.rb +0 -1
- data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +4 -4
- data/lib/dor/migrations/processable/unify_workflows.rb +1 -1
- data/lib/dor/models/admin_policy_object.rb +4 -4
- data/lib/dor/models/assembleable.rb +2 -3
- data/lib/dor/models/collection.rb +1 -1
- data/lib/dor/models/contentable.rb +113 -108
- data/lib/dor/models/describable.rb +136 -95
- data/lib/dor/models/editable.rb +205 -119
- data/lib/dor/models/embargoable.rb +16 -16
- data/lib/dor/models/eventable.rb +2 -2
- data/lib/dor/models/geoable.rb +3 -3
- data/lib/dor/models/governable.rb +25 -26
- data/lib/dor/models/identifiable.rb +66 -55
- data/lib/dor/models/item.rb +0 -1
- data/lib/dor/models/itemizable.rb +7 -8
- data/lib/dor/models/preservable.rb +7 -8
- data/lib/dor/models/processable.rb +76 -73
- data/lib/dor/models/publishable.rb +25 -30
- data/lib/dor/models/releaseable.rb +118 -155
- data/lib/dor/models/rightsable.rb +2 -3
- data/lib/dor/models/set.rb +1 -1
- data/lib/dor/models/shelvable.rb +8 -10
- data/lib/dor/models/upgradable.rb +5 -6
- data/lib/dor/models/versionable.rb +3 -4
- data/lib/dor/models/workflow_object.rb +15 -16
- data/lib/dor/services/cleanup_reset_service.rb +15 -16
- data/lib/dor/services/cleanup_service.rb +2 -4
- data/lib/dor/services/digital_stacks_service.rb +10 -13
- data/lib/dor/services/merge_service.rb +8 -9
- data/lib/dor/services/metadata_handlers/catalog_handler.rb +1 -1
- data/lib/dor/services/metadata_handlers/mdtoolkit_handler.rb +3 -3
- data/lib/dor/services/metadata_service.rb +19 -20
- data/lib/dor/services/registration_service.rb +80 -61
- data/lib/dor/services/reset_workspace_service.rb +6 -10
- data/lib/dor/services/sdr_ingest_service.rb +15 -16
- data/lib/dor/services/search_service.rb +18 -23
- data/lib/dor/services/suri_service.rb +6 -6
- data/lib/dor/services/technical_metadata_service.rb +27 -44
- data/lib/dor/utils/ng_tidy.rb +3 -3
- data/lib/dor/utils/sdr_client.rb +2 -3
- data/lib/dor/utils/solr_doc_helper.rb +1 -3
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +43 -40
- data/lib/dor/workflow/graph.rb +26 -26
- data/lib/dor/workflow/process.rb +34 -35
- data/lib/tasks/rdoc.rake +5 -5
- metadata +129 -111
- data/lib/dor/models/presentable.rb +0 -146
@@ -20,32 +20,33 @@ module Dor
|
|
20
20
|
t.human
|
21
21
|
end
|
22
22
|
|
23
|
-
t.creative_commons :path => '/use/machine', :type => 'creativeCommons'
|
23
|
+
t.creative_commons :path => '/use/machine[@type=\'creativeCommons\']', :type => 'creativeCommons' do
|
24
|
+
t.uri :path => '@uri'
|
25
|
+
end
|
24
26
|
t.creative_commons_human :path => '/use/human[@type=\'creativeCommons\']'
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
xml.human(:type => "creativeCommons")
|
30
|
-
xml.machine(:type => "creativeCommons")
|
31
|
-
}
|
27
|
+
t.open_data_commons :path => '/use/machine[@type=\'openDataCommons\']', :type => 'openDataCommons' do
|
28
|
+
t.uri :path => '@uri'
|
29
|
+
end
|
30
|
+
t.open_data_commons_human :path => '/use/human[@type=\'openDataCommons\']'
|
32
31
|
end
|
33
32
|
|
34
33
|
def self.xml_template
|
35
34
|
Nokogiri::XML::Builder.new do |xml|
|
36
|
-
xml.rightsMetadata{
|
37
|
-
xml.access(:type => 'discover'){
|
38
|
-
xml.machine{ xml.none }
|
35
|
+
xml.rightsMetadata {
|
36
|
+
xml.access(:type => 'discover') {
|
37
|
+
xml.machine { xml.none }
|
39
38
|
}
|
40
|
-
xml.access(:type => 'read'){
|
41
|
-
xml.machine{ xml.none } # dark default
|
39
|
+
xml.access(:type => 'read') {
|
40
|
+
xml.machine { xml.none } # dark default
|
42
41
|
}
|
43
|
-
xml.use{
|
42
|
+
xml.use {
|
44
43
|
xml.human(:type => 'useAndReproduction')
|
45
|
-
xml.human(:type =>
|
46
|
-
xml.machine(:type =>
|
44
|
+
xml.human(:type => 'creativeCommons')
|
45
|
+
xml.machine(:type => 'creativeCommons', :uri => '')
|
46
|
+
xml.human(:type => 'openDataCommons')
|
47
|
+
xml.machine(:type => 'openDataCommons', :uri => '')
|
47
48
|
}
|
48
|
-
xml.copyright{ xml.human }
|
49
|
+
xml.copyright { xml.human }
|
49
50
|
}
|
50
51
|
end.doc
|
51
52
|
end
|
@@ -57,7 +58,7 @@ module Dor
|
|
57
58
|
end
|
58
59
|
|
59
60
|
def dra_object
|
60
|
-
@dra_object ||= Dor::RightsAuth.parse(
|
61
|
+
@dra_object ||= Dor::RightsAuth.parse(ng_xml, true)
|
61
62
|
end
|
62
63
|
|
63
64
|
# @param rights [string] archetypical rights to assign: 'world', 'stanford', 'none' or 'dark'
|
@@ -66,44 +67,54 @@ module Dor
|
|
66
67
|
# TODO: convert xpath reads to dra_object calls
|
67
68
|
def set_read_rights(rights)
|
68
69
|
raise(ArgumentError, "Argument '#{rights}' is not a recognized value") unless %w(world stanford none dark).include? rights
|
69
|
-
rights_xml =
|
70
|
-
if
|
70
|
+
rights_xml = ng_xml
|
71
|
+
if rights_xml.search('//rightsMetadata/access[@type=\'read\']').length == 0
|
71
72
|
raise('The rights metadata stream doesnt contain an entry for machine read permissions. Consider populating it from the APO before trying to change it.')
|
72
73
|
end
|
73
|
-
label = rights=='dark' ? 'none' : 'world'
|
74
|
+
label = rights == 'dark' ? 'none' : 'world'
|
74
75
|
@dra_object = nil # until TODO complete, we'll expect to have to reparse after modification
|
75
76
|
rights_xml.search('//rightsMetadata/access[@type=\'discover\']/machine').each do |node|
|
76
77
|
node.children.remove
|
77
|
-
node.add_child Nokogiri::XML::Node.new(label,rights_xml)
|
78
|
+
node.add_child Nokogiri::XML::Node.new(label, rights_xml)
|
78
79
|
end
|
79
80
|
rights_xml.search('//rightsMetadata/access[@type=\'read\']').each do |node|
|
80
81
|
node.children.remove
|
81
|
-
machine_node = Nokogiri::XML::Node.new('machine',rights_xml)
|
82
|
+
machine_node = Nokogiri::XML::Node.new('machine', rights_xml)
|
82
83
|
node.add_child(machine_node)
|
83
84
|
if rights == 'world'
|
84
|
-
machine_node.add_child Nokogiri::XML::Node.new(rights,rights_xml)
|
85
|
+
machine_node.add_child Nokogiri::XML::Node.new(rights, rights_xml)
|
85
86
|
elsif rights == 'stanford'
|
86
|
-
group_node = Nokogiri::XML::Node.new('group',rights_xml)
|
87
|
-
group_node.content =
|
87
|
+
group_node = Nokogiri::XML::Node.new('group', rights_xml)
|
88
|
+
group_node.content = 'Stanford'
|
88
89
|
machine_node.add_child(group_node)
|
89
90
|
else # we know it is none or dark by the argument filter (first line)
|
90
|
-
machine_node.add_child Nokogiri::XML::Node.new('none',rights_xml)
|
91
|
+
machine_node.add_child Nokogiri::XML::Node.new('none', rights_xml)
|
91
92
|
end
|
92
93
|
end
|
94
|
+
self.content = rights_xml.to_xml
|
95
|
+
content_will_change!
|
93
96
|
end
|
94
97
|
|
95
|
-
def to_solr(solr_doc=
|
98
|
+
def to_solr(solr_doc = {}, *args)
|
96
99
|
super(solr_doc, *args)
|
97
|
-
dra =
|
100
|
+
dra = dra_object
|
98
101
|
solr_doc['rights_primary_ssi'] = dra.index_elements[:primary]
|
99
102
|
solr_doc['rights_errors_ssim'] = dra.index_elements[:errors] if dra.index_elements[:errors].size > 0
|
100
103
|
solr_doc['rights_characteristics_ssim'] = dra.index_elements[:terms] if dra.index_elements[:terms].size > 0
|
101
104
|
# suppress empties
|
102
|
-
%w
|
103
|
-
solr_doc[key] = solr_doc[key].reject{ |val| val.nil? || val == '' }.flatten unless solr_doc[key].nil?
|
105
|
+
%w(use_statement_ssim copyright_ssim).each do |key|
|
106
|
+
solr_doc[key] = solr_doc[key].reject { |val| val.nil? || val == '' }.flatten unless solr_doc[key].nil?
|
104
107
|
end
|
108
|
+
add_solr_value(solr_doc, 'use_license_machine', use_license, :string, [:stored_sortable])
|
109
|
+
|
105
110
|
solr_doc
|
106
111
|
end
|
107
112
|
|
108
|
-
|
113
|
+
def use_license
|
114
|
+
return creative_commons unless ['', nil].include?(creative_commons)
|
115
|
+
return open_data_commons unless ['', nil].include?(open_data_commons)
|
116
|
+
''
|
117
|
+
end
|
118
|
+
|
119
|
+
end # class
|
109
120
|
end
|
@@ -28,19 +28,19 @@ class RoleMetadataDS < ActiveFedora::OmDatastream
|
|
28
28
|
|
29
29
|
def self.xml_template
|
30
30
|
Nokogiri::XML::Builder.new do |xml|
|
31
|
-
xml.roleMetadata{
|
31
|
+
xml.roleMetadata {
|
32
32
|
}
|
33
33
|
end.doc
|
34
34
|
end
|
35
35
|
|
36
|
-
def to_solr(solr_doc=
|
37
|
-
|
36
|
+
def to_solr(solr_doc = {}, *args)
|
37
|
+
find_by_xpath('/roleMetadata/role/*').each do |actor|
|
38
38
|
role_type = actor.parent['type']
|
39
39
|
val = [actor.at_xpath('identifier/@type'), actor.at_xpath('identifier/text()')].join ':'
|
40
40
|
add_solr_value(solr_doc, "apo_role_#{actor.name}_#{role_type}", val, :string, [:symbol])
|
41
41
|
add_solr_value(solr_doc, "apo_role_#{role_type}", val, :string, [:symbol])
|
42
|
-
if ['dor-apo-manager','dor-apo-depositor'].include? role_type
|
43
|
-
add_solr_value(solr_doc,
|
42
|
+
if ['dor-apo-manager', 'dor-apo-depositor'].include? role_type
|
43
|
+
add_solr_value(solr_doc, 'apo_register_permissions', val, :string, [:symbol, :stored_searchable])
|
44
44
|
end
|
45
45
|
end
|
46
46
|
solr_doc
|
@@ -2,37 +2,36 @@ module Dor
|
|
2
2
|
class SimpleDublinCoreDs < ActiveFedora::OmDatastream
|
3
3
|
|
4
4
|
set_terminology do |t|
|
5
|
-
t.root(:path=>
|
6
|
-
t.title( :index_as=>[:stored_sortable, :stored_searchable], :xmlns =>
|
7
|
-
t.creator( :index_as=>[:stored_sortable, :stored_searchable], :xmlns =>
|
8
|
-
t.identifier(:index_as=>[:symbol, :stored_searchable], :xmlns =>
|
5
|
+
t.root(:path => 'dc', :xmlns => 'http://www.openarchives.org/OAI/2.0/oai_dc/', :schema => 'http://cosimo.stanford.edu/standards/oai_dc/v2/oai_dc.xsd', :namespace_prefix => 'oai_dc', :index_as => [:not_searchable])
|
6
|
+
t.title( :index_as => [:stored_sortable, :stored_searchable], :xmlns => 'http://purl.org/dc/elements/1.1/', :namespace_prefix => 'dc')
|
7
|
+
t.creator( :index_as => [:stored_sortable, :stored_searchable], :xmlns => 'http://purl.org/dc/elements/1.1/', :namespace_prefix => 'dc')
|
8
|
+
t.identifier(:index_as => [:symbol, :stored_searchable], :xmlns => 'http://purl.org/dc/elements/1.1/', :namespace_prefix => 'dc')
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.xml_template
|
12
12
|
builder = Nokogiri::XML::Builder.new do |xml|
|
13
|
-
xml.dc(:xmlns=>
|
14
|
-
'
|
15
|
-
|
16
|
-
|
17
|
-
xml['dc'].identifier
|
13
|
+
xml.dc(:xmlns => 'http://www.openarchives.org/OAI/2.0/oai_dc/', 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/') {
|
14
|
+
xml['dc'].title
|
15
|
+
xml['dc'].creator
|
16
|
+
xml['dc'].identifier
|
18
17
|
}
|
19
18
|
end
|
20
19
|
|
21
|
-
|
20
|
+
builder.doc
|
22
21
|
end
|
23
22
|
|
24
|
-
def to_solr(solr_doc=
|
23
|
+
def to_solr(solr_doc = {}, *args)
|
25
24
|
# There are a whole bunch of namespace-related things that can go
|
26
25
|
# wrong with this terminology. Until it's fixed in OM, ignore them all.
|
27
26
|
|
28
27
|
doc = super solr_doc, *args
|
29
28
|
|
30
|
-
add_solr_value(doc, 'dc_title',
|
31
|
-
add_solr_value(doc, 'dc_creator',
|
29
|
+
add_solr_value(doc, 'dc_title', title.first, :string, [:stored_sortable, :stored_searchable])
|
30
|
+
add_solr_value(doc, 'dc_creator', creator.first, :string, [:stored_sortable, :stored_searchable])
|
32
31
|
|
33
32
|
identifiers = {}
|
34
33
|
|
35
|
-
|
34
|
+
identifier.each { |i| ns, val = i.split(':'); identifiers[ns] ||= val }
|
36
35
|
|
37
36
|
identifiers.each do |ns, val|
|
38
37
|
add_solr_value(doc, "dc_identifier_#{ns}", val, :string, [:stored_sortable, :stored_searchable])
|
@@ -1,16 +1,15 @@
|
|
1
1
|
module Dor
|
2
|
-
|
3
2
|
class VersionTag
|
4
3
|
include Comparable
|
5
4
|
|
6
5
|
attr_reader :major, :minor, :admin
|
7
6
|
|
8
|
-
def <=>(
|
9
|
-
diff = @major <=>
|
7
|
+
def <=>(other)
|
8
|
+
diff = @major <=> other.major
|
10
9
|
return diff if diff != 0
|
11
|
-
diff = @minor <=>
|
10
|
+
diff = @minor <=> other.minor
|
12
11
|
return diff if diff != 0
|
13
|
-
@admin <=>
|
12
|
+
@admin <=> other.admin
|
14
13
|
end
|
15
14
|
|
16
15
|
# @param [String] raw_tag the value of the tag attribute from a Version node
|
@@ -51,10 +50,10 @@ module Dor
|
|
51
50
|
before_create :ensure_non_versionable
|
52
51
|
|
53
52
|
set_terminology do |t|
|
54
|
-
t.root(:path =>
|
53
|
+
t.root(:path => 'versionMetadata')
|
55
54
|
t.version do
|
56
|
-
t.version_id :path => { :attribute =>
|
57
|
-
t.tag :path => { :attribute =>
|
55
|
+
t.version_id :path => { :attribute => 'versionID' }
|
56
|
+
t.tag :path => { :attribute => 'tag' }
|
58
57
|
t.description
|
59
58
|
end
|
60
59
|
end
|
@@ -68,21 +67,21 @@ module Dor
|
|
68
67
|
}
|
69
68
|
}
|
70
69
|
end
|
71
|
-
|
70
|
+
builder.doc
|
72
71
|
end
|
73
72
|
|
74
73
|
def ensure_non_versionable
|
75
|
-
self.versionable =
|
74
|
+
self.versionable = 'false'
|
76
75
|
end
|
77
76
|
|
78
77
|
# @param [String] description optional text describing version change
|
79
78
|
# @param [Symbol] significance optional which part of the version tag to increment
|
80
79
|
# :major, :minor, :admin (see VersionTag#increment)
|
81
80
|
def increment_version(description = nil, significance = nil)
|
82
|
-
if
|
83
|
-
v = ng_xml.create_element
|
81
|
+
if find_by_terms(:version).size == 0
|
82
|
+
v = ng_xml.create_element 'version',
|
84
83
|
:versionId => '1', :tag => '1.0.0'
|
85
|
-
d = ng_xml.create_element
|
84
|
+
d = ng_xml.create_element 'description', 'Initial Version'
|
86
85
|
ng_xml.root['objectId'] = pid
|
87
86
|
ng_xml.root.add_child(v)
|
88
87
|
v.add_child d
|
@@ -91,7 +90,7 @@ module Dor
|
|
91
90
|
current_id = current[:versionId].to_i
|
92
91
|
current_tag = VersionTag.parse(current[:tag])
|
93
92
|
|
94
|
-
v = ng_xml.create_element
|
93
|
+
v = ng_xml.create_element 'version', :versionId => (current_id + 1).to_s
|
95
94
|
if significance && current_tag
|
96
95
|
v[:tag] = current_tag.increment(significance).to_s
|
97
96
|
end
|
@@ -99,7 +98,7 @@ module Dor
|
|
99
98
|
ng_xml.root.add_child(v)
|
100
99
|
|
101
100
|
if description
|
102
|
-
d = ng_xml.create_element
|
101
|
+
d = ng_xml.create_element 'description', description
|
103
102
|
v.add_child d
|
104
103
|
end
|
105
104
|
end
|
@@ -107,7 +106,7 @@ module Dor
|
|
107
106
|
|
108
107
|
# @return [String] value of the most current versionId
|
109
108
|
def current_version_id
|
110
|
-
current_version=current_version_node
|
109
|
+
current_version = current_version_node
|
111
110
|
if current_version.nil?
|
112
111
|
return '1'
|
113
112
|
else
|
@@ -129,7 +128,7 @@ module Dor
|
|
129
128
|
if d
|
130
129
|
d.content = opts[:description]
|
131
130
|
else
|
132
|
-
d_node = ng_xml.create_element
|
131
|
+
d_node = ng_xml.create_element 'description', opts[:description]
|
133
132
|
current.add_child d_node
|
134
133
|
end
|
135
134
|
end
|
@@ -140,7 +139,7 @@ module Dor
|
|
140
139
|
else
|
141
140
|
# get rid of the current tag
|
142
141
|
tags = find_by_terms(:version, :tag)
|
143
|
-
sorted_tags = tags.map{|t| VersionTag.parse(t.value)}.sort
|
142
|
+
sorted_tags = tags.map {|t| VersionTag.parse(t.value)}.sort
|
144
143
|
current_tag = sorted_tags[sorted_tags.length - 2] # Get the second greatest tag since we are dropping the current, greatest
|
145
144
|
current[:tag] = current_tag.increment(opts[:significance]).to_s
|
146
145
|
end
|
@@ -165,7 +164,7 @@ module Dor
|
|
165
164
|
end
|
166
165
|
|
167
166
|
def tag_for_version(versionId)
|
168
|
-
nodes=
|
167
|
+
nodes = ng_xml.search('//version[@versionId=\'' + versionId + '\']')
|
169
168
|
if nodes.length == 1
|
170
169
|
nodes.first['tag'].to_s
|
171
170
|
else
|
@@ -175,7 +174,7 @@ module Dor
|
|
175
174
|
|
176
175
|
# @return [String] The description for the specified version, or empty string if there is no description
|
177
176
|
def description_for_version(versionId)
|
178
|
-
nodes=
|
177
|
+
nodes = ng_xml.search('//version[@versionId=\'' + versionId + '\']')
|
179
178
|
if nodes.length == 1 && nodes.first.at_xpath('description')
|
180
179
|
nodes.first.at_xpath('description').content.to_s
|
181
180
|
else
|
@@ -185,7 +184,7 @@ module Dor
|
|
185
184
|
|
186
185
|
# @return [String] The description for the current version
|
187
186
|
def current_description
|
188
|
-
desc_node=current_version_node.at_xpath('description')
|
187
|
+
desc_node = current_version_node.at_xpath('description')
|
189
188
|
return desc_node.content if desc_node
|
190
189
|
''
|
191
190
|
end
|
@@ -200,7 +199,7 @@ module Dor
|
|
200
199
|
# @param [Hash] opts optional parameters
|
201
200
|
# @option opts [String] :description describes the version change
|
202
201
|
# @option opts [Symbol] :significance which part of the version tag to increment
|
203
|
-
def sync_then_increment_version
|
202
|
+
def sync_then_increment_version(known_version, opts = {})
|
204
203
|
cv = current_version_id.to_i
|
205
204
|
raise Dor::Exception.new("Cannot sync to a version greater than current: #{cv}, requested #{known_version}") if cv < known_version
|
206
205
|
|
@@ -222,7 +221,7 @@ module Dor
|
|
222
221
|
|
223
222
|
def newest_tag
|
224
223
|
tags = find_by_terms(:version, :tag)
|
225
|
-
tags.map{|t| VersionTag.parse(t.value)}.max
|
224
|
+
tags.map {|t| VersionTag.parse(t.value)}.max
|
226
225
|
end
|
227
226
|
|
228
227
|
end
|
@@ -3,17 +3,17 @@ class WorkflowDefinitionDs < ActiveFedora::OmDatastream
|
|
3
3
|
include SolrDocHelper
|
4
4
|
|
5
5
|
set_terminology do |t|
|
6
|
-
t.root(:path =>
|
6
|
+
t.root(:path => 'workflow-def', :index_as => [:not_searchable])
|
7
7
|
t.process(:index_as => [:not_searchable])
|
8
8
|
end
|
9
9
|
|
10
|
-
define_template :process do |builder,workflow,attrs|
|
10
|
+
define_template :process do |builder, workflow, attrs|
|
11
11
|
prereqs = attrs.delete('prerequisite')
|
12
12
|
prereqs = prereqs.split(/\s*,\s*/) if prereqs.is_a?(String)
|
13
13
|
attrs.keys.each { |k| attrs[k.to_s.dasherize.to_sym] = attrs.delete(k) }
|
14
14
|
builder.process(attrs) do |node|
|
15
15
|
Array(prereqs).each do |prereq|
|
16
|
-
(repo,wf,prereq_name) = prereq.split(/:/)
|
16
|
+
(repo, wf, prereq_name) = prereq.split(/:/)
|
17
17
|
if prereq_name.nil?
|
18
18
|
prereq_name = repo
|
19
19
|
repo = nil
|
@@ -37,13 +37,13 @@ class WorkflowDefinitionDs < ActiveFedora::OmDatastream
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def graph(parent = nil)
|
40
|
-
Workflow::Graph.from_processes(
|
40
|
+
Workflow::Graph.from_processes(repo, name, processes, parent)
|
41
41
|
end
|
42
42
|
|
43
43
|
def processes
|
44
44
|
ng_xml.xpath('/workflow-def/process').collect do |node|
|
45
|
-
Workflow::Process.new(
|
46
|
-
end.sort { |a,b| (a.sequence || 0) <=> (b.sequence || 0) }
|
45
|
+
Workflow::Process.new(repo, name, node)
|
46
|
+
end.sort { |a, b| (a.sequence || 0) <=> (b.sequence || 0) }
|
47
47
|
end
|
48
48
|
|
49
49
|
def name
|
@@ -63,17 +63,17 @@ class WorkflowDefinitionDs < ActiveFedora::OmDatastream
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def configuration=(hash)
|
66
|
-
self.ng_xml = Nokogiri::XML(%
|
66
|
+
self.ng_xml = Nokogiri::XML(%(<workflow-def id="#{hash['name']}" repository="#{hash['repository']}"/>))
|
67
67
|
i = 0
|
68
|
-
hash.each_pair do |k,v|
|
69
|
-
add_process(v.merge({:name => k, :sequence => i+=1})) if v.is_a?(Hash)
|
68
|
+
hash.each_pair do |k, v|
|
69
|
+
add_process(v.merge({:name => k, :sequence => i += 1})) if v.is_a?(Hash)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
# Creates the xml used by Dor::WorkflowService.create_workflow
|
74
74
|
# @return [String] An object's initial workflow as defined by the <workflow-def> in content
|
75
75
|
def initial_workflow
|
76
|
-
doc = Nokogiri::XML(
|
76
|
+
doc = Nokogiri::XML('<workflow/>')
|
77
77
|
root = doc.root
|
78
78
|
root['id'] = name
|
79
79
|
processes.each { |proc|
|
@@ -92,17 +92,17 @@ class WorkflowDefinitionDs < ActiveFedora::OmDatastream
|
|
92
92
|
Nokogiri::XML(doc.to_xml) { |x| x.noblanks }.to_xml { |config| config.no_declaration }
|
93
93
|
end
|
94
94
|
|
95
|
-
def to_solr(solr_doc=
|
96
|
-
super(solr_doc
|
97
|
-
add_solr_value(solr_doc,
|
95
|
+
def to_solr(solr_doc = {}, *args)
|
96
|
+
super(solr_doc, *args)
|
97
|
+
add_solr_value(solr_doc, 'workflow_name', name, :symbol, [:symbol])
|
98
98
|
processes.each do |p|
|
99
|
-
add_solr_value(solr_doc,
|
99
|
+
add_solr_value(solr_doc, 'process', "#{p.name}|#{p.label}", :symbol, [:displayable])
|
100
100
|
end
|
101
101
|
solr_doc
|
102
102
|
end
|
103
103
|
|
104
104
|
def to_yaml
|
105
|
-
YAML.dump(
|
105
|
+
YAML.dump(configuration)
|
106
106
|
end
|
107
107
|
|
108
108
|
end
|
@@ -1,85 +1,79 @@
|
|
1
1
|
module Dor
|
2
|
-
|
2
|
+
# TODO: class docs
|
3
|
+
class WorkflowDs < ActiveFedora::OmDatastream
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
set_terminology do |t|
|
6
|
+
t.root(:path => 'workflows')
|
7
|
+
t.workflow {
|
8
|
+
t.workflowId( :path => {:attribute => 'id'} )
|
9
|
+
t.process {
|
10
|
+
t.name_( :path => {:attribute => 'name' }, :index_as => [:displayable, :not_searchable] )
|
11
|
+
t.status( :path => {:attribute => 'status' }, :index_as => [:displayable, :not_searchable] )
|
12
|
+
t.timestamp(:path => {:attribute => 'datetime' }, :index_as => [:displayable, :not_searchable] ) # , :data_type => :date)
|
13
|
+
t.elapsed( :path => {:attribute => 'elapsed' }, :index_as => [:displayable, :not_searchable] )
|
14
|
+
t.lifecycle(:path => {:attribute => 'lifecycle'}, :index_as => [:displayable, :not_searchable] )
|
15
|
+
t.attempts( :path => {:attribute => 'attempts' }, :index_as => [:displayable, :not_searchable] )
|
16
|
+
}
|
15
17
|
}
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def get_workflow(wf, repo = 'dor')
|
20
|
-
xml = Dor::WorkflowService.get_workflow_xml(repo, self.pid, wf)
|
21
|
-
xml = Nokogiri::XML(xml)
|
22
|
-
return nil if xml.xpath('workflow').length == 0
|
23
|
-
Workflow::Document.new(xml.to_s)
|
24
|
-
end
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
20
|
+
def get_workflow(wf, repo = 'dor')
|
21
|
+
xml = Dor::WorkflowService.get_workflow_xml(repo, pid, wf)
|
22
|
+
xml = Nokogiri::XML(xml)
|
23
|
+
return nil if xml.xpath('workflow').length == 0
|
24
|
+
Workflow::Document.new(xml.to_s)
|
25
|
+
end
|
32
26
|
|
33
|
-
|
34
|
-
ng_xml
|
35
|
-
self.xml_loaded = true
|
36
|
-
end
|
27
|
+
alias_method :[], :get_workflow
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
|
29
|
+
def ng_xml
|
30
|
+
@ng_xml ||= Nokogiri::XML::Document.parse(content)
|
31
|
+
end
|
41
32
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
xml
|
33
|
+
# @param [Boolean] refresh The WorkflowDS caches the content retrieved from the workflow
|
34
|
+
# service. This flag will invalidate the cached content and refetch it from the workflow
|
35
|
+
# service directly
|
36
|
+
def content(refresh = false)
|
37
|
+
@content = nil if refresh
|
38
|
+
@content ||= Dor::WorkflowService.get_workflow_xml 'dor', pid, nil
|
39
|
+
rescue RestClient::ResourceNotFound
|
40
|
+
xml = Nokogiri::XML(%(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<workflows objectId="#{pid}"/>))
|
41
|
+
digital_object.datastreams.keys.each do |dsid|
|
42
|
+
next unless dsid =~ /WF$/
|
43
|
+
ds_content = Nokogiri::XML(Dor::WorkflowService.get_workflow_xml 'dor', pid, dsid)
|
44
|
+
xml.root.add_child(ds_content.root)
|
45
|
+
end
|
46
|
+
@content ||= xml.to_xml
|
50
47
|
end
|
51
|
-
@content ||= xml.to_xml
|
52
|
-
end
|
53
48
|
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
def workflows
|
50
|
+
@workflows ||= workflow.nodeset.collect { |wf_node| Workflow::Document.new wf_node.to_xml }
|
51
|
+
end
|
57
52
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
def graph(dir = nil)
|
54
|
+
result = GraphViz.digraph(pid)
|
55
|
+
sg = result.add_graph('rank') { |g| g[:rank => 'same'] }
|
56
|
+
workflows.reject(&:nil?).each do |wf|
|
57
|
+
g = wf.graph(result)
|
58
|
+
sg.add_node(g.root.id) unless g.nil?
|
59
|
+
end
|
60
|
+
result['rankdir'] = dir || 'TB'
|
61
|
+
result
|
64
62
|
end
|
65
|
-
result['rankdir'] = dir || 'TB'
|
66
|
-
result
|
67
|
-
end
|
68
63
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
64
|
+
# Finds the first workflow that is expedited, then returns the value of its priority
|
65
|
+
#
|
66
|
+
# @return [Integer] value of the priority. Defaults to 0 if none of the workflows are expedited
|
67
|
+
def current_priority
|
68
|
+
cp = workflows.detect &:expedited?
|
69
|
+
return 0 if cp.nil?
|
70
|
+
cp.priority.to_i
|
71
|
+
end
|
77
72
|
|
78
|
-
|
79
|
-
#
|
80
|
-
|
81
|
-
|
73
|
+
def to_solr(solr_doc = {}, *args)
|
74
|
+
# super solr_doc, *args
|
75
|
+
workflows.each { |wf| wf.to_solr(solr_doc, *args) }
|
76
|
+
solr_doc
|
77
|
+
end
|
82
78
|
end
|
83
|
-
|
84
|
-
end
|
85
79
|
end
|