rgen 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/CHANGELOG +20 -1
  2. data/MIT-LICENSE +1 -1
  3. data/README +12 -9
  4. data/lib/instantiators/ea_instantiator.rb +36 -0
  5. data/lib/metamodels/uml13_metamodel.rb +559 -0
  6. data/lib/metamodels/uml13_metamodel_ext.rb +26 -0
  7. data/lib/mmgen/metamodel_generator.rb +5 -5
  8. data/lib/mmgen/mm_ext/ecore_ext.rb +95 -0
  9. data/lib/mmgen/mmgen.rb +6 -4
  10. data/lib/mmgen/templates/annotations.tpl +37 -0
  11. data/lib/mmgen/templates/metamodel_generator.tpl +171 -0
  12. data/lib/rgen/ecore/ecore.rb +190 -0
  13. data/lib/rgen/ecore/ecore_instantiator.rb +25 -0
  14. data/lib/rgen/ecore/ecore_transformer.rb +85 -0
  15. data/lib/rgen/environment.rb +9 -24
  16. data/lib/rgen/find_helper.rb +68 -0
  17. data/lib/rgen/{instantiator.rb → instantiator/abstract_instantiator.rb} +6 -2
  18. data/lib/rgen/instantiator/abstract_xml_instantiator.rb +59 -0
  19. data/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
  20. data/lib/rgen/instantiator/ecore_xml_instantiator.rb +144 -0
  21. data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +157 -0
  22. data/lib/rgen/instantiator/xmi11_instantiator.rb +164 -0
  23. data/lib/rgen/metamodel_builder.rb +103 -9
  24. data/lib/rgen/metamodel_builder/build_helper.rb +26 -4
  25. data/lib/rgen/metamodel_builder/builder_extensions.rb +285 -88
  26. data/lib/rgen/metamodel_builder/builder_runtime.rb +7 -1
  27. data/lib/rgen/metamodel_builder/data_types.rb +67 -0
  28. data/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
  29. data/lib/rgen/metamodel_builder/metamodel_description.rb +232 -0
  30. data/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
  31. data/lib/rgen/metamodel_builder/module_extension.rb +33 -0
  32. data/lib/rgen/model_comparator.rb +56 -0
  33. data/lib/rgen/model_dumper.rb +5 -5
  34. data/lib/rgen/name_helper.rb +17 -1
  35. data/lib/rgen/template_language.rb +148 -28
  36. data/lib/rgen/template_language/directory_template_container.rb +56 -38
  37. data/lib/rgen/template_language/output_handler.rb +93 -77
  38. data/lib/rgen/template_language/template_container.rb +186 -143
  39. data/lib/rgen/transformer.rb +19 -14
  40. data/lib/transformers/uml13_to_ecore.rb +75 -0
  41. data/redist/xmlscan/ChangeLog +1301 -0
  42. data/redist/xmlscan/README +34 -0
  43. data/redist/xmlscan/THANKS +11 -0
  44. data/redist/xmlscan/doc/changes.html +74 -0
  45. data/redist/xmlscan/doc/changes.rd +80 -0
  46. data/redist/xmlscan/doc/en/conformance.html +136 -0
  47. data/redist/xmlscan/doc/en/conformance.rd +152 -0
  48. data/redist/xmlscan/doc/en/manual.html +356 -0
  49. data/redist/xmlscan/doc/en/manual.rd +402 -0
  50. data/redist/xmlscan/doc/ja/conformance.ja.html +118 -0
  51. data/redist/xmlscan/doc/ja/conformance.ja.rd +134 -0
  52. data/redist/xmlscan/doc/ja/manual.ja.html +325 -0
  53. data/redist/xmlscan/doc/ja/manual.ja.rd +370 -0
  54. data/redist/xmlscan/doc/src/Makefile +41 -0
  55. data/redist/xmlscan/doc/src/conformance.rd.src +256 -0
  56. data/redist/xmlscan/doc/src/langsplit.rb +110 -0
  57. data/redist/xmlscan/doc/src/manual.rd.src +614 -0
  58. data/redist/xmlscan/install.rb +41 -0
  59. data/redist/xmlscan/lib/xmlscan/encoding.rb +311 -0
  60. data/redist/xmlscan/lib/xmlscan/htmlscan.rb +289 -0
  61. data/redist/xmlscan/lib/xmlscan/namespace.rb +352 -0
  62. data/redist/xmlscan/lib/xmlscan/parser.rb +299 -0
  63. data/redist/xmlscan/lib/xmlscan/scanner.rb +1109 -0
  64. data/redist/xmlscan/lib/xmlscan/version.rb +22 -0
  65. data/redist/xmlscan/lib/xmlscan/visitor.rb +158 -0
  66. data/redist/xmlscan/lib/xmlscan/xmlchar.rb +441 -0
  67. data/redist/xmlscan/memo/CONFORMANCE +1249 -0
  68. data/redist/xmlscan/memo/PRODUCTIONS +195 -0
  69. data/redist/xmlscan/memo/contentspec.ry +335 -0
  70. data/redist/xmlscan/samples/chibixml.rb +105 -0
  71. data/redist/xmlscan/samples/getxmlchar.rb +122 -0
  72. data/redist/xmlscan/samples/rexml.rb +159 -0
  73. data/redist/xmlscan/samples/xmlbench.rb +88 -0
  74. data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +22 -0
  75. data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +29 -0
  76. data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +62 -0
  77. data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +22 -0
  78. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +62 -0
  79. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +22 -0
  80. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +22 -0
  81. data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +99 -0
  82. data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +116 -0
  83. data/redist/xmlscan/samples/xmlconftest.rb +200 -0
  84. data/redist/xmlscan/test.rb +7 -0
  85. data/redist/xmlscan/tests/deftestcase.rb +73 -0
  86. data/redist/xmlscan/tests/runtest.rb +47 -0
  87. data/redist/xmlscan/tests/testall.rb +14 -0
  88. data/redist/xmlscan/tests/testencoding.rb +438 -0
  89. data/redist/xmlscan/tests/testhtmlscan.rb +752 -0
  90. data/redist/xmlscan/tests/testnamespace.rb +457 -0
  91. data/redist/xmlscan/tests/testparser.rb +591 -0
  92. data/redist/xmlscan/tests/testscanner.rb +1749 -0
  93. data/redist/xmlscan/tests/testxmlchar.rb +143 -0
  94. data/redist/xmlscan/tests/visitor.rb +34 -0
  95. data/test/array_extensions_test.rb +2 -2
  96. data/test/ea_instantiator_test.rb +41 -0
  97. data/test/ecore_self_test.rb +53 -0
  98. data/test/environment_test.rb +11 -6
  99. data/test/metamodel_builder_test.rb +404 -245
  100. data/test/metamodel_roundtrip_test.rb +52 -0
  101. data/test/metamodel_roundtrip_test/TestModel.rb +65 -0
  102. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +64 -0
  103. data/test/metamodel_roundtrip_test/houseMetamodel.ecore +32 -0
  104. data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +39 -0
  105. data/test/rgen_test.rb +3 -3
  106. data/test/template_language_test.rb +65 -39
  107. data/test/template_language_test/expected_result.txt +24 -3
  108. data/test/template_language_test/templates/code/array.tpl +11 -0
  109. data/test/template_language_test/templates/content/author.tpl +7 -0
  110. data/test/template_language_test/templates/content/chapter.tpl +1 -1
  111. data/test/template_language_test/templates/root.tpl +17 -8
  112. data/test/template_language_test/testout.txt +24 -3
  113. data/test/testmodel/class_model_checker.rb +119 -0
  114. data/test/{xmi_instantiator_test/testmodel.eap → testmodel/ea_testmodel.eap} +0 -0
  115. data/test/{xmi_instantiator_test/testmodel.xml → testmodel/ea_testmodel.xml} +81 -14
  116. data/test/testmodel/ea_testmodel_partial.xml +317 -0
  117. data/test/testmodel/ecore_model_checker.rb +101 -0
  118. data/test/testmodel/manual_testmodel.xml +22 -0
  119. data/test/testmodel/object_model_checker.rb +67 -0
  120. data/test/transformer_test.rb +18 -10
  121. data/test/xml_instantiator_test.rb +81 -8
  122. data/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
  123. data/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
  124. data/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
  125. data/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
  126. metadata +126 -28
  127. data/lib/ea/xmi_class_instantiator.rb +0 -46
  128. data/lib/ea/xmi_helper.rb +0 -26
  129. data/lib/ea/xmi_metamodel.rb +0 -34
  130. data/lib/ea/xmi_object_instantiator.rb +0 -46
  131. data/lib/ea/xmi_to_classmodel.rb +0 -78
  132. data/lib/ea/xmi_to_objectmodel.rb +0 -92
  133. data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +0 -71
  134. data/lib/mmgen/templates/uml_classmodel.tpl +0 -63
  135. data/lib/rgen/xml_instantiator.rb +0 -132
  136. data/lib/uml/objectmodel_instantiator.rb +0 -53
  137. data/lib/uml/uml_classmodel.rb +0 -92
  138. data/lib/uml/uml_objectmodel.rb +0 -65
  139. data/test/metamodel_generator_test.rb +0 -44
  140. data/test/metamodel_generator_test/TestModel.rb +0 -40
  141. data/test/metamodel_generator_test/expected_result.txt +0 -40
  142. data/test/xmi_class_instantiator_test.rb +0 -24
  143. data/test/xmi_instantiator_test/class_model_checker.rb +0 -97
  144. data/test/xmi_object_instantiator_test.rb +0 -65
  145. data/test/xml_instantiator_test/testmodel.xml +0 -7
