Module: Dor::Identifiable

Extended by:
ActiveSupport::Concern
Includes:
Eventable, Upgradable, SolrDocHelper
Included in:
Abstract, AdminPolicyObject, BasicItem, Collection, Publishable, Set, WorkflowObject
Defined in:
lib/dor/models/identifiable.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

@@collection_hash =

Module-level variables, shared between ALL mixin includers!

{}
@@apo_hash =
{}
@@hydrus_apo_hash =
{}
@@hydrus_collection_hash =
{}

Instance Method Summary collapse

Methods included from Upgradable

add_upgrade_callback, included, run_upgrade_callbacks, #upgrade!

Methods included from Eventable

#add_event

Methods included from SolrDocHelper

#add_solr_value

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object

Syntactic sugar for identifying applied DOR Concerns e.g., obj.is_identifiable? is the same as obj.is_a?(Dor::Identifiable)



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dor/models/identifiable.rb', line 43

def method_missing sym, *args
  if sym.to_s =~ /^is_(.+)\?$/
    begin
      klass = Dor.const_get $1.capitalize.to_sym
      return self.is_a?(klass)
    rescue NameError
      return false
    end
  else
    super
  end
end

Instance Method Details

#add_other_Id(type, val) ⇒ Object



141
142
143
144
145
146
# File 'lib/dor/models/identifiable.rb', line 141

def add_other_Id(type,val)
  if self..otherId(type).length>0
    raise 'There is an existing entry for '+type+', consider using update_other_Id().'
  end
  self..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

param tag [string] The tag you wish to add



224
225
226
227
228
# File 'lib/dor/models/identifiable.rb', line 224

def add_tag(tag)
     = self.
    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



36
37
38
39
# File 'lib/dor/models/identifiable.rb', line 36

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

#identity_metadata_sourceString

Returns calculated value for Solr index.

Returns:

  • (String)

    calculated value for Solr index



126
127
128
129
130
131
132
133
134
135
# File 'lib/dor/models/identifiable.rb', line 126

def 
  if self..otherId('catkey').first ||
     self..otherId('barcode').first
    'Symphony'
  elsif self..otherId('mdtoolkit').first
    'Metadata Toolkit'
  else
    'DOR'
  end
end

#initialize(attrs = {}) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/dor/models/identifiable.rb', line 21

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

#normalize_tag(tag_str) ⇒ Object

take a tag string and return a normalized tag string



182
183
184
# File 'lib/dor/models/identifiable.rb', line 182

def normalize_tag(tag_str)
  return 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



177
178
179
# File 'lib/dor/models/identifiable.rb', line 177

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

#remove_other_Id(type, val = nil) ⇒ Object



159
160
161
162
163
164
165
166
167
168
# File 'lib/dor/models/identifiable.rb', line 159

def remove_other_Id(type, val=nil)
  removed=false
  self..ng_xml.search('//otherId[@name=\''+type+'\']').each do |node|
    if node.content===val || val.nil?
      node.remove
      removed=true
    end
  end
  return removed
end

#remove_tag(tag) ⇒ Object



230
231
232
233
234
235
236
237
238
239
# File 'lib/dor/models/identifiable.rb', line 230

def remove_tag(tag)
  removed = false
  self..ng_xml.search('//tag').each do |node|
    if normalize_tag(node.content) === normalize_tag(tag)
      node.remove
      removed = true
    end
  end
  return removed
end

#set_source_id(source_id) ⇒ Object



137
138
139
# File 'lib/dor/models/identifiable.rb', line 137

def set_source_id(source_id)
  self..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.



172
173
174
# File 'lib/dor/models/identifiable.rb', line 172

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

#tagsObject

helper method to get the tags as an array



31
32
33
# File 'lib/dor/models/identifiable.rb', line 31

def tags
  self..tag
end

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



62
63
64
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
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
117
118
119
120
121
122
123
# File 'lib/dor/models/identifiable.rb', line 62

