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
@@ -0,0 +1,54 @@
1
+ require 'dor/datastreams/workflow_definition_ds'
2
+
3
+ module Dor
4
+ class WorkflowObject < ::ActiveFedora::Base
5
+ include Identifiable
6
+ include SolrDocHelper
7
+ include Governable
8
+ @@xml_cache = {}
9
+
10
+ has_object_type 'workflow'
11
+ has_metadata :name => "workflowDefinition", :type => Dor::WorkflowDefinitionDs, :label => 'Workflow Definition'
12
+
13
+ def self.find_by_name(name, opts={})
14
+ Dor.find_all(%{objectType_t:"#{self.object_type}" workflow_name_s:"#{name}"}, opts).first
15
+ end
16
+
17
+ # Searches for the workflow definition object in DOR, then
18
+ # returns an object's initial workflow as defined in the worfklowDefinition datastream
19
+ # It will cache the result for subsequent requests
20
+ # @param [String] name the name of the workflow
21
+ # @return [String] the initial workflow xml
22
+ def self.initial_workflow(name)
23
+ return @@xml_cache[name] if(@@xml_cache.include?(name))
24
+
25
+ wobj = self.find_by_name(name)
26
+ wf_xml = wobj.generate_initial_workflow
27
+ @@xml_cache[name] = wf_xml
28
+ end
29
+
30
+ def definition
31
+ datastreams['workflowDefinition']
32
+ end
33
+
34
+ def graph *args
35
+ self.definition.graph *args
36
+ end
37
+
38
+ def to_solr solr_doc=Hash.new, *args
39
+ super solr_doc, *args
40
+ client = Dor::WorkflowService.workflow_resource
41
+ xml = client["workflow_archive?repository=#{definition.repo}&workflow=#{definition.name}&count-only=true"].get
42
+ count = Nokogiri::XML(xml).at_xpath('/objects/@count').value
43
+ add_solr_value(solr_doc,"#{definition.name}_archived",count,:integer,[:displayable])
44
+ solr_doc
45
+ end
46
+
47
+ def generate_initial_workflow
48
+ datastreams['workflowDefinition'].initial_workflow
49
+ end
50
+
51
+ alias_method :generate_intial_workflow, :generate_initial_workflow
52
+
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ require 'pathname'
2
+
3
+ module Dor
4
+
5
+ # Remove all traces of the object's data files from the workspace and export areas
6
+ class CleanupService
7
+
8
+ # @param [LyberCore::Robots::WorkItem] dor_item The DOR work item whose workspace should be cleaned up
9
+ # @return [void] Delete all workspace and export entities for the druid
10
+ def self.cleanup(dor_item)
11
+ druid = dor_item.druid
12
+ cleanup_by_druid druid
13
+ end
14
+
15
+ def self.cleanup_by_druid(druid)
16
+ cleanup_workspace_content(druid, Config.cleanup.local_workspace_root)
17
+ cleanup_workspace_content(druid, Config.cleanup.local_assembly_root)
18
+ cleanup_export(druid)
19
+ end
20
+
21
+ # @param [String] druid The identifier for the object whose data is to be removed
22
+ # @param [String] base The base directory to delete from
23
+ # @return [void] remove the object's data files from the workspace area
24
+ def self.cleanup_workspace_content(druid, base)
25
+ DruidTools::Druid.new(druid, base).prune!
26
+ end
27
+
28
+ # @param [String] druid The identifier for the object whose data is to be removed
29
+ # @return [void] remove copy of the data that was exported to preservation core
30
+ def self.cleanup_export(druid)
31
+ id = druid.split(':').last
32
+ bag_dir = File.join(Config.cleanup.local_export_home, id)
33
+ self.remove_branch(bag_dir)
34
+ tarfile = "#{bag_dir}.tar"
35
+ self.remove_branch(tarfile)
36
+ end
37
+
38
+ # @param [Pathname,String] pathname The full path of the branch to be removed
39
+ # @return [void] Remove the specified directory and all its children
40
+ def self.remove_branch(pathname)
41
+ pathname = Pathname(pathname) if pathname.instance_of? String
42
+ pathname.rmtree if pathname.exist?
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,55 @@
1
+ require 'net/ssh'
2
+ require 'net/sftp'
3
+
4
+ module Dor
5
+ class DigitalStacksService
6
+
7
+ def self.transfer_to_document_store(id, content, filename)
8
+ druid = DruidTools::PurlDruid.new id, Config.stacks.local_document_cache_root
9
+ druid.content_dir # create the druid tree if it doesn't exist yet
10
+ File.open(File.join(druid.content_dir, filename), 'w') {|f| f.write content }
11
+ end
12
+
13
+ def self.remove_from_stacks(id, files)
14
+ files.each do |file|
15
+ dr = DruidTools::StacksDruid.new id, Config.stacks.local_stacks_root
16
+ content = dr.find_content file
17
+ FileUtils.rm content if content
18
+ end
19
+ end
20
+
21
+ # @param [String] id object pid
22
+ # @param [Array<Array<String>>] file_map an array of two string arrays. Each inner array represents old-file/new-file mappings. First string is the old file name, second string is the new file name. e.g:
23
+ # [ ['src1.file', 'dest1.file'], ['src2.file', 'dest2.file'] ]
24
+ def self.rename_in_stacks(id, file_map)
25
+ dr = DruidTools::StacksDruid.new id, Config.stacks.local_stacks_root
26
+ content_dir = dr.find_filelist_parent('content', file_map.first.first)
27
+ file_map.each do |src, dest|
28
+ File.rename(File.join(content_dir, src), File.join(content_dir, dest))
29
+ end
30
+ end
31
+
32
+ def self.shelve_to_stacks(id, files)
33
+ workspace_druid = DruidTools::Druid.new(id,Config.stacks.local_workspace_root)
34
+ stacks_druid = DruidTools::StacksDruid.new(id,Config.stacks.local_stacks_root)
35
+ files.each do |file|
36
+ stacks_druid.content_dir
37
+ workspace_file = workspace_druid.find_content(file)
38
+ FileUtils.cp workspace_file, stacks_druid.content_dir
39
+ end
40
+ end
41
+
42
+ # Assumes the digital stacks storage root is mounted to the local file system
43
+ # TODO since this is delegating to the Druid, this method may not be necessary
44
+ def self.prune_stacks_dir(id)
45
+ stacks_druid_tree = DruidTools::StacksDruid.new(id, Config.stacks.local_stacks_root)
46
+ stacks_druid_tree.prune!
47
+ end
48
+
49
+ def self.prune_purl_dir(id)
50
+ druid = DruidTools::PurlDruid.new(id, Dor::Config.stacks.local_document_cache_root)
51
+ druid.prune!
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,96 @@
1
+ module Dor
2
+
3
+ class MergeService
4
+
5
+ def MergeService.merge_into_primary primary_druid, secondary_druids, tag, logger = nil
6
+ # TODO test the secondary_obj to see if we've processed it already
7
+ merge_service = Dor::MergeService.new primary_druid, secondary_druids, tag, logger
8
+ merge_service.check_objects_editable
9
+ merge_service.move_metadata_and_content
10
+ merge_service.decomission_secondaries
11
+ # kick off commonAccessioning for the primary?
12
+ end
13
+
14
+ def initialize primary_druid, secondary_pids, tag, logger = nil
15
+ @primary = Dor::Item.find primary_druid
16
+ @secondary_pids = secondary_pids
17
+ @secondary_objs = secondary_pids.map {|pid| Dor::Item.find pid }
18
+ if logger.nil?
19
+ @logger = Logger.new(STDERR)
20
+ else
21
+ @logger = logger
22
+ end
23
+ @tag = tag
24
+ end
25
+
26
+ def check_objects_editable
27
+ unless @primary.allows_modification?
28
+ raise Dor::Exception.new "Primary object is not editable: #{@primary.pid}"
29
+ end
30
+ if ( non_editable = (@secondary_objs.detect {|obj| ! obj.allows_modification? } ))
31
+ raise Dor::Exception.new "Secondary object is not editable: #{non_editable.pid}"
32
+ end
33
+ end
34
+
35
+ def move_metadata_and_content
36
+ @primary.copy_file_resources @secondary_pids
37
+ @primary.save
38
+ copy_workspace_content
39
+ end
40
+
41
+ # Copies the content from the secondary object workspace to the primary object's workspace
42
+ # Depends on Dor::Config.stacks.local_workspace_root
43
+ def copy_workspace_content
44
+ pri_file = @primary.contentMetadata.resource(0).file(0).id.first
45
+ pri_druid = DruidTools::Druid.new @primary.pid, Dor::Config.stacks.local_workspace_root
46
+ dest_path = pri_druid.find_filelist_parent 'content', pri_file
47
+ primary_cm = @primary.contentMetadata.ng_xml
48
+
49
+ @secondary_objs.each do |secondary|
50
+
51
+ sec_druid = DruidTools::Druid.new secondary.pid, Dor::Config.stacks.local_workspace_root
52
+ secondary.contentMetadata.ng_xml.xpath("//resource").each do |src_resource|
53
+ primary_resource = primary_cm.at_xpath "//resource[attr[@name = 'mergedFromPid']/text() = '#{secondary.pid}' and
54
+ attr[@name = 'mergedFromResource']/text() = '#{src_resource['id']}' ]"
55
+ sequence = primary_resource['sequence']
56
+ src_resource.xpath("//file/@id").map {|id| id.value }.each do |file_id|
57
+ copy_path = sec_druid.find_content file_id
58
+ new_name = secondary.new_secondary_file_name(file_id, sequence)
59
+ # TODO verify new_name exists in primary_cm?
60
+ FileUtils.cp(copy_path, File.join(dest_path, "/#{new_name}"))
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def decomission_secondaries
67
+ @secondary_objs.each do |secondary_obj|
68
+ begin
69
+ @current_secondary = secondary_obj
70
+ @current_secondary.decomission @tag
71
+ @current_secondary.save
72
+
73
+ unshelve
74
+ unpublish
75
+ Dor::CleanupService.cleanup_by_druid @current_secondary.pid
76
+ Dor::WorkflowService.archive_active_workflow 'dor', @current_secondary.pid
77
+ rescue => e
78
+ @logger.error "Unable to decomission #{@current_secondary.pid} with primary object #{@primary.pid}: #{e.inspect}"
79
+ @logger.error e.backtrace.join("\n")
80
+ end
81
+ end
82
+ end
83
+
84
+ # Remove content from stacks
85
+ # TODO might set workflow status in future for robot to do
86
+ def unshelve
87
+ DigitalStacksService.prune_stacks_dir @current_secondary.pid
88
+ end
89
+
90
+ # Withdraw item from Purl
91
+ # TODO might set workflow status in future for robot to do
92
+ def unpublish
93
+ @current_secondary.publish_metadata
94
+ end
95
+ end
96
+ end
@@ -1,8 +1,6 @@
1
1
  require 'rest-client'
