Module: Dor::Releaseable

Extended by:
ActiveSupport::Concern
Includes:
Itemizable
Included in:
BasicItem
Defined in:
lib/dor/models/releaseable.rb

Constant Summary

Constants included from Itemizable

Itemizable::DIFF_FILENAME, Itemizable::DIFF_QUERY

Instance Method Summary collapse

Methods included from Itemizable

#clear_diff_cache, #get_content_diff

Instance Method Details

#clean_release_tag_for_purl(tag) ⇒ Hash

Take a tag and return only the attributes we want to put into purl

Parameters:

  • tag (Hash)

    a tag

Returns:

  • (Hash)

    a hash of the attributes we want for purl



129
130
131
132
133
134
135
136
# File 'lib/dor/models/releaseable.rb', line 129

def clean_release_tag_for_purl(tag)
  for_purl = ['release']
  return_hash = {}
  for_purl.each do |attr|
    return_hash[attr] = tag[attr]
  end
  return return_hash
end

#combine_two_release_tag_hashes(hash_one, hash_two) ⇒ Hash

Take two hashes of tags and combine them, will not overwrite but will enforce uniqueness of the tags

Parameters:

  • hash_one (Hash)

    a hash of tags obtained via Dor::Item.release_tags or matching format

  • hash_two (Hash)

    a hash of tags obtained via Dor::Item.release_tags or matching format

Returns:

  • (Hash)

    the combined hash with uniquiness enforced



87
88
89
90
91
92
93
# File 'lib/dor/models/releaseable.rb', line 87

def combine_two_release_tag_hashes(hash_one, hash_two)
  hash_two.keys.each do |key|
    hash_one[key] = hash_two[key] if hash_one[key] == nil
    hash_one[key] = (hash_one[key] + hash_two[key]).uniq if hash_one[key] != nil
  end
  return hash_one
end

#does_release_tag_apply(release_tag, admin_tags = false) ⇒ Boolean

Takes a tag and returns true or false if it applies to the specific item

Parameters:

  • release_tag (Hash)

    the tag in a hashed form

  • Optional

    admin_tags [Array] the administrative tags on an item, if not supplied it will attempt to retrieve them

Returns:

  • (Boolean)

    true or false if it applies (not true or false if it is released, that is the release_tag data)



158
159
160
161
162
163
164
# File 'lib/dor/models/releaseable.rb', line 158

def does_release_tag_apply(release_tag, admin_tags=false)
  #Is the tag global or restricted 
  return true if release_tag['tag'] == nil  #there is no specific tag specificied, so that means this tag is global to all members of the collection, it applies, return true
    
  admin_tags = self.tags if not admin_tags #We use false instead of [], since an item can have no admin_tags that which point we'd be passing down this variable as [] and would not an attempt to retrieve it
  return admin_tags.include?(release_tag['tag'])
end

#generate_release_xmlString

Generate XML structure for inclusion to Purl

Returns:

  • (String)

    The XML release node as a string, with ReleaseDigest as the root document



10
11
12
13
14
15
16
17
18
19
# File 'lib/dor/models/releaseable.rb', line 10

def generate_release_xml
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.ReleaseDigest {
      self.released_for.each do |project,released_value|
        xml.release(released_value["release"],:to=>project)
      end  
      }        
    end
  return builder.to_xml
end

#get_newest_release_tag(tags) ⇒ Hash

Take a hash of tags as obtained via Dor::Item.release_tags and returns the newest tag for each namespace

Returns:

  • (Hash)

    a hash of latest tags for each to value



115
116
117
118
119
120
121
122
# File 'lib/dor/models/releaseable.rb', line 115

def get_newest_release_tag(tags)
  return_hash = {}
  tags.keys.each do |key|
    latest_for_key = newest_release_tag_in_an_array(tags[key])
    return_hash[key] = latest_for_key         
  end
  return return_hash
end

#get_release_tags_for_item_and_all_governing_setsHash

Take an item and get all of its release tags and all tags on collections it is a member of it

Returns:

  • (Hash)

    a hash of all tags



73
74
75
76
77
78
79
# File 'lib/dor/models/releaseable.rb', line 73

def get_release_tags_for_item_and_all_governing_sets
  return_tags = self.release_tags || {}
  self.collections.each do |collection|
    return_tags = combine_two_release_tag_hashes(return_tags, Dor::Item.find(collection.id).get_release_tags_for_item_and_all_governing_sets) #this will function recurvisely so parents of parents are found
  end
  return return_tags  
end

#get_self_release_tags(tags) ⇒ Hash

Take a hash of tags as obtained via Dor::Item.release_tags and returns all self tags

