Module: Dor::Identifiable

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

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

@@collection_hash =

Module-level variables, shared between ALL mixin includers (and ALL their includers/extenders)! used for caching found values

{}
@@apo_hash =
{}

Instance Method Summary collapse

Methods included from SolrDocHelper

#add_solr_value

Instance Method Details

#adapt_to_cmodelObject

Override ActiveFedora::Core#adapt_to_cmodel (used with associations, among other places) to preferentially use the objectType asserted in the identityMetadata.



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/dor/models/concerns/identifiable.rb', line 212

def adapt_to_cmodel
  object_type = .objectType.first
  object_class = Dor.registered_classes[object_type]

  if object_class
    self.instance_of?(object_class) ? self : self.adapt_to(object_class)
  else
    if ActiveFedora::VERSION < '8'
      result = super
      if result.class == Dor::Abstract
        self.adapt_to(Dor::Item)
      else
        result
      end
    else
      begin
        super
      rescue ActiveFedora::ModelNotAsserted
        self.adapt_to(Dor::Item)
      end
    end
  end
end

#add_other_Id(type, val) ⇒ Object



90
91
92
93
94
95
# File 'lib/dor/models/concerns/identifiable.rb', line 90

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

#add_tag(tag) ⇒ Object

Add an administrative tag to an item, you will need to seperately save the item to write it to fedora

Parameters:

  • tag (string)

    The tag you wish to add



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

def add_tag(tag)
   = 
  normalized_tag = validate_and_normalize_tag(tag, .tags)
  .add_value(:tag, normalized_tag)
end

#content_type_tagObject

helper method to get just the content type tag



32
33
34
35
# File 'lib/dor/models/concerns/identifiable.rb', line 32

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

#druid_regexRegex

a regex that can be used to identify a full druid with prefix (e.g. druid:oo000oo0001)

Returns:

  • (Regex)

    a regular expression to identify a full druid



199
200
201
# File 'lib/dor/models/concerns/identifiable.rb', line 199

def druid_regex
  /druid:#{pid_regex}/
end


185
186
187
188
189
# File 'lib/dor/models/concerns/identifiable.rb', line 185

def get_related_obj_display_title(related_obj, default_title)
  return default_title unless related_obj

  related_obj.full_title || default_title
end

#identity_metadata_sourceString

Returns calculated value for Solr index.

Returns:

  • (String)

    calculated value for Solr index



66
67
68
69
70
71
72
73
# File 'lib/dor/models/concerns/identifiable.rb', line 66

def 
  if .otherId('catkey').first ||
     .otherId('barcode').first
    'Symphony'
  else
    'DOR'
  end
end

#initialize(attrs = {}) ⇒ Object



19
20
21
22
23
24
# File 'lib/dor/models/concerns/identifiable.rb', line 19

def initialize(attrs = {})
  if Dor::Config.suri.mint_ids && !attrs[:pid]
    attrs = attrs.merge!({:pid => Dor::SuriService.mint_id, :new_object => true})
  end
  super
end

#normalize_tag(tag_str) ⇒ Object

take a tag string and return a normalized tag string



125
126
127
# File 'lib/dor/models/concerns/identifiable.rb', line 125

def normalize_tag(tag_str)
  normalize_tag_arr(split_tag_to_arr(tag_str))
end

#normalize_tag_arr(tag_arr) ⇒ Object

turn a tag array back into a tag string with a standard format



120
121
122
# File 'lib/dor/models/concerns/identifiable.rb', line 120

def normalize_tag_arr(tag_arr)
  tag_arr.join(' : ')
end

#pid_regexRegex

a regex that can be used to identify the last part of a druid (e.g. oo000oo0001)

Returns:

  • (Regex)

    a regular expression to identify the ID part of the druid



193
194
195
# File 'lib/dor/models/concerns/identifiable.rb', line 193

def pid_regex
  /[a-zA-Z]{2}[0-9]{3}[a-zA-Z]{2}[0-9]{4}/
end

#remove_druid_prefix(druid = id) ⇒ String

Since purl does not use the druid: prefix but much of dor does, use this function to strip the druid: if needed

Returns:

  • (String)

    the druid sans the druid: or if there was no druid: prefix, the entire string you passed



205
206
207
208
# File 'lib/dor/models/concerns/identifiable.rb', line 205

