dor-services 2.2.4 → 4.4.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +15 -0
  2. data/bin/dor-indexer +108 -0
  3. data/bin/dor-indexerd +73 -0
  4. data/bin/nokogiri +19 -0
  5. data/bin/rake +19 -0
  6. data/bin/ruby_noexec_wrapper +14 -0
  7. data/bin/solrizer +19 -0
  8. data/bin/solrizerd +19 -0
  9. data/config/certs/README +1 -0
  10. data/config/config_defaults.yml +62 -0
  11. data/config/dev_console_env.rb.example +67 -0
  12. data/config/predicate_mappings.yml +55 -0
  13. data/lib/dor-services.rb +152 -19
  14. data/lib/dor/config.rb +133 -35
  15. data/lib/dor/datastreams/administrative_metadata_ds.rb +84 -0
  16. data/lib/dor/datastreams/content_metadata_ds.rb +337 -0
  17. data/lib/dor/datastreams/datastream_spec_solrizer.rb +18 -0
  18. data/lib/dor/datastreams/default_object_rights_ds.rb +52 -0
  19. data/lib/dor/datastreams/desc_metadata_ds.rb +39 -0
  20. data/lib/{datastreams → dor/datastreams}/embargo_metadata_ds.rb +25 -20
  21. data/lib/{datastreams → dor/datastreams}/events_ds.rb +14 -9
  22. data/lib/dor/datastreams/identity.xsl +8 -0
  23. data/lib/dor/datastreams/identity_metadata_ds.rb +112 -0
  24. data/lib/dor/datastreams/role_metadata_ds.rb +51 -0
  25. data/lib/dor/datastreams/simple_dublin_core_ds.rb +45 -0
  26. data/lib/dor/datastreams/version_metadata_ds.rb +214 -0
  27. data/lib/dor/datastreams/workflow_definition_ds.rb +113 -0
  28. data/lib/dor/datastreams/workflow_ds.rb +103 -0
  29. data/lib/dor/exceptions.rb +0 -1
  30. data/lib/dor/migrations/content_metadata_ds/change_content_type.rb +7 -0
  31. data/lib/dor/migrations/identifiable/assert_adminPolicy.rb +9 -0
  32. data/lib/dor/migrations/identifiable/fix_model_assertions.rb +13 -0
  33. data/lib/dor/migrations/identifiable/record_remediation.rb +18 -0
  34. data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +18 -0
  35. data/lib/dor/migrations/identifiable/uriify_contentlocation_refs.rb +18 -0
  36. data/lib/dor/migrations/processable/unify_workflows.rb +17 -0
  37. data/lib/dor/migrations/versionable/add_missing_version_md.rb +9 -0
  38. data/lib/dor/models/admin_policy_object.rb +16 -0
  39. data/lib/dor/models/assembleable.rb +14 -0
  40. data/lib/dor/models/collection.rb +14 -0
  41. data/lib/dor/models/contentable.rb +227 -0
  42. data/lib/dor/models/describable.rb +194 -0
  43. data/lib/dor/models/discoverable.rb +66 -0
  44. data/lib/dor/models/editable.rb +267 -0
  45. data/lib/dor/models/embargoable.rb +97 -0
  46. data/lib/dor/models/eventable.rb +12 -0
  47. data/lib/dor/models/governable.rb +162 -0
  48. data/lib/dor/models/identifiable.rb +211 -0
  49. data/lib/dor/models/item.rb +44 -0
  50. data/lib/dor/models/itemizable.rb +66 -0
  51. data/lib/dor/{mods2dc.xslt → models/mods2dc.xslt} +39 -12
  52. data/lib/dor/models/preservable.rb +50 -0
  53. data/lib/dor/models/processable.rb +229 -0
  54. data/lib/dor/models/publishable.rb +74 -0
  55. data/lib/dor/models/set.rb +12 -0
  56. data/lib/dor/models/shelvable.rb +27 -0
  57. data/lib/dor/models/upgradable.rb +74 -0
  58. data/lib/dor/models/versionable.rb +94 -0
  59. data/lib/dor/models/workflow_object.rb +54 -0
  60. data/lib/dor/services/cleanup_service.rb +47 -0
  61. data/lib/dor/services/digital_stacks_service.rb +55 -0
  62. data/lib/dor/services/merge_service.rb +96 -0
  63. data/lib/dor/{metadata_handlers → services/metadata_handlers}/catalog_handler.rb +0 -2
  64. data/lib/dor/{metadata_handlers → services/metadata_handlers}/mdtoolkit_handler.rb +0 -2
  65. data/lib/dor/{metadata_service.rb → services/metadata_service.rb} +1 -3
  66. data/lib/dor/services/registration_service.rb +181 -0
  67. data/lib/dor/services/sdr_ingest_service.rb +181 -0
  68. data/lib/dor/services/search_service.rb +131 -0
  69. data/lib/dor/services/suri_service.rb +32 -0
  70. data/lib/dor/services/technical_metadata_service.rb +226 -0
  71. data/lib/dor/{tei2dc.xslt → services/tei2dc.xslt} +0 -0
  72. data/lib/dor/utils/ng_tidy.rb +37 -0
  73. data/lib/dor/utils/predicate_patch.rb +23 -0
  74. data/lib/dor/utils/solr_doc_helper.rb +9 -0
  75. data/lib/dor/utils/utc_date_field_mapper.rb +7 -0
  76. data/lib/dor/version.rb +3 -0
  77. data/lib/dor/workflow/document.rb +131 -0
  78. data/lib/dor/workflow/graph.rb +166 -0
  79. data/lib/dor/workflow/process.rb +99 -0
  80. data/lib/gsearch/demoFoxmlToSolr.xslt +340 -122
  81. data/lib/tasks/dor.rake +39 -0
  82. metadata +494 -384
  83. data/lib/datastreams/content_metadata_ds.rb +0 -12
  84. data/lib/datastreams/identity_metadata_ds.rb +0 -28
  85. data/lib/datastreams/ng_tidy.rb +0 -19
  86. data/lib/datastreams/simple_dublin_core_ds.rb +0 -23
  87. data/lib/datastreams/workflow_definition_ds.rb +0 -105
  88. data/lib/datastreams/workflow_ds.rb +0 -16
  89. data/lib/dor/admin_policy_object.rb +0 -11
  90. data/lib/dor/base.rb +0 -81
  91. data/lib/dor/cleanup_service.rb +0 -32
  92. data/lib/dor/digital_stacks_service.rb +0 -82
  93. data/lib/dor/druid_utils.rb +0 -41
  94. data/lib/dor/embargo.rb +0 -41
  95. data/lib/dor/item.rb +0 -141
  96. data/lib/dor/provenance_metadata_service.rb +0 -65
  97. data/lib/dor/registration_service.rb +0 -87
  98. data/lib/dor/rsolr.rb +0 -27
  99. data/lib/dor/sdr_ingest_service.rb +0 -117
  100. data/lib/dor/search_service.rb +0 -86
  101. data/lib/dor/suri_service.rb +0 -37
  102. data/lib/dor/workflow_object.rb +0 -13
  103. data/lib/dor/workflow_service.rb +0 -111
  104. data/lib/xml_models/foxml.rb +0 -261
  105. data/lib/xml_models/identity_metadata/dublin_core.rb +0 -119
  106. data/lib/xml_models/identity_metadata/identity_metadata.rb +0 -288