def to_solr(solr_doc=Hash.new, *args)
  self.assert_content_model
  super(solr_doc, *args)
  solr_doc[Dor::INDEX_VERSION_FIELD] = Dor::VERSION
  solr_doc['indexed_at_dtsi' ] = Time.now.utc.xmlschema
  solr_doc['indexed_day_dtsi'] = Time.now.beginning_of_day.utc.xmlschema  # technically unnecessary, but convenient
  datastreams.values.each do |ds|
    add_solr_value(solr_doc,'ds_specs',ds.datastream_spec_string,:string,[:displayable]) unless ds.new?
  end
  add_solr_value(solr_doc, 'title_sort', self.label, :string, [:sortable])
  title_attrs = [:searchable, :facetable, :displayable]
  rels_doc = Nokogiri::XML(self.datastreams['RELS-EXT'].content)
  apos=rels_doc.search('//rdf:RDF/rdf:Description/hydra:isGovernedBy','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.each do |apo_node|
    druid = apo_node['rdf:resource']
    next unless druid   # TODO: a warning about the bad APO would be nice
    druid=druid.gsub('info:fedora/','')
    # check cache first
    if @@apo_hash.has_key?(druid) || @@hydrus_apo_hash.has_key?(druid)
      add_solr_value(solr_doc, "hydrus_apo_title", @@hydrus_apo_hash[druid], :string, title_attrs) if @@hydrus_apo_hash.has_key? druid
      add_solr_value(solr_doc, "apo_title", @@apo_hash[druid] , :string, title_attrs) if @@apo_hash.has_key? druid
    else
      begin
        apo_object=Dor.find(druid)
        if apo_object.tags.include? 'Project : Hydrus'
          add_solr_value(solr_doc, "hydrus_apo_title", apo_object.label, :string, title_attrs)
          @@hydrus_apo_hash[druid]=apo_object.label
        else
          add_solr_value(solr_doc, "apo_title", apo_object.label, :string, title_attrs)
          @@apo_hash[druid]=apo_object.label
        end
      rescue
        add_solr_value(solr_doc, "apo_title", druid, :string, title_attrs)
      end
    end
  end
  collections=rels_doc.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#' )
  collections.each do |collection_node|
    druid=collection_node['rdf:resource']
    next unless druid     ## TODO: warning here would also be useful
    druid=druid.gsub('info:fedora/','')
    if @@collection_hash.has_key?(druid) || @@hydrus_collection_hash.has_key?(druid)
      add_solr_value(solr_doc, "hydrus_collection_title", @@hydrus_collection_hash[druid], :string, title_attrs) if @@hydrus_collection_hash.has_key? druid
      add_solr_value(solr_doc, "collection_title", @@collection_hash[druid], :string, title_attrs) if @@collection_hash.has_key? druid
    else
      begin
        collection_object=Dor.find(druid)
        if collection_object.tags.include? 'Project : Hydrus'
          add_solr_value(solr_doc, "hydrus_collection_title", collection_object.label, :string, title_attrs)
          @@hydrus_collection_hash[druid]=collection_object.label
        else
          add_solr_value(solr_doc, "collection_title", collection_object.label, :string, title_attrs)
          @@collection_hash[druid]=collection_object.label
        end
      rescue
        add_solr_value(solr_doc, "collection_title", druid, :string, title_attrs)
      end
    end
  end
  solr_doc["metadata_source_ssi"] = self.
  solr_doc
end

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



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

def update_other_Id(type, new_val, val=nil)
  updated=false
  self..ng_xml.search('//otherId[@name=\''+type+'\']').each do |node|
    if node.content==val || val.nil?
      node.content=new_val
      updated=true
    end
  end
  return updated
end

#update_tag(old_tag, new_tag) ⇒ Object



241
242
243
244
245
246
247
248
249
250
# File 'lib/dor/models/identifiable.rb', line 241

def update_tag(old_tag, new_tag)
  updated = false
  self..ng_xml.search('//tag').each do |node|
    if normalize_tag(node.content) == normalize_tag(old_tag)
      node.content = normalize_tag(new_tag)
      updated = true
    end
  end
  return updated
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.



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

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).downcase == normalized_tag.downcase }
  if dupe_existing_tag
    raise "An existing tag (#{dupe_existing_tag}) is the same, consider using update_tag?"
  end

  return normalized_tag
end

#validate_tag_format(tag_str) ⇒ Array

Ensure that an administrative tag meets the proper mininum format

Returns:

  • (Array)

    the tag split into an array via ‘:’



208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/dor/models/identifiable.rb', line 208

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
  return tag_arr
end