Class: Occi::Core::Parsers::Json::Entity

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

Overview

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

Author:

Constant Summary collapse

SINGLE_INSTANCE_TYPES =

Constants

%i[resource link].freeze
MULTI_INSTANCE_TYPES =
%i[entity-collection].freeze
TYPECASTER_HASH =
{
  IPAddr  => ->(val) { IPAddr.new val },
  URI     => ->(val) { URI.parse val },
  Float   => ->(val) { Float(val) rescue raise(Occi::Core::Errors::ParsingError, "Wrong value #{val}") },
  Integer => ->(val) { Integer(val) rescue raise(Occi::Core::Errors::ParsingError, "Wrong value #{val}") }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers::RawJsonParser

raw_hash

Methods included from Helpers::ErrorHandler

#handle, included

Constructor Details

#initialize(args = {}) ⇒ Entity

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

Parameters:

  • args (Hash) (defaults to: {})

    constructor arguments in a Hash

Options Hash (args):



34
35
36
37
38
39
40
41
# File 'lib/occi/core/parsers/json/entity.rb', line 34

def initialize(args = {})
  pre_initialize(args)
  default_args! args

  @model = args.fetch(:model)

  post_initialize(args)
end

Instance Attribute Details

#modelOcci::Core::Model, Occi::Infrastructure::Model

model to use as a primary reference point

Returns:



11
12
13
# File 'lib/occi/core/parsers/json/entity.rb', line 11

def model
  @model
end

Instance Method Details

#json(body, type) ⇒ Array

Builds an entity instances from the lines provided as input.

Parameters:

  • body (String)

    JSON body for parsing

  • type (Symbol)

    ‘:resource`, `:link`, or `:’entity-collection’‘

Returns:

  • (Array)

    constructed instances



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/occi/core/parsers/json/entity.rb', line 48

def json(body, type)
  symbol = case type
           when *SINGLE_INSTANCE_TYPES
             :json_single
           when *MULTI_INSTANCE_TYPES
             :json_collection
           else
             raise Occi::Core::Errors::ParserError, "#{type.inspect} is not a valid type"
           end

  send symbol, self.class.raw_hash(body)
end

#json_collection(hash) ⇒ Array

Builds entity instances from the hash provided as input.

Parameters:

  • hash (Hash)

    Hash body for parsing

Returns:

  • (Array)

    constructed instances



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/occi/core/parsers/json/entity.rb', line 81

def json_collection(hash)
  all = []

  logger.debug { "Converting #{hash.inspect} into multiple instances" }
  all.concat hash[:resources] if hash[:resources]
  all.concat hash[:links] if hash[:links]
  all.map! { |a| json_single(a) }

  logger.debug { "Created instances #{all.inspect}" }
  Set.new(all).flatten
end

#json_single(hash) ⇒ Array

Builds an entity instance from the hash provided as input.

Parameters:

  • hash (Hash)

    Hash body for parsing

Returns:

  • (Array)

    constructed instances



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/occi/core/parsers/json/entity.rb', line 65

def json_single(hash)
  logger.debug { "Converting #{hash.inspect} into a single instance" }
  instance = @_ib.get hash[:kind], mixins: lookup(hash[:mixins]), actions: lookup(hash[:actions])

  set_attributes! instance, hash[:attributes]
  set_links! instance, hash[:links] if instance.respond_to?(:links)
  set_target! instance, hash[:target] if instance.respond_to?(:target)

  logger.debug { "Created instance #{instance.inspect}" }
  Set.new [instance]
end

#lookup(ary) ⇒ Object

:nodoc:



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

def lookup(ary)
  return Set.new if ary.blank?
  cats = ary.map do |item|
    handle(Occi::Core::Errors::ParsingError) { model.find_by_identifier!(item) }
  end
  Set.new cats
end

#set_attributes!(instance, hash) ⇒ Object

:nodoc:



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/occi/core/parsers/json/entity.rb', line 103

def set_attributes!(instance, hash)
  return if hash.blank?
  hash.each_pair do |name, value|
    logger.debug { "Setting attribute #{name} to #{value.inspect}" }
    attribute = instance.attributes[name.to_s]
    unless attribute
      raise Occi::Core::Errors::ParsingError,
            "Attribute #{name.inspect} is not allowed for this entity"
    end
    attribute.value = typecast(value, attribute.attribute_definition.type)
  end
end

#set_links!(instance, ary) ⇒ Object

:nodoc:



117
118
119
120
# File 'lib/occi/core/parsers/json/entity.rb', line 117

def set_links!(instance, ary)
  return if ary.blank?
  ary.each { |l| instance.add_link(json_single(l).first) }
end

#set_target!(link, hash) ⇒ Object

:nodoc:



123
124
125
126
127
128
# File 'lib/occi/core/parsers/json/entity.rb', line 123

def set_target!(link, hash)
  return unless link.respond_to?(:target_kind)
  return if hash.blank? || hash[:kind].blank?

  link.target_kind = lookup([hash[:kind]]).first
end

#typecast(value, type) ⇒ Object

:nodoc:



131
132
133
134
135
136
137
138
139
# File 'lib/occi/core/parsers/json/entity.rb', line 131

def typecast(value, type)
  if value.nil? || type.nil?
    raise Occi::Core::Errors::ParsingError, 'Cannot typecast (un)set value to (un)set type'
  end
  return value unless TYPECASTER_HASH.key?(type)

  logger.debug { "Typecasting value #{value.inspect} to #{type}" }
  TYPECASTER_HASH[type].call(value)
end