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,211 @@
1
+ module Dor
2
+ module Identifiable
3
+ extend ActiveSupport::Concern
4
+ include SolrDocHelper
5
+ include Eventable
6
+ include Upgradable
7
+
8
+ included do
9
+ has_metadata :name => "DC", :type => SimpleDublinCoreDs, :label => 'Dublin Core Record for self object'
10
+ has_metadata :name => "identityMetadata", :type => Dor::IdentityMetadataDS, :label => 'Identity Metadata'
11
+ end
12
+
13
+ module ClassMethods
14
+ attr_reader :object_type
15
+ def has_object_type str
16
+ @object_type = str
17
+ Dor.registered_classes[str] = self
18
+ end
19
+ end
20
+
21
+ def initialize attrs={}
22
+ if Dor::Config.suri.mint_ids
23
+ unless attrs[:pid]
24
+ attrs = attrs.merge!({:pid=>Dor::SuriService.mint_id, :new_object => true})
25
+ end
26
+ end
27
+ super
28
+ end
29
+
30
+ # helper method to get the tags as an array
31
+ def tags
32
+ self.identityMetadata.tag
33
+ end
34
+
35
+ # helper method to get just the content type tag
36
+ def content_type_tag
37
+ content_tag=tags.select {|tag| tag.include?('Process : Content Type')}
38
+ content_tag.size == 1 ? content_tag[0].split(':').last.strip : ""
39
+ end
40
+
41
+ # Syntactic sugar for identifying applied DOR Concerns
42
+ # e.g., obj.is_identifiable? is the same as obj.is_a?(Dor::Identifiable)
43
+ def method_missing sym, *args
44
+ if sym.to_s =~ /^is_(.+)\?$/
45
+ begin
46
+ klass = Dor.const_get $1.capitalize.to_sym
47
+ return self.is_a?(klass)
48
+ rescue NameError
49
+ return false
50
+ end
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ @@collection_hash={}
57
+ @@apo_hash={}
58
+ @@hydrus_apo_hash={}
59
+ @@hydrus_collection_hash={}
60
+ def to_solr(solr_doc=Hash.new, *args)
61
+ self.assert_content_model
62
+ super(solr_doc)
63
+ solr_doc[Dor::INDEX_VERSION_FIELD] = Dor::VERSION
64
+ solr_doc[solr_name('indexed_at',:date)] = Time.now.utc.xmlschema
65
+ add_solr_value(solr_doc, 'indexed_day', Time.now.beginning_of_day.utc.xmlschema, :string, [:searchable, :facetable])
66
+ datastreams.values.each do |ds|
67
+ unless ds.new?
68
+ add_solr_value(solr_doc,'ds_specs',ds.datastream_spec_string,:string,[:displayable])
69
+ end
70
+ end
71
+ add_solr_value(solr_doc, 'title_sort', self.label, :string, [:sortable])
72
+ rels_doc = Nokogiri::XML(self.datastreams['RELS-EXT'].content)
73
+ apos=rels_doc.search('//rdf:RDF/rdf:Description/hydra:isGovernedBy','hydra' => 'http://projecthydra.org/ns/relations#', 'fedora' => 'info:fedora/fedora-system:def/relations-external#', 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' )
74
+ apos.each do |apo_node|
75
+ druid=apo_node['rdf:resource']
76
+ if druid
77
+ druid=druid.gsub('info:fedora/','')
78
+ if @@apo_hash.has_key? druid or @@hydrus_apo_hash.has_key? druid
79
+ add_solr_value(solr_doc, "hydrus_apo_title", @@hydrus_apo_hash[druid], :string, [:searchable, :facetable]) if @@hydrus_apo_hash.has_key? druid
80
+ add_solr_value(solr_doc, "apo_title", @@apo_hash[druid] , :string, [:searchable, :facetable]) if @@apo_hash.has_key? druid
81
+ else
82
+ begin
83
+ apo_object=Dor.find(druid)
84
+ if apo_object.tags.include? 'Project : Hydrus'
85
+ add_solr_value(solr_doc, "hydrus_apo_title", apo_object.label, :string, [:searchable, :facetable])
86
+ @@hydrus_apo_hash[druid]=apo_object.label
87
+ else
88
+ add_solr_value(solr_doc, "apo_title", apo_object.label, :string, [:searchable, :facetable])
89
+ @@apo_hash[druid]=apo_object.label
90
+ end
91
+ rescue
92
+ add_solr_value(solr_doc, "apo_title", druid, :string, [:searchable, :facetable])
93
+ end
94
+ end
95
+ end
96
+ end
97
+ collections=rels_doc.search('//rdf:RDF/rdf:Description/fedora:isMemberOfCollection','fedora' => 'info:fedora/fedora-system:def/relations-external#', 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' )
98
+ collections.each do |collection_node|
99
+ druid=collection_node['rdf:resource']
100
+ if(druid)
101
+ druid=druid.gsub('info:fedora/','')
102
+ if @@collection_hash.has_key? druid or @@hydrus_collection_hash.has_key? druid
103
+ add_solr_value(solr_doc, "hydrus_collection_title", @@hydrus_collection_hash[druid], :string, [:searchable, :facetable]) if @@hydrus_collection_hash.has_key? druid
104
+ add_solr_value(solr_doc, "collection_title", @@collection_hash[druid], :string, [:searchable, :facetable]) if @@collection_hash.has_key? druid
105
+ else
106
+ begin
107
+ collection_object=Dor.find(druid)
108
+ if collection_object.tags.include? 'Project : Hydrus'
109
+ add_solr_value(solr_doc, "hydrus_collection_title", collection_object.label, :string, [:searchable, :facetable])
110
+ @@hydrus_collection_hash[druid]=collection_object.label
111
+ else
112
+ add_solr_value(solr_doc, "collection_title", collection_object.label, :string, [:searchable, :facetable])
113
+ @@collection_hash[druid]=collection_object.label
114
+ end
115
+ rescue
116
+ add_solr_value(solr_doc, "collection_title", druid, :string, [:searchable, :facetable])
117
+ end
118
+ end
119
+ end
120
+ end
121
+ # Fix for ActiveFedora 3.3 to ensure all date fields are properly formatted as UTC XML Schema datetime strings
122
+ solr_doc.each_pair { |k,v|
123
+ if k =~ /_dt|_date$/
124
+ if v.is_a?(Array)
125
+ solr_doc[k] = v.collect { |t| Time.parse(t.to_s).utc.xmlschema }
126
+ else
127
+ solr_doc[k] = Time.parse(v.to_s).utc.xmlschema
128
+ end
129
+ end
130
+ }
131
+
132
+ solr_doc
133
+ end
134
+ def set_source_id(source_id)
135
+ self.identityMetadata.sourceId = source_id
136
+ end
137
+
138
+ def add_other_Id(type,val)
139
+ if self.identityMetadata.otherId(type).length>0
140
+ raise 'There is an existing entry for '+node_name+', consider using update_other_identifier.'
141
+ end
142
+ identity_metadata_ds = self.identityMetadata
143
+ identity_metadata_ds.add_otherId(type+':'+val)
144
+ end
145
+
146
+ def update_other_Id(type,new_val, val=nil)
147
+ identity_metadata_ds = self.identityMetadata
148
+ ds_xml=identity_metadata_ds.ng_xml
149
+ #split the thing they sent in to find the node name
150
+ updated=false
151
+ ds_xml.search('//otherId[@name=\''+type+'\']').each do |node|
152
+ if node.content==val or val==nil
153
+ node.content=new_val
154
+ updated=true
155
+ end
156
+ end
157
+ return updated
158
+ end
159
+
160
+ def remove_other_Id(type,val=nil)
161
+ ds_xml=self.identityMetadata.ng_xml
162
+ #split the thing they sent in to find the node name
163
+ removed=false
164
+
165
+ ds_xml.search('//otherId[@name=\''+type+'\']').each do |node|
166
+ if node.content===val or val==nil
167
+ node.remove
168
+ removed=true
169
+ end
170
+ end
171
+ return removed
172
+ end
173
+
174
+ def add_tag(tag)
175
+ identity_metadata_ds = self.identityMetadata
176
+ prefix=tag.split(/:/).first
177
+ identity_metadata_ds.tags.each do |existing_tag|
178
+ if existing_tag.split(/:/).first ==prefix
179
+ raise 'An existing tag ('+existing_tag+') has the same prefix, consider using update_tag?'
180
+ end
181
+ end
182
+ identity_metadata_ds.add_value(:tag,tag)
183
+ end
184
+
185
+ def remove_tag(tag)
186
+ identity_metadata_ds = self.identityMetadata
187
+ ds_xml=identity_metadata_ds.ng_xml
188
+ removed=false
189
+ ds_xml.search('//tag').each do |node|
190
+ if node.content===tag
191
+ node.remove
192
+ removed=true
193
+ end
194
+ end
195
+ return removed
196
+ end
197
+
198
+ def update_tag(old_tag,new_tag)
199
+ identity_metadata_ds = self.identityMetadata
200
+ ds_xml=identity_metadata_ds.ng_xml
201
+ updated=false
202
+ ds_xml.search('//tag').each do |node|
203
+ if node.content==old_tag
204
+ node.content=new_tag
205
+ updated = true
206
+ end
207
+ end
208
+ return updated
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,44 @@
1
+ module Dor
2
+ module BasicItem
3
+ extend ActiveSupport::Concern
4
+
5
+ include Identifiable
6
+ include Processable
7
+ include Governable
8
+ include Describable
9
+ include Publishable
10
+ include Shelvable
11
+ include Embargoable
12
+ include Preservable
13
+ include Assembleable
14
+ include Versionable
15
+ include Contentable
16
+ include Discoverable
17
+
18
+ end
19
+
20
+ class Abstract < ::ActiveFedora::Base
21
+ include Identifiable
22
+ end
23
+
24
+ class Item < ::ActiveFedora::Base
25
+ include BasicItem
26
+ has_object_type 'item'
27
+ end
28
+ end
29
+
30
+ # Describable = Descriptive metadata.
31
+ # Embargoable = Time limits and processes for embargoed materials.
32
+ # Governable = Relationships to collections and codified administrative policies.
33
+ # Identifiable = Object identity and source metadata.
34
+ # Itemizable = Hierarchical content metadata.
35
+ # Preservable = Provenance and technical metadata; preservation repository transfer.
36
+ # Processable = Workflow.
37
+ # Publishable = Transfer of metadata to discovery and access systems.
38
+ # Shelvable = Transfer of content to digital stacks.
39
+ # Upgradable = Remediation of existing objects when content standards change.
40
+
41
+ # Required for all DOR objects:
42
+ # - Identifiable
43
+ # - Governable
44
+ # - Describable
@@ -0,0 +1,66 @@
1
+ require 'fileutils'
2
+ require 'uri'
3
+
4
+ module Dor
5
+ module Itemizable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ has_metadata :name => "contentMetadata", :type => Dor::ContentMetadataDS, :label => 'Content Metadata', :control_group => 'M'
10
+ end
11
+
12
+ DIFF_FILENAME = 'cm_inv_diff'
13
+ DIFF_QUERY = DIFF_FILENAME.gsub('_', '-')
14
+
15
+ # Deletes all cm_inv_diff files in the workspace for the Item
16
+ def clear_diff_cache
17
+ if Dor::Config.stacks.local_workspace_root.nil?
18
+ raise ArgumentError, 'Missing Dor::Config.stacks.local_workspace_root'
19
+ end
20
+ druid = DruidTools::Druid.new(self.pid, Dor::Config.stacks.local_workspace_root)
21
+ diff_pattern = File.join(druid.temp_dir, DIFF_FILENAME + '.*')
22
+ FileUtils.rm_f Dir.glob(diff_pattern)
23
+ end
24
+
25
+ # Retrieves file difference manifest for contentMetadata from SDR
26
+ #
27
+ # @param [String] subset keyword for file attributes :shelve, :preserve, :publish. Default is :all.
28
+ # @param [String] version
29
+ # @return [String] XML contents of cm_inv_diff manifest
30
+ def get_content_diff(subset = :all, version = nil)
31
+ if Dor::Config.stacks.local_workspace_root.nil?
32
+ raise Dor::ParameterError, 'Missing Dor::Config.stacks.local_workspace_root'
33
+ end
34
+ unless %w{all shelve preserve publish}.include?(subset.to_s)
35
+ raise Dor::ParameterError, "Invalid subset value: #{subset}"
36
+ end
37
+
38
+ basename = version.nil? ? "#{DIFF_FILENAME}.#{subset}.xml" : "#{DIFF_FILENAME}.#{subset}.#{version}.xml"
39
+ druid = DruidTools::Druid.new(self.pid, Dor::Config.stacks.local_workspace_root)
40
+ diff_cache = File.join(druid.temp_dir, basename)
41
+ # check for cached copy before contacting SDR
42
+ if File.exists? diff_cache
43
+ File.read(diff_cache)
44
+ else
45
+ # fetch content metadata inventory difference from SDR
46
+ if Dor::Config.sdr.rest_client.nil?
47
+ raise Dor::ParameterError, 'Missing Dor::Config.sdr.rest_client'
48
+ end
49
+ sdr_client = Dor::Config.sdr.rest_client
50
+ current_content = self.datastreams['contentMetadata'].content
51
+ if current_content.nil?
52
+ raise Dor::Exception, "Missing contentMetadata datastream"
53
+ end
54
+ query_string = { :subset => subset.to_s }
55
+ query_string[:version] = version.to_s unless version.nil?
56
+ query_string = URI.encode_www_form(query_string)
57
+ sdr_query = "objects/#{self.pid}/#{DIFF_QUERY}?#{query_string}"
58
+ response = sdr_client[sdr_query].post(current_content, :content_type => 'application/xml')
59
+ # cache response
60
+ File.open(diff_cache, 'w') { |f| f << response }
61
+ response
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -42,7 +42,7 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
42
42
  <xsl:template match="/">
43
43
  <xsl:choose>
44
44
  <xsl:when test="//mods:modsCollection">
45
- <srw_dc:dcCollection xsi:schemaLocation="info:srw/schema/1/dc-schema http://www.loc.gov/standards/sru/dc-schema.xsd">
45
+ <srw_dc:dcCollection xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xsi:schemaLocation="info:srw/schema/1/dc-schema http://www.loc.gov/standards/sru/dc-schema.xsd">
46
46
  <xsl:apply-templates/>
47
47
  <xsl:for-each select="mods:modsCollection/mods:mods">
48
48
  <srw_dc:dc xsi:schemaLocation="info:srw/schema/1/dc-schema http://www.loc.gov/standards/sru/dc-schema.xsd">
@@ -54,7 +54,7 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
54
54
  </xsl:when>
55
55
  <xsl:otherwise>
56
56
  <xsl:for-each select="mods:mods">
57
- <oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
57
+ <oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
58
58
  <xsl:apply-templates/>
59
59
 
60
60
  </oai_dc:dc>
@@ -184,6 +184,8 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
184
184
 
185
185
  <xsl:template match="mods:abstract | mods:tableOfContents | mods:note">
186
186
  <dc:description>
187
+ <xsl:copy-of select="@type"/>
188
+ <xsl:copy-of select="@displayLabel"/>
187
189
  <xsl:value-of select="."/>
188
190
  </dc:description>
189
191
  </xsl:template>
@@ -191,7 +193,7 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
191
193
  <xsl:template match="mods:originInfo">
192
194
  <xsl:apply-templates select="*[@point='start']"/>
193
195
  <xsl:for-each
194
- select="mods:dateIssued[@point!='start' and @point!='end'] |mods:dateCreated[@point!='start' and @point!='end'] | mods:dateCaptured[@point!='start' and @point!='end'] | mods:dateOther[@point!='start' and @point!='end']">
196
+ select="mods:dateIssued[(count(@point) = 0) or (@point!='start' and @point!='end')] |mods:dateCreated[(count(@point) = 0) or (@point!='start' and @point!='end')] | mods:dateCaptured[(count(@point) = 0) or (@point!='start' and @point!='end')] | mods:dateOther[(count(@point) = 0) or (@point!='start' and @point!='end')]">
195
197
  <dc:date>
196
198
  <xsl:value-of select="."/>
197
199
  </dc:date>
@@ -335,7 +337,7 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
335
337
  </xsl:choose>
336
338
  </xsl:template>
337
339
 
338
- <xsl:template match="mods:location">
340
+ <xsl:template match="mods:location[mods:url]">
339
341
  <dc:identifier>
340
342
  <xsl:for-each select="mods:url">
341
343
  <xsl:value-of select="."/>
@@ -368,8 +370,12 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
368
370
  <xsl:when test="@type='series'"/>
369
371
  <xsl:otherwise>
370
372
  <dc:relation>
373
+ <xsl:if test="mods:location/mods:url">
374
+ <xsl:attribute name="type">url</xsl:attribute>
375
+ <xsl:attribute name="href"><xsl:value-of select="mods:location/mods:url"/></xsl:attribute>
376
+ </xsl:if>
371
377
  <xsl:for-each
372
- select="mods:titleInfo/mods:title | mods:identifier | mods:location/mods:url">
378
+ select="mods:titleInfo/mods:title | mods:identifier">
373
379
  <xsl:if test="normalize-space(.)!= ''">
374
380
  <xsl:value-of select="."/>
375
381
 
@@ -381,6 +387,27 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
381
387
  </xsl:choose>
382
388
  </xsl:template>
383
389
 
390
+
391
+ <xsl:template match="mods:location[mods:physicalLocation[@type='repository']]">
392
+ <dc:relation type="repository">
393
+ <xsl:value-of select="normalize-space(.)"/>
394
+ </dc:relation>
395
+ </xsl:template>
396
+ <xsl:template match="mods:relatedItem[@type='host']">
397
+ <xsl:choose>
398
+ <xsl:when test="mods:location/mods:physicalLocation[@type='location']">
399
+ <dc:relation type="location">
400
+ <xsl:value-of select="normalize-space(.)"/>
401
+ </dc:relation>
402
+ </xsl:when>
403
+ <xsl:when test="mods:typeOfResource[@collection='yes']">
404
+ <dc:relation type="collection">
405
+ <xsl:value-of select="normalize-space(mods:titleInfo/mods:title)"/>
406
+ </dc:relation>
407
+ </xsl:when>
408
+ </xsl:choose>
409
+ </xsl:template>
410
+
384
411
  <xsl:template match="mods:accessCondition">
385
412
 
386
413
  <dc:rights>
@@ -391,17 +418,18 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
391
418
  <xsl:template name="name">
392
419
  <xsl:variable name="name">
393
420
  <xsl:for-each select="mods:namePart[not(@type)]">
394
- <xsl:value-of select="."/>
395
-
396
- <xsl:text> </xsl:text>
421
+ <xsl:if test="normalize-space(.)!= ''">
422
+ <xsl:text> </xsl:text>
423
+ <xsl:value-of select="normalize-space(.)"/>
424
+ <xsl:text></xsl:text>
425
+ </xsl:if>
397
426
  </xsl:for-each>
398
427
  <xsl:value-of select="mods:namePart[@type='family']"/>
399
428
  <xsl:if test="mods:namePart[@type='given']">
400
429
  <xsl:text>, </xsl:text>
401
- <xsl:value-of select="mods:namePart[@type='given']"/>
430
+ <xsl:value-of select="normalize-space(mods:namePart[@type='given'])"/>
402
431
  </xsl:if>
403
432
  <xsl:if test="mods:namePart[@type='date']">
404
-
405
433
  <xsl:text>, </xsl:text>
406
434
  <xsl:value-of select="mods:namePart[@type='date']"/>
407
435
  <xsl:text/>
@@ -409,7 +437,6 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
409
437
  <xsl:if test="mods:displayForm">
410
438
  <xsl:text> (</xsl:text>
411
439
  <xsl:value-of select="mods:displayForm"/>
412
-
413
440
  <xsl:text>) </xsl:text>
414
441
  </xsl:if>
415
442
  <xsl:for-each select="mods:role[mods:roleTerm[@type='text']!='creator']">
@@ -434,7 +461,7 @@ Version 1.0 2007-05-04 Tracy Meehleib <tmee@loc.gov>
434
461
  <xsl:value-of select="."/>-<xsl:value-of select="../mods:temporal[@point='end']"/>
435
462
  </xsl:template>
436
463
 
437
- <xsl:template match="mods:temporal[@point!='start' and @point!='end'] ">
464
+ <xsl:template match="mods:temporal[(count(@point) = 0) or (@point!='start' and @point!='end')] ">
438
465
  <xsl:value-of select="."/>
439
466
  </xsl:template>
440
467
 
@@ -0,0 +1,50 @@
1
+ require 'tmpdir'
2
+
3
+ module Dor
4
+ module Preservable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_metadata :name => "provenanceMetadata", :type => ActiveFedora::OmDatastream, :label => 'Provenance Metadata'
9
+ has_metadata :name => "technicalMetadata", :type => ActiveFedora::OmDatastream, :label => 'Technical Metadata', :control_group => 'M'
10
+ end
11
+
12
+ def build_provenanceMetadata_datastream(workflow_id, event_text)
13
+ workflow_provenance = create_workflow_provenance(workflow_id, event_text)
14
+ dsname = 'provenanceMetadata'
15
+ ds = datastreams[dsname]
16
+ unless datastreams.keys.include?(dsname)
17
+ ds.label = 'Provenance Metadata'
18
+ end
19
+ ds.ng_xml = workflow_provenance
20
+ ds.content=ds.ng_xml.to_s
21
+ ds.save
22
+ end
23
+
24
+ def build_technicalMetadata_datastream(ds=nil)
25
+ TechnicalMetadataService.add_update_technical_metadata(self)
26
+ end
27
+
28
+ def sdr_ingest_transfer(agreement_id)
29
+ SdrIngestService.transfer(self,agreement_id)
30
+ end
31
+
32
+
33
+ # @return [Nokogiri::Document]
34
+ def create_workflow_provenance(workflow_id, event_text)
35
+ builder = Nokogiri::XML::Builder.new do |xml|
36
+ xml.provenanceMetadata(:objectId => self.pid) {
37
+ xml.agent(:name => 'DOR') {
38
+ xml.what(:object => self.pid) {
39
+ xml.event(:who => "DOR-#{workflow_id}", :when => Time.new.iso8601) {
40
+ xml.text(event_text)
41
+ }
42
+ }
43
+ }
44
+ }
45
+ end
46
+ builder.doc
47
+ end
48
+
49
+ end
50
+ end