rgen 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/lib/instantiators/ea_instantiator.rb +5 -2
- data/lib/metamodels/uml13_metamodel.rb +10 -10
- data/lib/mmgen/templates/annotations.tpl +1 -1
- data/lib/mmgen/templates/metamodel_generator.tpl +1 -1
- data/lib/rgen/ecore/ecore.rb +2 -2
- data/lib/rgen/ecore/ecore_instantiator.rb +4 -2
- data/lib/rgen/ecore/ecore_transformer.rb +6 -1
- data/lib/rgen/environment.rb +5 -0
- data/lib/rgen/environment.rb.bak +42 -0
- data/lib/rgen/instantiator/abstract_xml_instantiator.rb +40 -5
- data/lib/rgen/instantiator/ecore_xml_instantiator.rb +1 -1
- data/lib/rgen/instantiator/xmi11_instantiator.rb +1 -1
- data/lib/rgen/metamodel_builder/builder_extensions.rb +57 -39
- data/lib/rgen/serializer/xmi20_serializer.rb +60 -0
- data/lib/rgen/serializer/xml_serializer.rb +61 -0
- data/lib/rgen/template_language/output_handler.rb +15 -27
- data/lib/rgen/template_language/template_container.rb +1 -1
- data/lib/rgen/transformer.rb +50 -8
- data/test/metamodel_builder_test.rb +22 -0
- data/test/metamodel_roundtrip_test.rb +10 -0
- data/test/metamodel_roundtrip_test/TestModel.rb +2 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +10 -8
- data/test/metamodel_roundtrip_test/houseMetamodel.ecore +8 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +268 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +8 -5
- data/test/output_handler_test.rb +10 -0
- data/test/transformer_test.rb +13 -1
- metadata +7 -3
- data/lib/rgen/metamodel_builder/build_helper.rb +0 -51
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rgen/serializer/xml_serializer'
|
2
|
+
|
3
|
+
module RGen
|
4
|
+
|
5
|
+
module Serializer
|
6
|
+
|
7
|
+
class XMI20Serializer < XMLSerializer
|
8
|
+
|
9
|
+
def serialize(rootElement)
|
10
|
+
buildReferenceStrings(rootElement, "#/")
|
11
|
+
attrs = attributeHash(rootElement)
|
12
|
+
attrs['xmi:version'] = "2.0"
|
13
|
+
attrs['xmlns:xmi'] = "http://www.omg.org/XMI"
|
14
|
+
attrs['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
|
15
|
+
attrs['xmlns:ecore'] = "http://www.eclipse.org/emf/2002/Ecore"
|
16
|
+
tag = "ecore:"+rootElement.class.ecore.name
|
17
|
+
startTag(tag, attrs, 0)
|
18
|
+
writeComposites(rootElement, 1)
|
19
|
+
endTag(tag, 0)
|
20
|
+
end
|
21
|
+
|
22
|
+
def writeComposites(element, indent)
|
23
|
+
eachReferencedElement(element, containmentReferences(element)) do |r,te|
|
24
|
+
attrs = attributeHash(te)
|
25
|
+
attrs['xsi:type'] = "ecore:"+te.class.ecore.name
|
26
|
+
tag = r.name
|
27
|
+
startTag(tag, attrs, indent)
|
28
|
+
writeComposites(te, indent+1)
|
29
|
+
endTag(tag, indent)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def attributeHash(element)
|
34
|
+
result = {}
|
35
|
+
eAllAttributes(element).select{|a| !a.derived}.each do |a|
|
36
|
+
val = element.getGeneric(a.name)
|
37
|
+
result[a.name] = val unless val.nil? || val == ""
|
38
|
+
end
|
39
|
+
eAllReferences(element).select{|r| !r.containment && !r.derived}.each do |r|
|
40
|
+
targetElements = element.getGeneric(r.name)
|
41
|
+
targetElements = [targetElements] unless targetElements.is_a?(Array)
|
42
|
+
val = targetElements.collect{|te| @referenceStrings[te]}.compact.join(' ')
|
43
|
+
result[r.name] = val unless val.nil? || val == ""
|
44
|
+
end
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def buildReferenceStrings(element, string)
|
49
|
+
@referenceStrings ||= {}
|
50
|
+
@referenceStrings[element] = string
|
51
|
+
eachReferencedElement(element, containmentReferences(element)) do |r,te|
|
52
|
+
buildReferenceStrings(te, string+"/"+te.name) if te.respond_to?(:name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RGen
|
2
|
+
|
3
|
+
module Serializer
|
4
|
+
|
5
|
+
class XMLSerializer
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@output = ""
|
9
|
+
end
|
10
|
+
|
11
|
+
def result
|
12
|
+
@output
|
13
|
+
end
|
14
|
+
|
15
|
+
def serialize(rootElement)
|
16
|
+
raise "Abstract class, overwrite method in subclass!"
|
17
|
+
end
|
18
|
+
|
19
|
+
def startTag(tag, attributes, indent)
|
20
|
+
@output += " "*indent + "<#{tag} " + attributes.keys.collect{|k| "#{k}=\"#{attributes[k]}\""}.join(" ") + ">\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
def endTag(tag, indent)
|
24
|
+
@output += " "*indent + "</#{tag}>\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def eAllReferences(element)
|
30
|
+
@eAllReferences ||= {}
|
31
|
+
@eAllReferences[element.class] ||= element.class.ecore.eAllReferences
|
32
|
+
end
|
33
|
+
|
34
|
+
def eAllAttributes(element)
|
35
|
+
@eAllAttributes ||= {}
|
36
|
+
@eAllAttributes[element.class] ||= element.class.ecore.eAllAttributes
|
37
|
+
end
|
38
|
+
|
39
|
+
def eAllStructuralFeatures(element)
|
40
|
+
@eAllStructuralFeatures ||= {}
|
41
|
+
@eAllStructuralFeatures[element.class] ||= element.class.ecore.eAllStructuralFeatures
|
42
|
+
end
|
43
|
+
|
44
|
+
def eachReferencedElement(element, refs, &block)
|
45
|
+
refs.each do |r|
|
46
|
+
targetElements = element.getGeneric(r.name)
|
47
|
+
targetElements = [targetElements] unless targetElements.is_a?(Array)
|
48
|
+
targetElements.each do |te|
|
49
|
+
yield(r,te)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def containmentReferences(element)
|
55
|
+
eAllReferences(element).select{|r| r.containment}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -28,40 +28,28 @@ module TemplateLanguage
|
|
28
28
|
@output.concat(s)
|
29
29
|
elsif @mode == :explicit
|
30
30
|
while s.size > 0
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# ws contains a newline
|
38
|
-
if ws =~ /\A[\t ]*(\r?\n)(\s*)/m
|
39
|
-
@output.concat($1)
|
40
|
-
@state = :wait_for_nonws
|
41
|
-
s = $2 + rest
|
42
|
-
else
|
43
|
-
@output.concat(ws)
|
44
|
-
s = rest
|
45
|
-
end
|
31
|
+
if @state == :wait_for_nl
|
32
|
+
if s =~ /\A([^\r\n]*\r?\n)(.*)/m
|
33
|
+
rest = $2
|
34
|
+
@output.concat($1.gsub(/[\t ]+(?=\r|\n)/,''))
|
35
|
+
s = rest || ""
|
36
|
+
@state = :wait_for_nonws
|
46
37
|
else
|
47
|
-
s
|
38
|
+
@output.concat(s)
|
39
|
+
s = ""
|
48
40
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if @state == :wait_for_nonws
|
54
|
-
# within the same output handle we can recognize a newline by ourselves
|
55
|
-
# but if the output handler is changed, someone has to tell us
|
56
|
-
if !@noIndentNextLine && !(@output =~ /[^\n]\z/)
|
41
|
+
elsif @state == :wait_for_nonws
|
42
|
+
if s =~ /\A\s*(\S+.*)/m
|
43
|
+
s = $1 || ""
|
44
|
+
if !@noIndentNextLine && !(@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0])
|
57
45
|
@output.concat(" "*@indent)
|
58
46
|
else
|
59
47
|
@noIndentNextLine = false
|
60
48
|
end
|
49
|
+
@state = :wait_for_nl
|
50
|
+
else
|
51
|
+
s = ""
|
61
52
|
end
|
62
|
-
@output.concat(nonws)
|
63
|
-
@state = :wait_for_nl
|
64
|
-
s = rest
|
65
53
|
end
|
66
54
|
end
|
67
55
|
end
|
@@ -130,7 +130,7 @@ module RGen
|
|
130
130
|
@indent = params[:indent] || @indent
|
131
131
|
# if this is the first call to expand within this container, @output is nil
|
132
132
|
noIndentNextLine = params[:noIndentNextLine]
|
133
|
-
noIndentNextLine = (@output.to_s
|
133
|
+
noIndentNextLine = (@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0]) if noIndentNextLine.nil?
|
134
134
|
old_context, @context = @context, context if context
|
135
135
|
local_output = nil
|
136
136
|
if template =~ LOCAL_TEMPLATE_REGEX
|
data/lib/rgen/transformer.rb
CHANGED
@@ -13,6 +13,10 @@ module RGen
|
|
13
13
|
# Within the subclass, the Transformer.transform class method can be used to specify transformation
|
14
14
|
# blocks for specific metamodel classes of the source metamodel.
|
15
15
|
#
|
16
|
+
# If there is no transformation rule for the current object's class, a rule for the superclass
|
17
|
+
# is used instead. If there's no rule for the superclass, the class hierarchy is searched
|
18
|
+
# this way until Object.
|
19
|
+
#
|
16
20
|
# Here is an example:
|
17
21
|
#
|
18
22
|
# class MyTransformer < RGen::Transformer
|
@@ -30,7 +34,7 @@ module RGen
|
|
30
34
|
# as well as for elements of class OtherInputClass. The former is to be transformed into
|
31
35
|
# an instance of OutputClass, the latter into an instance of OtherOutputClass.
|
32
36
|
# Note that the Ruby class objects are used to specifiy the classes.
|
33
|
-
#
|
37
|
+
#
|
34
38
|
# =Transforming Attributes
|
35
39
|
#
|
36
40
|
# Besides the target class of a transformation, the attributes of the result object are
|
@@ -98,7 +102,7 @@ module RGen
|
|
98
102
|
#
|
99
103
|
# Here is an example:
|
100
104
|
#
|
101
|
-
#
|
105
|
+
# transform ModelIn, :to => ModelOut do
|
102
106
|
# { :number => doubleNumber }
|
103
107
|
# end
|
104
108
|
#
|
@@ -128,6 +132,9 @@ module RGen
|
|
128
132
|
# value is true, the corresponding block is used for transformation. If more than one
|
129
133
|
# conditions are true, only the first transformer block will be evaluated.
|
130
134
|
#
|
135
|
+
# If there is no rule with a condition evaluating to true, rules for superclasses will
|
136
|
+
# be checked as described above.
|
137
|
+
#
|
131
138
|
# Here is an example:
|
132
139
|
#
|
133
140
|
# transform ModelIn, :to => ModelOut, :if => :largeNumber do
|
@@ -225,6 +232,7 @@ class Transformer
|
|
225
232
|
@env_in = env_in
|
226
233
|
@env_out = env_out
|
227
234
|
@transformer_results = {}
|
235
|
+
@transformer_jobs = []
|
228
236
|
end
|
229
237
|
|
230
238
|
|
@@ -235,7 +243,7 @@ class Transformer
|
|
235
243
|
# In addition, the result is cached, i.e. a second invocation with the same parameter
|
236
244
|
# object will return the same result object without any further evaluation of the
|
237
245
|
# transformation rules. Nil will be transformed into nil. Ruby "singleton" objects
|
238
|
-
# +true+, +false+, numerics and symbols will be
|
246
|
+
# +true+, +false+, numerics and symbols will be returned without any change. Ruby strings
|
239
247
|
# will be duplicated with the result being cached.
|
240
248
|
#
|
241
249
|
# The transformation input can be given as:
|
@@ -253,16 +261,41 @@ class Transformer
|
|
253
261
|
return @transformer_results[obj] if @transformer_results[obj]
|
254
262
|
return @transformer_results[obj] = obj.dup if obj.is_a?(String)
|
255
263
|
return obj.collect{|o| trans(o)}.compact if obj.is_a? Array
|
256
|
-
raise StandardError.new("No transformer for class #{obj.class.name}") unless
|
264
|
+
raise StandardError.new("No transformer for class #{obj.class.name}") unless _transformerBlock(obj.class)
|
257
265
|
block_desc = _evaluateCondition(obj)
|
258
266
|
return nil unless block_desc
|
259
267
|
@transformer_results[obj] = _instantiateTargetClass(obj, block_desc.target)
|
268
|
+
# we will transform the properties later
|
269
|
+
@transformer_jobs << TransformerJob.new(self, obj, block_desc)
|
270
|
+
# if there have been jobs in the queue before, don't process them in this call
|
271
|
+
# this way calls to trans are not nested; a recursive implementation
|
272
|
+
# may cause a "Stack level too deep" exception for large models
|
273
|
+
return @transformer_results[obj] if @transformer_jobs.size > 1
|
274
|
+
# otherwise this is the first call of trans, process all jobs here
|
275
|
+
# more jobs will be added during job execution
|
276
|
+
while @transformer_jobs.size > 0
|
277
|
+
@transformer_jobs.first.execute
|
278
|
+
@transformer_jobs.shift
|
279
|
+
end
|
280
|
+
@transformer_results[obj]
|
281
|
+
end
|
282
|
+
|
283
|
+
def _transformProperties(obj, block_desc) #:nodoc:
|
260
284
|
old_object, @current_object = @current_object, obj
|
261
285
|
block_result = instance_eval(&block_desc.block)
|
262
286
|
raise StandardError.new("Transformer must return a hash") unless block_result.is_a? Hash
|
263
287
|
@current_object = old_object
|
264
288
|
_attributesFromHash(@transformer_results[obj], block_result)
|
265
289
|
end
|
290
|
+
|
291
|
+
class TransformerJob #:nodoc:
|
292
|
+
def initialize(transformer, obj, block_desc)
|
293
|
+
@transformer, @obj, @block_desc = transformer, obj, block_desc
|
294
|
+
end
|
295
|
+
def execute
|
296
|
+
@transformer._transformProperties(@obj, @block_desc)
|
297
|
+
end
|
298
|
+
end
|
266
299
|
|
267
300
|
# Each call which is not handled by the transformer object is passed to the object
|
268
301
|
# currently being transformed.
|
@@ -278,15 +311,23 @@ class Transformer
|
|
278
311
|
end
|
279
312
|
|
280
313
|
private
|
314
|
+
|
315
|
+
# returns _transformer_blocks content for clazz or one of its superclasses
|
316
|
+
def _transformerBlock(clazz) # :nodoc:
|
317
|
+
block = self.class._transformer_blocks[clazz]
|
318
|
+
block = _transformerBlock(clazz.superclass) if block.nil? && clazz != Object
|
319
|
+
block
|
320
|
+
end
|
281
321
|
|
282
|
-
# returns the first TransformationDescription for
|
283
|
-
|
284
|
-
|
322
|
+
# returns the first TransformationDescription for clazz or one of its superclasses
|
323
|
+
# for which condition is true
|
324
|
+
def _evaluateCondition(obj, clazz=obj.class) # :nodoc:
|
325
|
+
tb = self.class._transformer_blocks[clazz]
|
285
326
|
block_description = nil
|
286
327
|
if tb.is_a?(TransformationDescription)
|
287
328
|
# non-conditional
|
288
329
|
block_description = tb
|
289
|
-
|
330
|
+
elsif tb
|
290
331
|
old_object, @current_object = @current_object, obj
|
291
332
|
tb.each_pair {|condition, block|
|
292
333
|
if condition.is_a?(Proc)
|
@@ -303,6 +344,7 @@ class Transformer
|
|
303
344
|
}
|
304
345
|
@current_object = old_object
|
305
346
|
end
|
347
|
+
block_description = _evaluateCondition(obj, clazz.superclass) if block_description.nil? && clazz != Object
|
306
348
|
block_description
|
307
349
|
end
|
308
350
|
|
@@ -417,4 +417,26 @@ class MetamodelBuilderTest < Test::Unit::TestCase
|
|
417
417
|
end
|
418
418
|
end
|
419
419
|
|
420
|
+
module SomePackage
|
421
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
422
|
+
|
423
|
+
class ClassA < RGen::MetamodelBuilder::MMBase
|
424
|
+
end
|
425
|
+
|
426
|
+
module SubPackage
|
427
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
428
|
+
|
429
|
+
class ClassB < RGen::MetamodelBuilder::MMBase
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_ecore_identity
|
435
|
+
subPackage = SomePackage::SubPackage.ecore
|
436
|
+
assert_equal subPackage.eClassifiers.first.object_id, SomePackage::SubPackage::ClassB.ecore.object_id
|
437
|
+
|
438
|
+
somePackage = SomePackage.ecore
|
439
|
+
assert_equal somePackage.eSubpackages.first.object_id, subPackage.object_id
|
440
|
+
end
|
441
|
+
|
420
442
|
end
|
@@ -5,6 +5,7 @@ require 'rgen/array_extensions'
|
|
5
5
|
require 'rgen/model_comparator'
|
6
6
|
require 'mmgen/metamodel_generator'
|
7
7
|
require 'rgen/instantiator/ecore_xml_instantiator'
|
8
|
+
require 'rgen/serializer/xmi20_serializer'
|
8
9
|
|
9
10
|
class MetamodelGeneratorTest < Test::Unit::TestCase
|
10
11
|
|
@@ -49,4 +50,13 @@ class MetamodelGeneratorTest < Test::Unit::TestCase
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
53
|
+
def test_ecore_serializer
|
54
|
+
require TEST_DIR+"/TestModel.rb"
|
55
|
+
File.open(TEST_DIR+"/houseMetamodel_Regenerated.ecore","w") do |f|
|
56
|
+
ser = RGen::Serializer::XMI20Serializer.new
|
57
|
+
ser.serialize(HouseMetamodel.ecore)
|
58
|
+
f.write(ser.result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
52
62
|
end
|
@@ -4,6 +4,7 @@ module HouseMetamodel
|
|
4
4
|
extend RGen::MetamodelBuilder::ModuleExtension
|
5
5
|
include RGen::MetamodelBuilder::DataTypes
|
6
6
|
|
7
|
+
SexEnum = Enum.new(:name => "SexEnum", :literals => [ :male, :female ])
|
7
8
|
# TODO: Datatypes
|
8
9
|
# AggregationKind = Enum.new([ :none, :aggregate, :composite ])
|
9
10
|
|
@@ -13,6 +14,7 @@ module HouseMetamodel
|
|
13
14
|
|
14
15
|
class Person < RGen::MetamodelBuilder::MMBase
|
15
16
|
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'
|
17
|
+
has_attr 'sex', SexEnum
|
16
18
|
end
|
17
19
|
|
18
20
|
class House < RGen::MetamodelBuilder::MMBase
|
@@ -4,6 +4,7 @@ module HouseMetamodel
|
|
4
4
|
extend RGen::MetamodelBuilder::ModuleExtension
|
5
5
|
include RGen::MetamodelBuilder::DataTypes
|
6
6
|
|
7
|
+
SexEnum = Enum.new(:name => 'SexEnum', :literals =>[ :male, :female ])
|
7
8
|
|
8
9
|
module Rooms
|
9
10
|
extend RGen::MetamodelBuilder::ModuleExtension
|
@@ -27,26 +28,27 @@ class HouseMetamodel::House < RGen::MetamodelBuilder::MMBase
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
class HouseMetamodel::MeetingPlace < RGen::MetamodelBuilder::MMBase
|
31
|
-
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'}
|
32
|
-
end
|
33
|
-
|
34
31
|
class HouseMetamodel::Person < RGen::MetamodelBuilder::MMBase
|
35
32
|
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'
|
33
|
+
has_attr 'sex', HouseMetamodel::SexEnum
|
36
34
|
end
|
37
35
|
|
38
|
-
class HouseMetamodel::
|
39
|
-
annotation
|
36
|
+
class HouseMetamodel::MeetingPlace < RGen::MetamodelBuilder::MMBase
|
37
|
+
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'}
|
40
38
|
end
|
41
39
|
|
42
|
-
class HouseMetamodel::Rooms::
|
43
|
-
annotation 'complexity' => '1', 'date_created' => '2005-
|
40
|
+
class HouseMetamodel::Rooms::Room < RGen::MetamodelBuilder::MMBase
|
41
|
+
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
42
|
end
|
45
43
|
|
46
44
|
class HouseMetamodel::Rooms::Bathroom < HouseMetamodel::Rooms::Room
|
47
45
|
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'
|
48
46
|
end
|
49
47
|
|
48
|
+
class HouseMetamodel::Rooms::Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, HouseMetamodel::Rooms::Room)
|
49
|
+
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'
|
50
|
+
end
|
51
|
+
|
50
52
|
class HouseMetamodel::DependingOnRooms::RoomSub < HouseMetamodel::Rooms::Room
|
51
53
|
end
|
52
54
|
|
@@ -3,6 +3,9 @@
|
|
3
3
|
xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
4
4
|
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="HouseMetamodel">
|
5
5
|
<eClassifiers xsi:type="ecore:EClass" name="House">
|
6
|
+
<eAnnotations source="bla">
|
7
|
+
<details key="a" value="b"/>
|
8
|
+
</eAnnotations>
|
6
9
|
<eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="#//String"
|
7
10
|
changeable="false"/>
|
8
11
|
<eStructuralFeatures xsi:type="ecore:EReference" name="bathroom" lowerBound="1"
|
@@ -16,8 +19,13 @@
|
|
16
19
|
<eClassifiers xsi:type="ecore:EClass" name="Person">
|
17
20
|
<eStructuralFeatures xsi:type="ecore:EReference" name="house" upperBound="-1"
|
18
21
|
eType="#//House"/>
|
22
|
+
<eStructuralFeatures xsi:type="ecore:EAttribute" name="sex" eType="#//SexEnum"/>
|
19
23
|
</eClassifiers>
|
20
24
|
<eClassifiers xsi:type="ecore:EDataType" name="String" instanceClassName="java.lang.String"/>
|
25
|
+
<eClassifiers xsi:type="ecore:EEnum" name="SexEnum">
|
26
|
+
<eLiterals name="male"/>
|
27
|
+
<eLiterals name="female"/>
|
28
|
+
</eClassifiers>
|
21
29
|
<eSubpackages name="Rooms">
|
22
30
|
<eClassifiers xsi:type="ecore:EClass" name="Room">
|
23
31
|
<eStructuralFeatures xsi:type="ecore:EReference" name="house" eType="#//House"
|