2
2
 
3
3
  handler = Class.new do
4
- Dor::Config.metadata.declare(:catalog) { url nil }
5
-
6
4
  def fetch(prefix, identifier)
7
5
  client = RestClient::Resource.new(Dor::Config.metadata.catalog.url)
8
6
  client["?#{prefix.chomp}=#{identifier.chomp}"].get
@@ -2,8 +2,6 @@ require 'nokogiri'
2
2
  require 'rest-client'
3
3
 
4
4
  handler = Class.new do
5
- Dor::Config.metadata.declare(:exist) { url nil }
6
-
7
5
  def fetch(prefix, identifier)
8
6
  query = <<-QUERY
9
7
  <?xml version="1.0" encoding="UTF-8"?>
@@ -18,14 +18,12 @@ module Dor
18
18
 
19
19
  class MetadataService
20
20
 
21
- Config.declare(:metadata)
22
-
23
21
  class << self
24
22
  @@cache = Cache.new(nil, nil, 250, 300)
25
23
 
26
24
  def register(handler_class)
27
25
  ['fetch', 'label', 'prefixes'].each do |method|
28
- unless handler_class.instance_methods.include?(method)
26
+ unless handler_class.instance_methods.include?(method) or handler_class.instance_methods.include?(method.to_sym)
29
27
  raise TypeError, "Metadata handlers must define ##{method.to_s}"
