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
|
@@ -11,16 +11,38 @@ class BuildHelper
|
|
|
11
11
|
include NameHelper
|
|
12
12
|
|
|
13
13
|
def self.build(mod,bnd,tpl)
|
|
14
|
-
mod.module_eval ERB.new(tpl).result(BuildHelper.new(bnd).bnd)
|
|
14
|
+
mod.module_eval ERB.new(tpl).result(BuildHelper.new(mod, bnd).bnd)
|
|
15
15
|
end
|
|
16
|
-
def initialize(bnd)
|
|
16
|
+
def initialize(mod, bnd)
|
|
17
17
|
@outer_binding = bnd
|
|
18
|
+
@mod = mod
|
|
18
19
|
end
|
|
19
20
|
def bnd
|
|
20
21
|
binding
|
|
21
22
|
end
|
|
22
|
-
def method_missing(m)
|
|
23
|
-
|
|
23
|
+
def method_missing(m, *args)
|
|
24
|
+
if args.empty?
|
|
25
|
+
eval("#{m}",@outer_binding)
|
|
26
|
+
else
|
|
27
|
+
@mod.instance_eval do
|
|
28
|
+
send(m,*args)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
def type_check_code(varname, props)
|
|
33
|
+
code = ""
|
|
34
|
+
if props.impl_type.is_a?(Class)
|
|
35
|
+
code << "unless #{varname}.nil? or #{varname}.is_a? #{props.impl_type}\n"
|
|
36
|
+
expected = props.impl_type.to_s
|
|
37
|
+
elsif props.impl_type.is_a?(RGen::MetamodelBuilder::DataTypes::Enum)
|
|
38
|
+
code << "unless #{varname}.nil? or [#{props.impl_type.literals_as_strings.join(',')}].include?(#{varname})\n"
|
|
39
|
+
expected = "["+props.impl_type.literals_as_strings.join(',')+"]"
|
|
40
|
+
else
|
|
41
|
+
raise StandardError.new("Unkown type "+props.impl_type.to_s)
|
|
42
|
+
end
|
|
43
|
+
code << "raise _assignmentTypeError(self,#{varname},\"#{expected}\")\n"
|
|
44
|
+
code << "end"
|
|
45
|
+
code
|
|
24
46
|
end
|
|
25
47
|
end
|
|
26
48
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
require 'erb'
|
|
5
5
|
require 'rgen/metamodel_builder/build_helper'
|
|
6
|
+
require 'rgen/metamodel_builder/metamodel_description.rb'
|
|
6
7
|
|
|
7
8
|
module RGen
|
|
8
9
|
|
|
@@ -16,19 +17,50 @@ module MetamodelBuilder
|
|
|
16
17
|
# See MetamodelBuilder for an example.
|
|
17
18
|
#
|
|
18
19
|
module BuilderExtensions
|
|
20
|
+
include NameHelper
|
|
19
21
|
|
|
22
|
+
class FeatureBlockEvaluator
|
|
23
|
+
def self.eval(block, props1, props2=nil)
|
|
24
|
+
return unless block
|
|
25
|
+
e = self.new(props1, props2)
|
|
26
|
+
e.instance_eval(&block)
|
|
27
|
+
end
|
|
28
|
+
def initialize(props1, props2)
|
|
29
|
+
@props1, @props2 = props1, props2
|
|
30
|
+
end
|
|
31
|
+
def annotation(hash)
|
|
32
|
+
@props1.annotations << Intermediate::Annotation.new(hash)
|
|
33
|
+
end
|
|
34
|
+
def opposite_annotation(hash)
|
|
35
|
+
raise "No opposite available" unless @props2
|
|
36
|
+
@props2.annotations << Intermediate::Annotation.new(hash)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def has_attr(role, target_class=nil, raw_props={}, &block)
|
|
41
|
+
props = AttributeDescription.new(target_class, _ownProps(raw_props).merge({
|
|
42
|
+
:name=>role, :upperBound=>1}))
|
|
43
|
+
raise "No opposite available" unless _oppositeProps(raw_props).empty?
|
|
44
|
+
FeatureBlockEvaluator.eval(block, props)
|
|
45
|
+
_build_internal(props)
|
|
46
|
+
end
|
|
47
|
+
|
|
20
48
|
# Add a single attribute or unidirectional association.
|
|
21
49
|
# 'role' specifies the name which is used to access the attribute.
|
|
22
|
-
# 'target_class'
|
|
23
|
-
#
|
|
50
|
+
# 'target_class' specifies the type of objects which can be held by this attribute.
|
|
51
|
+
# If no target class is given, String will be default.
|
|
24
52
|
#
|
|
25
53
|
# This class method adds the following instance methods, where 'role' is to be
|
|
26
54
|
# replaced by the given role name:
|
|
27
55
|
# class#role # getter
|
|
28
56
|
# class#role=(value) # setter
|
|
29
57
|
#
|
|
30
|
-
def has_one(role, target_class=nil)
|
|
31
|
-
|
|
58
|
+
def has_one(role, target_class=nil, raw_props={}, &block)
|
|
59
|
+
props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
60
|
+
:name=>role, :upperBound=>1, :containment=>false}))
|
|
61
|
+
raise "No opposite available" unless _oppositeProps(raw_props).empty?
|
|
62
|
+
FeatureBlockEvaluator.eval(block, props)
|
|
63
|
+
_build_internal(props)
|
|
32
64
|
end
|
|
33
65
|
|
|
34
66
|
# Add an unidirectional _many_ association.
|
|
@@ -44,8 +76,28 @@ module BuilderExtensions
|
|
|
44
76
|
# Note that the first letter of the role name is turned into an uppercase
|
|
45
77
|
# for the add and remove methods.
|
|
46
78
|
#
|
|
47
|
-
def has_many(role, target_class=nil)
|
|
48
|
-
|
|
79
|
+
def has_many(role, target_class=nil, raw_props={}, &block)
|
|
80
|
+
props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
81
|
+
:name=>role, :upperBound=>-1, :containment=>false}))
|
|
82
|
+
raise "No opposite available" unless _oppositeProps(raw_props).empty?
|
|
83
|
+
FeatureBlockEvaluator.eval(block, props)
|
|
84
|
+
_build_internal(props)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def contains_one_uni(role, target_class=nil, raw_props={}, &block)
|
|
88
|
+
props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
89
|
+
:name=>role, :upperBound=>1, :containment=>true}))
|
|
90
|
+
raise "No opposite available" unless _oppositeProps(raw_props).empty?
|
|
91
|
+
FeatureBlockEvaluator.eval(block, props)
|
|
92
|
+
_build_internal(props)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def contains_many_uni(role, target_class=nil, raw_props={}, &block)
|
|
96
|
+
props = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
97
|
+
:name=>role, :upperBound=>-1, :containment=>true}))
|
|
98
|
+
raise "No opposite available" unless _oppositeProps(raw_props).empty?
|
|
99
|
+
FeatureBlockEvaluator.eval(block, props)
|
|
100
|
+
_build_internal(props)
|
|
49
101
|
end
|
|
50
102
|
|
|
51
103
|
# Add a bidirectional one-to-many association between two classes.
|
|
@@ -69,15 +121,32 @@ module BuilderExtensions
|
|
|
69
121
|
# When an element is added/set on either side, this element also receives the element
|
|
70
122
|
# is is added to as a new element.
|
|
71
123
|
#
|
|
72
|
-
def one_to_many(
|
|
73
|
-
|
|
74
|
-
|
|
124
|
+
def one_to_many(target_role, target_class, own_role, raw_props={}, &block)
|
|
125
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
126
|
+
:name=>target_role, :upperBound=>-1, :containment=>false}))
|
|
127
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
128
|
+
:name=>own_role, :upperBound=>1, :containment=>false}))
|
|
129
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
130
|
+
_build_internal(props1, props2)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def contains_many(target_role, target_class, own_role, raw_props={}, &block)
|
|
134
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
135
|
+
:name=>target_role, :upperBound=>-1, :containment=>true}))
|
|
136
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
137
|
+
:name=>own_role, :upperBound=>1, :containment=>false}))
|
|
138
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
139
|
+
_build_internal(props1, props2)
|
|
75
140
|
end
|
|
76
141
|
|
|
77
142
|
# This is the inverse of one_to_many provided for convenience.
|
|
78
|
-
def many_to_one(
|
|
79
|
-
|
|
80
|
-
|
|
143
|
+
def many_to_one(target_role, target_class, own_role, raw_props={}, &block)
|
|
144
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
145
|
+
:name=>target_role, :upperBound=>1, :containment=>false}))
|
|
146
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
147
|
+
:name=>own_role, :upperBound=>-1, :containment=>false}))
|
|
148
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
149
|
+
_build_internal(props1, props2)
|
|
81
150
|
end
|
|
82
151
|
|
|
83
152
|
# Add a bidirectional many-to-many association between two classes.
|
|
@@ -102,9 +171,13 @@ module BuilderExtensions
|
|
|
102
171
|
# When an element is added on either side, this element also receives the element
|
|
103
172
|
# is is added to as a new element.
|
|
104
173
|
#
|
|
105
|
-
def many_to_many(
|
|
106
|
-
|
|
107
|
-
|
|
174
|
+
def many_to_many(target_role, target_class, own_role, raw_props={}, &block)
|
|
175
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
176
|
+
:name=>target_role, :upperBound=>-1, :containment=>false}))
|
|
177
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
178
|
+
:name=>own_role, :upperBound=>-1, :containment=>false}))
|
|
179
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
180
|
+
_build_internal(props1, props2)
|
|
108
181
|
end
|
|
109
182
|
|
|
110
183
|
# Add a bidirectional one-to-one association between two classes.
|
|
@@ -125,93 +198,217 @@ module BuilderExtensions
|
|
|
125
198
|
# When an element is set on either side, this element also receives the element
|
|
126
199
|
# is is added to as the new element.
|
|
127
200
|
#
|
|
128
|
-
def one_to_one(
|
|
129
|
-
|
|
130
|
-
|
|
201
|
+
def one_to_one(target_role, target_class, own_role, raw_props={}, &block)
|
|
202
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
203
|
+
:name=>target_role, :upperBound=>1, :containment=>false}))
|
|
204
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
205
|
+
:name=>own_role, :upperBound=>1, :containment=>false}))
|
|
206
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
207
|
+
_build_internal(props1, props2)
|
|
131
208
|
end
|
|
132
209
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
210
|
+
def contains_one(target_role, target_class, own_role, raw_props={}, &block)
|
|
211
|
+
props1 = ReferenceDescription.new(target_class, _ownProps(raw_props).merge({
|
|
212
|
+
:name=>target_role, :upperBound=>1, :containment=>true}))
|
|
213
|
+
props2 = ReferenceDescription.new(self, _oppositeProps(raw_props).merge({
|
|
214
|
+
:name=>own_role, :upperBound=>1, :containment=>false}))
|
|
215
|
+
FeatureBlockEvaluator.eval(block, props1, props2)
|
|
216
|
+
_build_internal(props1, props2)
|
|
140
217
|
end
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def many_attributes
|
|
145
|
-
@many_attributes ||= []
|
|
146
|
-
result = @many_attributes.dup
|
|
147
|
-
result += superclass.many_attributes if superclass.respond_to?(:many_attributes)
|
|
148
|
-
result
|
|
218
|
+
|
|
219
|
+
def _metamodel_description # :nodoc:
|
|
220
|
+
@metamodel_description ||= []
|
|
149
221
|
end
|
|
150
222
|
|
|
223
|
+
def inherited(c)
|
|
224
|
+
c._class_module
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def _class_module # :nodoc:
|
|
228
|
+
unless const_defined?(:ClassModule)
|
|
229
|
+
const_set(:ClassModule, Module.new)
|
|
230
|
+
include const_get(:ClassModule)
|
|
231
|
+
end
|
|
232
|
+
const_get(:ClassModule)
|
|
233
|
+
end
|
|
234
|
+
|
|
151
235
|
protected
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
236
|
+
|
|
237
|
+
# Central builder method
|
|
238
|
+
#
|
|
239
|
+
def _build_internal(props1, props2=nil)
|
|
240
|
+
_metamodel_description << props1
|
|
241
|
+
if props1.is_a?(ReferenceDescription) && props1.many?
|
|
242
|
+
_build_many_methods(props1, props2)
|
|
243
|
+
else
|
|
244
|
+
_build_one_methods(props1, props2)
|
|
245
|
+
end
|
|
246
|
+
if props2
|
|
247
|
+
# this is a bidirectional reference
|
|
248
|
+
props1.opposite, props2.opposite = props2, props1
|
|
249
|
+
other_class = props1.impl_type
|
|
250
|
+
other_class._metamodel_description << props2
|
|
251
|
+
raise "Internal error: second description must be a ReferenceDescription" \
|
|
252
|
+
unless props2.is_a?(ReferenceDescription)
|
|
253
|
+
if props2.many?
|
|
254
|
+
other_class._build_many_methods(props2, props1)
|
|
255
|
+
else
|
|
256
|
+
other_class._build_one_methods(props2, props1)
|
|
170
257
|
end
|
|
171
|
-
|
|
172
|
-
alias set<%= firstToUpper(name) %> #{name}=
|
|
173
|
-
CODE
|
|
258
|
+
end
|
|
174
259
|
end
|
|
175
260
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
261
|
+
# To-One association methods
|
|
262
|
+
#
|
|
263
|
+
def _build_one_methods(props, other_props=nil)
|
|
264
|
+
name = props.value(:name)
|
|
265
|
+
other_role = other_props && other_props.value(:name)
|
|
266
|
+
other_kind = other_props && ( other_props.many? ? :many : :one )
|
|
267
|
+
|
|
268
|
+
if props.value(:derived)
|
|
269
|
+
build_derived_method(name, props, :one)
|
|
270
|
+
else
|
|
271
|
+
BuildHelper.build _class_module, binding, <<-CODE
|
|
272
|
+
|
|
273
|
+
def #{name}
|
|
274
|
+
<% if props.is_a?(AttributeDescription) && props.value(:defaultValueLiteral) %>
|
|
275
|
+
<% defVal = props.value(:defaultValueLiteral) %>
|
|
276
|
+
<% defVal = '"'+defVal+'"' if props.impl_type == String %>
|
|
277
|
+
<% defVal = ':'+defVal if props.impl_type.is_a?(DataTypes::Enum) %>
|
|
278
|
+
@#{name}.nil? ? <%= defVal %> : @#{name}
|
|
279
|
+
<% else %>
|
|
280
|
+
@#{name}
|
|
281
|
+
<% end %>
|
|
282
|
+
end
|
|
283
|
+
alias get<%= firstToUpper(name) %> #{name}
|
|
284
|
+
|
|
285
|
+
CODE
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
if props.value(:changeable)
|
|
289
|
+
BuildHelper.build _class_module, binding, <<-CODE
|
|
290
|
+
|
|
291
|
+
def #{name}=(val)
|
|
292
|
+
return if val == @#{name}
|
|
293
|
+
<%= type_check_code("val", props) %>
|
|
294
|
+
oldval = @#{name}
|
|
295
|
+
@#{name} = val
|
|
296
|
+
<% if other_role && other_kind %>
|
|
297
|
+
_unregister(self,oldval,"#{other_role}","#{other_kind}")
|
|
298
|
+
_register(self,val,"#{other_role}","#{other_kind}")
|
|
299
|
+
<% end %>
|
|
300
|
+
end
|
|
301
|
+
alias set<%= firstToUpper(name) %> #{name}=
|
|
302
|
+
|
|
303
|
+
CODE
|
|
304
|
+
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# To-Many association methods
|
|
309
|
+
#
|
|
310
|
+
def _build_many_methods(props, other_props=nil)
|
|
311
|
+
name = props.value(:name)
|
|
312
|
+
other_role = other_props && other_props.value(:name)
|
|
313
|
+
other_kind = other_props && ( other_props.many? ? :many : :one )
|
|
314
|
+
|
|
315
|
+
if props.value(:derived)
|
|
316
|
+
build_derived_method(name, props, :many)
|
|
317
|
+
else
|
|
318
|
+
BuildHelper.build _class_module, binding, <<-CODE
|
|
319
|
+
|
|
320
|
+
def #{name}
|
|
321
|
+
( @#{name} ? @#{name}.dup : [] )
|
|
322
|
+
end
|
|
323
|
+
alias get<%= firstToUpper(name) %> #{name}
|
|
324
|
+
|
|
325
|
+
CODE
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
if props.value(:changeable)
|
|
329
|
+
BuildHelper.build _class_module, binding, <<-CODE
|
|
330
|
+
|
|
331
|
+
def add<%= firstToUpper(name) %>(val)
|
|
332
|
+
@#{name} = [] unless @#{name}
|
|
333
|
+
return if val.nil? or @#{name}.include?(val)
|
|
334
|
+
<%= type_check_code("val", props) %>
|
|
335
|
+
@#{name}.push val
|
|
336
|
+
<% if other_role && other_kind %>
|
|
337
|
+
_register(self, val, "#{other_role}", "#{other_kind}")
|
|
338
|
+
<% end %>
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def remove<%= firstToUpper(name) %>(val)
|
|
342
|
+
@#{name} = [] unless @#{name}
|
|
343
|
+
return unless @#{name}.include?(val)
|
|
344
|
+
@#{name}.delete val
|
|
345
|
+
<% if other_role && other_kind %>
|
|
346
|
+
_unregister(self, val, "#{other_role}", "#{other_kind}")
|
|
347
|
+
<% end %>
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def #{name}=(val)
|
|
351
|
+
return if val.nil?
|
|
352
|
+
raise _assignmentTypeError(self, val, Array) unless val.is_a? Array
|
|
353
|
+
getGeneric(:#{name}).each {|e|
|
|
354
|
+
remove<%= firstToUpper(name) %>(e)
|
|
355
|
+
}
|
|
356
|
+
val.each {|v|
|
|
357
|
+
add<%= firstToUpper(name) %>(v)
|
|
358
|
+
}
|
|
359
|
+
end
|
|
360
|
+
alias set<%= firstToUpper(name) %> #{name}=
|
|
361
|
+
|
|
362
|
+
CODE
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
private
|
|
368
|
+
|
|
369
|
+
def build_derived_method(name, props, kind)
|
|
370
|
+
raise "Implement method #{name}_derived instead of method #{name}" \
|
|
371
|
+
if (public_instance_methods+protected_instance_methods+private_instance_methods).include?(name)
|
|
372
|
+
BuildHelper.build _class_module, binding, <<-CODE
|
|
373
|
+
|
|
196
374
|
def #{name}
|
|
197
|
-
|
|
375
|
+
raise "Derived feature requires public implementation of method #{name}_derived" \
|
|
376
|
+
unless respond_to?(:#{name+"_derived"})
|
|
377
|
+
val = #{name}_derived
|
|
378
|
+
<% if kind == :many %>
|
|
379
|
+
raise _assignmentTypeError(self,val,Array) unless val && val.is_a?(Array)
|
|
380
|
+
val.each do |v|
|
|
381
|
+
<%= type_check_code("v", props) %>
|
|
382
|
+
end
|
|
383
|
+
<% else %>
|
|
384
|
+
<%= type_check_code("val", props) %>
|
|
385
|
+
<% end %>
|
|
386
|
+
val
|
|
198
387
|
end
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
#{name}.each {|e|
|
|
203
|
-
remove<%= firstToUpper(name) %>(e)
|
|
204
|
-
}
|
|
205
|
-
val.each {|v|
|
|
206
|
-
add<%= firstToUpper(name) %>(v)
|
|
207
|
-
}
|
|
208
|
-
end
|
|
209
|
-
alias get<%= firstToUpper(name) %> #{name}
|
|
210
|
-
alias set<%= firstToUpper(name) %> #{name}=
|
|
388
|
+
alias get#{firstToUpper(name)} #{name}
|
|
389
|
+
#TODO final_method :#{name}
|
|
390
|
+
|
|
211
391
|
CODE
|
|
212
|
-
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
private
|
|
395
|
+
|
|
396
|
+
def _ownProps(props)
|
|
397
|
+
Hash[*(props.select{|k,v| !(k.to_s =~ /^opposite_/)}.flatten)]
|
|
398
|
+
end
|
|
213
399
|
|
|
400
|
+
def _oppositeProps(props)
|
|
401
|
+
r = {}
|
|
402
|
+
props.each_pair do |k,v|
|
|
403
|
+
if k.to_s =~ /^opposite_(.*)$/
|
|
404
|
+
r[$1.to_sym] = v
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
r
|
|
408
|
+
end
|
|
409
|
+
|
|
214
410
|
end
|
|
411
|
+
|
|
215
412
|
end
|
|
216
413
|
|
|
217
414
|
end
|