dor-services 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/lib/datastreams/content_metadata_ds.rb +12 -0
  2. data/lib/datastreams/embargo_metadata_ds.rb +107 -0
  3. data/lib/datastreams/events_ds.rb +58 -0
  4. data/lib/datastreams/identity_metadata_ds.rb +28 -0
  5. data/lib/datastreams/ng_tidy.rb +19 -0
  6. data/lib/datastreams/simple_dublin_core_ds.rb +23 -0
  7. data/lib/datastreams/workflow_definition_ds.rb +105 -0
  8. data/lib/datastreams/workflow_ds.rb +16 -0
  9. data/lib/dor-services.rb +19 -0
  10. data/lib/dor/admin_policy_object.rb +11 -0
  11. data/lib/dor/base.rb +81 -0
  12. data/lib/dor/cleanup_service.rb +32 -0
  13. data/lib/dor/config.rb +45 -0
  14. data/lib/dor/digital_stacks_service.rb +82 -0
  15. data/lib/dor/druid_utils.rb +41 -0
  16. data/lib/dor/embargo.rb +41 -0
  17. data/lib/dor/exceptions.rb +13 -0
  18. data/lib/dor/item.rb +141 -0
  19. data/lib/dor/metadata_handlers/catalog_handler.rb +22 -0
  20. data/lib/dor/metadata_handlers/mdtoolkit_handler.rb +42 -0
  21. data/lib/dor/metadata_service.rb +88 -0
  22. data/lib/dor/mods2dc.xslt +447 -0
  23. data/lib/dor/provenance_metadata_service.rb +65 -0
  24. data/lib/dor/registration_service.rb +87 -0
  25. data/lib/dor/rsolr.rb +27 -0
  26. data/lib/dor/sdr_ingest_service.rb +117 -0
  27. data/lib/dor/search_service.rb +86 -0
  28. data/lib/dor/suri_service.rb +37 -0
  29. data/lib/dor/tei2dc.xslt +102 -0
  30. data/lib/dor/workflow_object.rb +13 -0
  31. data/lib/dor/workflow_service.rb +111 -0
  32. data/lib/gsearch/demoFoxmlToSolr.xslt +384 -0
  33. data/lib/gsearch/schema.xml +229 -0
  34. data/lib/tasks/rdoc.rake +32 -0
  35. data/lib/xml_models/foxml.rb +261 -0
  36. data/lib/xml_models/identity_metadata/dublin_core.rb +119 -0
  37. data/lib/xml_models/identity_metadata/identity_metadata.rb +288 -0
  38. metadata +462 -0
