Class: Occi::Core::Parsers::Json::Category

Inherits:
Object
  • Object
show all
Extended by:
Helpers::ParserDereferencer, Helpers::RawJsonParser
Includes:
Helpers::ErrorHandler, Yell::Loggable
Defined in:
lib/occi/core/parsers/json/category.rb

Overview

Static parsing class responsible for extracting categories from JSON. Class supports ‘application/json’ via ‘json`. No other formats are supported.

Author:

Constant Summary collapse

TYPECASTER_HASH =

Typecasting lambdas

{
  'boolean' => Boolean,
  'string'  => String,
  'number'  => Numeric,
  'array'   => Array,
  'object'  => Hash
}.freeze
PARENT_KEY =

Hash constants for ParserDereferencer

:parent
APPLIES_KEY =
:applies
DEPENDS_KEY =
:depends

Class Method Summary collapse

Methods included from Helpers::ParserDereferencer

dereference_identifiers!, first_or_die, lookup_action_references!, lookup_applies_references!, lookup_depends_references!, lookup_parent_references!, lookup_references!

Methods included from Helpers::RawJsonParser

raw_hash

Methods included from Helpers::ErrorHandler

#handle, included

Class Method Details

.attribute_definitions(raw) ⇒ Object

:nodoc:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/occi/core/parsers/json/category.rb', line 75

def attribute_definitions(raw)
  return {} if raw.blank?

  attr_defs = {}
  raw.each_pair do |k, v|
    logger.debug { "Creating AttributeDefinition for #{k.inspect} from #{v.inspect}" }
    def_hsh = typecast(v)
    unless def_hsh[:type]
      raise Occi::Core::Errors::ParsingError, "Attribute #{k.to_s.inspect} has no type"
    end
    fix_links!(k, def_hsh)
    attr_defs[k.to_s] = Occi::Core::AttributeDefinition.new(def_hsh)
  end

  attr_defs
end

.fix_links!(name, definition_hash) ⇒ Object

:nodoc:



118
119
120
121
122
# File 'lib/occi/core/parsers/json/category.rb', line 118

def fix_links!(name, definition_hash)
  return unless %w[occi.core.source occi.core.target].include?(name.to_s)
  logger.debug { "Forcing attribute type on #{name.to_s.inspect} from #{definition_hash[:type]} to URI" }
  definition_hash[:type] = URI # forcing 'string' to URI for validation purposes
end

.instantiate_hashes!(raw, model) ⇒ Object

:nodoc:



50
51
52
53
54
# File 'lib/occi/core/parsers/json/category.rb', line 50

def instantiate_hashes!(raw, model)
  raw[:kinds].each { |k| model << instatiate_hash(k, Occi::Core::Kind) } if raw[:kinds]
  raw[:mixins].each { |k| model << instatiate_hash(k, Occi::Core::Mixin) } if raw[:mixins]
  raw[:actions].each { |k| model << instatiate_hash(k, Occi::Core::Action) } if raw[:actions]
end

.instatiate_hash(raw, klass) ⇒ Object

:nodoc:



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/occi/core/parsers/json/category.rb', line 57

def instatiate_hash(raw, klass)
  logger.debug { "Creating #{klass} from #{raw.inspect}" }

  obj = klass.new(
    term: raw[:term], schema: raw[:scheme], title: raw[:title],
    attributes: attribute_definitions(raw[:attributes])
  )

  if obj.respond_to?(:location)
    logger.debug { "Setting location #{raw[:location].inspect}" }
    obj.location = handle(Occi::Core::Errors::ParsingError) { URI.parse(raw[:location]) }
  end

  logger.debug { "Created category #{obj.inspect}" }
  obj
end

.json(body, model) ⇒ Occi::Core::Model

Parses categories into instances of subtypes of ‘Occi::Core::Category`. Internal references between objects are converted from strings to actual objects. Categories provided in the model will be reused but have to be declared in the parsed model as well.

Parameters:

  • body (String)

    JSON body for parsing

  • model (Occi::Core::Model)

    model with existing categories

Returns:



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/occi/core/parsers/json/category.rb', line 37

def json(body, model)
  parsed = raw_hash(body)
  instantiate_hashes! parsed, model
  logger.debug { "Parsed into raw hashes #{parsed.inspect}" }

  raw_categories = [parsed[:kinds], parsed[:mixins]].flatten.compact
  dereference_identifiers! model.categories, raw_categories

  logger.debug { "Returning (updated) model #{model.inspect}" }
  model
end

.lookup_applies_references!(mixin, derefd, parsed_rel) ⇒ Object

:nodoc:



104
105
106
107
108
# File 'lib/occi/core/parsers/json/category.rb', line 104

def lookup_applies_references!(mixin, derefd, parsed_rel)
  logger.debug { "Looking up applies from #{parsed_rel.inspect}" }
  return if parsed_rel.blank?
  parsed_rel.each { |kind| mixin.applies << first_or_die(derefd, kind) }
end

.lookup_depends_references!(mixin, derefd, parsed_rel) ⇒ Object

:nodoc:



111
112
113
114
115
# File 'lib/occi/core/parsers/json/category.rb', line 111

def lookup_depends_references!(mixin, derefd, parsed_rel)
  logger.debug { "Looking up depens from #{parsed_rel.inspect}" }
  return if parsed_rel.blank?
  parsed_rel.each { |mxn| mixin.depends << first_or_die(derefd, mxn) }
end

.typecast(hash) ⇒ Object

:nodoc:



93
94
95
96
97
98
99
100
101
# File 'lib/occi/core/parsers/json/category.rb', line 93

def typecast(hash)
  hash = hash.clone
  hash[:type] = TYPECASTER_HASH[hash[:type]]

  return hash if hash[:pattern].blank?
  hash[:pattern] = handle(Occi::Core::Errors::ParsingError) { Regexp.new(hash[:pattern]) }

  hash
end