rgen 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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