@@ -2,152 +2,195 @@
2
2
  # (c) Martin Thiede, 2006
3
3
 
4
4
  require 'erb'
5
+ require 'fileutils'
5
6
  require 'rgen/template_language/output_handler'
6
7
  require 'rgen/template_language/template_helper'
7
8
 
8
9
  module RGen
10
+
11
+ module TemplateLanguage
12
+
13
+ class TemplateContainer
14
+ include TemplateHelper
15
+
16
+ def initialize(metamodels, output_path, parent, filename)
17
+ @templates = {}
18
+ @parent = parent
19
+ @filename = filename
20
+ @indent = 0
21
+ @output_path = output_path
22
+ raise StandardError.new("Can not set metamodel, dup class first") if self.class == TemplateContainer
23
+ @@metamodels = metamodels
24
+ @@metamodels = [ @@metamodels ] unless @@metamodels.is_a?(Array)
25
+ end
26
+
27
+ def load
28
+ #print "Loading templates in #{@filename} ...\n"
29
+ File.open(@filename) { |f|
30
+ begin
31
+ ERB.new(f.read,nil,nil,'@output').result(binding)
32
+ rescue Exception => e
33
+ processAndRaise(e)
34
+ end
35
+ }
36
+ end
37
+
38
+ # if this container can handle the call, the expansion result is returned
39
+ # otherwise expand is called on the appropriate container and the result is added to @output
40
+ def expand(template, *all_args)
41
+ args, params = _splitArgsAndOptions(all_args)
42
+ if params[:foreach].is_a? Enumerable
43
+ _expand_foreach(template, args, params)
44
+ else
45
+ _expand(template, args, params)
46
+ end
47
+ end
48
+
49
+ def this
50
+ @context
51
+ end
52
+
53
+ def method_missing(name, *args)
54
+ @context.send(name, *args)
55
+ end
56
+
57
+ def self.const_missing(name)
58
+ super unless @@metamodels
59
+ @@metamodels.each do |mm|
60
+ return mm.const_get(name) rescue NameError
61
+ end
62
+ super
63
+ end
64
+
65
+ private
66
+
67
+ def nonl
68
+ @output.ignoreNextNL
69
+ end
70
+
71
+ def nows
72
+ @output.ignoreNextWS
73
+ end
74
+
75
+ def nl
76
+ _direct_concat("\n")
77
+ end
78
+
79
+ def ws
80
+ _direct_concat(" ")
81
+ end
82
+
83
+ def iinc
84
+ @indent += 1
85
+ @output.indent = @indent
86
+ end
87
+
88
+ def idec
89
+ @indent -= 1 if @indent > 0
90
+ @output.indent = @indent
91
+ end
92
+
93
+ def define(template, params={}, &block)
94
+ @templates[template] ||= {}
95
+ cls = params[:for] || Object
96
+ @templates[template][cls] = block
97
+ end
98
+
99
+ def file(name)
100
+ old_output, @output = @output, OutputHandler.new(@indent)
101
+ begin
102
+ yield
103
+ rescue Exception => e
104
+ processAndRaise(e)
105
+ end
106
+ path = ""
107
+ path += @output_path+"/" if @output_path
108
+ dirname = File.dirname(path+name)
109
+ FileUtils.makedirs(dirname) unless File.exist?(dirname)
110
+ File.open(path+name,"w") { |f| f.write(@output) }
111
+ @output = old_output
112
+ end
113
+
114
+ # private private
115
+
116
+ def _expand_foreach(template, args, params)
117
+ sep = params[:separator]
118
+ params[:foreach].each_with_index {|e,i|
119
+ single_params = params.dup
120
+ single_params[:for] = e
121
+ _direct_concat(sep.to_s) if sep && i > 0
122
+ _expand(template, args, single_params)
123
+ }
124
+ end
125
+
126
+ LOCAL_TEMPLATE_REGEX = /^:*(\w+)$/
127
+
128
+ def _expand(template, args, params)
129
+ context = params[:for]
130
+ @indent = params[:indent] || @indent
131
+ # if this is the first call to expand within this container, @output is nil
132
+ noIndentNextLine = params[:noIndentNextLine]
133
+ noIndentNextLine = (@output.to_s =~ /[^\n]\z/ ? true : false) if noIndentNextLine.nil?
134
+ old_context, @context = @context, context if context
135
+ local_output = nil
136
+ if template =~ LOCAL_TEMPLATE_REGEX
137
+ tplname = $1
138
+ throw "Template not found: #{$1}" unless @templates[tplname]
139
+ old_output, @output = @output, OutputHandler.new(@indent)
140
+ @output.noIndentNextLine if noIndentNextLine
141
+ _call_template(tplname, @context, args)
142
+ local_output, @output = @output, old_output
143
+ else
144
+ local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent, :noIndentNextLine => noIndentNextLine}))
145
+ end
146
+ _direct_concat(local_output)
147
+ @context = old_context if old_context
148
+ local_output
149
+ end
150
+
151
+ def processAndRaise(e, tpl=nil)
152
+ bt = e.backtrace.dup
153
+ e.backtrace.each_with_index do |t,i|
154
+ if t =~ /\(erb\):(\d+):/
155
+ bt[i] = "#{@filename}:#{$1}"
156
+ bt[i] += ":in '#{tpl}'" if tpl
157
+ break
158
+ end
159
+ end
160
+ raise e, e.to_s, bt
161
+ end
9
162
 
