rgen 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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"