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.
Files changed (30) hide show
  1. data/CHANGELOG +15 -0
  2. data/lib/instantiators/ea_instantiator.rb +5 -2
  3. data/lib/metamodels/uml13_metamodel.rb +10 -10
  4. data/lib/mmgen/templates/annotations.tpl +1 -1
  5. data/lib/mmgen/templates/metamodel_generator.tpl +1 -1
  6. data/lib/rgen/ecore/ecore.rb +2 -2
  7. data/lib/rgen/ecore/ecore_instantiator.rb +4 -2
  8. data/lib/rgen/ecore/ecore_transformer.rb +6 -1
  9. data/lib/rgen/environment.rb +5 -0
  10. data/lib/rgen/environment.rb.bak +42 -0
  11. data/lib/rgen/instantiator/abstract_xml_instantiator.rb +40 -5
  12. data/lib/rgen/instantiator/ecore_xml_instantiator.rb +1 -1
  13. data/lib/rgen/instantiator/xmi11_instantiator.rb +1 -1
  14. data/lib/rgen/metamodel_builder/builder_extensions.rb +57 -39
  15. data/lib/rgen/serializer/xmi20_serializer.rb +60 -0
  16. data/lib/rgen/serializer/xml_serializer.rb +61 -0
  17. data/lib/rgen/template_language/output_handler.rb +15 -27
  18. data/lib/rgen/template_language/template_container.rb +1 -1
  19. data/lib/rgen/transformer.rb +50 -8
  20. data/test/metamodel_builder_test.rb +22 -0
  21. data/test/metamodel_roundtrip_test.rb +10 -0
  22. data/test/metamodel_roundtrip_test/TestModel.rb +2 -0
  23. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +10 -8
  24. data/test/metamodel_roundtrip_test/houseMetamodel.ecore +8 -0
  25. data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +268 -0
  26. data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +8 -5
  27. data/test/output_handler_test.rb +10 -0
  28. data/test/transformer_test.rb +13 -1
  29. metadata +7 -3
  30. 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
- #puts "DEGUB: #{@state} #{s.dump}"
32
- # s starts with whitespace
33
- if s =~ /\A(\s+)(.*)/m
34
- ws = $1; rest = $2
35
- #puts "DEGUB: ws #{ws.dump} rest #{rest.dump}"
36
- if @state == :wait_for_nl
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 = rest
38
+ @output.concat(s)
39
+ s = ""
48
40
  end
49
- # s starts with non-whitespace
50
- elsif s =~ /\A(\S+)(.*)/m
51
- nonws = $1; rest = $2
52
- #puts "DEGUB: nonws #{nonws.dump} rest #{rest.dump}"
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 =~ /[^\n]\z/ ? true : false) if noIndentNextLine.nil?
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
@@ -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
- # transform ModelIn, :to => ModelOut do
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 return without any change. Ruby strings
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 self.class._transformer_blocks[obj.class]
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 which condition is true :nodoc:
283
- def _evaluateCondition(obj)
284
- tb = self.class._transformer_blocks[obj.class]
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
- else
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::Rooms::Room < RGen::MetamodelBuilder::MMBase
39
- 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'
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::Kitchen < RGen::MetamodelBuilder::MMMultiple(HouseMetamodel::MeetingPlace, HouseMetamodel::Rooms::Room)
43
- 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'
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"