Module: Dor::Processable

Extended by:
ActiveSupport::Concern
Includes:
Upgradable, SolrDocHelper
Included in:
AdminPolicyObject, BasicItem, Collection, Set, Versionable
Defined in:
lib/dor/models/processable.rb

Constant Summary collapse

STATUS_CODE_DISP_TXT =

verbiage we want to use to describe an item when it has completed a particular step

{
  0 => 'Unknown Status', #if there are no milestones for the current version, someone likely messed up the versioning process.
  1 => 'Registered',
  2 => 'In accessioning',
  3 => 'In accessioning (described)',
  4 => 'In accessioning (described, published)',
  5 => 'In accessioning (described, published, deposited)',
  6 => 'Accessioned',
  7 => 'Accessioned (indexed)',
  8 => 'Accessioned (indexed, ingested)',
  9 => 'Opened'
}
STEPS =

milestones from accessioning and the order they happen in

{
  'registered' => 1,
  'submitted' => 2,
  'described' => 3,
  'published' => 4,
  'deposited' => 5,
  'accessioned' => 6,
  'indexed' => 7,
  'shelved' => 8,
  'opened' => 1
}

Instance Method Summary collapse

Methods included from Upgradable

add_upgrade_callback, included, run_upgrade_callbacks, #upgrade!

Methods included from SolrDocHelper

#add_solr_value

Instance Method Details

#build_datastream(datastream, force = false, is_required = false) ⇒ Object

Takes the name of a datastream, as a string (fooMetadata). Builds that datastream using the content of a file if such a file exists and is newer than the object’s current datastream; otherwise, builds the datastream by calling build_fooMetadata_datastream.



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
# File 'lib/dor/models/processable.rb', line 73

def build_datastream(datastream, force = false, is_required = false)
  # See if the datastream exists as a file and if the file's
  # timestamp is newer than the datastream's timestamp.
  ds       = datastreams[datastream]
  filename = (datastream)
  use_file = filename && (ds.createDate.nil? || File.mtime(filename) >= ds.createDate)
  # Build datastream.
  if use_file
    content = File.read(filename)
    ds.content = content
    ds.ng_xml = Nokogiri::XML(content) if ds.respond_to?(:ng_xml)
    ds.save unless ds.digital_object.new?
  elsif force || empty_datastream?(ds)
    meth = "build_#{datastream}_datastream".to_sym
    if respond_to?(meth)
      content = self.send(meth, ds)
      ds.save unless ds.digital_object.new?
    end
  end
  # Check for success.
  if is_required && empty_datastream?(ds)
    raise "Required datastream #{datastream} could not be populated!"
  end
  return ds
end

#cleanupObject



99
100
101
# File 'lib/dor/models/processable.rb', line 99

def cleanup
  CleanupService.cleanup(self)
end

#empty_datastream?(datastream) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
59
# File 'lib/dor/models/processable.rb', line 51

def empty_datastream?(datastream)
  if datastream.new?
    true
  elsif datastream.class.respond_to?(:xml_template)
    datastream.content.to_s.empty? || EquivalentXml.equivalent?(datastream.content, datastream.class.xml_template)
  else
    datastream.content.to_s.empty?
  end
end

#find_metadata_file(datastream) ⇒ Object

Takes the name of a datastream, as a string. Tries to find a file for the datastream. Returns the path to it or nil.



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

def (datastream)
  druid = DruidTools::Druid.new(pid, Dor::Config.stacks.local_workspace_root)
  return druid.("#{datastream}.xml")
end

#initialize_workflow(name, create_ds = true, priority = 0) ⇒ Object

Initilizes workflow for the object in the workflow service

It will set the priorty of the new workflow to the current_priority if it is > 0
It will set lane_id from the item's APO default workflow lane

Parameters:

  • name (String)

    of the workflow to be initialized

  • create_ds (Boolean) (defaults to: true)

    create a ‘workflows’ datastream in Fedora for the object

  • priority (Integer) (defaults to: 0)

    the workflow’s priority level



215
216
217
218
219
220
# File 'lib/dor/models/processable.rb', line 215

def initialize_workflow(name, create_ds=true, priority=0)
  priority = workflows.current_priority if priority == 0
  opts = { :create_ds => create_ds, :lane_id => default_workflow_lane }
  opts[:priority] = priority if priority > 0
  Dor::WorkflowService.create_workflow(Dor::WorkflowObject.initial_repo(name), self.pid, name, Dor::WorkflowObject.initial_workflow(name), opts)
end

#milestonesObject



103
104
105
# File 'lib/dor/models/processable.rb', line 103

def milestones
  Dor::WorkflowService.get_milestones('dor',self.pid)
end

#set_workflows_datastream_locationObject

This is a work-around for some strange logic in ActiveFedora that don’t allow self.workflows.new? to work if we load the object using .load_instance_from_solr.



44
45
46
47
48
49
# File 'lib/dor/models/processable.rb', line 44

