class Occi::Core::Parsers::Text::Entity

Static parsing class responsible for extracting entities from plain text. Class supports 'text/plain' via `plain`. No other formats are supported.

@attr model [Occi::Core::Model, Occi::Infrastructure::Model] model to use as a primary reference point

@author Boris Parak <parak@cesnet.cz>

Constants

ATTRIBUTE_REGEXP

Regexp constants

DEFAULT_LAMBDA

Typecasting lambdas

DELEGATED

Shortcuts to interesting methods on logger

FLOAT_LAMBDA
JSON_LAMBDA
TYPECASTER_HASH

Attributes

model[R]

Public Class Methods

new(args = {}) click to toggle source

Constructs an instance of the entity parser. Only entities (their kinds) defined by the model are allowed.

@param args [Hash] constructor arguments in a Hash @option args [Occi::Core::Model] :model model to use as a primary reference point

# File lib/occi/core/parsers/text/entity.rb, line 48
def initialize(args = {})
  pre_initialize(args)
  default_args! args

  @model = args.fetch(:model)

  post_initialize(args)
end
typecaster() click to toggle source

Constructs a map pointing from expected attribute types to conversion lambdas.

@return [Hash] typecaster hash with conversion lambdas

# File lib/occi/core/parsers/text/entity.rb, line 245
def typecaster
  Hash.new(DEFAULT_LAMBDA).merge(TYPECASTER_HASH)
end

Public Instance Methods

plain(lines) click to toggle source

Builds an entity instances from the lines provided as input.

@param lines [Array] list of lines containing a single entity rendering @return [Occi::Core::Entity] constructed instance

# File lib/occi/core/parsers/text/entity.rb, line 61
def plain(lines)
  cats = plain_categories(lines)
  kind = cats.detect { |c| c.is_a?(Occi::Core::Kind) }
  raise Occi::Core::Errors::ParsingError, 'Entity does not specify its kind' unless kind
  logger.debug "Identified entity kind #{kind.inspect}" if logger_debug?

  entity = @_ib.build(kind.identifier)
  cats.each { |cat| cat.is_a?(Occi::Core::Mixin) && entity << cat }

  plain_attributes! lines, entity.attributes
  plain_links! lines, entity

  logger.debug "Created instance #{entity.inspect}" if logger_debug?
  entity
end
plain_action!(md, entity) click to toggle source

Looks up the action mentioned in the given action “link” and assigns it to the given partially constructed entity instance.

@param md [MatchData] Hash-like structure with matched parts of the link @param entity [Occi::Core::Entity] partially constructed entity instance to be updated

# File lib/occi/core/parsers/text/entity.rb, line 162
def plain_action!(md, entity)
  entity << handle(Occi::Core::Errors::ParsingError) { model.find_by_identifier!(md[:rel]) }
end
plain_attributes!(lines, attributes) click to toggle source

Parses attributes from entity lines. Every attribute value is typed according to the attribute specification provided by the model (in the defined kind).

@param lines [Array] list of lines containing a single entity rendering @param attributes [Hash] defined attributes @return [Hash] parsed and typed attributes

# File lib/occi/core/parsers/text/entity.rb, line 96
def plain_attributes!(lines, attributes)
  lines.each do |line|
    next unless line.start_with?(TextParser::ATTRIBUTE_KEYS.first)

    name, value = raw_attribute(line)
    unless attributes[name]
      raise Occi::Core::Errors::ParsingError,
            "Attribute #{name.inspect} is not allowed for this entity"
    end

    attributes[name].value = handle(Occi::Core::Errors::ParsingError) do
      typecast value, attributes[name].attribute_definition.type
    end
  end

  attributes
end
plain_categories(lines) click to toggle source

Parses categories from entity lines. Every category is looked up in the model.

@param lines [Array] list of lines containing a single entity rendering @return [Array] list of identified category instances

# File lib/occi/core/parsers/text/entity.rb, line 81
def plain_categories(lines)
  categories = lines.map do |line|
    next unless line.start_with?(TextParser::CATEGORY_KEYS.first)
    cat = Category.plain_category(line, false)
    handle(Occi::Core::Errors::ParsingError) { model.find_by_identifier!("#{cat[:scheme]}#{cat[:term]}") }
  end
  categories.compact
end
raw_attribute(line) click to toggle source

Parses a single attribute line to identify name and value.

@param line [String] line containing a single entity attribute @return [Array] two-element array with name and value of the attribute

# File lib/occi/core/parsers/text/entity.rb, line 118
def raw_attribute(line)
  logger.debug "Parsing attribute line #{line.inspect}" if logger_debug?
  matched = line.match(ATTRIBUTE_REGEXP)
  unless matched
    raise Occi::Core::Errors::ParsingError, "#{line.inspect} does not match expectations for Attribute"
  end
  [matched[:name], matched[:string] || matched[:number] || matched[:bool]]
end
typecast(value, type) click to toggle source

Typecasts attribute values from String to the desired type.

@param value [String] attribute value @param type [Class,Module] desired attribute type @return [Object] typecasted value

# File lib/occi/core/parsers/text/entity.rb, line 232
def typecast(value, type)
  if value.nil? || type.nil?
    raise Occi::Core::Errors::ParsingError, 'Cannot typecast (un)set value to (un)set type'
  end

  logger.debug "Typecasting value #{value.inspect} to #{type}" if logger_debug?
  self.class.typecaster[type].call(value)
end