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



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

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



96
97
98
99
100
101
102
103
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 96

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)



129
130
131
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 129

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



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 136

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

#other_ids=(values) ⇒ Object

Parameters:

  • values (Array<String>)


92
93
94
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 92

def other_ids=(values)
  values.each { |value| add_otherId(value) }
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



224
225
226
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 224

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)



153
154
155
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 153

def previous_catkeys
  otherId(PREVIOUS_CATKEY_TYPE_ID)
end

#release_tagsNokogiri::XML::NodeSet

Helper method to get the release tags as a nodeset

Returns:

  • (Nokogiri::XML::NodeSet)

    all release tags and their attributes



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 159

def release_tags
  release_tags = ng_xml.xpath('//release')
  return_hash = {}
  release_tags.each do |release_tag|
    hashed_node = release_tag_node_to_hash(release_tag)
    if !return_hash[hashed_node[:to]].nil?
      return_hash[hashed_node[:to]] << hashed_node[:attrs]
    else
      return_hash[hashed_node[:to]] = [hashed_node[:attrs]]
    end
  end
  return_hash
end

#remove_other_Id(type, val = nil) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 119

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
  tag
end

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



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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 173

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



111
112
113
114
115
116
117
# File 'lib/dor/datastreams/identity_metadata_ds.rb', line 111

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