Class: XMI11Instantiator

Inherits:
AbstractXMLInstantiator show all
Includes:
RGen::ECore
Defined in:
lib/rgen/instantiator/xmi11_instantiator.rb

Defined Under Namespace

Classes: ResolverDescription

Constant Summary collapse

INFO =
0
WARN =
1
ERROR =
2

Constants included from RGen::ECore

RGen::ECore::EBoolean, RGen::ECore::EFloat, RGen::ECore::EInt, RGen::ECore::EJavaClass, RGen::ECore::EJavaObject, RGen::ECore::ERubyClass, RGen::ECore::ERubyObject, RGen::ECore::EString

Instance Method Summary collapse

Methods included from RGen::MetamodelBuilder::ModuleExtension

#_annotations, #_constantOrder, #annotation, extended, #final_method, #method_added

Methods included from RGen::ECore::ECoreInterface

#_set_ecore_internal, clear_ecore_cache, #ecore

Methods inherited from AbstractXMLInstantiator

#text

Constructor Details

#initialize(env, fix_map = {}, loglevel = ERROR) ⇒ XMI11Instantiator

Returns a new instance of XMI11Instantiator.



15
16
17
18
19
20
21
# File 'lib/rgen/instantiator/xmi11_instantiator.rb', line 15

def initialize(env, fix_map={}, loglevel=ERROR)
  @env = env
  @fix_map = fix_map
  @loglevel = loglevel
  @rolestack = []
  @elementstack = []
end

Instance Method Details

#add_metamodel(ns, mod) ⇒ Object



23
24
25
26
# File 'lib/rgen/instantiator/xmi11_instantiator.rb', line 23

def add_metamodel(ns, mod)
  @ns_module_map ||={}
  @ns_module_map[ns] = mod
end

#end_tag(prefix, tag) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/rgen/instantiator/xmi11_instantiator.rb', line 85

def end_tag(prefix, tag)
  if tag =~ /\w+\.(\w+)/
    @rolestack.pop
  else
    @elementstack.pop
  end
end

#instantiate(str) ⇒ Object



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

def instantiate(str)
  @resolver_descs = []
  @element_by_id = {}
  super(str, 1000)
  @resolver_descs.each do |rd|
    if rd.many
      newval = rd.value.split(" ").collect{|v| @element_by_id[v]}
    else
      newval = @element_by_id[rd.value]
    end
    log WARN, "Could not resolve reference #{rd.attribute} on #{rd.object}" unless newval
    begin
      rd.object.setGeneric(rd.attribute,newval)
    rescue Exception
      log WARN, "Could not set reference #{rd.attribute} on #{rd.object}"
    end
  end
end

#set_attribute(attr, value) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rgen/instantiator/xmi11_instantiator.rb', line 93

def set_attribute(attr, value)
  return unless @elementstack.last
  if attr == "xmi.id"
    @element_by_id[value] = @elementstack.last
  else
    attr_name = map_feature_name(attr) || attr
    eFeat = eAllStructuralFeatures(@elementstack.last).find{|a| a.name == attr_name}
    unless eFeat
      log WARN, "No structural feature found for #{attr_name} on #{@elementstack.last}"
      return
    end
    if eFeat.is_a?(RGen::ECore::EReference)
      if map_feature_value(attr_name, value).is_a?(eFeat.eType.instanceClass)
        @elementstack.last.setGeneric(attr_name, map_feature_value(attr_name, value))
      else
        rd = ResolverDescription.new
        rd.object = @elementstack.last
        rd.attribute = attr_name
        rd.value = value
        rd.many = eFeat.many
        @resolver_descs << rd
      end
    else
      value = map_feature_value(attr_name, value) || value
      value = true if value == "true" && eFeat.eType == EBoolean
      value = false if value == "false" && eFeat.eType == EBoolean
      value = value.to_i if eFeat.eType == EInt
      value = value.to_f if eFeat.eType == EFloat
      value = value.to_sym if eFeat.eType.is_a?(EEnum)
      @elementstack.last.setGeneric(attr_name, value)
    end
  end
end

#start_tag(prefix, tag, namespaces, attributes) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rgen/instantiator/xmi11_instantiator.rb', line 47

def start_tag(prefix, tag, namespaces, attributes)
  if tag =~ /\w+\.(\w+)/
    # XMI role
    role_name = map_feature_name($1) || $1
    eRef = @elementstack.last && eAllReferences(@elementstack.last).find{|r|r.name == role_name}
    log WARN, "No reference found for #{role_name} on #{@elementstack.last}" unless eRef
    @rolestack.push eRef
  elsif attributes["xmi.idref"]
    # reference
    rd = ResolverDescription.new
    rd.object = @elementstack.last
    rd.attribute = @rolestack.last.name
    rd.value = attributes["xmi.idref"]
    rd.many = @rolestack.last.many      
    @resolver_descs << rd
    @elementstack.push nil
  else
    # model element
    value = map_tag(tag, attributes) || tag
    if value.is_a?(String)
      mod = @ns_module_map[namespaces[prefix]]
      unless mod
        log WARN, "Ignoring tag #{tag}"
        return
      end
      value = mod.const_get(value).new
    end
    @env << value
    eRef = @rolestack.last
    if eRef && eRef.many
      @elementstack.last.addGeneric(eRef.name, value)
    elsif eRef
      @elementstack.last.setGeneric(eRef.name, value)
    end
    @elementstack.push value
  end
end