rgen 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -1
- data/Rakefile +2 -2
- data/lib/rgen/ecore/ecore_transformer.rb +5 -4
- data/lib/rgen/instantiator/json_parser.rb +7 -2
- data/lib/rgen/instantiator/json_parser.y +5 -0
- data/lib/rgen/metamodel_builder.rb +1 -0
- data/lib/rgen/metamodel_builder/builder_extensions.rb +1 -0
- data/lib/rgen/metamodel_builder/constant_order_helper.rb +89 -0
- data/lib/rgen/metamodel_builder/data_types.rb +2 -1
- data/lib/rgen/metamodel_builder/module_extension.rb +10 -1
- data/lib/rgen/serializer/json_serializer.rb +2 -1
- data/test/json_test.rb +12 -4
- data/test/metamodel_order_test.rb +125 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +39 -37
- data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +129 -129
- data/test/metamodel_roundtrip_test/using_builtin_types_serialized.ecore +5 -5
- data/test/model_builder/ecore_internal.rb +56 -56
- data/test/rgen_test.rb +1 -0
- data/test/testmodel/ea_testmodel_regenerated.xml +584 -584
- metadata +16 -5
data/CHANGELOG
CHANGED
@@ -99,7 +99,7 @@
|
|
99
99
|
* Fixed metamodel builder bug: _register at one-side did not unregister from the element referenced by the old value
|
100
100
|
* Added helper class for building simple model comparators
|
101
101
|
|
102
|
-
=0.5.2 ( )
|
102
|
+
=0.5.2 (Jun 13th, 2010)
|
103
103
|
|
104
104
|
* Added has_many_attr to metamodel builder, support for "many" attributes
|
105
105
|
* Added JSON support (json instantiator and serializer)
|
@@ -110,3 +110,8 @@
|
|
110
110
|
* Fixed ecore xml instantiator and serializer to handle references to builtin datatypes correctly
|
111
111
|
* Fixed bug in ecore xml serializer to not output references which are opposites of containment references
|
112
112
|
|
113
|
+
=0.5.3 (Aug 13th, 2010)
|
114
|
+
|
115
|
+
* Fixed string escaping in JSON instantiator and serializer
|
116
|
+
* Fixed order of eClassifiers and eSubpackages within an EPackage created by reflection on a RGen module
|
117
|
+
|
data/Rakefile
CHANGED
@@ -3,8 +3,8 @@ require 'rake/rdoctask'
|
|
3
3
|
|
4
4
|
RGenGemSpec = Gem::Specification.new do |s|
|
5
5
|
s.name = %q{rgen}
|
6
|
-
s.version = "0.5.
|
7
|
-
s.date = %q{2010-
|
6
|
+
s.version = "0.5.3"
|
7
|
+
s.date = %q{2010-08-13}
|
8
8
|
s.summary = %q{Ruby Modelling and Generator Framework}
|
9
9
|
s.email = %q{martin dot thiede at gmx de}
|
10
10
|
s.homepage = %q{http://ruby-gen.org}
|
@@ -32,13 +32,14 @@ class ECoreTransformer < Transformer
|
|
32
32
|
|
33
33
|
transform Module, :to => EPackage, :if => :convert? do
|
34
34
|
@enumParentModule ||= {}
|
35
|
-
|
35
|
+
_constants = _constantOrder + (constants - _constantOrder)
|
36
|
+
_constants.select {|c| const_get(c).is_a?(MetamodelBuilder::DataTypes::Enum)}.
|
36
37
|
each {|c| @enumParentModule[const_get(c)] = @current_object}
|
37
38
|
{ :name => name.gsub(/.*::(\w+)$/,'\1'),
|
38
|
-
:eClassifiers => trans(
|
39
|
+
:eClassifiers => trans(_constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Class) ||
|
39
40
|
(c.is_a?(MetamodelBuilder::DataTypes::Enum) && c != MetamodelBuilder::DataTypes::Boolean) }),
|
40
41
|
:eSuperPackage => trans(name =~ /(.*)::\w+$/ ? eval($1) : nil),
|
41
|
-
:eSubpackages => trans(
|
42
|
+
:eSubpackages => trans(_constants.collect{|c| const_get(c)}.select{|c| c.is_a?(Module) && !c.is_a?(Class)}),
|
42
43
|
:eAnnotations => trans(_annotations)
|
43
44
|
}
|
44
45
|
end
|
@@ -87,4 +88,4 @@ end
|
|
87
88
|
|
88
89
|
end
|
89
90
|
|
90
|
-
end
|
91
|
+
end
|
@@ -15,7 +15,7 @@ module Instantiator
|
|
15
15
|
|
16
16
|
class JsonParser < Racc::Parser
|
17
17
|
|
18
|
-
module_eval <<'..end json_parser.y modeval..
|
18
|
+
module_eval <<'..end json_parser.y modeval..id3d5fb611e2', 'json_parser.y', 38
|
19
19
|
|
20
20
|
ParserToken = Struct.new(:line, :file, :value)
|
21
21
|
|
@@ -45,6 +45,11 @@ module_eval <<'..end json_parser.y modeval..ide42306a0dd', 'json_parser.y', 38
|
|
45
45
|
sval = $1
|
46
46
|
sval.gsub!('\\\\','\\')
|
47
47
|
sval.gsub!('\\"','"')
|
48
|
+
sval.gsub!('\\n',"\n")
|
49
|
+
sval.gsub!('\\r',"\r")
|
50
|
+
sval.gsub!('\\t',"\t")
|
51
|
+
sval.gsub!('\\f',"\f")
|
52
|
+
sval.gsub!('\\b',"\b")
|
48
53
|
@q << [:STRING, ParserToken.new(line, file, sval)]
|
49
54
|
when /\A(\{|\}|\[|\]|,|:|true|false)/
|
50
55
|
str = $'
|
@@ -62,7 +67,7 @@ module_eval <<'..end json_parser.y modeval..ide42306a0dd', 'json_parser.y', 38
|
|
62
67
|
r
|
63
68
|
end
|
64
69
|
|
65
|
-
..end json_parser.y modeval..
|
70
|
+
..end json_parser.y modeval..id3d5fb611e2
|
66
71
|
|
67
72
|
##### racc 1.4.5 generates ###
|
68
73
|
|
@@ -64,6 +64,11 @@ module Instantiator
|
|
64
64
|
sval = $1
|
65
65
|
sval.gsub!('\\\\','\\')
|
66
66
|
sval.gsub!('\\"','"')
|
67
|
+
sval.gsub!('\\n',"\n")
|
68
|
+
sval.gsub!('\\r',"\r")
|
69
|
+
sval.gsub!('\\t',"\t")
|
70
|
+
sval.gsub!('\\f',"\f")
|
71
|
+
sval.gsub!('\\b',"\b")
|
67
72
|
@q << [:STRING, ParserToken.new(line, file, sval)]
|
68
73
|
when /\A(\{|\}|\[|\]|,|:|true|false)/
|
69
74
|
str = $'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module RGen
|
2
|
+
|
3
|
+
module MetamodelBuilder
|
4
|
+
|
5
|
+
# The purpose of the ConstantOrderHelper is to capture the definition order of RGen metamodel builder
|
6
|
+
# classes, modules and enums. The problem is that Ruby doesn't seem to track the order of
|
7
|
+
# constants being created in a module. However the order is important because it defines the order
|
8
|
+
# of eClassifiers and eSubpackages in a EPackage.
|
9
|
+
#
|
10
|
+
# It would be helpful here if Ruby provided a +const_added+ callback, but this is not the case up to now.
|
11
|
+
#
|
12
|
+
# The idea for capturing is that all events of creating a RGen class, module or enum are reported to the
|
13
|
+
# ConstantOrderHelper singleton.
|
14
|
+
# For classes and modules it tries to add their names to the parent's +_constantOrder+ array.
|
15
|
+
# The parent module is derived from the class's or module's name. However, the new name is only added
|
16
|
+
# if the respective parent module has a new constant (which is not yet in +_constantOrder+) which
|
17
|
+
# points to the new class or module.
|
18
|
+
# For enums it is a bit more complicated, because at the time the enum is created, the parent
|
19
|
+
# module does not yet contain the constant to which the enum is assigned. Therefor, the enum is remembered
|
20
|
+
# and it is tried to be stored on the next event (class, module or enum) within the module which was
|
21
|
+
# created last (which was last extended with ModuleExtension). If it can not be found in that module,
|
22
|
+
# all parent modules of the last module are searched. This way it should also be correctly entered in
|
23
|
+
# case it was defined outside of the last created module.
|
24
|
+
# Note that an enum is not stored to the constant order array unless another event occurs. That's why
|
25
|
+
# it is possible that one enum is missing at the enum. This needs to be taken care of by the ECore transformer.
|
26
|
+
#
|
27
|
+
# This way of capturing should be sufficient for the regular use cases of the RGen metamodel builder language.
|
28
|
+
# However, it is possible to write code which messes this up, see unit tests for details.
|
29
|
+
# In the worst case, the new classes, modules or enums will just not be found in a parent module and thus be ignored.
|
30
|
+
#
|
31
|
+
ConstantOrderHelper = Class.new do
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@currentModule = nil
|
35
|
+
@pendingEnum = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def classCreated(c)
|
39
|
+
handlePendingEnum
|
40
|
+
cont = containerModule(c)
|
41
|
+
name = c.name.split("::").last
|
42
|
+
return unless cont.respond_to?(:_constantOrder) && !cont._constantOrder.include?(name)
|
43
|
+
cont._constantOrder << name
|
44
|
+
end
|
45
|
+
|
46
|
+
def moduleCreated(m)
|
47
|
+
handlePendingEnum
|
48
|
+
cont = containerModule(m)
|
49
|
+
name = m.name.split("::").last
|
50
|
+
return unless cont.respond_to?(:_constantOrder) && !cont._constantOrder.include?(name)
|
51
|
+
cont._constantOrder << name
|
52
|
+
@currentModule = m
|
53
|
+
end
|
54
|
+
|
55
|
+
def enumCreated(e)
|
56
|
+
handlePendingEnum
|
57
|
+
@pendingEnum = e
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def containerModule(m)
|
63
|
+
containerName = m.name.split("::")[0..-2].join("::")
|
64
|
+
containerName.empty? ? nil : eval(containerName, TOPLEVEL_BINDING)
|
65
|
+
end
|
66
|
+
|
67
|
+
def handlePendingEnum
|
68
|
+
return unless @pendingEnum
|
69
|
+
m = @currentModule
|
70
|
+
while m
|
71
|
+
if m.respond_to?(:_constantOrder)
|
72
|
+
newConstants = m.constants - m._constantOrder
|
73
|
+
const = newConstants.find{|c| m.const_get(c).object_id == @pendingEnum.object_id}
|
74
|
+
if const
|
75
|
+
m._constantOrder << const
|
76
|
+
break
|
77
|
+
end
|
78
|
+
end
|
79
|
+
m = containerModule(m)
|
80
|
+
end
|
81
|
+
@pendingEnum = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
end.new
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
@@ -21,6 +21,7 @@ module DataTypes
|
|
21
21
|
|
22
22
|
# Creates a new named enum type object consisting of the elements passed as arguments.
|
23
23
|
def initialize(params)
|
24
|
+
MetamodelBuilder::ConstantOrderHelper.enumCreated(self)
|
24
25
|
if params.is_a?(Array)
|
25
26
|
@literals = params
|
26
27
|
@name = "anonymous"
|
@@ -64,4 +65,4 @@ end
|
|
64
65
|
|
65
66
|
end
|
66
67
|
|
67
|
-
end
|
68
|
+
end
|
@@ -17,6 +17,10 @@ module ModuleExtension
|
|
17
17
|
def _annotations
|
18
18
|
@_annotations ||= []
|
19
19
|
end
|
20
|
+
|
21
|
+
def _constantOrder
|
22
|
+
@_constantOrder ||= []
|
23
|
+
end
|
20
24
|
|
21
25
|
def final_method(m)
|
22
26
|
@final_methods ||= []
|
@@ -26,8 +30,13 @@ module ModuleExtension
|
|
26
30
|
def method_added(m)
|
27
31
|
raise "Method #{m} can not be redefined" if @final_methods && @final_methods.include?(m)
|
28
32
|
end
|
33
|
+
|
34
|
+
def self.extended(m)
|
35
|
+
MetamodelBuilder::ConstantOrderHelper.moduleCreated(m)
|
36
|
+
end
|
37
|
+
|
29
38
|
end
|
30
39
|
|
31
40
|
end
|
32
41
|
|
33
|
-
end
|
42
|
+
end
|
@@ -101,7 +101,8 @@ class JsonSerializer
|
|
101
101
|
|
102
102
|
def attributeValue(value, a)
|
103
103
|
if a.eType == RGen::ECore::EString || a.eType.is_a?(RGen::ECore::EEnum)
|
104
|
-
"\""+value.to_s.gsub('
|
104
|
+
"\""+value.to_s.gsub('\\','\\\\\\\\').gsub('"','\\"').gsub("\n","\\n").gsub("\r","\\r").
|
105
|
+
gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")+"\""
|
105
106
|
else
|
106
107
|
value.to_s
|
107
108
|
end
|
data/test/json_test.rb
CHANGED
@@ -46,18 +46,26 @@ class JsonTest < Test::Unit::TestCase
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_json_serializer_escapes
|
49
|
-
testModel = TestMM::TestNode.new(:text => %
|
49
|
+
testModel = TestMM::TestNode.new(:text => %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f))
|
50
50
|
output = StringWriter.new
|
51
51
|
ser = RGen::Serializer::JsonSerializer.new(output)
|
52
52
|
|
53
|
-
assert_equal %q({ "_class": "TestNode", "text": "some \"
|
53
|
+
assert_equal %q({ "_class": "TestNode", "text": "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f" }),
|
54
|
+
ser.serialize(testModel)
|
54
55
|
end
|
55
56
|
|
56
57
|
def test_json_instantiator_escapes
|
57
58
|
env = RGen::Environment.new
|
58
59
|
inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
|
59
|
-
inst.instantiate(%q({ "_class": "TestNode", "text": "some \"
|
60
|
-
assert_equal %
|
60
|
+
inst.instantiate(%q({ "_class": "TestNode", "text": "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f" }))
|
61
|
+
assert_equal %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f), env.elements.first.text
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_json_instantiator_escape_single_backslash
|
65
|
+
env = RGen::Environment.new
|
66
|
+
inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
|
67
|
+
inst.instantiate(%q({ "_class": "TestNode", "text": "a single \\ will be just itself" }))
|
68
|
+
assert_equal %q(a single \\ will be just itself), env.elements.first.text
|
61
69
|
end
|
62
70
|
|
63
71
|
def test_json_serializer_integer
|
@@ -0,0 +1,125 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rgen/ecore/ecore'
|
5
|
+
require 'rgen/array_extensions'
|
6
|
+
|
7
|
+
class MetamodelReflectionTest < Test::Unit::TestCase
|
8
|
+
include RGen::ECore
|
9
|
+
|
10
|
+
module TestMM1
|
11
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
12
|
+
|
13
|
+
class Class11 < RGen::MetamodelBuilder::MMBase
|
14
|
+
end
|
15
|
+
|
16
|
+
module Module11
|
17
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
18
|
+
|
19
|
+
DataType111 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType111" ,:literals => {:b => 1})
|
20
|
+
DataType112 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType112", :literals => {:b => 1})
|
21
|
+
|
22
|
+
class Class111 < RGen::MetamodelBuilder::MMBase
|
23
|
+
end
|
24
|
+
|
25
|
+
# anonymous classes won't be handled by the order helper, but will be in eClassifiers
|
26
|
+
Class112 = Class.new(RGen::MetamodelBuilder::MMBase)
|
27
|
+
|
28
|
+
# classes that are not MMBase won't be handled
|
29
|
+
class Class113
|
30
|
+
end
|
31
|
+
|
32
|
+
# modules that are not extended by the ModuleExtension are not handled
|
33
|
+
module Module111
|
34
|
+
end
|
35
|
+
|
36
|
+
# however it can be extendend later on
|
37
|
+
module Module112
|
38
|
+
# this one is not handled by the order helper since Module112 doesn't have the ModuleExtension yet
|
39
|
+
# however, it will be in eClassifiers
|
40
|
+
class Class1121 < RGen::MetamodelBuilder::MMBase
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# this datatype must be in Module11 not Module112
|
44
|
+
DataType113 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType113", :literals => {:b => 1})
|
45
|
+
|
46
|
+
Module112.extend(RGen::MetamodelBuilder::ModuleExtension)
|
47
|
+
# this datatype must be in Module11 not Module112
|
48
|
+
DataType114 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType114", :literals => {:b => 1})
|
49
|
+
module Module112
|
50
|
+
# this one is handled because now Module112 is extended
|
51
|
+
class Class1122 < RGen::MetamodelBuilder::MMBase
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
DataType115 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType115", :literals => {:b => 1})
|
56
|
+
DataType116 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType116", :literals => {:b => 1})
|
57
|
+
end
|
58
|
+
|
59
|
+
DataType11 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType11", :literals => {:a => 1})
|
60
|
+
|
61
|
+
class Class12 < RGen::MetamodelBuilder::MMBase
|
62
|
+
end
|
63
|
+
|
64
|
+
class Class13 < RGen::MetamodelBuilder::MMBase
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# datatypes outside of a module won't be handled
|
69
|
+
DataType1 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType1", :literals => {:b => 1})
|
70
|
+
|
71
|
+
# classes outside of a module won't be handled
|
72
|
+
class Class1 < RGen::MetamodelBuilder::MMBase
|
73
|
+
end
|
74
|
+
|
75
|
+
module TestMM2
|
76
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
77
|
+
|
78
|
+
TestMM1::Module11.extend(RGen::MetamodelBuilder::ModuleExtension)
|
79
|
+
# this is a critical case: because of the previous extension of Module11 which is in a different
|
80
|
+
# hierarchy, DataType7 is looked for in Module11 and its parents; finally it is not
|
81
|
+
# found and the definition is ignored for order calculation
|
82
|
+
DataType21 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType21", :literals => {:b => 1})
|
83
|
+
|
84
|
+
module Module21
|
85
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
86
|
+
end
|
87
|
+
|
88
|
+
module Module22
|
89
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
90
|
+
end
|
91
|
+
|
92
|
+
module Module23
|
93
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
94
|
+
end
|
95
|
+
|
96
|
+
# if there is no other class or module after the last datatype, it won't show up in _constantOrder
|
97
|
+
# however, the order of eClassifiers can still be reconstructed
|
98
|
+
DataType22 = RGen::MetamodelBuilder::DataTypes::Enum.new(:name => "DataType22", :literals => {:b => 1})
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_constant_order
|
102
|
+
assert_equal ["Class11", "Module11", "DataType11", "Class12", "Class13"], TestMM1._constantOrder
|
103
|
+
assert_equal ["DataType111", "DataType112", "Class111", "DataType113", "Module112", "DataType114", "DataType115", "DataType116"], TestMM1::Module11._constantOrder
|
104
|
+
assert_equal ["Class1122"], TestMM1::Module11::Module112._constantOrder
|
105
|
+
assert_equal ["Module21", "Module22", "Module23"], TestMM2._constantOrder
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_classifier_order
|
109
|
+
# eClassifiers also contains the ones which where ignored in order calculation, these are expected at the end
|
110
|
+
# (in an arbitrary order)
|
111
|
+
assert_equal ["Class11", "DataType11", "Class12", "Class13"], TestMM1.ecore.eClassifiers.name
|
112
|
+
assert_equal ["DataType111", "DataType112", "Class111", "DataType113", "DataType114", "DataType115", "DataType116", "Class112"], TestMM1::Module11.ecore.eClassifiers.name
|
113
|
+
assert_equal ["Class1122", "Class1121"], TestMM1::Module11::Module112.ecore.eClassifiers.name
|
114
|
+
assert_equal ["DataType22", "DataType21"], TestMM2.ecore.eClassifiers.name
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_subpackage_order
|
118
|
+
assert_equal ["Module11"], TestMM1.ecore.eSubpackages.name
|
119
|
+
assert_equal ["Module112"], TestMM1::Module11.ecore.eSubpackages.name
|
120
|
+
assert_equal [], TestMM1::Module11::Module112.ecore.eSubpackages.name
|
121
|
+
assert_equal ["Module21", "Module22", "Module23"], TestMM2.ecore.eSubpackages.name
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
@@ -6,55 +6,60 @@ module HouseMetamodel
|
|
6
6
|
|
7
7
|
SexEnum = Enum.new(:name => 'SexEnum', :literals =>[ :male, :female ])
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
class MeetingPlace < RGen::MetamodelBuilder::MMBase
|
10
|
+
annotation :source => "testmodel", :details => {'complexity' => '1', 'date_created' => '2006-07-12 08:40:46', 'date_modified' => '2006-07-12 08:44:02', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'}
|
11
|
+
end
|
12
12
|
|
13
|
+
class Person < RGen::MetamodelBuilder::MMBase
|
14
|
+
annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:34:23', 'date_modified' => '2006-06-27 08:34:26', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
15
|
+
has_attr 'sex', HouseMetamodel::SexEnum
|
16
|
+
has_many_attr 'nicknames', String
|
13
17
|
end
|
14
18
|
|
15
|
-
|
19
|
+
class House < RGen::MetamodelBuilder::MMBase
|
20
|
+
annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:18', 'date_modified' => '2006-02-28 08:29:19', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'stereotype' => 'dummy', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
21
|
+
has_attr 'size', Integer
|
22
|
+
has_attr 'module', String
|
23
|
+
has_attr 'address', String, :changeable => false do
|
24
|
+
annotation 'collection' => 'false', 'containment' => 'Not Specified', 'derived' => '0', 'duplicates' => '0', 'ea_guid' => '{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068}', 'lowerBound' => '1', 'ordered' => '0', 'position' => '0', 'styleex' => 'volatile=0;', 'type' => 'String', 'upperBound' => '1'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
module Rooms
|
16
30
|
extend RGen::MetamodelBuilder::ModuleExtension
|
17
31
|
include RGen::MetamodelBuilder::DataTypes
|
18
32
|
|
19
|
-
end
|
20
|
-
end
|
21
33
|
|
22
|
-
class
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
has_attr 'address', String, :changeable => false do
|
27
|
-
annotation 'collection' => 'false', 'containment' => 'Not Specified', 'derived' => '0', 'duplicates' => '0', 'ea_guid' => '{A8DF581B-9AC6-4f75-AB48-8FAEDFC6E068}', 'lowerBound' => '1', 'ordered' => '0', 'position' => '0', 'styleex' => 'volatile=0;', 'type' => 'String', 'upperBound' => '1'
|
28
|
-
end
|
29
|
-
end
|
34
|
+
class Room < RGen::MetamodelBuilder::MMBase
|
35
|
+
abstract
|
36
|
+
annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:28', 'date_modified' => '2006-06-22 21:15:25', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
37
|
+
end
|
30
38
|
|
31
|
-
class
|
32
|
-
|
33
|
-
|
34
|
-
has_many_attr 'nicknames', String
|
35
|
-
end
|
39
|
+
class Bathroom < Room
|
40
|
+
annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:32:25', 'date_modified' => '2006-06-27 08:34:23', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
41
|
+
end
|
36
42
|
|
37
|
-
class
|
38
|
-
|
39
|
-
end
|
43
|
+
class Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, Room)
|
44
|
+
annotation 'complexity' => '1', 'date_created' => '2005-11-30 19:26:13', 'date_modified' => '2006-06-22 21:15:34', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
45
|
+
end
|
40
46
|
|
41
|
-
|
42
|
-
abstract
|
43
|
-
annotation 'complexity' => '1', 'date_created' => '2005-09-16 19:52:28', 'date_modified' => '2006-06-22 21:15:25', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
44
|
-
end
|
47
|
+
end
|
45
48
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
module DependingOnRooms
|
50
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
51
|
+
include RGen::MetamodelBuilder::DataTypes
|
49
52
|
|
50
|
-
class HouseMetamodel::Rooms::Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, HouseMetamodel::Rooms::Room)
|
51
|
-
annotation 'complexity' => '1', 'date_created' => '2005-11-30 19:26:13', 'date_modified' => '2006-06-22 21:15:34', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_F9D8C6E3_4DAD_4aa2_AD47_D0ABA4E93E08', 'package_name' => 'Rooms', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
|
52
|
-
end
|
53
53
|
|
54
|
-
class
|
55
|
-
end
|
54
|
+
class RoomSub < HouseMetamodel::Rooms::Room
|
55
|
+
end
|
56
56
|
|
57
|
+
end
|
58
|
+
end
|
57
59
|
|
60
|
+
HouseMetamodel::Person.has_many 'home', HouseMetamodel::House do
|
61
|
+
annotation 'containment' => 'Unspecified'
|
62
|
+
end
|
58
63
|
HouseMetamodel::House.has_one 'bathroom', HouseMetamodel::Rooms::Bathroom, :transient => true, :lowerBound => 1
|
59
64
|
HouseMetamodel::House.one_to_one 'kitchen', HouseMetamodel::Rooms::Kitchen, 'house', :lowerBound => 1, :opposite_lowerBound => 1 do
|
60
65
|
annotation 'containment' => 'Unspecified'
|
@@ -63,6 +68,3 @@ end
|
|
63
68
|
HouseMetamodel::House.contains_many 'room', HouseMetamodel::Rooms::Room, 'house', :lowerBound => 1 do
|
64
69
|
opposite_annotation 'containment' => 'Unspecified'
|
65
70
|
end
|
66
|
-
HouseMetamodel::Person.has_many 'home', HouseMetamodel::House do
|
67
|
-
annotation 'containment' => 'Unspecified'
|
68
|
-
end
|