Class: ROF::Filters::Label

Inherits:
Object
  • Object
show all
Defined in:
lib/rof/filters/label.rb

Overview

Class Label locates in-place labels of the form “$(label_name)” in the ROF file, assigns each label a pid, then replaces the label with that pid.

Defined Under Namespace

Classes: MissingLabel, NoPool, NoidsPool, OutOfIdentifiers

Instance Method Summary collapse

Constructor Details

#initialize(prefix, options) ⇒ Label

Create a new label assigner and resolver. The source of identifiers is given using options. Use :noid_server and :pool_name to connect to an external noid server. Use :id_list to pass in a ruby object responding to #shift and #empty? to generate ids. This is usually a list, to facilitate testing.

If prefix is not nil, then “#prefix:” is prepended to every identifier.



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rof/filters/label.rb', line 26

def initialize(prefix, options)
  @id_list =  case
              when options[:id_list]
                options[:id_list]
              when options[:noid_server]
                NoidsPool.new(options[:noid_server], options[:pool_name])
              else
                raise NoPool
              end
  @prefix = "#{prefix}:" if prefix
  # The first match group in the RE provides the label name
  @label_re = /\$\(([^)]+)\)/
end

Instance Method Details

#assign_pid(obj, labels) ⇒ Object

assign pids, recording any labels we find. obj is mutated



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rof/filters/label.rb', line 76

def assign_pid(obj, labels)
  return if obj['type'] != 'fobject'

  label = nil
  unless obj['pid'].nil?
    label = find_label(obj['pid'])
    # skip if the "pid" is not a label
    return if label.nil?
  end
  pid = "#{@prefix}#{next_id}"
  obj['pid'] = pid
  labels[label] = pid unless label.nil?
end

#find_label(s) ⇒ Object



128
129
130
# File 'lib/rof/filters/label.rb', line 128

def find_label(s)
  s[@label_re, 1]
end

#next_idObject

Raises:



132
133
134
135
# File 'lib/rof/filters/label.rb', line 132

def next_id
  raise OutOfIdentifiers if @id_list.empty?
  @id_list.shift
end

#process(obj_list, _fname) ⇒ Object

mutate obj_list by assigning labels and resolving labels where needed Every fobject will be assigned an pid and a bendo_item



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rof/filters/label.rb', line 42

def process(obj_list, _fname)
  labels = {}

  # Use two passes. First assign ids, and then resolve labels
  # Do this since labels can be referenced before being defined

  # Assign pids to each fobject. If we find any labels in the pid field, then
  # record a mapping of label => pid into the labels hash.
  obj_list.each do |obj|
    assign_pid(obj, labels)
  end

  # now replace any reference labels with the pids we've assigned them
  obj_list.each do |obj|
    replace_labels_in_obj(obj, labels)
  end

  # now assign bendo ids
  bendo_item = nil
  obj_list.each do |obj|
    # for now we just use the first item's pid stripped of any namespaces as the bendo item id
    if bendo_item.nil?
      bendo_item = obj['pid'].gsub(/^.*:/, '') unless obj['pid'].nil?
      next if bendo_item.nil?
    end
    # don't touch if a bendo item has already been assigned
    obj['bendo-item'] = bendo_item if obj['bendo-item'].nil? || obj['bendo-item'] == ''
  end

  obj_list
end

#replace_labels(obj, labels, force = false) ⇒ Object

recurse through obj replacing any labels in strings with the id in labels, which is a hash. The relacement is done in place. Hash keys are not touched (only hash values). if force is true, labels which don’t resolve will raise a MissingLabel error.



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/rof/filters/label.rb', line 106

def replace_labels(obj, labels, force = false)
  if obj.is_a?(Array)
    obj.map! { |x| replace_labels(x, labels, force) }
  elsif obj.is_a?(Hash)
    obj.each { |k, v| obj[k] = replace_labels(v, labels, force) }
    obj
  elsif obj.is_a?(String)
    replace_match(obj, labels, force)
  else
    obj
  end
end

#replace_labels_in_obj(obj, labels) ⇒ Object

replace any label references we find in obj. obj is mutated



92
93
94
95
96
97
98
# File 'lib/rof/filters/label.rb', line 92

def replace_labels_in_obj(obj, labels)
  return if obj['type'] != 'fobject'
  obj.each do |k, v|
    # only force labels to exist if we are looking in the rels-ext
    obj[k] = replace_labels(v, labels, k == 'rels-ext')
  end
end

#replace_match(obj, labels, force) ⇒ Object

small matching function- uses regular expression



120
121
122
123
124
125
126
# File 'lib/rof/filters/label.rb', line 120

def replace_match(obj, labels, force)
  obj.gsub(@label_re) do |match|
    pid = labels[Regexp.last_match(1)]
    raise MissingLabel if pid.nil? && force
    pid.nil? ? match : pid
  end
end