class Noid::Template

Constants

VALID_PATTERN

Attributes

characters[R]
generator[R]
prefix[R]
template[R]

Public Class Methods

new(template) click to toggle source

@param [String] template A Template is a coded string of the form Prefix.Mask that governs how identifiers will be minted.

# File lib/noid/template.rb, line 8
def initialize(template)
  @template = template
  parse!
end

Public Instance Methods

==(other) click to toggle source
# File lib/noid/template.rb, line 49
def ==(other)
  return false unless other.is_a? Noid::Template
  template == other.template
end
checkdigit(str) click to toggle source

calculate a checkdigit for the str @param [String] str @return [String] checkdigit

# File lib/noid/template.rb, line 35
def checkdigit(str)
  Noid::XDIGIT[str.split('').map { |x| Noid::XDIGIT.index(x).to_i }.each_with_index.map { |n, idx| n * (idx + 1) }.inject { |sum, n| sum + n } % Noid::XDIGIT.length]
end
max() click to toggle source

maximum sequence value for the template

# File lib/noid/template.rb, line 56
def max
  @max ||= if generator == 'z'
             nil
           else
             size_list.inject(1) { |total, x| total * x }
           end
end
min() click to toggle source

minimum sequence value

# File lib/noid/template.rb, line 41
def min
  @min ||= 0
end
mint(n) click to toggle source
# File lib/noid/template.rb, line 13
def mint(n)
  str = prefix
  str += n2xdig(n)
  str += checkdigit(str) if checkdigit?
  str
end
to_s() click to toggle source
# File lib/noid/template.rb, line 45
def to_s
  template
end
valid?(str) click to toggle source

Is the string valid against this template string and checksum? @param [String] str @return bool

# File lib/noid/template.rb, line 24
def valid?(str)
  match = validation_regex.match(str)
  return false if match.nil?
  return checkdigit(match[1]) == match[3] if checkdigit?
  true
end

Protected Instance Methods

character_list() click to toggle source
# File lib/noid/template.rb, line 118
def character_list
  characters.split('')
end
character_space(c) click to toggle source

total size of a given template character value @param [String] c

# File lib/noid/template.rb, line 133
def character_space(c)
  case c
  when 'e'
    Noid::XDIGIT.length
  when 'd'
    10
  end
end
character_to_pattern(c) click to toggle source
# File lib/noid/template.rb, line 101
def character_to_pattern(c)
  case c
  when 'e', 'k'
    xdigit_pattern
  when 'd'
    '\d'
  else
    ''
  end
end
checkdigit?() click to toggle source
# File lib/noid/template.rb, line 126
def checkdigit?
  @checkdigit
end
mask() click to toggle source
# File lib/noid/template.rb, line 122
def mask
  generator + characters
end
n2xdig(n) click to toggle source

convert a minter position to a noid string under this template @param [Integer] n @return [String]

# File lib/noid/template.rb, line 146
def n2xdig(n)
  xdig = size_list.reverse.map { |size|
    value = n % size
    n /= size
    Noid::XDIGIT[value]
  }.compact.join('')

  if generator == 'z'
    size = size_list.last
    while n > 0
      value = n % size
      n /= size
      xdig += Noid::XDIGIT[value]
    end
  end

  raise 'Exhausted noid sequence pool' if n > 0

  xdig.reverse
end
parse!() click to toggle source

parse template and put the results into instance variables raise an exception if there is a parse error

# File lib/noid/template.rb, line 88
def parse!
  match = VALID_PATTERN.match(template)
  raise Noid::TemplateError, "Malformed noid template '#{template}'" unless match
  @prefix = match[1]
  @generator = match[2]
  @characters = match[3]
  @checkdigit = (match[4] == 'k')
end
size_list() click to toggle source

Return a list giving the number of possible characters at each position

# File lib/noid/template.rb, line 114
def size_list
  @size_list ||= character_list.map { |c| character_space(c) }
end
validation_regex() click to toggle source

A noid has the structure (prefix)(code)(checkdigit) the regexp has the following captures

1 - the prefix and the code
2 - the changing id characters (not the prefix and not the checkdigit)
3 - the checkdigit, if there is one. This field is missing if there is no checkdigit
# File lib/noid/template.rb, line 72
def validation_regex
  @validation_regex ||= begin
                          character_pattern = ''
                          # the first character in the mask after the type character is the most significant
                          # acc. to the Noid spec (p.9):
                          # https://wiki.ucop.edu/display/Curation/NOID?preview=/16744482/16973835/noid.pdf
                          character_pattern += character_to_pattern(character_list.first) + "*" if generator == 'z'
                          character_pattern += character_list.map { |c| character_to_pattern(c) }.join

                          %r{\A(#{Regexp.escape(prefix)}(#{character_pattern}))(#{character_to_pattern('k') if checkdigit?})\Z}
                        end
end
xdigit_pattern() click to toggle source
# File lib/noid/template.rb, line 97
def xdigit_pattern
  @xdigit_pattern ||= '[' + Noid::XDIGIT.join('') + ']'
end