Parameters:

  • tags (Hash)

    a hash of tags obtained via Dor::Item.release_tags or matching format

Returns:

  • (Hash)

    a hash of self tags for each to value



65
66
67
# File 'lib/dor/models/releaseable.rb', line 65

def get_self_release_tags(tags)
  return get_tags_for_what_value(tags, 'self')
end

#get_tags_for_what_value(tags, what_target) ⇒ Hash

Take a hash of tags and return all tags with the matching what target

Parameters:

  • tags (Hash)

    a hash of tags obtained via Dor::Item.release_tags or matching format

  • what_target (String)

    the target for the ‘what’ key, self or collection

Returns:

  • (Hash)

    a hash of self tags for each to value



101
102
103
104
105
106
107
108
# File 'lib/dor/models/releaseable.rb', line 101

def get_tags_for_what_value(tags, what_target)
  return_hash = {}
  tags.keys.each do |key|
    self_tags =  tags[key].select{|tag| tag['what'] == what_target.downcase}
    return_hash[key] = self_tags if self_tags.size > 0
  end
  return return_hash
end

#latest_applicable_release_tag_in_array(release_tags, admin_tags) ⇒ Hash

Takes an array of release tags and returns the most recent one that applies to this item

param admin_tags [Array] the administrative tags on an on item

Parameters:

  • release_tags (Array)

    an array of release tags in hashed form

Returns:

  • (Hash)

    the tag



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/dor/models/releaseable.rb', line 172

def latest_applicable_release_tag_in_array(release_tags, admin_tags)
  newest_tag = newest_release_tag_in_an_array(release_tags)
  return newest_tag if does_release_tag_apply(newest_tag, admin_tags) #Return true if we have it
  
  #The latest tag wasn't applicable, slice it off and try again
  #This could be optimized by reordering on the timestamp and just running down it instead of constantly resorting, at least if we end up getting numerous release tags on an item
  release_tags.slice!(release_tags.index(newest_tag))
  
  return latest_applicable_release_tag_in_array(release_tags, admin_tags) if release_tags.size > 0 #Try again after dropping the one that wasn't applicable 
  
  return nil #We're out of tags, no applicable ones
end

#newest_release_tag_in_an_array(array_of_tags) ⇒ Hash

Takes an array of release tags and returns the most recent one

Returns:

  • (Hash)

    the most recent tag



143
144
145
146
147
148
149
# File 'lib/dor/models/releaseable.rb', line 143

def newest_release_tag_in_an_array(array_of_tags)
  latest_tag_in_array = array_of_tags[0] || {}
  array_of_tags.each do |tag|
    latest_tag_in_array = tag if tag['when'] > latest_tag_in_array['when']
  end
  return latest_tag_in_array
end

#released_forHash

Determine which projects an item is released for

Returns:

  • (Hash)

    all namespaces in the form of => Boolean



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dor/models/releaseable.rb', line 24

def released_for
  released_hash = {}
  
  #Get release tags on the item itself 
  release_tags_on_this_item = self.release_tags
  
  #Get any self tags on this item
  self_release_tags = self.get_self_release_tags(release_tags_on_this_item)
  
  #Get the most recent self tag for all targets and save their result since most recent self always trumps any other non self tags
  latest_self_tags = self.get_newest_release_tag(self_release_tags)
  latest_self_tags.keys.each do |target|
    released_hash[target] =  self.clean_release_tag_for_purl(latest_self_tags[target])
  end
  
  #With Self Tags Resolved We Now need to deal with tags on all sets this object is part of 
  
  potential_applicable_release_tags = {}  #This will be where we store all tags that apply, regardless of their timestamp
   
  #Get all release tags on the item and strip out the what = self ones, we've already processed all the self tags on this item 
  potential_applicable_release_tags = get_tags_for_what_value(self.get_release_tags_for_item_and_all_governing_sets, 'collection')
  
  administrative_tags = self.tags  #Get them once here and pass them down
  
  #We now have the keys for all potential releases, we need to check the tags and the most recent time stamp with an explicit true or false wins, in a nil case, the lack of an explicit false tag we do nothing
  (potential_applicable_release_tags.keys-released_hash.keys).each do |key|  #don't bother checking the ones already added to the release hash, they were added due to a self tag and that has won
    latest_applicable_tag_for_key = latest_applicable_release_tag_in_array(potential_applicable_release_tags[key], administrative_tags)
    if latest_applicable_tag_for_key != nil #We have a valid tag, record it
      released_hash[key] = self.clean_release_tag_for_purl(latest_applicable_tag_for_key) 
    end
    
  end
    
  return released_hash
end