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.
- 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
|