Module: Dor::Describable

Extended by:
ActiveSupport::Concern
Included in:
AdminPolicyObject, BasicItem, Collection, Publishable, Set
Defined in:
lib/dor/models/describable.rb

Defined Under Namespace

Classes: CrosswalkError

Constant Summary collapse

DESC_MD_FORMATS =
{
  "http://www.tei-c.org/ns/1.0" => 'tei',
  "http://www.loc.gov/mods/v3" =>   'mods'
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_collection_title(obj) ⇒ Object



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/dor/models/describable.rb', line 203

def self.get_collection_title(obj)
 xml=obj..ng_xml
 preferred_citation=xml.search('//mods:mods/mods:note[@type=\'preferredCitation\']','mods' => 'http://www.loc.gov/mods/v3')
 title=''
 if preferred_citation.length == 1
   title=preferred_citation.first.content
  else
    title=xml.search('//mods:mods/mods:titleInfo/mods:title','mods' => 'http://www.loc.gov/mods/v3').first.content
    subtitle=xml.search('//mods:mods/mods:titleInfo/mods:subTitle','mods' => 'http://www.loc.gov/mods/v3')
    if(subtitle.length==1)
      title+=' ('+subtitle.first.content+')'
     end
   end
   title
end

Instance Method Details

#add_access_conditions(doc) ⇒ Object

Note:

this method modifies the passed in doc

Create MODS accessCondition statements from rightsMetadata

Parameters:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dor/models/describable.rb', line 65

def add_access_conditions(doc)
   # clear out any existing accessConditions
   doc.xpath('//mods:accessCondition').each {|n| n.remove}
   rights = self.datastreams['rightsMetadata'].ng_xml

   rights.xpath('//use/human[@type="useAndReproduction"]').each do |use|
     new_use =  doc.create_element("accessCondition", use.text.strip, :type => 'useAndReproduction')
     doc.root.element_children.last.add_next_sibling new_use
   end
   rights.xpath('//copyright/human[@type="copyright"]').each do |cr|
     new_use =  doc.create_element("accessCondition", cr.text.strip, :type => 'copyright')
     doc.root.element_children.last.add_next_sibling new_use
   end
   rights.xpath("//use/machine[#{ci_compare('type', 'creativecommons')}]").each do |lic|
     next if(lic.text =~ /none/i)
     new_text = "CC #{lic.text} : " << rights.at_xpath("//use/human[#{ci_compare('type', 'creativecommons')}]").text.strip
     new_lic =  doc.create_element("accessCondition", new_text, :type => 'license')
     doc.root.element_children.last.add_next_sibling new_lic
   end
   rights.xpath("//use/machine[#{ci_compare('type', 'opendata')}]").each do |lic|
     next if(lic.text =~ /none/i)
     new_text = "ODC #{lic.text} : " << rights.at_xpath("//use/human[#{ci_compare('type', 'opendata')}]").text.strip
     new_lic =  doc.create_element("accessCondition", new_text, :type => 'license')
     doc.root.element_children.last.add_next_sibling new_lic
   end
end

#add_collection_reference(doc) ⇒ Object

Note:

this method modifies the passed in doc

returns the desc metadata a relatedItem with information about the collection this object belongs to for use in published mods and mods to DC conversion

Parameters:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/dor/models/describable.rb', line 95

def add_collection_reference(doc)
 if not self.methods.include? :public_relationships
    return
  end
 relationships=self.public_relationships

 collections=relationships.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#'   )
 #if there is an existing relatedItem node with type=host and a child typeOfResource @collection=yes dont add anything
 existing_node=doc.search('//mods:relatedItem/mods:typeOfResource[@collection=\'yes\']', 'mods' => 'http://www.loc.gov/mods/v3')
  if(existing_node.length > 0)
    return
  end
  collections.each do |collection_node|
    druid=collection_node['rdf:resource']
    druid=druid.gsub('info:fedora/','')
    collection_obj=Dor::Item.find(druid)
    collection_title = Dor::Describable.get_collection_title(collection_obj)
    related_item_node=Nokogiri::XML::Node.new('relatedItem',doc)
    related_item_node['type']='host'
    title_info_node=Nokogiri::XML::Node.new('titleInfo',doc)
    title_node=Nokogiri::XML::Node.new('title',doc)
    title_node.content=collection_title
    type_node=Nokogiri::XML::Node.new('typeOfResource',doc)
    type_node['collection'] = 'yes'
    doc.root.add_child(related_item_node)
    related_item_node.add_child(title_info_node)
    title_info_node.add_child(title_node)
    related_item_node.add_child(type_node)
  end
end

#add_identifier(type, value) ⇒ Object



166
167
168
169
170
171
172
173
174
# File 'lib/dor/models/describable.rb', line 166

def add_identifier(type, value)
  ds_xml=self..ng_xml
  ds_xml.search('//mods:mods','mods' => 'http://www.loc.gov/mods/v3').each do |node|
  new_node=Nokogiri::XML::Node.new('identifier',ds_xml) #this ends up being mods:identifier without having to specify the namespace
  new_node['type']=type
  new_node.content=value
  node.add_child(new_node)
  end
end

#build_descMetadata_datastream(ds) ⇒ Object



25
26
27
28
29
30
31
32
33
# File 'lib/dor/models/describable.rb', line 25

def (ds)
  content = 
  unless content.nil?
    ds.dsLabel = 'Descriptive Metadata'
    ds.ng_xml = Nokogiri::XML(content)
    ds.ng_xml.normalize_text!
    ds.content = ds.ng_xml.to_xml
  end
end

#delete_identifier(type, value = nil) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/dor/models/describable.rb', line 175

def delete_identifier(type,value=nil)

  ds_xml=self..ng_xml
  ds_xml.search('//mods:identifier','mods' => 'http://www.loc.gov/mods/v3').each do |node|
    if node.content == value or value==nil
      node.remove
      return true
    end
  end
  return false
end

#fetch_descMetadata_datastreamObject



15
16
17
18
19
20
21
22
23
# File 'lib/dor/models/describable.rb', line 15

def 
  candidates = self.datastreams['identityMetadata'].otherId.collect { |oid| oid.to_s }
   = Dor::MetadataService.resolvable(candidates).first
  unless .nil?
    return Dor::MetadataService.fetch(.to_s)
  else
    return nil
  end
end

#generate_dublin_coreObject

Generates Dublin Core from the MODS in the descMetadata datastream using the LoC mods2dc stylesheet Should not be used for the Fedora DC datastream

Raises:

  • (Exception)

    Raises an Exception if the generated DC is empty or has no children



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/dor/models/describable.rb', line 38

def generate_dublin_core
  format = self.
  if format.nil?
    raise CrosswalkError, "Unknown descMetadata namespace: #{metadata_namespace.inspect}"
  end
  xslt = Nokogiri::XSLT(File.new(File.expand_path(File.dirname(__FILE__) + "/#{format}2dc.xslt")) )
  desc_md = self..ng_xml.dup(1)
  self.add_collection_reference(desc_md)
  dc_doc = xslt.transform(desc_md)
  # Remove empty nodes
  dc_doc.xpath('/oai_dc:dc/*[count(text()) = 0]').remove
  if(dc_doc.root.nil? || dc_doc.root.children.size == 0)
    raise CrosswalkError, "Dor::Item#generate_dublin_core produced incorrect xml:\n#{dc_doc.to_xml}"
  end
  dc_doc
end

#generate_public_desc_mdObject



55
56
57
58
59
60
# File 'lib/dor/models/describable.rb', line 55

def generate_public_desc_md
   doc = self..ng_xml.dup(1)
   add_collection_reference(doc)
   add_access_conditions(doc)
   Nokogiri::XML(doc.to_xml) { |x| x.noblanks }.to_xml { |config| config.no_declaration }
end

#metadata_formatObject



134
135
136
# File 'lib/dor/models/describable.rb', line 134

def 
  DESC_MD_FORMATS[]
end

#metadata_namespaceObject



125
126
127
128
129
130
131
132
# File 'lib/dor/models/describable.rb', line 125

def 
  desc_md = self.datastreams['descMetadata'].ng_xml
  if desc_md.nil? or desc_md.root.nil? or desc_md.root.namespace.nil?
    return nil
  else
    return desc_md.root.namespace.href
  end
end

#set_desc_metadata_using_label(force = false) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/dor/models/describable.rb', line 187

def (force=false)
  ds=self.
  unless force or ds.new?#22 is the length of <?xml version="1.0"?>
    raise 'Cannot proceed, there is already content in the descriptive metadata datastream.'+ds.content.to_s
  end
  label=self.label
  builder = Nokogiri::XML::Builder.new { |xml|
  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'){
    xml.titleInfo{
      xml.title label
      }
    }
  }
  self..content=builder.to_xml
end

#to_solr(solr_doc = Hash.new, *args) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/dor/models/describable.rb', line 138

def to_solr(solr_doc=Hash.new, *args)
  super solr_doc, *args
  add_solr_value(solr_doc, "metadata_format", self., :string, [:searchable, :facetable])
  begin
    dc_doc = self.generate_dublin_core
    dc_doc.xpath('/oai_dc:dc/*').each do |node|
      add_solr_value(solr_doc, "public_dc_#{node.name}", node.text, :string, [:searchable])
    end
    creator=''
    dc_doc.xpath('//dc:creator').each do |node|
      creator=node.text
    end
    title=''
    dc_doc.xpath('//dc:title').each do |node|
      title=node.text
    end
      creator_title=creator+title
      add_solr_value(solr_doc, 'creator_title', creator_title , :string, [:sortable])
  rescue CrosswalkError => e
    ActiveFedora.logger.warn "Cannot index #{self.pid}.descMetadata: #{e.message}"
  end
  solr_doc
end

#update_title(new_title) ⇒ Object



161
162
163
164
165
# File 'lib/dor/models/describable.rb', line 161

def update_title(new_title)
  if not update_simple_field('mods:mods/mods:titleInfo/mods:title',new_title)
    raise 'Descriptive metadata has no title to update!'
  end
end