def set_workflows_datastream_location
  return if self.respond_to?(:inner_object) && self.inner_object.is_a?(ActiveFedora::SolrDigitalObject)
  return unless self.workflows.new?
  workflows.mimeType   = 'application/xml'
  workflows.dsLocation = File.join(Dor::Config.workflow.url,"dor/objects/#{self.pid}/workflows")
end

#simplified_status_code_disp_txt(status_code) ⇒ Object

return the text translation of the status code, minus any trailing parenthetical explanation e.g. ‘In accessioning (described)’ and ‘In accessioning (described, published)’ both come back as ‘In accessioning’



153
154
155
# File 'lib/dor/models/processable.rb', line 153

def simplified_status_code_disp_txt(status_code)
  return STATUS_CODE_DISP_TXT[status_code].gsub(/\(.*\)$/, '').strip
end

#status(include_time = false) ⇒ String

Returns single composed status from status_info.

Parameters:

  • include_time (Boolean) (defaults to: false)

Returns:

  • (String)

    single composed status from status_info



140
141
142
143
144
145
146
147
148
# File 'lib/dor/models/processable.rb', line 140

def status(include_time=false)
  status_info_hash = status_info()
  current_version, status_code, status_time = status_info_hash[:current_version], status_info_hash[:status_code], status_info_hash[:status_time]

  #use the translation table to get the appropriate verbage for the latest step
  result = "v#{current_version} #{STATUS_CODE_DISP_TXT[status_code]}"
  result += " #{format_date(status_time)}" if include_time
  return result
end

#status_infoHash

Returns including :current_version, :status_code and :status_time.

Returns:

  • (Hash)

    including :current_version, :status_code and :status_time



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/dor/models/processable.rb', line 108

def status_info
  current_version = '1'
  begin
    current_version = self..current_version_id
  rescue
  end

  current_milestones = []
  #only get steps that are part of accessioning and part of the current version. That can mean they were archived with the current version
  #number, or they might be active (no version number).
  milestones.each do |m|
    if STEPS.keys.include?(m[:milestone]) && (m[:version].nil? || m[:version] == current_version)
      current_milestones << m unless m[:milestone] == 'registered' && current_version.to_i > 1
    end
  end

  status_code = 0
  status_time = ''
  #for each milestone in the current version, see if it comes after the current 'last' step, if so, make it the last and record the date/time
  current_milestones.each do |m|
    name = m[:milestone]
    time = m[:at].utc.xmlschema
    next unless STEPS.keys.include?(name) && STEPS[name] > status_code
    status_code = STEPS[name]
    status_time = time
  end

  return {:current_version => current_version, :status_code => status_code, :status_time => status_time}
end

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



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
201
202
203
204
205
206
207
# File 'lib/dor/models/processable.rb', line 157

def to_solr(solr_doc=Hash.new, *args)
  super(solr_doc, *args)
  sortable_milestones = {}
  current_version='1'
  begin
    current_version = self..current_version_id
  rescue
  end
  current_version_num=current_version.to_i

  if self.respond_to?('versionMetadata')
    #add an entry with version id, tag and description for each version
    while current_version_num > 0
      add_solr_value(solr_doc, 'versions', current_version_num.to_s + ';' + self..tag_for_version(current_version_num.to_s) + ';' + self..description_for_version(current_version_num.to_s), :string, [:displayable])
      current_version_num -= 1
    end
  end

  self.milestones.each do |milestone|
    timestamp = milestone[:at].utc.xmlschema
    sortable_milestones[milestone[:milestone]] ||= []
    sortable_milestones[milestone[:milestone]] << timestamp
    milestone[:version] ||= current_version
    solr_doc['lifecycle_ssim'] ||= []
    solr_doc['lifecycle_ssim'] << milestone[:milestone]
    add_solr_value(solr_doc, 'lifecycle', "#{milestone[:milestone]}:#{timestamp};#{milestone[:version]}", :symbol)
  end

  sortable_milestones.each do |milestone, unordered_dates|
    dates = unordered_dates.sort
    #create the published_dttsi and published_day fields and the like
    dates.each do |date|
      solr_doc["#{milestone}_dttsim"] ||= []
      solr_doc["#{milestone}_dttsim"] << date unless solr_doc["#{milestone}_dttsim"].include?(date)
    end
    #fields for OAI havester to sort on: _dttsi is trie date +stored +indexed (single valued, i.e. sortable)
    solr_doc["#{milestone}_earliest_dttsi"] = dates.first
    solr_doc["#{milestone}_latest_dttsi"  ] = dates.last
  end
  solr_doc["status_ssi"] = status # status is singular (i.e. the current one)
  solr_doc["current_version_isi"] = current_version.to_i
  solr_doc["modified_latest_dttsi"] = self.modified_date.to_datetime.utc.strftime('%FT%TZ')
  add_solr_value(solr_doc, "rights", rights, :string, [:symbol]) if self.respond_to? :rights

  status_info_hash = status_info()
  status_code = status_info_hash[:status_code]
  add_solr_value(solr_doc, 'processing_status_text', simplified_status_code_disp_txt(status_code), :string, [:stored_sortable])
  solr_doc['processing_status_code_isi'] = status_code # no _isi in Solrizer's default descriptors

  return solr_doc
end