rgen 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +20 -1
- data/MIT-LICENSE +1 -1
- data/README +12 -9
- data/lib/instantiators/ea_instantiator.rb +36 -0
- data/lib/metamodels/uml13_metamodel.rb +559 -0
- data/lib/metamodels/uml13_metamodel_ext.rb +26 -0
- data/lib/mmgen/metamodel_generator.rb +5 -5
- data/lib/mmgen/mm_ext/ecore_ext.rb +95 -0
- data/lib/mmgen/mmgen.rb +6 -4
- data/lib/mmgen/templates/annotations.tpl +37 -0
- data/lib/mmgen/templates/metamodel_generator.tpl +171 -0
- data/lib/rgen/ecore/ecore.rb +190 -0
- data/lib/rgen/ecore/ecore_instantiator.rb +25 -0
- data/lib/rgen/ecore/ecore_transformer.rb +85 -0
- data/lib/rgen/environment.rb +9 -24
- data/lib/rgen/find_helper.rb +68 -0
- data/lib/rgen/{instantiator.rb → instantiator/abstract_instantiator.rb} +6 -2
- data/lib/rgen/instantiator/abstract_xml_instantiator.rb +59 -0
- data/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
- data/lib/rgen/instantiator/ecore_xml_instantiator.rb +144 -0
- data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +157 -0
- data/lib/rgen/instantiator/xmi11_instantiator.rb +164 -0
- data/lib/rgen/metamodel_builder.rb +103 -9
- data/lib/rgen/metamodel_builder/build_helper.rb +26 -4
- data/lib/rgen/metamodel_builder/builder_extensions.rb +285 -88
- data/lib/rgen/metamodel_builder/builder_runtime.rb +7 -1
- data/lib/rgen/metamodel_builder/data_types.rb +67 -0
- data/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
- data/lib/rgen/metamodel_builder/metamodel_description.rb +232 -0
- data/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
- data/lib/rgen/metamodel_builder/module_extension.rb +33 -0
- data/lib/rgen/model_comparator.rb +56 -0
- data/lib/rgen/model_dumper.rb +5 -5
- data/lib/rgen/name_helper.rb +17 -1
- data/lib/rgen/template_language.rb +148 -28
- data/lib/rgen/template_language/directory_template_container.rb +56 -38
- data/lib/rgen/template_language/output_handler.rb +93 -77
- data/lib/rgen/template_language/template_container.rb +186 -143
- data/lib/rgen/transformer.rb +19 -14
- data/lib/transformers/uml13_to_ecore.rb +75 -0
- data/redist/xmlscan/ChangeLog +1301 -0
- data/redist/xmlscan/README +34 -0
- data/redist/xmlscan/THANKS +11 -0
- data/redist/xmlscan/doc/changes.html +74 -0
- data/redist/xmlscan/doc/changes.rd +80 -0
- data/redist/xmlscan/doc/en/conformance.html +136 -0
- data/redist/xmlscan/doc/en/conformance.rd +152 -0
- data/redist/xmlscan/doc/en/manual.html +356 -0
- data/redist/xmlscan/doc/en/manual.rd +402 -0
- data/redist/xmlscan/doc/ja/conformance.ja.html +118 -0
- data/redist/xmlscan/doc/ja/conformance.ja.rd +134 -0
- data/redist/xmlscan/doc/ja/manual.ja.html +325 -0
- data/redist/xmlscan/doc/ja/manual.ja.rd +370 -0
- data/redist/xmlscan/doc/src/Makefile +41 -0
- data/redist/xmlscan/doc/src/conformance.rd.src +256 -0
- data/redist/xmlscan/doc/src/langsplit.rb +110 -0
- data/redist/xmlscan/doc/src/manual.rd.src +614 -0
- data/redist/xmlscan/install.rb +41 -0
- data/redist/xmlscan/lib/xmlscan/encoding.rb +311 -0
- data/redist/xmlscan/lib/xmlscan/htmlscan.rb +289 -0
- data/redist/xmlscan/lib/xmlscan/namespace.rb +352 -0
- data/redist/xmlscan/lib/xmlscan/parser.rb +299 -0
- data/redist/xmlscan/lib/xmlscan/scanner.rb +1109 -0
- data/redist/xmlscan/lib/xmlscan/version.rb +22 -0
- data/redist/xmlscan/lib/xmlscan/visitor.rb +158 -0
- data/redist/xmlscan/lib/xmlscan/xmlchar.rb +441 -0
- data/redist/xmlscan/memo/CONFORMANCE +1249 -0
- data/redist/xmlscan/memo/PRODUCTIONS +195 -0
- data/redist/xmlscan/memo/contentspec.ry +335 -0
- data/redist/xmlscan/samples/chibixml.rb +105 -0
- data/redist/xmlscan/samples/getxmlchar.rb +122 -0
- data/redist/xmlscan/samples/rexml.rb +159 -0
- data/redist/xmlscan/samples/xmlbench.rb +88 -0
- data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +29 -0
- data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +99 -0
- data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +116 -0
- data/redist/xmlscan/samples/xmlconftest.rb +200 -0
- data/redist/xmlscan/test.rb +7 -0
- data/redist/xmlscan/tests/deftestcase.rb +73 -0
- data/redist/xmlscan/tests/runtest.rb +47 -0
- data/redist/xmlscan/tests/testall.rb +14 -0
- data/redist/xmlscan/tests/testencoding.rb +438 -0
- data/redist/xmlscan/tests/testhtmlscan.rb +752 -0
- data/redist/xmlscan/tests/testnamespace.rb +457 -0
- data/redist/xmlscan/tests/testparser.rb +591 -0
- data/redist/xmlscan/tests/testscanner.rb +1749 -0
- data/redist/xmlscan/tests/testxmlchar.rb +143 -0
- data/redist/xmlscan/tests/visitor.rb +34 -0
- data/test/array_extensions_test.rb +2 -2
- data/test/ea_instantiator_test.rb +41 -0
- data/test/ecore_self_test.rb +53 -0
- data/test/environment_test.rb +11 -6
- data/test/metamodel_builder_test.rb +404 -245
- data/test/metamodel_roundtrip_test.rb +52 -0
- data/test/metamodel_roundtrip_test/TestModel.rb +65 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +64 -0
- data/test/metamodel_roundtrip_test/houseMetamodel.ecore +32 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +39 -0
- data/test/rgen_test.rb +3 -3
- data/test/template_language_test.rb +65 -39
- data/test/template_language_test/expected_result.txt +24 -3
- data/test/template_language_test/templates/code/array.tpl +11 -0
- data/test/template_language_test/templates/content/author.tpl +7 -0
- data/test/template_language_test/templates/content/chapter.tpl +1 -1
- data/test/template_language_test/templates/root.tpl +17 -8
- data/test/template_language_test/testout.txt +24 -3
- data/test/testmodel/class_model_checker.rb +119 -0
- data/test/{xmi_instantiator_test/testmodel.eap → testmodel/ea_testmodel.eap} +0 -0
- data/test/{xmi_instantiator_test/testmodel.xml → testmodel/ea_testmodel.xml} +81 -14
- data/test/testmodel/ea_testmodel_partial.xml +317 -0
- data/test/testmodel/ecore_model_checker.rb +101 -0
- data/test/testmodel/manual_testmodel.xml +22 -0
- data/test/testmodel/object_model_checker.rb +67 -0
- data/test/transformer_test.rb +18 -10
- data/test/xml_instantiator_test.rb +81 -8
- data/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
- data/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
- data/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
- data/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
- metadata +126 -28
- data/lib/ea/xmi_class_instantiator.rb +0 -46
- data/lib/ea/xmi_helper.rb +0 -26
- data/lib/ea/xmi_metamodel.rb +0 -34
- data/lib/ea/xmi_object_instantiator.rb +0 -46
- data/lib/ea/xmi_to_classmodel.rb +0 -78
- data/lib/ea/xmi_to_objectmodel.rb +0 -92
- data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +0 -71
- data/lib/mmgen/templates/uml_classmodel.tpl +0 -63
- data/lib/rgen/xml_instantiator.rb +0 -132
- data/lib/uml/objectmodel_instantiator.rb +0 -53
- data/lib/uml/uml_classmodel.rb +0 -92
- data/lib/uml/uml_objectmodel.rb +0 -65
- data/test/metamodel_generator_test.rb +0 -44
- data/test/metamodel_generator_test/TestModel.rb +0 -40
- data/test/metamodel_generator_test/expected_result.txt +0 -40
- data/test/xmi_class_instantiator_test.rb +0 -24
- data/test/xmi_instantiator_test/class_model_checker.rb +0 -97
- data/test/xmi_object_instantiator_test.rb +0 -65
- 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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
data/lib/rgen/transformer.rb
CHANGED
@@ -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
|
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[
|
209
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|