dor-services 4.25.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/dor-indexer +20 -19
- data/bin/dor-indexerd +3 -2
- data/config/certs/robots-dor-dev.crt +29 -0
- data/config/certs/robots-dor-dev.key +27 -0
- data/config/config_defaults.yml +0 -6
- data/config/dev_console_env.rb +65 -0
- data/config/environments/development.rb +84 -0
- data/config/environments/development.rb.old +84 -0
- data/config/environments/test.rb +84 -0
- data/lib/dor-services.rb +8 -18
- data/lib/dor/config.rb +18 -24
- data/lib/dor/datastreams/administrative_metadata_ds.rb +8 -7
- data/lib/dor/datastreams/content_metadata_ds.rb +200 -278
- data/lib/dor/datastreams/datastream_spec_solrizer.rb +1 -1
- data/lib/dor/datastreams/default_object_rights_ds.rb +10 -8
- data/lib/dor/datastreams/desc_metadata_ds.rb +30 -34
- data/lib/dor/datastreams/embargo_metadata_ds.rb +17 -13
- data/lib/dor/datastreams/events_ds.rb +12 -12
- data/lib/dor/datastreams/geo_metadata_ds.rb +3 -244
- data/lib/dor/datastreams/identity_metadata_ds.rb +34 -30
- data/lib/dor/datastreams/role_metadata_ds.rb +6 -6
- data/lib/dor/datastreams/simple_dublin_core_ds.rb +12 -9
- data/lib/dor/datastreams/version_metadata_ds.rb +14 -33
- data/lib/dor/datastreams/workflow_definition_ds.rb +18 -18
- data/lib/dor/datastreams/workflow_ds.rb +74 -65
- data/lib/dor/migrations/identifiable/assert_adminPolicy.rb +1 -1
- data/lib/dor/migrations/identifiable/fix_model_assertions.rb +1 -1
- data/lib/dor/migrations/identifiable/record_remediation.rb +2 -2
- data/lib/dor/migrations/identifiable/uriify_augmented_contentlocation_refs.rb +1 -1
- data/lib/dor/migrations/identifiable/uriify_contentlocation_refs.rb +1 -1
- data/lib/dor/migrations/processable/unify_workflows.rb +4 -4
- data/lib/dor/migrations/versionable/add_missing_version_md.rb +1 -1
- data/lib/dor/models/admin_policy_object.rb +1 -1
- data/lib/dor/models/assembleable.rb +3 -4
- data/lib/dor/models/collection.rb +0 -2
- data/lib/dor/models/contentable.rb +34 -35
- data/lib/dor/models/describable.rb +80 -122
- data/lib/dor/models/editable.rb +57 -73
- data/lib/dor/models/embargoable.rb +13 -15
- data/lib/dor/models/eventable.rb +3 -3
- data/lib/dor/models/geoable.rb +8 -9
- data/lib/dor/models/governable.rb +36 -54
- data/lib/dor/models/identifiable.rb +119 -115
- data/lib/dor/models/item.rb +4 -4
- data/lib/dor/models/itemizable.rb +9 -9
- data/lib/dor/models/presentable.rb +133 -0
- data/lib/dor/models/preservable.rb +4 -4
- data/lib/dor/models/processable.rb +29 -28
- data/lib/dor/models/publishable.rb +36 -30
- data/lib/dor/models/releasable.rb +310 -0
- data/lib/dor/models/shelvable.rb +14 -14
- data/lib/dor/models/upgradable.rb +13 -13
- data/lib/dor/models/versionable.rb +4 -7
- data/lib/dor/models/workflow_object.rb +16 -36
- data/lib/dor/services/cleanup_reset_service.rb +28 -34
- data/lib/dor/services/cleanup_service.rb +4 -4
- data/lib/dor/services/digital_stacks_service.rb +10 -10
- data/lib/dor/services/merge_service.rb +1 -1
- data/lib/dor/services/metadata_handlers/mdtoolkit_handler.rb +2 -2
- data/lib/dor/services/metadata_service.rb +20 -20
- data/lib/dor/services/registration_service.rb +26 -27
- data/lib/dor/services/reset_workspace_service.rb +15 -15
- data/lib/dor/services/sdr_ingest_service.rb +4 -4
- data/lib/dor/services/search_service.rb +4 -9
- data/lib/dor/services/suri_service.rb +5 -5
- data/lib/dor/services/technical_metadata_service.rb +3 -2
- data/lib/dor/utils/ng_tidy.rb +9 -9
- data/lib/dor/utils/predicate_patch.rb +1 -1
- data/lib/dor/utils/solr_doc_helper.rb +13 -5
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +28 -30
- data/lib/dor/workflow/graph.rb +36 -36
- data/lib/dor/workflow/process.rb +12 -12
- data/lib/tasks/dor.rake +1 -1
- data/lib/tasks/rdoc.rake +3 -3
- metadata +67 -76
- data/lib/dor/datastreams/geo2mods.xsl +0 -867
- data/lib/dor/models/discoverable.rb +0 -64
- data/lib/dor/models/releaseable.rb +0 -357
- data/lib/dor/services/indexing_service.rb +0 -64
- data/lib/dor/utils/sdr_client.rb +0 -23
- data/lib/dor/utils/utc_date_field_mapper.rb +0 -7
@@ -4,7 +4,7 @@ Dor::Identifiable.on_upgrade '3.6.1', 'Assert correct models' do |obj|
|
|
4
4
|
obj.remove_relationship :has_model, 'info:fedora/hydra:commonMetadata'
|
5
5
|
applied = true
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
unless obj.relationships.predicates.any? { |p| p.to_s == 'info:fedora/fedora-system:def/model#hasModel' }
|
9
9
|
obj.assert_content_model
|
10
10
|
applied = true
|
@@ -5,11 +5,11 @@ Dor::Processable.on_upgrade '3.5.0', 'Replace individual *WF datastreams with un
|
|
5
5
|
obj.workflows.content
|
6
6
|
run = true
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
# Remove individual *WF datastreams
|
10
|
-
obj.datastreams.each_pair do |dsid,ds|
|
11
|
-
if ds.controlGroup == 'E'
|
12
|
-
ds.delete
|
10
|
+
obj.datastreams.each_pair do |dsid,ds|
|
11
|
+
if ds.controlGroup == 'E' and dsid =~ /WF$/
|
12
|
+
ds.delete
|
13
13
|
run = true
|
14
14
|
end
|
15
15
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Dor
|
2
2
|
module Assembleable
|
3
|
-
|
4
|
-
def initialize_workspace(source
|
3
|
+
|
4
|
+
def initialize_workspace(source=nil)
|
5
|
+
druid = DruidTools::Druid.new(self.pid, Config.stacks.local_workspace_root)
|
5
6
|
if(source.nil?)
|
6
|
-
druid = DruidTools::Druid.new(pid,Config.stacks.local_workspace_root)
|
7
7
|
druid.mkdir
|
8
8
|
else
|
9
|
-
druid = DruidTools::Druid.new(pid, Config.stacks.local_workspace_root)
|
10
9
|
druid.mkdir_with_final_link(source)
|
11
10
|
end
|
12
11
|
end
|
@@ -6,8 +6,6 @@ module Dor
|
|
6
6
|
include Describable
|
7
7
|
include Publishable
|
8
8
|
include Versionable
|
9
|
-
include Discoverable
|
10
|
-
include Releaseable
|
11
9
|
|
12
10
|
has_many :members, :property => :is_member_of_collection, :inbound => true, :class_name => "ActiveFedora::Base"
|
13
11
|
has_object_type 'collection'
|
@@ -3,17 +3,17 @@ module Dor
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
#add a file to a resource, not to be confused with add a resource to an object
|
6
|
-
def add_file file, resource, file_name, mime_type
|
7
|
-
contentMD=datastreams['contentMetadata']
|
6
|
+
def add_file file, resource, file_name, mime_type=nil,publish='no', shelve='no', preserve='no'
|
7
|
+
contentMD=self.datastreams['contentMetadata']
|
8
8
|
xml=contentMD.ng_xml
|
9
9
|
#make sure the resource exists
|
10
10
|
if xml.search('//resource[@id=\''+resource+'\']').length == 0
|
11
11
|
raise 'resource doesnt exist.'
|
12
12
|
end
|
13
13
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
14
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
14
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
15
15
|
location=druid_tools.path(file_name)
|
16
|
-
oldlocation=location.gsub('/'+pid.gsub('druid:',''),'')
|
16
|
+
oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
|
17
17
|
md5=Digest::MD5.file(file.path).hexdigest
|
18
18
|
sha1=Digest::SHA1.file(file.path).hexdigest
|
19
19
|
size=File.size?(file.path)
|
@@ -26,7 +26,7 @@ module Dor
|
|
26
26
|
raise 'The file '+file_name+' already exists!'
|
27
27
|
rescue Net::SFTP::StatusException
|
28
28
|
sftp.upload!(file.path,location)
|
29
|
-
contentMetadata.add_file file_hash,resource
|
29
|
+
self.contentMetadata.add_file file_hash,resource
|
30
30
|
end
|
31
31
|
rescue Net::SFTP::StatusException
|
32
32
|
#the directory layout doesnt match the new style, so use the old style.
|
@@ -36,7 +36,7 @@ module Dor
|
|
36
36
|
rescue Net::SFTP::StatusException
|
37
37
|
#the file doesnt already exist, which is good. Add it
|
38
38
|
sftp.upload!(file.path,oldlocation)
|
39
|
-
contentMetadata.add_file file_hash,resource
|
39
|
+
self.contentMetadata.add_file file_hash,resource
|
40
40
|
end
|
41
41
|
end
|
42
42
|
#can only arrive at this point if a non status exception occurred.
|
@@ -44,10 +44,10 @@ module Dor
|
|
44
44
|
|
45
45
|
def replace_file file,file_name
|
46
46
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
47
|
-
item=Dor::Item.find(pid)
|
48
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
47
|
+
item=Dor::Item.find(self.pid)
|
48
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
49
49
|
location=druid_tools.path(file_name)
|
50
|
-
oldlocation=location.gsub('/'+pid.gsub('druid:',''),'')
|
50
|
+
oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
|
51
51
|
|
52
52
|
md5=Digest::MD5.file(file.path).hexdigest
|
53
53
|
sha1=Digest::SHA1.file(file.path).hexdigest
|
@@ -66,7 +66,7 @@ module Dor
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def get_preserved_file file, version
|
69
|
-
preservation_server=Config.content.sdr_server+'/sdr/objects/'+pid+"/content/"
|
69
|
+
preservation_server=Config.content.sdr_server+'/sdr/objects/'+self.pid+"/content/"
|
70
70
|
file=URI.encode(file)
|
71
71
|
add=preservation_server+file+"?version="+version
|
72
72
|
uri = URI(add)
|
@@ -78,9 +78,9 @@ module Dor
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def get_file file
|
81
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
81
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
82
82
|
location=druid_tools.path(file)
|
83
|
-
oldlocation=location.gsub('/'+file,'').gsub('/'+pid.gsub('druid:',''),'')+'/'+file
|
83
|
+
oldlocation=location.gsub('/'+file,'').gsub('/'+self.pid.gsub('druid:',''),'')+'/'+file
|
84
84
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
85
85
|
begin
|
86
86
|
data=sftp.download!(location)
|
@@ -89,9 +89,9 @@ module Dor
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
def remove_file filename
|
92
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
92
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
93
93
|
location=druid_tools.path(filename)
|
94
|
-
oldlocation=location.gsub('/'+pid.gsub('druid:',''),'')
|
94
|
+
oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
|
95
95
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
96
96
|
begin
|
97
97
|
data=sftp.remove!(location)
|
@@ -102,37 +102,38 @@ module Dor
|
|
102
102
|
rescue Net::SFTP::StatusException
|
103
103
|
end
|
104
104
|
end
|
105
|
-
contentMetadata.remove_file filename
|
105
|
+
self.contentMetadata.remove_file filename
|
106
106
|
end
|
107
107
|
def rename_file old_name, new_name
|
108
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
108
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
109
109
|
location=druid_tools.path(old_name)
|
110
|
-
oldlocation=location.gsub('/'+pid.gsub('druid:',''),'')
|
110
|
+
oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
|
111
111
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
112
112
|
begin
|
113
113
|
data=sftp.rename!(location,location.gsub(old_name,new_name))
|
114
114
|
rescue
|
115
115
|
data=sftp.rename!(oldlocation,oldlocation.gsub(old_name,new_name))
|
116
116
|
end
|
117
|
-
contentMetadata.rename_file(old_name, new_name)
|
117
|
+
self.contentMetadata.rename_file(old_name, new_name)
|
118
118
|
end
|
119
119
|
def remove_resource resource_name
|
120
120
|
#run delete for all of the files in the resource
|
121
|
-
xml=contentMetadata.ng_xml
|
121
|
+
xml=self.contentMetadata.ng_xml
|
122
122
|
files=xml.search('//resource[@id=\''+resource_name+'\']/file').each do |file|
|
123
|
-
remove_file(file['id'])
|
123
|
+
self.remove_file(file['id'])
|
124
124
|
end
|
125
125
|
#remove the resource record from the metadata and renumber the resource sequence
|
126
|
-
contentMetadata.remove_resource resource_name
|
126
|
+
self.contentMetadata.remove_resource resource_name
|
127
127
|
end
|
128
|
+
|
128
129
|
#list files in the workspace
|
129
130
|
def list_files
|
130
131
|
filename='none'
|
131
132
|
files=[]
|
132
133
|
sftp=Net::SFTP.start(Config.content.content_server,Config.content.content_user,:auth_methods=>['publickey'])
|
133
|
-
druid_tools=DruidTools::Druid.new(pid,Config.content.content_base_dir)
|
134
|
+
druid_tools=DruidTools::Druid.new(self.pid,Config.content.content_base_dir)
|
134
135
|
location=druid_tools.path(filename).gsub(filename,'')
|
135
|
-
oldlocation=location.gsub('/'+pid.gsub('druid:',''),'')
|
136
|
+
oldlocation=location.gsub('/'+self.pid.gsub('druid:',''),'')
|
136
137
|
begin
|
137
138
|
sftp.dir.entries(location, "*") do |file|
|
138
139
|
files<<file.name
|
@@ -146,7 +147,13 @@ module Dor
|
|
146
147
|
return files
|
147
148
|
end
|
148
149
|
end
|
149
|
-
files
|
150
|
+
return files
|
151
|
+
end
|
152
|
+
|
153
|
+
# determine whether the file in question is present in the object's workspace.
|
154
|
+
def is_file_in_workspace? filename
|
155
|
+
druid_obj = DruidTools::Druid.new(self.pid, Dor::Config.stacks.local_workspace_root)
|
156
|
+
return druid_obj.find_content(filename) != nil
|
150
157
|
end
|
151
158
|
|
152
159
|
# Appends contentMetadata file resources from the source objects to this object
|
@@ -172,7 +179,7 @@ module Dor
|
|
172
179
|
secondary_file['id'] = new_secondary_file_name(secondary_file['id'], max_sequence)
|
173
180
|
|
174
181
|
if primary_cm.at_xpath("//file[@id = '#{secondary_file["id"]}']")
|
175
|
-
raise Dor::Exception.new "File '#{secondary_file['id']}' from secondary object #{src_pid} already exist in primary object: #{pid}"
|
182
|
+
raise Dor::Exception.new "File '#{secondary_file['id']}' from secondary object #{src_pid} already exist in primary object: #{self.pid}"
|
176
183
|
end
|
177
184
|
end
|
178
185
|
|
@@ -194,7 +201,7 @@ module Dor
|
|
194
201
|
resource_copy.first_element_child.add_previous_sibling attr_node
|
195
202
|
end
|
196
203
|
end
|
197
|
-
contentMetadata.content_will_change!
|
204
|
+
self.contentMetadata.content_will_change!
|
198
205
|
end
|
199
206
|
|
200
207
|
def new_secondary_file_name old_name, sequence_num
|
@@ -222,13 +229,5 @@ module Dor
|
|
222
229
|
rightsMetadata.content = '<rightsMetadata/>'
|
223
230
|
add_tag "Decommissioned : #{tag}"
|
224
231
|
end
|
225
|
-
|
226
|
-
# Adds a RELS-EXT constituent relationship to the given druid
|
227
|
-
# @param [String] druid the parent druid of the constituent relationship
|
228
|
-
# e.g.,
|
229
|
-
# <fedora:isConstituentOf rdf:resource="info:fedora/druid:hj097bm8879" />
|
230
|
-
def add_constituent(druid)
|
231
|
-
add_relationship :is_constituent_of, ActiveFedora::Base.find(druid)
|
232
|
-
end
|
233
232
|
end
|
234
|
-
end
|
233
|
+
end
|
@@ -3,20 +3,19 @@ module Dor
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
DESC_MD_FORMATS = {
|
6
|
-
|
7
|
-
|
6
|
+
"http://www.tei-c.org/ns/1.0" => 'tei',
|
7
|
+
"http://www.loc.gov/mods/v3" => 'mods'
|
8
8
|
}
|
9
9
|
class CrosswalkError < Exception; end
|
10
10
|
|
11
11
|
included do
|
12
|
-
has_metadata :name =>
|
12
|
+
has_metadata :name => "descMetadata", :type => Dor::DescMetadataDS, :label => 'Descriptive Metadata', :control_group => 'M'
|
13
13
|
end
|
14
14
|
|
15
15
|
def fetch_descMetadata_datastream
|
16
|
-
candidates = datastreams['identityMetadata'].otherId.collect { |oid| oid.to_s }
|
16
|
+
candidates = self.datastreams['identityMetadata'].otherId.collect { |oid| oid.to_s }
|
17
17
|
metadata_id = Dor::MetadataService.resolvable(candidates).first
|
18
|
-
return nil
|
19
|
-
Dor::MetadataService.fetch(metadata_id.to_s)
|
18
|
+
return metadata_id.nil? ? nil : Dor::MetadataService.fetch(metadata_id.to_s)
|
20
19
|
end
|
21
20
|
|
22
21
|
def build_descMetadata_datastream(ds)
|
@@ -30,31 +29,29 @@ module Dor
|
|
30
29
|
end
|
31
30
|
|
32
31
|
# Generates Dublin Core from the MODS in the descMetadata datastream using the LoC mods2dc stylesheet
|
33
|
-
#
|
32
|
+
# Should not be used for the Fedora DC datastream
|
34
33
|
# @raise [Exception] Raises an Exception if the generated DC is empty or has no children
|
35
34
|
def generate_dublin_core
|
36
|
-
format = metadata_format
|
35
|
+
format = self.metadata_format
|
37
36
|
if format.nil?
|
38
37
|
raise CrosswalkError, "Unknown descMetadata namespace: #{metadata_namespace.inspect}"
|
39
38
|
end
|
40
39
|
xslt = Nokogiri::XSLT(File.new(File.expand_path(File.dirname(__FILE__) + "/#{format}2dc.xslt")) )
|
41
|
-
desc_md = descMetadata.ng_xml.dup(1)
|
42
|
-
add_collection_reference(desc_md)
|
40
|
+
desc_md = self.descMetadata.ng_xml.dup(1)
|
41
|
+
self.add_collection_reference(desc_md)
|
43
42
|
dc_doc = xslt.transform(desc_md)
|
44
43
|
# Remove empty nodes
|
45
44
|
dc_doc.xpath('/oai_dc:dc/*[count(text()) = 0]').remove
|
46
|
-
if
|
45
|
+
if(dc_doc.root.nil? || dc_doc.root.children.size == 0)
|
47
46
|
raise CrosswalkError, "Dor::Item#generate_dublin_core produced incorrect xml:\n#{dc_doc.to_xml}"
|
48
47
|
end
|
49
48
|
dc_doc
|
50
49
|
end
|
51
50
|
|
52
51
|
def generate_public_desc_md
|
53
|
-
doc = descMetadata.ng_xml.dup(1)
|
52
|
+
doc = self.descMetadata.ng_xml.dup(1)
|
54
53
|
add_collection_reference(doc)
|
55
54
|
add_access_conditions(doc)
|
56
|
-
add_constituent_relations(doc)
|
57
|
-
doc.xpath('//comment()').remove
|
58
55
|
new_doc = Nokogiri::XML(doc.to_xml) { |x| x.noblanks }
|
59
56
|
new_doc.encoding = 'UTF-8'
|
60
57
|
new_doc.to_xml
|
@@ -66,33 +63,31 @@ module Dor
|
|
66
63
|
def add_access_conditions(doc)
|
67
64
|
# clear out any existing accessConditions
|
68
65
|
doc.xpath('//mods:accessCondition', 'mods' => 'http://www.loc.gov/mods/v3').each {|n| n.remove}
|
69
|
-
rights = datastreams['rightsMetadata'].ng_xml
|
66
|
+
rights = self.datastreams['rightsMetadata'].ng_xml
|
70
67
|
|
71
68
|
rights.xpath('//use/human[@type="useAndReproduction"]').each do |use|
|
72
69
|
txt = use.text.strip
|
73
70
|
next if txt.empty?
|
74
|
-
|
75
|
-
doc.root.element_children.last.add_next_sibling new_use
|
71
|
+
doc.root.element_children.last.add_next_sibling doc.create_element("accessCondition", txt, :type => 'useAndReproduction')
|
76
72
|
end
|
77
73
|
rights.xpath('//copyright/human[@type="copyright"]').each do |cr|
|
78
74
|
txt = cr.text.strip
|
79
75
|
next if txt.empty?
|
80
|
-
|
81
|
-
doc.root.element_children.last.add_next_sibling new_use
|
76
|
+
doc.root.element_children.last.add_next_sibling doc.create_element("accessCondition", txt, :type => 'copyright')
|
82
77
|
end
|
83
78
|
rights.xpath("//use/machine[#{ci_compare('type', 'creativecommons')}]").each do |lic_type|
|
84
79
|
next if lic_type.text =~ /none/i
|
85
80
|
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'creativecommons')}]").text.strip
|
86
81
|
next if lic_text.empty?
|
87
|
-
|
88
|
-
doc.root.element_children.last.add_next_sibling
|
82
|
+
new_text = "CC #{lic_type.text}: #{lic_text}"
|
83
|
+
doc.root.element_children.last.add_next_sibling doc.create_element("accessCondition", new_text, :type => 'license')
|
89
84
|
end
|
90
85
|
rights.xpath("//use/machine[#{ci_compare('type', 'opendatacommons')}]").each do |lic_type|
|
91
86
|
next if lic_type.text =~ /none/i
|
92
87
|
lic_text = rights.at_xpath("//use/human[#{ci_compare('type', 'opendatacommons')}]").text.strip
|
93
88
|
next if lic_text.empty?
|
94
|
-
|
95
|
-
doc.root.element_children.last.add_next_sibling
|
89
|
+
new_text = "ODC #{lic_type.text}: #{lic_text}"
|
90
|
+
doc.root.element_children.last.add_next_sibling doc.create_element("accessCondition", new_text, :type => 'license')
|
96
91
|
end
|
97
92
|
end
|
98
93
|
|
@@ -100,8 +95,8 @@ module Dor
|
|
100
95
|
# @param [Nokogiri::XML::Document] doc A copy of the descriptiveMetadata of the object
|
101
96
|
# @note this method modifies the passed in doc
|
102
97
|
def add_collection_reference(doc)
|
103
|
-
return unless methods.include? :public_relationships
|
104
|
-
collections
|
98
|
+
return unless self.methods.include? :public_relationships
|
99
|
+
collections=self.public_relationships.search('//rdf:RDF/rdf:Description/fedora:isMemberOfCollection',
|
105
100
|
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
106
101
|
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' )
|
107
102
|
return if collections.empty?
|
@@ -112,153 +107,116 @@ module Dor
|
|
112
107
|
end
|
113
108
|
|
114
109
|
collections.each do |collection_node|
|
115
|
-
druid
|
116
|
-
druid
|
117
|
-
collection_obj
|
110
|
+
druid=collection_node['rdf:resource']
|
111
|
+
druid=druid.gsub('info:fedora/','')
|
112
|
+
collection_obj=Dor::Item.find(druid)
|
118
113
|
collection_title = Dor::Describable.get_collection_title(collection_obj)
|
119
|
-
related_item_node
|
120
|
-
related_item_node['type']
|
121
|
-
title_info_node
|
122
|
-
title_node
|
123
|
-
title_node.content
|
114
|
+
related_item_node=Nokogiri::XML::Node.new('relatedItem',doc)
|
115
|
+
related_item_node['type']='host'
|
116
|
+
title_info_node=Nokogiri::XML::Node.new('titleInfo',doc)
|
117
|
+
title_node=Nokogiri::XML::Node.new('title',doc)
|
118
|
+
title_node.content=collection_title
|
124
119
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
# </location>
|
129
|
-
loc_node = doc.create_element('location')
|
130
|
-
url_node = doc.create_element('url')
|
131
|
-
url_node.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
|
132
|
-
loc_node << url_node
|
120
|
+
id_node=Nokogiri::XML::Node.new('identifier',doc)
|
121
|
+
id_node['type'] = 'uri'
|
122
|
+
id_node.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
|
133
123
|
|
134
|
-
type_node
|
124
|
+
type_node=Nokogiri::XML::Node.new('typeOfResource',doc)
|
135
125
|
type_node['collection'] = 'yes'
|
136
126
|
doc.root.add_child(related_item_node)
|
137
127
|
related_item_node.add_child(title_info_node)
|
138
128
|
title_info_node.add_child(title_node)
|
139
|
-
related_item_node.add_child(
|
129
|
+
related_item_node.add_child(id_node)
|
140
130
|
related_item_node.add_child(type_node)
|
141
131
|
end
|
142
132
|
end
|
143
|
-
|
144
|
-
# expand constituent relations into relatedItem references -- see JUMBO-18
|
145
|
-
# @param [Nokogiri::XML] doc public MODS XML being built
|
146
|
-
def add_constituent_relations(doc)
|
147
|
-
self.public_relationships.search('//rdf:RDF/rdf:Description/fedora:isConstituentOf',
|
148
|
-
'fedora' => 'info:fedora/fedora-system:def/relations-external#',
|
149
|
-
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' ).each do |parent|
|
150
|
-
# fetch the parent object to get title
|
151
|
-
druid = parent['rdf:resource'].gsub(/^info:fedora\//, '')
|
152
|
-
parent_item = Dor::Item.find(druid)
|
153
|
-
|
154
|
-
# create the MODS relation
|
155
|
-
relatedItem = doc.create_element 'relatedItem'
|
156
|
-
relatedItem['type'] = 'host'
|
157
|
-
relatedItem['displayLabel'] = 'Appears in'
|
158
|
-
|
159
|
-
# load the title from the parent's DC.title
|
160
|
-
titleInfo = doc.create_element 'titleInfo'
|
161
|
-
title = doc.create_element 'title'
|
162
|
-
title.content = parent_item.datastreams['DC'].title.first
|
163
|
-
titleInfo << title
|
164
|
-
relatedItem << titleInfo
|
165
|
-
|
166
|
-
# point to the PURL for the parent
|
167
|
-
location = doc.create_element 'location'
|
168
|
-
url = doc.create_element 'url'
|
169
|
-
url.content = "http://#{Dor::Config.stacks.document_cache_host}/#{druid.split(':').last}"
|
170
|
-
location << url
|
171
|
-
relatedItem << location
|
172
|
-
|
173
|
-
# finish up by adding relation to public MODS
|
174
|
-
doc.root << relatedItem
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
133
|
def metadata_namespace
|
179
|
-
desc_md = datastreams['descMetadata'].ng_xml
|
180
|
-
|
181
|
-
|
134
|
+
desc_md = self.datastreams['descMetadata'].ng_xml
|
135
|
+
if desc_md.nil? || desc_md.root.nil? || desc_md.root.namespace.nil?
|
136
|
+
return nil
|
137
|
+
else
|
138
|
+
return desc_md.root.namespace.href
|
139
|
+
end
|
182
140
|
end
|
183
141
|
|
184
142
|
def metadata_format
|
185
143
|
DESC_MD_FORMATS[metadata_namespace]
|
186
144
|
end
|
187
145
|
|
188
|
-
def to_solr(solr_doc
|
146
|
+
def to_solr(solr_doc=Hash.new, *args)
|
189
147
|
super solr_doc, *args
|
190
|
-
add_solr_value(solr_doc,
|
148
|
+
add_solr_value(solr_doc, "metadata_format", self.metadata_format, :string, [:symbol, :searchable, :facetable])
|
191
149
|
begin
|
192
|
-
dc_doc = generate_dublin_core
|
150
|
+
dc_doc = self.generate_dublin_core
|
193
151
|
dc_doc.xpath('/oai_dc:dc/*').each do |node|
|
194
|
-
add_solr_value(solr_doc, "public_dc_#{node.name}", node.text, :string, [:
|
152
|
+
add_solr_value(solr_doc, "public_dc_#{node.name}", node.text, :string, [:stored_searchable])
|
195
153
|
end
|
196
|
-
creator
|
154
|
+
creator=''
|
197
155
|
dc_doc.xpath('//dc:creator').each do |node|
|
198
|
-
creator
|
156
|
+
creator=node.text
|
199
157
|
end
|
200
|
-
title
|
158
|
+
title=''
|
201
159
|
dc_doc.xpath('//dc:title').each do |node|
|
202
|
-
title
|
160
|
+
title=node.text
|
203
161
|
end
|
204
|
-
creator_title
|
205
|
-
add_solr_value(solr_doc, 'creator_title', creator_title, :string, [:sortable])
|
162
|
+
creator_title=creator+title
|
163
|
+
add_solr_value(solr_doc, 'creator_title', creator_title , :string, [:sortable])
|
206
164
|
rescue CrosswalkError => e
|
207
|
-
ActiveFedora.logger.warn "Cannot index #{pid}.descMetadata: #{e.message}"
|
165
|
+
ActiveFedora.logger.warn "Cannot index #{self.pid}.descMetadata: #{e.message}"
|
208
166
|
end
|
209
167
|
solr_doc
|
210
168
|
end
|
211
|
-
|
212
169
|
def update_title(new_title)
|
213
|
-
|
170
|
+
if not update_simple_field('mods:mods/mods:titleInfo/mods:title',new_title)
|
214
171
|
raise 'Descriptive metadata has no title to update!'
|
215
172
|
end
|
216
173
|
end
|
217
|
-
|
218
174
|
def add_identifier(type, value)
|
219
|
-
ds_xml
|
175
|
+
ds_xml=self.descMetadata.ng_xml
|
220
176
|
ds_xml.search('//mods:mods','mods' => 'http://www.loc.gov/mods/v3').each do |node|
|
221
|
-
new_node
|
222
|
-
new_node['type']
|
223
|
-
new_node.content
|
177
|
+
new_node=Nokogiri::XML::Node.new('identifier',ds_xml) #this ends up being mods:identifier without having to specify the namespace
|
178
|
+
new_node['type']=type
|
179
|
+
new_node.content=value
|
224
180
|
node.add_child(new_node)
|
225
181
|
end
|
226
182
|
end
|
227
|
-
|
228
|
-
|
229
|
-
|
183
|
+
def delete_identifier(type,value=nil)
|
184
|
+
ds_xml=self.descMetadata.ng_xml
|
185
|
+
ds_xml.search('//mods:identifier','mods' => 'http://www.loc.gov/mods/v3').each do |node|
|
230
186
|
if node.content == value || value.nil?
|
231
187
|
node.remove
|
232
188
|
return true
|
233
189
|
end
|
234
190
|
end
|
235
|
-
false
|
191
|
+
return false
|
236
192
|
end
|
237
193
|
|
238
|
-
def set_desc_metadata_using_label(force
|
239
|
-
ds
|
194
|
+
def set_desc_metadata_using_label(force=false)
|
195
|
+
ds=self.descMetadata
|
240
196
|
unless force || ds.new?
|
241
|
-
raise 'Cannot proceed, there is already content in the descriptive metadata datastream.'
|
197
|
+
raise 'Cannot proceed, there is already content in the descriptive metadata datastream.'+ds.content.to_s
|
242
198
|
end
|
243
|
-
label
|
199
|
+
label=self.label
|
244
200
|
builder = Nokogiri::XML::Builder.new { |xml|
|
245
|
-
xml.mods( 'xmlns' => 'http://www.loc.gov/mods/v3', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
201
|
+
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'){
|
246
202
|
xml.titleInfo{
|
247
203
|
xml.title label
|
248
204
|
}
|
249
205
|
}
|
250
206
|
}
|
251
|
-
descMetadata.content=builder.to_xml
|
207
|
+
self.descMetadata.content=builder.to_xml
|
252
208
|
end
|
253
209
|
|
254
210
|
def self.get_collection_title(obj)
|
255
|
-
xml
|
256
|
-
title
|
211
|
+
xml=obj.descMetadata.ng_xml
|
212
|
+
title=''
|
257
213
|
title_node = xml.at_xpath('//mods:mods/mods:titleInfo/mods:title','mods' => 'http://www.loc.gov/mods/v3')
|
258
|
-
if
|
214
|
+
if(title_node)
|
259
215
|
title = title_node.content
|
260
|
-
subtitle
|
261
|
-
|
216
|
+
subtitle=xml.at_xpath('//mods:mods/mods:titleInfo/mods:subTitle','mods' => 'http://www.loc.gov/mods/v3')
|
217
|
+
if(subtitle)
|
218
|
+
title += ' (' + subtitle.content + ')'
|
219
|
+
end
|
262
220
|
end
|
263
221
|
title
|
264
222
|
end
|
@@ -266,21 +224,21 @@ module Dor
|
|
266
224
|
private
|
267
225
|
#generic updater useful for updating things like title or subtitle which can only have a single occurance and must be present
|
268
226
|
def update_simple_field(field,new_val)
|
269
|
-
ds_xml
|
227
|
+
ds_xml=self.descMetadata.ng_xml
|
270
228
|
ds_xml.search('//'+field,'mods' => 'http://www.loc.gov/mods/v3').each do |node|
|
271
|
-
node.content
|
229
|
+
node.content=new_val
|
272
230
|
return true
|
273
231
|
end
|
274
|
-
false
|
232
|
+
return false
|
275
233
|
end
|
276
234
|
|
277
235
|
# Builds case-insensitive xpath translate function call that will match the attribute to a value
|
278
236
|
def ci_compare(attribute, value)
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
237
|
+
"translate(
|
238
|
+
@#{attribute},
|
239
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
240
|
+
'abcdefghijklmnopqrstuvwxyz'
|
241
|
+
) = '#{value}' "
|
284
242
|
end
|
285
243
|
|
286
244
|
end
|