def remove_druid_prefix(druid=id)
  result=druid.match(/#{pid_regex}/)
  result.nil? ? druid : result[0]  # if no matches, return the string passed in, otherwise return the match 
end

#remove_other_Id(type, val = nil) ⇒ Object



105
106
107
108
109
110
111
# File 'lib/dor/models/concerns/identifiable.rb', line 105

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

#remove_tag(tag) ⇒ Object



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

def remove_tag(tag)
  normtag = normalize_tag(tag)
  .ng_xml.search('//tag')
    .select { |node| normalize_tag(node.content) == normtag }
    .each { .ng_xml_will_change! }
    .each(&:remove)
    .any?
end

#source_idObject

Convenience method



76
77
78
# File 'lib/dor/models/concerns/identifiable.rb', line 76

def source_id
  .sourceId
end

#source_id=(source_id) ⇒ String Also known as: set_source_id

Convenience method

Parameters:

  • source_id (String)

    the new source identifier

Returns:

  • (String)

    same value, as per Ruby assignment convention

Raises:

  • (ArgumentError)

    see IdentityMetadataDS for logic



84
85
86
# File 'lib/dor/models/concerns/identifiable.rb', line 84

def source_id=(source_id)
  .sourceId = source_id
end

#split_tag_to_arr(tag_str) ⇒ Object

turns a tag string into an array with one element per tag part. split on “:”, disregard leading and trailing whitespace on tokens.



115
116
117
# File 'lib/dor/models/concerns/identifiable.rb', line 115

def split_tag_to_arr(tag_str)
  tag_str.split(':').map {|str| str.strip}
end

#tagsObject

helper method to get the tags as an array



27
28
29
# File 'lib/dor/models/concerns/identifiable.rb', line 27

def tags
  .tag
end

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



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dor/models/concerns/identifiable.rb', line 42

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

  solr_doc[Dor::INDEX_VERSION_FIELD] = Dor::VERSION
  solr_doc['indexed_at_dtsi'] = Time.now.utc.xmlschema
  datastreams.values.each do |ds|
    add_solr_value(solr_doc, 'ds_specs', ds.datastream_spec_string, :string, [:symbol]) unless ds.new?
  end

  add_solr_value(solr_doc, 'title_sort', label, :string, [:stored_sortable])

  rels_doc = Nokogiri::XML(datastreams['RELS-EXT'].content)
  ns_hash = {'hydra' => 'http://projecthydra.org/ns/relations#', 'fedora' => 'info:fedora/fedora-system:def/relations-external#', 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'}
  apos = rels_doc.search('//rdf:RDF/rdf:Description/hydra:isGovernedBy', ns_hash)
  collections = rels_doc.search('//rdf:RDF/rdf:Description/fedora:isMemberOfCollection', ns_hash)
  solrize_related_obj_titles(solr_doc, apos, @@apo_hash, 'apo_title', 'nonhydrus_apo_title', 'hydrus_apo_title')
  solrize_related_obj_titles(solr_doc, collections, @@collection_hash, 'collection_title', 'nonhydrus_collection_title', 'hydrus_collection_title')
  solr_doc['public_dc_relation_tesim'] ||= solr_doc['collection_title_tesim'] if solr_doc['collection_title_tesim']
  solr_doc['metadata_source_ssi'] = 
  solr_doc
end

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



97
98
99
100
101
102
103
# File 'lib/dor/models/concerns/identifiable.rb', line 97

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

#update_tag(old_tag, new_tag) ⇒ Object



176
177
178
179
180
181
182
183
# File 'lib/dor/models/concerns/identifiable.rb', line 176

def update_tag(old_tag, new_tag)
  normtag = normalize_tag(old_tag)
  .ng_xml.search('//tag')
    .select { |node| normalize_tag(node.content) == normtag }
    .each { .ng_xml_will_change! }
    .each  { |node| node.content = normalize_tag(new_tag)  }
    .any?
end

#validate_and_normalize_tag(tag_str, existing_tag_list) ⇒ Object

take a proposed tag string and a list of the existing tags for the object being edited. if the proposed tag is valid, return it in normalized form. if not, raise an exception with an explanatory message.



132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/dor/models/concerns/identifiable.rb', line 132

def validate_and_normalize_tag(tag_str, existing_tag_list)
  tag_arr = validate_tag_format(tag_str)

  # note that the comparison for duplicate tags is case-insensitive, but we don't change case as part of the normalized version
  # we return, because we want to preserve the user's intended case.
  normalized_tag = normalize_tag_arr(tag_arr)
  dupe_existing_tag = existing_tag_list.detect { |existing_tag| normalize_tag(existing_tag).casecmp(normalized_tag) == 0 }
  if dupe_existing_tag
    raise "An existing tag (#{dupe_existing_tag}) is the same, consider using update_tag?"
  end
  normalized_tag
end

#validate_tag_format(tag_str) ⇒ Array

Ensure that an administrative tag meets the proper mininum format

Parameters:

  • tag_str (String)

    the tag

Returns:

  • (Array)

    the tag split into an array via ‘:’



148
149
150
151
152
153
154
155
156
157
# File 'lib/dor/models/concerns/identifiable.rb', line 148

def validate_tag_format(tag_str)
  tag_arr = split_tag_to_arr(tag_str)
  if tag_arr.length < 2
    raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' must have at least 2 elements"
  end
  if tag_arr.detect {|str| str.empty?}
    raise ArgumentError, "Invalid tag structure: tag '#{tag_str}' contains empty elements"
  end
  tag_arr
end