rgen 0.4.0 → 0.4.1
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 +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"
|