30
28
  end
31
29
  end
@@ -0,0 +1,181 @@
1
+ require 'uuidtools'
2
+
3
+ module Dor
4
+
5
+ class RegistrationService
6
+
7
+ class << self
8
+ def register_object(params = {})
9
+ Dor.ensure_models_loaded!
10
+ [:object_type, :label].each do |required_param|
11
+ raise Dor::ParameterError, "#{required_param.inspect} must be specified in call to #{self.name}.register_object" unless params[required_param]
12
+ end
13
+ metadata_source=params[:metadata_source]
14
+ if params[:label].length<1 and (metadata_source=='label' || metadata_source=='none')
15
+ raise Dor::ParameterError, "label cannot be empty to call #{self.name}.register_object"
16
+ end
17
+ object_type = params[:object_type]
18
+ item_class = Dor.registered_classes[object_type]
19
+ raise Dor::ParameterError, "Unknown item type: '#{object_type}'" if item_class.nil?
20
+
21
+ content_model = params[:content_model]
22
+ admin_policy = params[:admin_policy]
23
+ label = params[:label]
24
+ source_id = params[:source_id] || {}
25
+ other_ids = params[:other_ids] || {}
26
+ tags = params[:tags] || []
27
+ parent = params[:parent]
28
+ collection = params[:collection]
29
+ pid = nil
30
+ metadata_source=params[:metadata_source]
31
+ if params[:pid]
32
+ pid = params[:pid]
33
+ existing_pid = SearchService.query_by_id(pid).first
34
+ unless existing_pid.nil?
35
+ raise Dor::DuplicateIdError.new(existing_pid), "An object with the PID #{pid} has already been registered."
36
+ end
37
+ else
38
+ pid = Dor::SuriService.mint_id
39
+ end
40
+
41
+ rights=nil
42
+ if params[:rights]
43
+ rights=params[:rights]
44
+ if not ['world','stanford','dark','default','none'].include? rights
45
+ raise Dor::ParameterError,"Unknown rights setting" + rights + "when calling #{self.name}.register_object"
46
+ end
47
+ end
48
+
49
+ source_id_string = [source_id.keys.first,source_id[source_id.keys.first]].compact.join(':')
50
+ unless source_id.empty?
51
+ existing_pid = SearchService.query_by_id("#{source_id_string}").first
52
+ unless existing_pid.nil?
53
+ raise Dor::DuplicateIdError.new(existing_pid), "An object with the source ID '#{source_id_string}' has already been registered."
54
+ end
55
+ end
56
+
57
+ if (other_ids.has_key?(:uuid) or other_ids.has_key?('uuid')) == false
58
+ other_ids[:uuid] = UUIDTools::UUID.timestamp_create.to_s
59
+ end
60
+ short_label=label
61
+ if label.length>254
62
+ short_label=label[0,254]
63
+ end
64
+
65
+ apo_object = Dor.find(admin_policy, :lightweight => true)
66
+ adm_xml = apo_object.administrativeMetadata.ng_xml
67
+
68
+ new_item = item_class.new(:pid => pid)
69
+ new_item.label = short_label
70
+ idmd = new_item.identityMetadata
71
+ idmd.sourceId = source_id_string
72
+ idmd.add_value(:objectId, pid)
73
+ idmd.add_value(:objectCreator, 'DOR')
74
+ idmd.add_value(:objectLabel, label)
75
+ idmd.add_value(:objectType, object_type)
76
+ idmd.add_value(:adminPolicy, admin_policy)
77
+ other_ids.each_pair { |name,value| idmd.add_otherId("#{name}:#{value}") }
78
+ tags.each { |tag| idmd.add_value(:tag, tag) }
79
+ new_item.admin_policy_object = apo_object
80
+
81
+ adm_xml.xpath('/administrativeMetadata/relationships/*').each do |rel|
82
+ short_predicate = ActiveFedora::RelsExtDatastream.short_predicate rel.namespace.href+rel.name
83
+ if short_predicate.nil?
84
+ ix = 0
85
+ ix += 1 while ActiveFedora::Predicates.predicate_mappings[rel.namespace.href].has_key?(short_predicate = :"extra_predicate_#{ix}")
86
+ ActiveFedora::Predicates.predicate_mappings[rel.namespace.href][short_predicate] = rel.name
87
+ end
88
+ new_item.add_relationship short_predicate, rel['rdf:resource']
89
+ end
90
+ if collection
91
+ new_item.add_collection(collection)
92
+ end
93
+ if(rights and ['item','collection'].include? object_type )
94
+ rights_xml=apo_object.defaultObjectRights.ng_xml
95
+ new_item.datastreams['rightsMetadata'].content=rights_xml.to_s
96
+ new_item.set_read_rights(rights)
97
+ end
98
+ #create basic mods from the label
99
+ if(metadata_source=='label')
100
+ ds=new_item.build_datastream('descMetadata');
101
+ builder = Nokogiri::XML::Builder.new { |xml|
102
+ xml.mods( 'xmlns' => 'http://www.loc.gov/mods/v3', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',:version => '3.3', "xsi:schemaLocation" => 'http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd'){
103
+ xml.titleInfo{
104
+ xml.title label
105
+ }
106
+ }
107
+ }
108
+
109
+ ds.content=builder.to_xml
110
+
111
+ end
112
+
113
+ workflow_priority = params[:workflow_priority] ? params[:workflow_priority].to_i : 0
114
+
115
+ Array(params[:seed_datastream]).each { |datastream_name| new_item.build_datastream(datastream_name) }
116
+ Array(params[:initiate_workflow]).each { |workflow_id| new_item.initialize_workflow(workflow_id, 'dor', !new_item.new_object?, workflow_priority)}
117
+
118
+ new_item.assert_content_model
119
+ new_item.save
120
+ begin
121
+ new_item.update_index if ::ENABLE_SOLR_UPDATES
122
+ rescue StandardError => e
123
+ Dor.logger.warn "Dor::RegistrationService.register_object failed to update solr index for #{new_item.pid}: #<#{e.class.name}: #{e.message}>"
124
+ end
125
+ return(new_item)
126
+ end
127
+
128
+ def create_from_request(params)
129
+ other_ids = Array(params[:other_id]).collect do |id|
130
+ if id =~ /^symphony:(.+)$/
131
+ "#{$1.length < 14 ? 'catkey' : 'barcode'}:#{$1}"
132
+ else
133
+ id
134
+ end
135
+ end
136
+
137
+ if params[:label] == ':auto'
138
+ params.delete(:label)
139
+ params.delete('label')
140
+ metadata_id = Dor::MetadataService.resolvable(other_ids).first
141
+ params[:label] = Dor::MetadataService.label_for(metadata_id)
142
+ end
143
+
144
+ dor_params = {
145
+ :pid => params[:pid],
146
+ :admin_policy => params[:admin_policy],
147
+ :content_model => params[:model],
148
+ :label => params[:label],
149
+ :object_type => params[:object_type],
150
+ :other_ids => ids_to_hash(other_ids),
151
+ :parent => params[:parent],
152
+ :source_id => ids_to_hash(params[:source_id]),
153
+ :tags => params[:tag] || [],
154
+ :seed_datastream => params[:seed_datastream],
155
+ :initiate_workflow => Array(params[:initiate_workflow]) + Array(params[:workflow_id]),
156
+ :rights => params[:rights],
157
+ :metadata_source => params[:metadata_source],
158
+ :collection => params[:collection],
159
+ :workflow_priority => params[:workflow_priority]
160
+ }
161
+ dor_params.delete_if { |k,v| v.nil? }
162
+
163
+ dor_obj = self.register_object(dor_params)
164
+ pid = dor_obj.pid
165
+ location = URI.parse(Dor::Config.fedora.safeurl.sub(/\/*$/,'/')).merge("objects/#{pid}").to_s
166
+ reg_response = dor_params.dup.merge({ :location => location, :pid => pid })
167
+ end
168
+
169
+ private
170
+ def ids_to_hash(ids)
171
+ if ids.nil?
172
+ nil
173
+ else
174
+ Hash[Array(ids).collect { |id| id.split(/:/) }]
175
+ end
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ end