Module: Dor::Describable

Extended by:
ActiveSupport::Concern
Included in:
Abstract
Defined in:
lib/dor/models/concerns/describable.rb

Defined Under Namespace

Classes: CrosswalkError

Constant Summary collapse

MODS_TO_DC_XSLT =
Nokogiri::XSLT(File.new(File.expand_path(File.dirname(__FILE__) + "/mods2dc.xslt")))
XMLNS_OAI_DC =
'http://www.openarchives.org/OAI/2.0/oai_dc/'.freeze
XMLNS_DC =
'http://purl.org/dc/elements/1.1/'.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_collection_title(obj) ⇒ Object



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

def self.get_collection_title(obj)
  obj.full_title
end

Instance Method Details

#add_metadata_format_to_solr_doc(solr_doc) ⇒ Object



73
74
75
76
# File 'lib/dor/models/concerns/describable.rb', line 73

def (solr_doc)
  solr_doc['metadata_format_ssim'] ||= []
  solr_doc['metadata_format_ssim'] += ['mods']
end

#add_mods_to_solr_doc(solr_doc) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/dor/models/concerns/describable.rb', line 78

def add_mods_to_solr_doc(solr_doc)
  mods_sources = {
    sw_title_display: %w(sw_display_title_tesim),
    main_author_w_date: %w(sw_author_ssim sw_author_tesim),
    sw_sort_author: %w(sw_author_sort_ssi),
    sw_language_facet: %w(sw_language_ssim sw_language_tesim),
    sw_genre: %w(sw_genre_ssim sw_genre_tesim),
    format_main: %w(sw_format_ssim sw_format_tesim),
    topic_facet: %w(sw_topic_ssim sw_topic_tesim),
    era_facet: %w(sw_subject_temporal_ssim sw_subject_temporal_tesim),
    geographic_facet: %w(sw_subject_geographic_ssim sw_subject_geographic_tesim),
    [:term_values, :typeOfResource] => %w(mods_typeOfResource_ssim mods_typeOfResource_tesim),
    pub_year_sort_str: %w(sw_pub_date_sort_ssi),
    pub_year_int: %w(sw_pub_date_sort_isi),
    pub_year_display_str: %w(sw_pub_date_facet_ssi)
  }

  mods_sources.each_pair do |meth, solr_keys|
    vals = meth.is_a?(Array) ? stanford_mods.send(meth.shift, *meth) : stanford_mods.send(meth)

    next if vals.nil? || (vals.respond_to?(:empty?) && vals.empty?)

    solr_keys.each do |key|
      solr_doc[key] ||= []
      solr_doc[key].push *vals
    end
    # asterisk to avoid multi-dimensional array: push values, not the array
  end

  # convert multivalued fields to single value
  %w(sw_pub_date_sort_ssi sw_pub_date_sort_isi sw_pub_date_facet_ssi).each do |key|
    solr_doc[key] = solr_doc[key].first unless solr_doc[key].nil?
  end
  # some fields get explicit "(none)" placeholder values, mostly for faceting
  %w(sw_language_tesim sw_genre_tesim sw_format_tesim).each do |key|
    solr_doc[key] = ['(none)'] if solr_doc[key].nil? || solr_doc[key].empty?
  end
  solr_doc
end

#build_descMetadata_datastream(ds) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/dor/models/concerns/describable.rb', line 35

def (ds)
  content = 
  return nil if 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

#fetch_descMetadata_datastreamObject



29
30
31
32
33
# File 'lib/dor/models/concerns/describable.rb', line 29

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

#full_titleObject



139
140
141
# File 'lib/dor/models/concerns/describable.rb', line 139

def full_title
  stanford_mods.sw_title_display
end

#generate_dublin_core(include_collection_as_related_item: true) ⇒ Nokogiri::Doc

Generates Dublin Core from the MODS in the descMetadata datastream using the LoC mods2dc stylesheet

Should not be used for the Fedora DC datastream

Returns:

  • (Nokogiri::Doc)

    the DublinCore XML document object

Raises:

  • (CrosswalkError)

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



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dor/models/concerns/describable.rb', line 48

def generate_dublin_core(include_collection_as_related_item: true)
  desc_md = if include_collection_as_related_item
              Nokogiri::XML(generate_public_desc_md(include_access_conditions: false))
            else
              .ng_xml
            end

  dc_doc = MODS_TO_DC_XSLT.transform(desc_md)
  dc_doc.xpath('/oai_dc:dc/*[count(text()) = 0]', oai_dc: XMLNS_OAI_DC).remove # Remove empty nodes
  raise CrosswalkError, "Dor::Item#generate_dublin_core produced incorrect xml (no root):\n#{dc_doc.to_xml}" if dc_doc.root.nil?
  raise CrosswalkError, "Dor::Item#generate_dublin_core produced incorrect xml (no children):\n#{dc_doc.to_xml}" if dc_doc.root.children.size == 0
  dc_doc
end

#generate_public_desc_md(**options) ⇒ String

Returns Public descriptive medatada XML.

Returns:

  • (String)

    Public descriptive medatada XML



63
64
65
# File 'lib/dor/models/concerns/describable.rb', line 63

def generate_public_desc_md(**options)
  PublicDescMetadataService.new(self).to_xml(**options)
end

#set_desc_metadata_using_label(force = false) ⇒ String

Returns descMetadata.content XML.

Parameters:

  • force (Boolean) (defaults to: false)

    Overwrite existing XML

Returns:

  • (String)

    descMetadata.content XML



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/dor/models/concerns/describable.rb', line 120

def (force = false)
  unless force || .new?
    raise 'Cannot proceed, there is already content in the descriptive metadata datastream: ' + .content.to_s
  end
  label = self.label
  builder = Nokogiri::XML::Builder.new { |xml|
    xml.mods(Dor::DescMetadataDS::MODS_HEADER_CONFIG) {
      xml.titleInfo {
        xml.title label
      }
    }
  }
  .content = builder.to_xml
end

#stanford_mods(content = nil, ns_aware = true) ⇒ Object

intended for read-access, “as SearchWorks would see it”, mostly for to_solr()

Parameters:

  • content (Nokogiri::XML::Document) (defaults to: nil)

    Nokogiri descMetadata document (overriding internal data)

  • ns_aware (boolean) (defaults to: true)

    namespace awareness toggle for from_nk_node()



20
21
22
23
24
25
26
27
# File 'lib/dor/models/concerns/describable.rb', line 20

def stanford_mods(content = nil, ns_aware = true)
  @stanford_mods ||= begin
    m = Stanford::Mods::Record.new
    desc = content.nil? ? .ng_xml : content
    m.from_nk_node(desc.root, ns_aware)
    m
  end
end

#to_solr(solr_doc = {}, *args) ⇒ Object



67
68
69
70
71
# File 'lib/dor/models/concerns/describable.rb', line 67

def to_solr(solr_doc = {}, *args)
  solr_doc = super solr_doc, *args
  (solr_doc)
  add_mods_to_solr_doc(solr_doc)
end