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

DELEGATED =

Shortcuts to interesting methods on logger

%i[debug? info? warn? error? fatal?].freeze
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):


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

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


52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/occi/core/parsers/json/entity.rb', line 52

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


85
86
87
88
89
90
91
92
93
94
95
# File 'lib/occi/core/parsers/json/entity.rb', line 85

def json_collection(hash)
  all = []

  logger.debug "Converting #{hash.inspect} into multiple instances" if logger_debug?
  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}" if logger_debug?
  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


69
70
71
72
73
74
75
76
77
78
79
# File 'lib/occi/core/parsers/json/entity.rb', line 69

def json_single(hash)
  logger.debug "Converting #{hash.inspect} into a single instance" if logger_debug?
  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}" if logger_debug?
  Set.new [instance]
end

#lookup(ary) ⇒ Object

:nodoc:


98
99
100
101
102
103
104
# File 'lib/occi/core/parsers/json/entity.rb', line 98

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:


107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/occi/core/parsers/json/entity.rb', line 107

def set_attributes!(instance, hash)
  return if hash.blank?
  hash.each_pair do |name, value|
    logger.debug "Setting attribute #{name} to #{value.inspect}" if logger_debug?
    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:


121
122
123
124
# File 'lib/occi/core/parsers/json/entity.rb', line 121

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:


127
128
129
130
131
132
# File 'lib/occi/core/parsers/json/entity.rb', line 127

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:


135
136
137
138
139
140
141
142
143
# File 'lib/occi/core/parsers/json/entity.rb', line 135

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}" if logger_debug?
  TYPECASTER_HASH[type].call(value)
end