10
- module TemplateLanguage
11
-
12
- class TemplateContainer
13
- include TemplateHelper
14
-
15
- def initialize(metamodel, output_path, parent)
16
- @templates = {}
17
- @parent = parent
18
- @indent = 0
19
- @output_path = output_path
20
- raise StandardError.new("Can not set metamodel, dup class first") if self.class == TemplateContainer
21
- @@metamodel = metamodel
22
- end
23
-
24
- def load(filename)
25
- #print "Loading templates in #{filename} ...\n"
26
- File.open(filename) { |f|
27
- ERB.new(f.read,nil,nil,'@output').result(binding)
28
- }
29
- end
30
-
31
- # if this container can handle the call, the expansion result is returned
32
- # otherwise expand is called on the appropriate container and the result is added to @output
33
- def expand(template, *all_args)
34
- args, params = _splitArgsAndOptions(all_args)
35
- if params[:foreach].is_a? Enumerable
36
- _expand_foreach(template, args, params)
37
- else
38
- _expand(template, args, params)
39
- end
40
- end
41
-
42
- def this
43
- @context
44
- end
45
-
46
- def method_missing(name, *args)
47
- @context.send(name, *args)
48
- end
49
-
50
- def self.const_missing(name)
51
- super unless @@metamodel
52
- @@metamodel.const_get(name)
53
- end
54
-
55
- private
56
-
57
- def nonl
58
- @output.ignoreNextNL
59
- end
60
-
61
- def nows
62
- @output.ignoreNextWS
63
- end
64
-
65
- def nl
66
- _direct_concat("\n")
67
- end
68
-
69
- def iinc
70
- @indent += 1
71
- @output.indent = @indent
72
- end
73
-
74
- def idec
75
- @indent -= 1 if @indent > 0
76
- @output.indent = @indent
77
- end
78
-
79
- def define(template, params={}, &block)
80
- @templates[template] ||= {}
81
- cls = params[:for] || Object
82
- @templates[template][cls] = block
83
- end
84
-
85
- def file(name)
86
- old_output, @output = @output, OutputHandler.new(@indent)
87
- yield
88
- path = ""
89
- path += @output_path+"/" if @output_path
90
- File.open(path+name,"w") { |f| f.write(@output) }
91
- @output = old_output
92
- end
93
-
94
- # private private
95
-
96
- def _expand_foreach(template, args, params)
97
- params[:foreach].each {|e|
98
- single_params = params.dup
99
- single_params[:for] = e
100
- _expand(template, args, single_params)
101
- }
102
- end
103
-
104
- LOCAL_TEMPLATE_REGEX = /^:*(\w+)$/
105
-
106
- def _expand(template, args, params)
107
- context = params[:for]
108
- @indent = params[:indent] || @indent
109
- old_context, @context = @context, context if context
110
- local_output = nil
111
- if template =~ LOCAL_TEMPLATE_REGEX
112
- throw "Template not found: #{$1}" unless @templates[$1]
113
- old_output, @output = @output, OutputHandler.new(@indent)
114
- _call_template($1, @context, args)
115
- local_output, @output = @output, old_output
116
- else
117
- local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent}))
118
- end
119
- _direct_concat(local_output)
120
- @context = old_context if old_context
121
- local_output
122
- end
123
-
124
- def _call_template(tpl, context, args)
125
- found = false
126
- @templates[tpl].each_pair { |key, value|
127
- if context.is_a?(key)
128
- proc = @templates[tpl][key]
129
- arity = proc.arity
130
- arity = 0 if arity == -1 # if no args are given
131
- raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+
163
+ def _call_template(tpl, context, args)
164
+ found = false
165
+ @templates[tpl].each_pair { |key, value|
166
+ if context.is_a?(key)
167
+ proc = @templates[tpl][key]
168
+ arity = proc.arity
169
+ arity = 0 if arity == -1 # if no args are given
170
+ raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+
132
171
  "(Beware: Hashes as last arguments are taken as options and are ignored)") \
133
- if arity != args.size
134
- proc.call(*args)
135
- found = true
136
- end
137
- }
138
- raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found
139
- end
140
-
141
- def _direct_concat(s)
142
- if @output.is_a? OutputHandler
143
- @output.direct_concat(s)
144
- else
145
- @output << s
146
- end
147
- end
148
-
149
- end
150
-
151
- end
152
-
153
- end
172
+ if arity != args.size
173
+ begin
174
+ proc.call(*args)
175
+ rescue Exception => e
176
+ processAndRaise(e, tpl)
177
+ end
178
+ found = true
179
+ end
180
+ }
181
+ raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found
182
+ end
183
+
184
+ def _direct_concat(s)
185
+ if @output.is_a? OutputHandler
186
+ @output.direct_concat(s)
187
+ else
188
+ @output << s
189
+ end
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+
196
+ end
@@ -198,16 +198,13 @@ class Transformer
198
198
 