@@ -0,0 +1,13 @@
1
+ require 'datastreams/workflow_definition_ds'
2
+
3
+ module Dor
4
+
5
+ class WorkflowObject < Base
6
+ has_metadata :name => "workflowDefinition", :type => WorkflowDefinitionDs
7
+
8
+ def definition
9
+ datastreams['workflowDefinition']
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,111 @@
1
+ require 'rest-client'
2
+
3
+ module Dor
4
+
5
+ # Methods to create and update workflow
6
+ #
7
+ # ==== Required Constants
8
+ # - Dor::CREATE_WORKFLOW : true or false. Can be used to turn of workflow in a particular environment, like development
9
+ # - Dor::WF_URI : The URI to the workflow service. An example URI is 'http://lyberservices-dev.stanford.edu/workflow'
10
+ module WorkflowService
11
+
12
+ Config.declare(:workflow) { url nil }
13
+
14
+ class << self
15
+ # Creates a workflow for a given object in the repository. If this particular workflow for this objects exists,
16
+ # it will replace the old workflow with wf_xml passed to this method. You have the option of creating a datastream or not.
17
+ # Returns true on success. Caller must handle any exceptions
18
+ #
19
+ # == Parameters
20
+ # - <b>repo</b> - The repository the object resides in. The service recoginzes "dor" and "sdr" at the moment
21
+ # - <b>druid</b> - The id of the object
22
+ # - <b>workflow_name</b> - The name of the workflow you want to create
23
+ # - <b>wf_xml</b> - The xml that represents the workflow
24
+ # - <B>opts</b> - Options Hash where you can set
25
+ # :create_ds - If true, a workflow datastream will be created in Fedora. Set to false if you do not want a datastream to be created
26
+ # If you do not pass in an <b>opts</b> Hash, then :create_ds is set to true by default
27
+ #
28
+ def create_workflow(repo, druid, workflow_name, wf_xml, opts = {:create_ds => true})
29
+ workflow_resource["#{repo}/objects/#{druid}/workflows/#{workflow_name}"].put(wf_xml, :content_type => 'application/xml',
30
+ :params => {'create-ds' => opts[:create_ds] })
31
+ return true
32
+ end
33
+
34
+ # Updates the status of one step in a workflow.
35
+ # Returns true on success. Caller must handle any exceptions
36
+ #
37
+ # == Required Parameters
38
+ # - <b>repo</b> - The repository the object resides in. The service recoginzes "dor" and "sdr" at the moment
39
+ # - <b>druid</b> - The id of the object
40
+ # - <b>workflow_name</b> - The name of the workflow
41
+ # - <b>status</b> - The status that you want to set. Typical statuses are 'waiting', 'completed', 'error', but could be any string
42
+ #
43
+ # == Optional Parameters
44
+ # - <b>elapsed</b> - The number of seconds it took to complete this step. Can have a decimal. Is set to 0 if not passed in.
45
+ # - <b>lifecycle</b> - Bookeeping label for this particular workflow step. Examples are: 'registered', 'shelved'
46
+ #
47
+ # == Http Call
48
+ # The method does an HTTP PUT to the URL defined in Dor::WF_URI. As an example:
49
+ # PUT "/dor/objects/pid:123/workflows/GoogleScannedWF/convert"
50
+ # <process name=\"convert\" status=\"completed\" />"
51
+ def update_workflow_status(repo, druid, workflow, process, status, elapsed = 0, lifecycle = nil)
52
+ xml = create_process_xml(:name => process, :status => status, :elapsed => elapsed.to_s, :lifecycle => lifecycle)
53
+ workflow_resource["#{repo}/objects/#{druid}/workflows/#{workflow}/#{process}"].put(xml, :content_type => 'application/xml')
54
+ return true
55
+ end
56
+
57
+ #
58
+ # Retrieves the process status of the given workflow for the given object identifier
59
+ #
60
+ def get_workflow_status(repo, druid, workflow, process)
61
+ workflow_md = workflow_resource["#{repo}/objects/#{druid}/workflows/#{workflow}"].get
62
+ doc = Nokogiri::XML(workflow_md)
63
+ raise Exception.new("Unable to parse response:\n#{workflow_md}") if(doc.root.nil?)
64
+
65
+ status = doc.root.at_xpath("//process[@name='#{process}']/@status").content
66
+ return status
67
+ end
68
+
69
+ def get_workflow_xml(repo, druid, workflow)
70
+ workflow_resource["#{repo}/objects/#{druid}/workflows/#{workflow}"].get
71
+ end
72
+
73
+ # Updates the status of one step in a workflow to error.
74
+ # Returns true on success. Caller must handle any exceptions
75
+ #
76
+ # == Required Parameters
77
+ # - <b>repo</b> - The repository the object resides in. The service recoginzes "dor" and "sdr" at the moment
78
+ # - <b>druid</b> - The id of the object
79
+ # - <b>workflow_name</b> - The name of the workflow
80
+ # - <b>error_msg</b> - The error message. Ideally, this is a brief message describing the error
81
+ #
82
+ # == Optional Parameters
83
+ # - <b>error_txt</b> - A slot to hold more information about the error, like a full stacktrace
84
+ #
85
+ # == Http Call
86
+ # The method does an HTTP PUT to the URL defined in Dor::WF_URI. As an example:
87
+ # PUT "/dor/objects/pid:123/workflows/GoogleScannedWF/convert"
88
+ # <process name=\"convert\" status=\"error\" />"
89
+ def update_workflow_error_status(repo, druid, workflow, process, error_msg, error_txt = nil)
90
+ xml = create_process_xml(:name => process, :status => 'error', :errorMessage => error_msg, :errorText => error_txt)
91
+ workflow_resource["#{repo}/objects/#{druid}/workflows/#{workflow}/#{process}"].put(xml, :content_type => 'application/xml')
92
+ return true
93
+ end
94
+
95
+ # private
96
+ def create_process_xml(params)
97
+ builder = Nokogiri::XML::Builder.new do |xml|
98
+ attrs = params.reject { |k,v| v.nil? }
99
+ xml.process(attrs)
100
+ end
101
+ return builder.to_xml
102
+ end
103
+
104
+ def workflow_resource
105
+ RestClient::Resource.new(Config.workflow.url,
106
+ :ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(Config.fedora.cert_file)),
107
+ :ssl_client_key => OpenSSL::PKey::RSA.new(File.read(Config.fedora.key_file), Config.fedora.key_pass))
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,384 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- $Id: demoFoxmlToLucene.xslt 5734 2006-11-28 11:20:15Z gertsp $ -->
3
+ <xsl:stylesheet exclude-result-prefixes="exts" version="1.0"
4
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
5
+ xmlns:exts="xalan://dk.defxws.fedoragsearch.server.GenericOperationsImpl"
6
+ xmlns:fedora-model="info:fedora/fedora-system:def/model#"
7
+ xmlns:fedora-types="http://www.fedora.info/definitions/1/0/types/"
8
+ xmlns:foxml="info:fedora/fedora-system:def/foxml#" xmlns:mods="http://www.loc.gov/mods/v3"
9
+ xmlns:hydra="http://projecthydra.org/ns/relations#"
10
+ xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
11
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
12
+ xmlns:rel="info:fedora/fedora-system:def/relations-external#"
13
+ xmlns:uvalibadmin="http://dl.lib.virginia.edu/bin/admin/admin.dtd/"
14
+ xmlns:uvalibdesc="http://dl.lib.virginia.edu/bin/dtd/descmeta/descmeta.dtd"
15
+ xmlns:fn="http://www.w3.org/TR/xpath-functions/"
16
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:zs="http://www.loc.gov/zing/srw/">
17
+ <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
18
+ <!--
19
+ This xslt stylesheet generates the Solr doc element consisting of field elements
20
+ from a FOXML record. The PID field is mandatory.
21
+ Options for tailoring:
22
+ - generation of fields from other XML metadata streams than DC
23
+ - generation of fields from other datastream types than XML
24
+ - from datastream by ID, text fetched, if mimetype can be handled
25
+ currently the mimetypes text/plain, text/xml, text/html, application/pdf can be handled.
26
+ -->
27
+ <xsl:param name="REPOSITORYNAME" select="repositoryName"/>
28
+ <xsl:param name="FEDORASOAP" select="repositoryName"/>
29
+ <xsl:param name="FEDORAUSER" select="repositoryName"/>
30
+ <xsl:param name="FEDORAPASS" select="repositoryName"/>
31
+ <xsl:param name="TRUSTSTOREPATH" select="repositoryName"/>
32
+ <xsl:param name="TRUSTSTOREPASS" select="repositoryName"/>
33
+ <xsl:variable name="scheme" select="substring-before($FEDORASOAP,'//')"/>
34
+ <xsl:variable name="path" select="substring-before(substring-after($FEDORASOAP,'//'),'/services')"/>
35
+ <xsl:variable name="FEDORAROOT">
36
+ <xsl:value-of select="concat($scheme,'//',$FEDORAUSER,':',$FEDORAPASS,'@',$path)"/>
37
+ </xsl:variable>
38
+ <xsl:variable name="PID" select="/foxml:digitalObject/@PID"/>
39
+ <xsl:variable name="docBoost" select="1.4*2.5"/>
40
+
41
+ <xsl:variable name="OBJECTTYPE" select="//foxml:datastream/foxml:datastreamVersion[last()]//identityMetadata/objectType/text()"/>
42
+
43
+ <xsl:variable name="INDEXVERSION">1.3.2011102001</xsl:variable>
44
+
45
+ <!-- or any other calculation, default boost is 1.0 -->
46
+ <xsl:template match="/">
47
+ <add>
48
+ <doc boost="{$docBoost}">
49
+ <xsl:apply-templates/>
50
+ </doc>
51
+ </add>
52
+ </xsl:template>
53
+
54
+ <xsl:template match="/foxml:digitalObject">
55
+ <field name="index_version_field">
56
+ <xsl:value-of select="$INDEXVERSION"/>
57
+ </field>
58
+ <field boost="2.5" name="PID">
59
+ <xsl:value-of select="$PID"/>
60
+ </field>
61
+ <field name="namespace_field">
62
+ <xsl:value-of select="substring-before($PID,':')"/>
63
+ </field>
64
+ <field name="namespace_facet">
65
+ <xsl:value-of select="substring-before($PID,':')"/>
66
+ </field>
67
+ <field name="link_text_display">
68
+ <xsl:choose>
69
+ <xsl:when test="//dc:title"><xsl:value-of select="//dc:title/text()"/></xsl:when>
70
+ <xsl:otherwise><xsl:value-of select="$PID"/></xsl:otherwise>
71
+ </xsl:choose>
72
+ </field>
73
+ <xsl:apply-templates select="*"/>
74
+ </xsl:template>
75
+
76
+ <xsl:template match="foxml:objectProperties/foxml:property">
77
+ <field>
78
+ <xsl:attribute name="name">
79
+ <!-- if this is a data field, append with date, otherwise field -->
80
+ <xsl:choose>
81
+ <xsl:when test="contains(@NAME, 'Date')">
82
+ <xsl:value-of
83
+ select="concat('fgs_', substring-after(@NAME,'#'), '_date')"/>
84
+ </xsl:when>
85
+ <xsl:otherwise>
86
+ <xsl:value-of
87
+ select="concat('fgs_', substring-after(@NAME,'#'), '_field')"/>
88
+ </xsl:otherwise>
89
+ </xsl:choose>
90
+ </xsl:attribute>
91
+ <xsl:value-of select="@VALUE"/>
92
+ </field>
93
+ </xsl:template>
94
+
95
+ <xsl:template match="foxml:datastream">
96
+ <!--
97
+ <field name="fedora_datastream_id_field">
98
+ <xsl:value-of select="@ID"/>
99
+ </field>
100
+ -->
101
+ <xsl:apply-templates select="./foxml:datastreamVersion[last()]/foxml:xmlContent"/>
102
+ <xsl:apply-templates select="./foxml:datastreamVersion[last()]/foxml:contentLocation"/>
103
+ </xsl:template>
104
+
105
+ <!-- Index RELS-EXT -->
106
+ <xsl:template match="rdf:RDF[ancestor::foxml:datastream[@ID='RELS-EXT']]/rdf:Description">
107
+ <!-- Grab the cmodel -->
108
+ <xsl:for-each select="./fedora-model:hasModel">
109
+ <field name="fedora_has_model_field">
110
+ <xsl:value-of select="@rdf:resource"/>
111
+ </field>
112
+ </xsl:for-each>
113
+
114
+ <xsl:for-each select="*[@rdf:resource]">
115
+ <xsl:variable name="doc-pid" select="substring-after(./@rdf:resource,'info:fedora/')"></xsl:variable>
116
+ <field name="{local-name(.)}_id_field">
117
+ <xsl:value-of select="$doc-pid"/>
118
+ </field>
119
+ <field name="{local-name(.)}_id_facet">
120
+ <xsl:value-of select="$doc-pid"/>
121
+ </field>
122
+ </xsl:for-each>
123
+ </xsl:template>
124
+
125
+ <!-- Index DC -->
126
+ <xsl:template match="oai_dc:dc[ancestor::foxml:datastream[@ID='DC']]">
127
+ <xsl:for-each select="dc:title|dc:creator|dc:identifier">
128
+ <field name="dc_{local-name(.)}_text">
129
+ <xsl:value-of select="text()"/>
130
+ </field>
131
+ </xsl:for-each>
132
+ <xsl:for-each select="./*">
133
+ <field name="dc_{local-name(.)}_field">
134
+ <xsl:value-of select="text()"/>
135
+ </field>
136
+ </xsl:for-each>
137
+ </xsl:template>
138
+
139
+ <!-- Index identity metadata -->
140
+ <xsl:template match="identityMetadata[ancestor::foxml:datastream[@ID='identityMetadata']]">
141
+ <xsl:for-each select="./objectType">
142
+ <field name="object_type_field">
143
+ <xsl:value-of select="./text()"/>
144
+ </field>
145
+ </xsl:for-each>
146
+ <xsl:for-each select="./sourceId">
147
+ <field name="dor_id_field">
148
+ <xsl:value-of select="concat(@source, ':', normalize-space(./text()))"/>
149
+ </field>
150
+ <field name="source_id_field">
151
+ <xsl:value-of select="normalize-space(./text())"/>
152
+ </field>
153
+ <field name="identifier_text">
154
+ <xsl:value-of select="concat(@source, ':', normalize-space(./text()))"/>
155
+ </field>
156
+ <field name="identifier_text">
157
+ <xsl:value-of select="normalize-space(./text())"/>
158
+ </field>
159
+ </xsl:for-each>
160
+ <xsl:for-each select="./otherId">
161
+ <field name="dor_id_field">
162
+ <xsl:value-of select="concat(@name, ':', normalize-space(./text()))"/>
163
+ </field>
164
+ <field name="dor_{@name}_id_field">
165
+ <xsl:value-of select="normalize-space(./text())"/>
166
+ </field>
167
+ </xsl:for-each>
168
+ <!-- tags -->
169
+ <xsl:for-each select="./tag">
170
+ <xsl:variable name="text-value" select="normalize-space(./text())"/>
171
+ <field name="tag_field">
172
+ <xsl:value-of select="$text-value"/>
173
+ </field>
174
+ <field name="tag_facet">
175
+ <xsl:value-of select="$text-value"/>
176
+ </field>
177
+ <xsl:variable name="tag-name"
178
+ select="normalize-space(substring-before($text-value, ':'))"/>
179
+ <xsl:variable name="field-name">
180
+ <xsl:call-template name="valid-field-name"><xsl:with-param name="name" select="$tag-name"/></xsl:call-template>
181
+ <xsl:text>_tag</xsl:text>
182
+ </xsl:variable>
183
+ <field name="{$field-name}_field">
184
+ <xsl:value-of select="normalize-space(substring-after($text-value, ':'))"/>
185
+ </field>
186
+ <field name="{$field-name}_facet">
187
+ <xsl:value-of select="normalize-space(substring-after($text-value, ':'))"/>
188
+ </field>
189
+ </xsl:for-each>
190
+ </xsl:template>
191
+
192
+ <!-- Index MODS descriptive metadata -->
193
+ <xsl:template match="mods:mods[ancestor::foxml:datastream[@ID='descMetadata']]">
194
+ <!-- Grab the MODS identifiers -->
195
+ <xsl:for-each select="./mods:identifier">
196
+ <xsl:variable name="identifier-label">
197
+ <xsl:call-template name="valid-field-name"><xsl:with-param name="name" select="@displayLabel"/></xsl:call-template>
198
+ </xsl:variable>
199
+ <field name="mods_identifier_field">
200
+ <xsl:value-of select="@displayLabel"/>:<xsl:value-of select="text()"/>
201
+ </field>
202
+ <field name="mods_{$identifier-label}_identifier_field">
203
+ <xsl:value-of select="text()"/>
204
+ </field>
205
+ <field name="mods_identifier_text">
206
+ <xsl:value-of select="@displayLabel"/>:<xsl:value-of select="text()"/>
207
+ </field>
208
+ <field name="mods_{$identifier-label}_identifier_text">
209
+ <xsl:value-of select="text()"/>
210
+ </field>
211
+ </xsl:for-each>
212
+
213
+ <xsl:for-each select="mods:titleInfo">
214
+ <xsl:variable name="title-info">
215
+ <xsl:value-of select="mods:nonSort/text()"/>
216
+ <xsl:value-of select="mods:title/text()"/>
217
+ <xsl:if test="mods:subTitle">
218
+ <xsl:text> : </xsl:text>
219
+ <xsl:value-of select="mods:subTitle/text()"/>
220
+ </xsl:if>
221
+ </xsl:variable>
222
+ <field name="mods_titleInfo_field">
223
+ <xsl:value-of select="$title-info"/>
224
+ </field>
225
+ <field name="mods_title_text">
226
+ <xsl:value-of select="$title-info"/>
227
+ </field>
228
+ </xsl:for-each>
229
+
230
+ <xsl:for-each select="mods:name">
231
+ <field name="mods_name_field">
232
+ <xsl:value-of select="mods:namePart/text()"/>
233
+ </field>
234
+ <field name="mods_name_text">
235
+ <xsl:value-of select="mods:namePart/text()"/>
236
+ </field>
237
+ </xsl:for-each>
238
+
239
+ <!-- Index some, but not all, MODS fields -->
240
+ <xsl:for-each select="//mods:coordinates|//mods:extent|//mods:scale|//mods:topic">
241
+ <xsl:if test="./text()">
242
+ <field name="mods_{local-name(.)}_field">
243
+ <xsl:value-of select="text()"/>
244
+ </field>
245
+ </xsl:if>
246
+ </xsl:for-each>
247
+
248
+ <xsl:for-each select="//mods:*[contains(local-name(),'date') or contains(local-name(), 'Date')]">
249
+ <xsl:variable name="date-label">
250
+ <xsl:call-template name="valid-field-name"><xsl:with-param name="name" select="local-name()"/></xsl:call-template>
251
+ </xsl:variable>
252
+ <field name="mods_{$date-label}_field">
253
+ <xsl:value-of select="normalize-space(./text())"/>
254
+ </field>
255
+ </xsl:for-each>
256
+ <!--
257
+ <xsl:for-each select=".//mods:*[string-length(normalize-space(text())) &gt; 0]">
258
+ <field name="mods_{local-name(.)}_field"><xsl:value-of select="normalize-space(./text())"/></field>
259
+ </xsl:for-each>
260
+ -->
261
+ </xsl:template>
262
+
263
+ <!-- Index content metadata -->
264
+ <xsl:template match="contentMetadata[ancestor::foxml:datastream[@ID='contentMetadata']]">
265
+ <field name="content_type_facet">
266
+ <xsl:value-of select="@type"/>
267
+ </field>
268
+ <xsl:apply-templates/>
269
+ </xsl:template>
270
+
271
+ <xsl:template match="contentMetadata/resource/file">
272
+ <field name="content_file_field">
273
+ <xsl:value-of select="@id"/>
274
+ </field>
275
+ <xsl:if test="@shelve = 'yes'">
276
+ <field name="shelved_content_file_field">
277
+ <xsl:value-of select="@id"/>
278
+ </field>
279
+ </xsl:if>
280
+ </xsl:template>
281
+
282
+ <!-- Index embargo metadata -->
283
+ <xsl:template match="embargoMetadata[ancestor::foxml:datastream[@ID='embargoMetadata']]">
284
+ <xsl:if test="(status != '') and (releaseDate != '')">
285
+ <field name="embargo_status_field">
286
+ <xsl:value-of select="status"/>
287
+ </field>
288
+ <field name="embargo_release_date">
289
+ <xsl:value-of select="releaseDate"/>
290
+ </field>
291
+ </xsl:if>
292
+ </xsl:template>
293
+
294
+ <!-- Workflows -->
295
+ <xsl:template match="foxml:contentLocation[contains(@REF,'/workflows/')]">
296
+ <xsl:apply-templates select="document(@REF)/workflow">
297
+ <xsl:with-param name="workflow-name" select="ancestor::foxml:datastream/@ID"/>
298
+ </xsl:apply-templates>
299
+ </xsl:template>
300
+
301
+ <xsl:template match="workflow">
302
+ <xsl:param name="workflow-name" select="ancestor::foxml:datastream/@ID"/>
303
+ <xsl:variable name="workflow-token">
304
+ <xsl:call-template name="valid-field-name"><xsl:with-param name="name" select="$workflow-name"/></xsl:call-template>
305
+ </xsl:variable>
306
+ <field name="wf_facet"><xsl:value-of select="$workflow-name"/></field>
307
+ <field name="wf_wsp_facet"><xsl:value-of select="$workflow-name"/></field>
308
+ <field name="wf_wps_facet"><xsl:value-of select="$workflow-name"/></field>
309
+ <xsl:for-each select="process">
310
+ <field name="wf_wsp_facet">
311
+ <xsl:value-of select="concat($workflow-name,':',@status)"/>
312
+ </field>
313
+ <field name="wf_wsp_facet">
314
+ <xsl:value-of select="concat($workflow-name,':',@status,':',@name)"/>
315
+ </field>
316
+
317
+ <field name="wf_wps_facet">
318
+ <xsl:value-of select="concat($workflow-name,':',@name)"/>
319
+ </field>
320
+ <field name="wf_wps_facet">
321
+ <xsl:value-of select="concat($workflow-name,':',@name,':',@status)"/>
322
+ </field>
323
+
324
+ <field name="wf_swp_facet">
325
+ <xsl:value-of select="@status"/>
326
+ </field>
327
+ <field name="wf_swp_facet">
328
+ <xsl:value-of select="concat(@status,':',$workflow-name)"/>
329
+ </field>
330
+ <field name="wf_swp_facet">
331
+ <xsl:value-of select="concat(@status,':',$workflow-name,':',@name)"/>
332
+ </field>
333
+ </xsl:for-each>
334
+ </xsl:template>
335
+
336
+ <!-- Admin Policy specific fields -->
337
+ <xsl:template match="administrativeMetadata[ancestor::foxml:datastream[@ID='administrativeMetadata']]">
338
+ <xsl:if test="./descMetadata/format">
339
+ <field name="apo_metadata_format_field">
340
+ <xsl:value-of select="./descMetadata/format/text()"/>
341
+ </field>
342
+ </xsl:if>
343
+ <xsl:if test="./descMetadata/format">
344
+ <field name="apo_metadata_source_field">
345
+ <xsl:value-of select="./descMetadata/source/text()"/>
346
+ </field>
347
+ </xsl:if>
348
+
349
+ <xsl:for-each select="registration/workflow">
350
+ <field name="apo_registration_workflow_field">
351
+ <xsl:value-of select="@id"/>
352
+ </field>
353
+ </xsl:for-each>
354
+ </xsl:template>
355
+
356
+ <xsl:template match="roleMetadata[ancestor::foxml:datastream[@ID='roleMetadata']]">
357
+ <xsl:for-each select="./role/*">
358
+ <xsl:variable name="role_value"><xsl:value-of select="identifier/@type"/>:<xsl:value-of select="identifier/text()"/></xsl:variable>
359
+ <field name="apo_role_{local-name(.)}_{../@type}_field">
360
+ <xsl:value-of select="$role_value"/>
361
+ </field>
362
+ <field name="apo_role_{local-name(.)}_{../@type}_facet">
363
+ <xsl:value-of select="$role_value"/>
364
+ </field>
365
+ <xsl:if test="../@type = 'depositor' or ../@type = 'manager'">
366
+ <field name="apo_register_permissions_field">
367
+ <xsl:value-of select="$role_value"/>
368
+ </field>
369
+ <field name="apo_register_permissions_facet">
370
+ <xsl:value-of select="$role_value"/>
371
+ </field>
372
+ </xsl:if>
373
+ </xsl:for-each>
374
+ </xsl:template>
375
+
376
+ <!-- Utility Templates -->
377
+ <xsl:template match="text()|@*|processing-instruction()|comment()"/>
378
+
379
+ <xsl:template name="valid-field-name">
380
+ <xsl:param name="name"/>
381
+ <xsl:value-of select="translate($name,' ABCDEFGHIJKLMNOPQRSTUVWXYZ','_abcdefghijklmnopqrstuvwxyz')"/>
382
+ </xsl:template>
383
+
384
+ </xsl:stylesheet>