@@ -1,86 +0,0 @@
1
- require 'json'
2
- require 'active_support/core_ext'
3
-
4
- module Dor
5
-
6
- class SearchService
7
-
8
- RISEARCH_TEMPLATE = "select $object from <#ri> where $object <dc:identifier> '%s'"
9
-
10
- Config.declare(:gsearch) {
11
- url nil
12
- instance_eval do
13
- def client
14
- RestClient::Resource.new(
15
- self.url,
16
- :ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(Config.fedora.cert_file)),
17
- :ssl_client_key => OpenSSL::PKey::RSA.new(File.read(Config.fedora.key_file), Config.fedora.key_pass)
18
- )
19
- end
20
- end
21
- }
22
-
23
- class << self
24
-
25
- def reindex(*pids)
26
- fedora_client = Config.fedora.client
27
- solr_client = Config.gsearch.client
28
- xsl = Nokogiri::XSLT(File.read(File.expand_path('../../gsearch/demoFoxmlToSolr.xslt', __FILE__)))
29
- pids.in_groups_of(20, false) do |group|
30
- doc = Nokogiri::XML('<update/>')
31
- group.each do |pid|
32
- begin
33
- foxml = Dor::Base.get_foxml(pid,true)
34
- doc.root.add_child(xsl.transform(foxml).root)
35
- rescue RestClient::ResourceNotFound
36
- doc.root.add_child("<delete><id>#{pid}</id></delete>")
37
- end
38
- end
39
- yield group if block_given?
40
- solr_client['update'].post(doc.to_xml, :content_type => 'application/xml')
41
- end
42
- pids
43
- end
44
-
45
- def risearch(query, opts = {})
46
- client = Config.fedora.client['risearch']
47
- client.options[:timeout] = opts.delete(:timeout)
48
- query_params = {
49
- :type => 'tuples',
50
- :lang => 'itql',
51
- :format => 'CSV',
52
- :limit => '1000',
53
- :stream => 'on',
54
- :query => query
55
- }.merge(opts)
56
- result = client.post(query_params)
57
- result.split(/\n/)[1..-1].collect { |pid| pid.chomp.sub(/^info:fedora\//,'') }
58
- end
59
-
60
- def gsearch(params)
61
- client = Config.gsearch.client
62
- query_params = params.merge(:wt => 'json')
63
- query_string = query_params.collect { |k,v|
64
- if v.is_a?(Array)
65
- v.collect { |vv| "#{k}=#{URI.encode(vv.to_s)}" }.join('&')
66
- else
67
- "#{k}=#{URI.encode(v.to_s)}"
68
- end
69
- }.join('&')
70
- result = JSON.parse(client["select?#{query_string}"].get)
71
- end
72
-
73
- def query_by_id(id)
74
- if id.is_a?(Hash) # Single valued: { :google => 'STANFORD_0123456789' }
75
- id = id.collect { |*v| v.join(':') }.first
76
- elsif id.is_a?(Array) # Two values: [ 'google', 'STANFORD_0123456789' ]
77
- id = id.join(':')
78
- end
79
- self.risearch(RISEARCH_TEMPLATE % id)
80
- end
81
-
82
- end
83
-
84
- end
85
-
86
- end
@@ -1,37 +0,0 @@
1
- require 'rest-client'
2
- require 'active_fedora'
3
-
4
- module Dor
5
- class SuriService
6
-
7
- Config.declare(:suri) do
8
- url nil
9
- user nil
10
- pass nil
11
- id_namespace 'druid'
12
- mint_ids false
13
- end
14
-
15
- # If Dor::Config.suri.mint_ids is set to true, then this method
16
- # returns Config.suri.id_namespace:id_from_suri
17
- # Throws an exception if there were any problems
18
- def self.mint_id
19
- unless(Config.suri.mint_ids)
20
- return Fedora::Repository.instance.nextid
21
- end
22
-
23
- #Post with no body
24
- resource = RestClient::Resource.new("#{Config.suri.url}/suri2/namespaces/#{Config.suri.id_namespace}/identifiers",
25
- :user => Config.suri.user, :password => Config.suri.pass)
26
- id = resource.post('').chomp
27
-
28
- return "#{Config.suri.id_namespace}:#{id.strip}"
29
-
30
- # rescue Exception => e
31
- # Rails.logger.error("Unable to mint id from suri: #{e.to_s}")
32
- # raise e
33
- end
34
-
35
-
36
- end
37
- end
@@ -1,13 +0,0 @@
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
@@ -1,111 +0,0 @@
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
@@ -1,261 +0,0 @@
1
- require 'nokogiri'
2
-
3
- # TODO: Rewrite in OM
4
-
5
- class Foxml
6
- attr_reader :xml
7
-
8
- NAMESPACES = {
9
- "dc" => "http://purl.org/dc/elements/1.1/",
10
- "fedora-model" => "info:fedora/fedora-system:def/model#",
11
- "foxml" => "info:fedora/fedora-system:def/foxml#",
12
- "oai_dc" => "http://www.openarchives.org/OAI/2.0/oai_dc/",
13
- "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
14
- "rel" => "info:fedora/fedora-system:def/relations-external#",
15
- "hydra" => "http://projecthydra.org/ns/relations#"
16
- }
17
-
18
- def initialize(pid=nil, label=nil, content_model=nil, identity_metadata=nil, admin_policy_object=nil, parent = nil)
19
- @xml = Nokogiri::XML(XML_TEMPLATE) { |config| config.default_xml.noblanks }
20
- @defined_namespaces = { '' => nil }
21
- @xml.traverse { |node|
22
- if node.respond_to?(:namespace_definitions)
23
- node.namespace_definitions.each { |ns|
24
- @defined_namespaces[ns.prefix] = ns
25
- }
26
- end
27
- }
28
-
29
- self.pid = pid.to_s
30
- self.label = label.to_s
31
- self.content_model = content_model
32
- self.identity_metadata = identity_metadata
33
- self.admin_policy_object = admin_policy_object
34
- self.parent = parent
35
- end
36
-
37
- def pid
38
- self.xpath('/foxml:digitalObject/@PID').first.value
39
- end
40
-
41
- def pid=(value)
42
- self.xpath('/foxml:digitalObject/@PID').first.value = value
43
- self.get_datastream("RELS-EXT","rdf:RDF/rdf:Description/@rdf:about").value = "info:fedora/#{value}"
44
- update_dc_identifiers
45
- end
46
-
47
- def content_model
48
- self.get_rels_ext_resource("fedora-model:hasModel")
49
- end
50
-
51
- def content_model=(value)
52
- self.set_rels_ext_resource("fedora-model:hasModel",value)
53
- end
54
-
55
- def dublin_core
56
- self.get_datastream("DC","oai_dc:dc")
57
- end
58
-
59
- def dublin_core=(value)
60
- self.set_datastream("DC",value,'<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"/>')
61
- end
62
-
63
- def identity_metadata
64
- self.get_datastream("identityMetadata","identityMetadata")
65
- end
66
-
67
- def identity_metadata=(value)
68
- self.set_datastream("identityMetadata",value,"<identityMetadata/>")
69
- # strip the namespace Nokogiri attaches to identityMetadata
70
- self.get_datastream("identityMetadata","*[local-name()='identityMetadata']").traverse { |n| n.namespace = nil }
71
- update_dc_identifiers
72
- end
73
-
74
- def label
75
- self.xpath('//foxml:property[@NAME="info:fedora/fedora-system:def/model#label"]/@VALUE').first
76
- end
77
-
78
- def label=(value)
79
- self.xpath('//foxml:property[@NAME="info:fedora/fedora-system:def/model#label"]/@VALUE').first.value = value[0..254]
80
- if existing_title = self.get_datastream("DC","//dc:title")
81
- existing_title.remove
82
- end
83
- new_child = @xml.create_element('dc:title')
84
- new_child.content = value
85
- self.dublin_core.add_child(new_child)
86
- fix_namespaces(new_child)
87
- return new_child
88
- end
89
-
90
- def admin_policy_object
91
- self.get_rels_ext_resource("hydra:isGovernedBy")
92
- end
93
-
94
- def admin_policy_object=(value)
95
- self.set_rels_ext_resource("hydra:isGovernedBy",value)
96
- end
97
-
98
- def parent
99
- self.get_rels_ext_resource("rel:isPartOf")
100
- end
101
-
102
- def parent=(value)
103
- self.set_rels_ext_resource("rel:isPartOf",value)
104
- end
105
-
106
- def get_rels_ext_resource(predicate)
107
- resource = self.get_datastream("RELS-EXT","//#{predicate}/@rdf:resource")
108
- if resource.nil?
109
- nil
110
- else
111
- resource.value.split(/\//).last
112
- end
113
- end
114
-
115
- def set_rels_ext_resource(predicate,value)
116
- if existing_parent = self.get_datastream("RELS-EXT","//#{predicate}")
117
- existing_parent.remove
118
- end
119
- if value.nil?
120
- return nil
121
- else
122
- new_child = @xml.create_element(predicate, 'rdf:resource' => "info:fedora/#{value}")
123
- self.get_datastream("RELS-EXT","//rdf:Description").add_child(new_child)
124
- fix_namespaces(new_child)
125
- return new_child
126
- end
127
- end
128
-
129
- def get_datastream(ds_name, *paths)
130
- result = self.xpath(%{//foxml:datastream[@ID="#{ds_name}"]/foxml:datastreamVersion/foxml:xmlContent}).first
131
- paths.each do |path|
132
- result = result.xpath(path, NAMESPACES).first
133
- end
134
- return result
135
- end
136
-
137
- def set_datastream(ds_name, new_value, nil_value = nil)
138
- new_value ||= nil_value
139
- if new_value.is_a?(Nokogiri::XML::Document)
140
- new_value = new_value.root.clone
141
- elsif new_value.is_a?(Nokogiri::XML::Node)
142
- new_value = new_value.clone
143
- end
144
- parent = self.get_datastream(ds_name)
145
- parent.children.each { |c| c.remove }
146
- unless new_value.nil?
147
- parent.add_child(new_value)
148
- end
149
- end
150
-
151
- def to_xml(opts = {})
152
- undent_datastreams = opts.delete(:undent_datastreams)
153
- @xml.traverse { |node| if node.is_a?(Nokogiri::XML::Text) and node.text.chomp.strip.empty?; node.remove; end }
154
- result = @xml.to_xml(opts)
155
-
156
- # Fedora FOXML ingest treats some (but not all) whitespace as significant. In order to get
157
- # our datastreams to look pretty, we need to un-indent them. This an ugly hack, and only
158
- # works because we've strictly controlled Nokogiri's serialization of whitespace.
159
- if undent_datastreams
160
- result.gsub!(/^(\s*)<foxml:xmlContent>\n(.+?)\n\s*<\/foxml:xmlContent>/m) { |m|
161
- sp = $1
162
- data = $2
163
- "#{sp}<foxml:xmlContent>\n" + data.gsub(/^#{sp} /,'') + "\n#{sp}</foxml:xmlContent>"
164
- }
165
- end
166
- return result
167
- end
168
-
169
- def xpath(path)
170
- @xml.xpath(path, NAMESPACES)
171
- end
172
-
173
- def update_dc_identifiers
174
- new_ids = self.identity_metadata.xpath('*[local-name() = "sourceId" or local-name() = "otherId"]').collect do |n|
175
- n.attribute_nodes.first.value + ":" + n.content
176
- end
177
- unless self.pid.nil? or self.pid.empty?
178
- new_ids << self.pid
179
- end
180
-
181
- dc = self.dublin_core
182
- dc.xpath('dc:identifier',NAMESPACES).each { |existing_id| existing_id.remove }
183
- new_ids.uniq.each do |id|
184
- new_child = @xml.create_element('dc:identifier')
185
- new_child.content = id
186
- dc.add_child(new_child)
187
- fix_namespaces(new_child)
188
- end
189
- return new_ids
190
- end
191
-
192
- def fix_namespaces(node)
193
- if node.is_a?(Nokogiri::XML::CharacterData)
194
- node.namespace = nil
195
- else
196
- if node.name =~ /:/
197
- (prefix,name) = node.name.split(/:/)
198
- node.name = name
199
- node.namespace = @defined_namespaces[prefix]
200
- end
201
- unless node.is_a?(Nokogiri::XML::Attr)
202
- node.children.each { |n| fix_namespaces(n) }
203
- node.attribute_nodes.each { |n| fix_namespaces(n) }
204
- end
205
- end
206
- end
207
-
208
- def method_missing(sym,*args)
209
- if @xml.respond_to?(sym)
210
- @xml.send(sym,*args)
211
- else
212
- super
213
- end
214
- end
215
-
216
- XML_TEMPLATE = %{
217
- <?xml version="1.0" encoding="UTF-8"?>
218
- <foxml:digitalObject PID="$$PID$$" VERSION="1.1"
219
- xmlns:foxml="info:fedora/fedora-system:def/foxml#"
220
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
221
- <foxml:objectProperties>
222
- <foxml:property NAME="info:fedora/fedora-system:def/model#state" VALUE="Active"/>
223
- <foxml:property NAME="info:fedora/fedora-system:def/model#label" VALUE="$$LABEL$$"/>
224
- <foxml:property NAME="info:fedora/fedora-system:def/model#ownerId" VALUE="DOR"/>
225
- </foxml:objectProperties>
226
- <foxml:datastream CONTROL_GROUP="X" ID="DC" STATE="A" VERSIONABLE="false">
227
- <foxml:datastreamVersion
228
- FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" ID="DC1.0"
229
- LABEL="Dublin Core Record for this object" MIMETYPE="text/xml">
230
- <foxml:xmlContent>
231
- <oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"/>
232
- </foxml:xmlContent>
233
- </foxml:datastreamVersion>
234
- </foxml:datastream>
235
- <foxml:datastream CONTROL_GROUP="X" ID="identityMetadata" STATE="A" VERSIONABLE="false">
236
- <foxml:datastreamVersion
237
- ID="identityMetadata.0" LABEL="Identity Metadata" MIMETYPE="text/xml">
238
- <foxml:xmlContent>
239
- <identityMetadata/>
240
- </foxml:xmlContent>
241
- </foxml:datastreamVersion>
242
- </foxml:datastream>
243
- <foxml:datastream CONTROL_GROUP="X" ID="RELS-EXT" STATE="A">
244
- <foxml:datastreamVersion
245
- FORMAT_URI="info:fedora/fedora-system:FedoraRELSExt-1.0" ID="RELS-EXT.0"
246
- LABEL="RDF Statements about this object" MIMETYPE="application/rdf+xml">
247
- <foxml:xmlContent>
248
- <rdf:RDF xmlns:fedora-model="info:fedora/fedora-system:def/model#"
249
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
250
- xmlns:fedora="info:fedora/fedora-system:def/relations-external#"
251
- xmlns:hydra="http://projecthydra.org/ns/relations#">
252
- <rdf:Description rdf:about="info:fedora/$$PID$$">
253
- </rdf:Description>
254
- </rdf:RDF>
255
- </foxml:xmlContent>
256
- </foxml:datastreamVersion>
257
- </foxml:datastream>
258
- </foxml:digitalObject>
259
- }.strip
260
-
261
- end