199
199
  # This class method specifies that all objects of class +from+ are to be copied
200
200
  # into an object of class +to+. If +to+ is omitted, +from+ is used as target class.
201
- # During copy, all attributes according to
202
- # MetamodelBuilder::BuilderExtensions.one_attributes and
203
- # MetamodelBuilder::BuilderExtensions.many_attributes of the target object
201
+ # During copy, all attributes and references of the target object
204
202
  # are set to their transformed counterparts of the source object.
205
203
  #
206
204
  def self.copy(from, to=nil)
207
205
  transform(from, :to => to || from) do
208
- Hash[*(@current_object.class.one_attributes +
209
- @current_object.class.many_attributes).inject([]) {|l,a|
210
- l + [a.to_sym, trans(@current_object.send(a))]
206
+ Hash[*@current_object.class.ecore.eAllStructuralFeatures.inject([]) {|l,a|
207
+ l + [a.name.to_sym, trans(@current_object.send(a.name))]
211
208
  }]
212
209
  end
213
210
  end
@@ -221,9 +218,10 @@ class Transformer
221
218
  end
222
219
 
223
220
 
224
- # Creates a new transformer with the specified input and output Environment.
221
+ # Creates a new transformer
222
+ # Optionally an input and output Environment can be specified.
225
223
  #
226
- def initialize(env_in, env_out)
224
+ def initialize(env_in=nil, env_out=nil)
227
225
  @env_in = env_in
228
226
  @env_out = env_out
229
227
  @transformer_results = {}
@@ -236,7 +234,9 @@ class Transformer
236
234
  # The transformation result element is created in the output environment and returned.
237
235
  # In addition, the result is cached, i.e. a second invocation with the same parameter
238
236
  # object will return the same result object without any further evaluation of the
239
- # transformation rules. Nil will be transformed into nil.
237
+ # transformation rules. Nil will be transformed into nil. Ruby "singleton" objects
238
+ # +true+, +false+, numerics and symbols will be return without any change. Ruby strings
239
+ # will be duplicated with the result being cached.
240
240
  #
241
241
  # The transformation input can be given as:
242
242
  # * a single object
@@ -244,7 +244,10 @@ class Transformer
244
244
  # * a hash used as input to Environment#find with the result being transformed
245
245
  #
246
246
  def trans(obj)
247
- obj = @env_in.find(obj) if obj.is_a?(Hash)
247
+ if obj.is_a?(Hash)
248
+ raise StandardError.new("No input environment available to find model element.") unless @env_in
249
+ obj = @env_in.find(obj)
250
+ end
248
251
  return nil if obj.nil?
249
252
  return obj if obj.is_a?(TrueClass) or obj.is_a?(FalseClass) or obj.is_a?(Numeric) or obj.is_a?(Symbol)
250
253
  return @transformer_results[obj] if @transformer_results[obj]
@@ -266,11 +269,11 @@ class Transformer
266
269
  # If that object also does not respond to the call, it is treated as a transformer
267
270
  # method call (see Transformer.method).
268
271
  #
269
- def method_missing(m) #:nodoc:
272
+ def method_missing(m, *args) #:nodoc:
270
273
  if @current_object.respond_to?(m)
271
- @current_object.send(m)
274
+ @current_object.send(m, *args)
272
275
  else
273
- _invokeMethod(m)
276
+ _invokeMethod(m, *args)
274
277
  end
275
278
  end
276
279
 
@@ -313,7 +316,9 @@ class Transformer
313
316
  target_class = target_desc
314
317
  end
315
318
  @current_object = old_object
316
- @env_out.new target_class
319
+ result = target_class.new
320
+ @env_out << result if @env_out
321
+ result
317
322
  end
318
323
 
319
324
  def _invokeMethod(m) # :nodoc:
@@ -0,0 +1,75 @@
1
+ require 'metamodels/uml13_metamodel'
2
+ require 'rgen/transformer'
3
+ require 'rgen/ecore/ecore'
4
+ require 'rgen/array_extensions'
5
+
6
+ class UML13ToECore < RGen::Transformer
7
+ include RGen::ECore
8
+
9
+ def transform
10
+ trans(:class => UML13::Class)
11
+ end
12
+
13
+ transform UML13::Model, :to => EPackage do
14
+ trans(ownedClassOrPackage)
15
+ { :name => name && name.strip }
16
+ end
17
+
18
+ transform UML13::Package, :to => EPackage do
19
+ trans(ownedClassOrPackage)
20
+ { :name => name && name.strip,
21
+ :eSuperPackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil) }
22
+ end
23
+
24
+ method :ownedClassOrPackage do
25
+ ownedElement.select{|e| e.is_a?(UML13::Package) || e.is_a?(UML13::Class)}
26
+ end
27
+
28
+ transform UML13::Class, :to => EClass do
29
+ { :name => name && name.strip,
30
+ :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil),
31
+ :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + associationEnd),
32
+ :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}),
33
+ :eSuperTypes => trans(generalization.parent + clientDependency.select{|d| d.stereotype.name == "implements"}.supplier),
34
+ :eAnnotations => [ EAnnotation.new(:details => trans(taggedValue)) ] }
35
+ end
36
+
37
+ transform UML13::Interface, :to => EClass do
38
+ { :name => name && name.strip,
39
+ :ePackage => trans(namespace.is_a?(UML13::Package) ? namespace : nil),
40
+ :eStructuralFeatures => trans(feature.select{|f| f.is_a?(UML13::Attribute)} + associationEnd),
41
+ :eOperations => trans(feature.select{|f| f.is_a?(UML13::Operation)}),
42
+ :eSuperTypes => trans(generalization.parent)}
43
+ end
44
+
45
+ transform UML13::Attribute, :to => EAttribute do
46
+ typemap = { "string" => EString, "boolean" => EBoolean, "int" => EInt, "float" => EFloat }
47
+ typetv = taggedValue.find{|tv| tv.tag == "type"}
48
+ { :name => name && name.strip, :eType => (typetv && typetv.value && typemap[typetv.value.downcase]),
49
+ :eAnnotations => [ EAnnotation.new(:details => trans(taggedValue)) ] }
50
+ end
51
+
52
+ transform UML13::Operation, :to => EOperation do
53
+ { :name => name && name.strip }
54
+ end
55
+
56
+ transform UML13::AssociationEnd, :to => EReference, :if => :isReference do
57
+ otherEnd = association.connection.find{|ae| ae != @current_object}
58
+ { :eType => trans(otherEnd.type),
59
+ :name => otherEnd.name && otherEnd.name.strip,
60
+ :eOpposite => trans(otherEnd),
61
+ :lowerBound => otherEnd.multiplicity ? otherEnd.multiplicity.range.first.lower.to_i : 0,
62
+ :upperBound => otherEnd.multiplicity ? otherEnd.multiplicity.range.first.upper.gsub('*','-1').to_i : 1,
63
+ :containment => (aggregation == :composite),
64
+ :eAnnotations => [ EAnnotation.new(:details => trans(association.taggedValue)) ] }
65
+ end
66
+
67
+ method :isReference do
68
+ otherEnd = association.connection.find{|ae| ae != @current_object}
69
+ otherEnd.name && otherEnd.name.size > 0
70
+ end
71
+
72
+ transform UML13::TaggedValue, :to => EStringToStringMapEntry do
73
+ { :key => tag, :value => value}
74
+ end
75
+ end