Class: RGen::Instantiator::JsonInstantiator

Inherits:
Object
  • Object
show all
Defined in:
lib/rgen/instantiator/json_instantiator.rb

Overview

JsonInstantiator is used to create RGen models from JSON.

Each JSON object needs to have an attribute “_class” which is used to find the metamodel class to instantiate. The value of “_class” should be the the relative qualified class name within the root package as a string.

If the option “short_class_names” is set to true, unqualified class names can be used. In this case, metamodel classes are searched in the metamodel root package first. If this search is not successful, all subpackages will be searched for the class name.

Instance Method Summary collapse

Constructor Details

#initialize(env, mm, options = {}) ⇒ JsonInstantiator

Model elements will be created in evironment env, classes are looked for in metamodel package module mm, options include:

short_class_names: if true subpackages will be searched for unqualifed class names (default: true)
ignore_keys:       an array of json object key names which are to be ignored (default: none)

The options are also passed to the underlying QualifiedNameResolver.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rgen/instantiator/json_instantiator.rb', line 28

def initialize(env, mm, options={})
  @env = env
  @mm = mm
  @options = options
  @short_class_names = !@options.has_key?(:short_class_names) || @options[:short_class_names]
  @ignore_keys = @options[:ignore_keys] || []
  @unresolvedReferences = []
  @classes = {}
  @classes_flat = {}
  mm.ecore.eAllClasses.each do |c|
    @classes[c.instanceClass.name.sub(mm.name+"::","")] = c
    @classes_flat[c.name] = c
  end
  @parser = JsonParser.new(self)
end

Instance Method Details

#createObject(hash) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rgen/instantiator/json_instantiator.rb', line 61

def createObject(hash)
  className = hash["_class"]
  # hashes without a _class key are returned as is
  return hash unless className
  if @classes[className]
    clazz = @classes[className].instanceClass
  elsif @short_class_names && @classes_flat[className]
    clazz = @classes_flat[className].instanceClass
  else 
    raise "class not found: #{className}"
  end
  hash.delete("_class")
  @ignore_keys.each do |k|
    hash.delete(k)
  end
  urefs = []
  hash.keys.each do |k|
    f = eFeature(k, clazz)
    hash[k] = [hash[k]] if f.many && !hash[k].is_a?(Array)
    if f.is_a?(RGen::ECore::EReference) && !f.containment
      if f.many
        idents = hash[k]
        hash[k] = idents.collect do |i|
          proxy = RGen::MetamodelBuilder::MMProxy.new(i)
          urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy)
          proxy
        end
      else
        ident = hash[k]
        ident = ident.first if ident.is_a?(Array)
        proxy = RGen::MetamodelBuilder::MMProxy.new(ident)
        hash[k] = proxy
        urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy)
      end
    elsif f.eType.is_a?(RGen::ECore::EEnum)
      hash[k] = hash[k].to_sym
    elsif f.eType.instanceClassName == "Float"
      hash[k] = hash[k].to_f
    end
  end  
  obj = @env.new(clazz, hash)
  urefs.each do |r|
    r.element = obj
    @unresolvedReferences << r 
  end
  obj
end

#instantiate(str, options = {}) ⇒ Object

Creates the elements described by the json string str. Returns an array of ReferenceResolver::UnresolvedReference describing the references which could not be resolved

Options:

:root_elements: if an array is provided, it will be filled with the root elements


51
52
53
54
55
56
57
58
59
# File 'lib/rgen/instantiator/json_instantiator.rb', line 51

def instantiate(str, options={})
  root = @parser.parse(str)
  if options[:root_elements].is_a?(Array)
    options[:root_elements].clear
    root.each{|r| options[:root_elements] << r}
  end
  resolver = QualifiedNameResolver.new(root, @options)
  resolver.resolveReferences(@unresolvedReferences)
end