Class: Dor::IdentityMetadataDS

Inherits:
ActiveFedora::OmDatastream
  • Object
show all
Includes:
SolrDocHelper
Defined in:
lib/dor/datastreams/identity_metadata_ds.rb

Overview

Object identity and source metadata

Constant Summary collapse

CATKEY_TYPE_ID =

ids for previous and current catkeys

'catkey'
PREVIOUS_CATKEY_TYPE_ID =
'previous_catkey'

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SolrDocHelper

#add_solr_value

Class Method Details

.xml_templateObject



33
34
35
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 33

def self.xml_template
  Nokogiri::XML('<identityMetadata/>')
end

Instance Method Details

#add_other_Id(type, val) ⇒ Object



100
101
102
103
104
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 100

def add_other_Id(type, val)
  raise 'There is an existing entry for ' + type + ', consider using update_other_Id().' if otherId(type).length > 0

  add_otherId(type + ':' + val)
end

#add_otherId(other_id) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 91

def add_otherId(other_id)
  ng_xml_will_change!
  (name, val) = other_id.split(/:/, 2)
  node = ng_xml.root.add_child('<otherId/>').first
  node['name'] = name
  node.content = val
  node
end

#add_value(name, value, attrs = {}) ⇒ Object



37
38
39
40
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 37

def add_value(name, value, attrs = {})
  ng_xml_will_change!
  add_child_node(ng_xml.root, :value, name, value, attrs)
end

#catkeyString

Convenience method to get the current catkey

Returns:

  • (String)

    current catkey value (or nil if none found)



124
125
126
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 124

def catkey
  otherId(CATKEY_TYPE_ID).first
end

#catkey=(val) ⇒ String

Convenience method to set the catkey

Parameters:

  • val (String)

    the new source identifier

Returns:

  • (String)

    same value, as per Ruby assignment convention



131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 131

def catkey=(val)
  # if there was already a catkey in the record, store that in the "previous" spot (assuming there is no change)
  add_otherId("#{PREVIOUS_CATKEY_TYPE_ID}:#{catkey}") if val != catkey && !catkey.blank?

  if val.blank? # if we are setting the catkey to blank, remove the node from XML
    remove_other_Id(CATKEY_TYPE_ID)
  elsif catkey.blank? # if there is no current catkey, then add it
    add_other_Id(CATKEY_TYPE_ID, val)
  else # if there is a current catkey, update the current catkey to the new value
    update_other_Id(CATKEY_TYPE_ID, val)
  end

  val
end

#content_type_tagObject

helper method to get just the content type tag



77
78
79
80
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 77

def content_type_tag
   = tags.select { |tag| tag.include?('Process : Content Type') }
  .size == 1 ? [0].split(':').last.strip : ''
end

#objectIdObject



42
43
44
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 42

def objectId
  find_by_terms(:objectId).text
end

#otherId(type = nil) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 82

def otherId(type = nil)
  result = find_by_terms(:otherId).to_a
  if type.nil?
    result.collect { |n| [n['name'], n.text].join(':') }
  else
    result.select { |n| n['name'] == type }.collect(&:text)
  end
end

#prefixObject

maintain AF < 8 indexing behavior



203
204
205
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 203

def prefix
  ''
end

#previous_catkeysArray

Convenience method to get the previous catkeys (will be an array)

Returns:

  • (Array)

    previous catkey values (empty array if none found)



148
149
150
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 148

def previous_catkeys
  otherId(PREVIOUS_CATKEY_TYPE_ID)
end

#remove_other_Id(type, val = nil) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 114

def remove_other_Id(type, val = nil)
  ng_xml.search('//otherId[@name=\'' + type + '\']')
        .select { |node| val.nil? || node.content == val }
        .each { ng_xml_will_change! }
        .each(&:remove)
        .any?
end

#sourceIdObject Also known as: source_id



46
47
48
49
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 46

def sourceId
  node = find_by_terms(:sourceId).first
  node ? [node['source'], node.text].join(':') : nil
end

#sourceId=(value) ⇒ String, Nil Also known as: source_id=

Note:

The actual values assigned will have leading/trailing whitespace stripped.

Returns The same value, as per Ruby convention for assignment operators.

Parameters:

  • value (String, Nil)

    The value to set or a nil/empty string to delete sourceId node

Returns:

  • (String, Nil)

    The same value, as per Ruby convention for assignment operators

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 55

def sourceId=(value)
  ng_xml_will_change!
  node = find_by_terms(:sourceId).first
  unless value.present? # so setting it to '' is the same as removal: worth documenting maybe?
    node&.remove
    return nil
  end
  parts = value.split(':', 2).map(&:strip)
  raise ArgumentError, "Source ID must follow the format 'namespace:value', not '#{value}'" unless
    parts.length == 2 && parts[0].present? && parts[1].present?

  node ||= ng_xml.root.add_child('<sourceId/>').first
  node['source'] = parts[0]
  node.content = parts[1]
end

#tagsObject



72
73
74
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 72

def tags
  ng_xml.search('//tag').collect(&:content)
end

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



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 152

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

  if digital_object.respond_to?(:profile)
    digital_object.profile.each_pair do |property, value|
      add_solr_value(solr_doc, property.underscore, value, (property =~ /Date/ ? :date : :symbol), [:stored_searchable])
    end
  end

  if sourceId.present?
    (name, id) = sourceId.split(/:/, 2)
    add_solr_value(solr_doc, 'dor_id', id, :symbol, [:stored_searchable])
    add_solr_value(solr_doc, 'identifier', sourceId, :symbol, [:stored_searchable])
    add_solr_value(solr_doc, 'source_id', sourceId, :symbol, [])
  end
  otherId.compact.each do |qid|
    # this section will solrize barcode and catkey, which live in otherId
    (name, id) = qid.split(/:/, 2)
    add_solr_value(solr_doc, 'dor_id', id, :symbol, [:stored_searchable])
    add_solr_value(solr_doc, 'identifier', qid, :symbol, [:stored_searchable])
    add_solr_value(solr_doc, "#{name}_id", id, :symbol, [])
  end

  # do some stuff to make tags in general and project tags specifically more easily searchable and facetable
  find_by_terms(:tag).each do |tag|
    (prefix, rest) = tag.text.split(/:/, 2)
    prefix = prefix.downcase.strip.gsub(/\s/, '_')
    unless rest.nil?
      # this part will index a value in a field specific to the tag, e.g. registered_by_tag_*,
      # book_tag_*, project_tag_*, remediated_by_tag_*, etc.  project_tag_* and registered_by_tag_*
      # definitley get used, but most don't.  we can limit the prefixes that get solrized if things
      # get out of hand.
      add_solr_value(solr_doc, "#{prefix}_tag", rest.strip, :symbol, [])
    end

    # solrize each possible prefix for the tag, inclusive of the full tag.
    # e.g., for a tag such as "A : B : C", this will solrize to an _ssim field
    # that contains ["A",  "A : B",  "A : B : C"].
    tag_parts = tag.text.split(/:/)
    progressive_tag_prefix = ''
    tag_parts.each_with_index do |part, index|
      progressive_tag_prefix += ' : ' if index > 0
      progressive_tag_prefix += part.strip
      add_solr_value(solr_doc, 'exploded_tag', progressive_tag_prefix, :symbol, [])
    end
  end

  solr_doc
end

#update_other_Id(type, new_val, val = nil) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 106

def update_other_Id(type, new_val, val = nil)
  ng_xml.search('//otherId[@name=\'' + type + '\']')
        .select { |node| val.nil? || node.content == val }
        .each { ng_xml_will_change! }
        .each { |node| node.content = new_val }
        .any?
end