rgen 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CHANGELOG +9 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +73 -0
  4. data/lib/ea/xmi_class_instantiator.rb +45 -0
  5. data/lib/ea/xmi_helper.rb +26 -0
  6. data/lib/ea/xmi_metamodel.rb +19 -0
  7. data/lib/ea/xmi_object_instantiator.rb +42 -0
  8. data/lib/ea/xmi_to_classmodel.rb +78 -0
  9. data/lib/ea/xmi_to_objectmodel.rb +89 -0
  10. data/lib/mmgen/metamodel_generator.rb +19 -0
  11. data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +71 -0
  12. data/lib/mmgen/mmgen.rb +21 -0
  13. data/lib/mmgen/templates/uml_classmodel.tpl +63 -0
  14. data/lib/rgen/array_extensions.rb +23 -0
  15. data/lib/rgen/auto_class_creator.rb +56 -0
  16. data/lib/rgen/environment.rb +57 -0
  17. data/lib/rgen/metamodel_builder.rb +102 -0
  18. data/lib/rgen/metamodel_builder/build_helper.rb +29 -0
  19. data/lib/rgen/metamodel_builder/builder_extensions.rb +191 -0
  20. data/lib/rgen/metamodel_builder/builder_runtime.rb +67 -0
  21. data/lib/rgen/name_helper.rb +18 -0
  22. data/lib/rgen/template_language.rb +169 -0
  23. data/lib/rgen/template_language/directory_template_container.rb +51 -0
  24. data/lib/rgen/template_language/output_handler.rb +84 -0
  25. data/lib/rgen/template_language/template_container.rb +153 -0
  26. data/lib/rgen/template_language/template_helper.rb +26 -0
  27. data/lib/rgen/transformer.rb +316 -0
  28. data/lib/rgen/xml_instantiator/dependency_resolver.rb +23 -0
  29. data/lib/rgen/xml_instantiator/xml_instantiator.rb +78 -0
  30. data/lib/rgen/xml_instantiator/xml_parser.rb +39 -0
  31. data/lib/uml/objectmodel_instantiator.rb +53 -0
  32. data/lib/uml/uml_classmodel.rb +92 -0
  33. data/lib/uml/uml_objectmodel.rb +65 -0
  34. data/test/array_extensions_test.rb +54 -0
  35. data/test/environment_test.rb +47 -0
  36. data/test/metamodel_builder_test.rb +175 -0
  37. data/test/metamodel_generator_test.rb +45 -0
  38. data/test/metamodel_generator_test/TestModel.rb +40 -0
  39. data/test/metamodel_generator_test/expected_result.txt +40 -0
  40. data/test/output_handler_test.rb +40 -0
  41. data/test/rgen_test.rb +13 -0
  42. data/test/template_language_test.rb +46 -0
  43. data/test/template_language_test/expected_result.txt +10 -0
  44. data/test/template_language_test/templates/content/chapter.tpl +5 -0
  45. data/test/template_language_test/templates/index/c/cmod.tpl +1 -0
  46. data/test/template_language_test/templates/index/chapter.tpl +3 -0
  47. data/test/template_language_test/templates/root.tpl +22 -0
  48. data/test/template_language_test/testout.txt +10 -0
  49. data/test/transformer_test.rb +176 -0
  50. data/test/xmi_class_instantiator_test.rb +107 -0
  51. data/test/xmi_instantiator_test/testmodel.eap +0 -0
  52. data/test/xmi_instantiator_test/testmodel.xml +962 -0
  53. data/test/xmi_object_instantiator_test.rb +65 -0
  54. metadata +117 -0
@@ -0,0 +1,53 @@
1
+ module ObjectmodelInstantiator
2
+
3
+ def instantiateObjectModel(env_in, env_out, metamodel)
4
+ objectMap = {}
5
+ env_in.find(:class => UMLObjectModel::UMLObject).each do |o_in|
6
+ o_out = env_out.new metamodel.const_get(o_in.classname)
7
+ objectMap[o_in] = o_out
8
+ o_out.name = o_in.name
9
+ o_in.attributeSettings.each { |as|
10
+ conversions = ["to_s", "to_i", "to_f"]
11
+ conv = conversions.first
12
+ begin
13
+ o_out.send(as.name+"=",as.value.send(conv))
14
+ rescue StandardError
15
+ conv = conversions[conversions.index(conv)+1]
16
+ retry if conv
17
+ raise
18
+ end
19
+ }
20
+ end
21
+ env_in.find(:class => UMLObjectModel::UMLAssociation).each do |a_in|
22
+ begin
23
+ if a_in.roleA
24
+ begin
25
+ o_out = objectMap[a_in.objectB]
26
+ es = o_out.send(a_in.roleA)
27
+ rescue NoMethodError
28
+ raise StandardError.new("In #{o_out.class.name}(#{o_out.name}): method not found #{a_in.roleA}")
29
+ end
30
+ if es.is_a? RGen::MetamodelBuilder::ElementSet
31
+ es << objectMap[a_in.objectA]
32
+ else
33
+ objectMap[a_in.objectB].send(a_in.roleA+"=", objectMap[a_in.objectA])
34
+ end
35
+ elsif a_in.roleB
36
+ begin
37
+ o_out = objectMap[a_in.objectA]
38
+ es = o_out.send(a_in.roleB)
39
+ rescue NoMethodError
40
+ raise StandardError.new("In #{o_out.class.name}(#{o_out.name}): method not found #{a_in.roleB}")
41
+ end
42
+ if es.is_a? RGen::MetamodelBuilder::ElementSet
43
+ es << objectMap[a_in.objectB]
44
+ else
45
+ objectMap[a_in.objectA].send(a_in.roleB+"=", objectMap[a_in.objectB])
46
+ end
47
+ end
48
+ rescue StandardError => e
49
+ puts e.message
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,92 @@
1
+ require 'rgen/metamodel_builder'
2
+
3
+ module UMLClassModel
4
+
5
+ include RGen::MetamodelBuilder
6
+
7
+ class UMLPackage < MMBase
8
+ has_one 'name', String
9
+ def allClasses
10
+ subpackages.inject(classes) {|r,p| r.concat(p.allClasses) }
11
+ end
12
+ end
13
+
14
+ class UMLClass < MMBase
15
+ has_one 'name', String
16
+ has_many 'stereotypes', String
17
+ def remoteNavigableEnds
18
+ assocEnds.otherEnd.select{|e| e.navigable}
19
+ end
20
+ def localNavigableEnds
21
+ assocEnds.select{|e| e.navigable}
22
+ end
23
+ def localCompositeEnds
24
+ assocEnds.select{|e| e.composite}
25
+ end
26
+ def remoteCompositeEnds
27
+ assocEnds.otherEnd.select{|e| e.composite}
28
+ # put constraint check here and return the container directly ?
29
+ end
30
+ end
31
+
32
+ class UMLOperation < MMBase
33
+ has_one 'name', String
34
+ end
35
+
36
+ class UMLAttribute < MMBase
37
+ has_one 'name', String
38
+ has_one 'type', String
39
+ end
40
+
41
+ class UMLTaggedValue < MMBase
42
+ has_one 'tag'
43
+ has_one 'value'
44
+ end
45
+
46
+ class UMLAssociation < MMBase
47
+ end
48
+
49
+ class UMLAggregation < UMLAssociation
50
+ end
51
+
52
+ class UMLAssociationEnd < MMBase
53
+ has_one 'multiplicity', String
54
+ has_one 'navigable' # boolean
55
+ has_one 'composite' # boolean
56
+ has_one 'role', String
57
+ def assoc
58
+ assocA || assocB
59
+ end
60
+ def otherEnd
61
+ return unless assoc
62
+ assoc.endA == self ? assoc.endB : assoc.endA
63
+ end
64
+ def lowerMult
65
+ return unless multiplicity
66
+ stringToMult(multiplicity.split("..")[0])
67
+ end
68
+ def upperMult
69
+ return unless multiplicity
70
+ ma = multiplicity.split("..")
71
+ stringToMult(ma[1] || ma[0])
72
+ end
73
+ private
74
+ def stringToMult(s)
75
+ return :many if s == "*"
76
+ return s.to_i
77
+ end
78
+ end
79
+
80
+ UMLPackage.one_to_many 'subpackages', UMLPackage, 'superpackage'
81
+ UMLPackage.one_to_many 'classes', UMLClass, 'package'
82
+
83
+ UMLClass.many_to_many 'superclasses', UMLClass, 'subclasses'
84
+ UMLClass.one_to_many 'assocEnds', UMLAssociationEnd, 'clazz'
85
+ UMLClass.one_to_many 'attributes', UMLAttribute, 'clazz'
86
+ UMLClass.one_to_many 'operations', UMLOperation, 'clazz'
87
+ UMLClass.one_to_many 'taggedvalues', UMLTaggedValue, 'clazz'
88
+
89
+ UMLAssociation.one_to_one 'endA', UMLAssociationEnd, 'assocA'
90
+ UMLAssociation.one_to_one 'endB', UMLAssociationEnd, 'assocB'
91
+
92
+ end
@@ -0,0 +1,65 @@
1
+ require 'rgen/metamodel_builder'
2
+
3
+ module UMLObjectModel
4
+
5
+ include RGen::MetamodelBuilder
6
+
7
+ class UMLPackage < MMBase
8
+ has_one 'name', String
9
+ def allObjects
10
+ subpackages.inject(objects) {|r,p| r.concat(p.allObjects) }
11
+ end
12
+ end
13
+
14
+ class UMLObject < MMBase
15
+ has_one 'name', String
16
+ has_one 'classname', String
17
+ def remoteNavigableEnds
18
+ assocEnds.otherEnd.select{|e| e.navigable}
19
+ end
20
+ def localNavigableEnds
21
+ assocEnds.select{|e| e.navigable}
22
+ end
23
+ def localCompositeEnds
24
+ assocEnds.select{|e| e.composite}
25
+ end
26
+ def remoteCompositeEnds
27
+ assocEnds.otherEnd.select{|e| e.composite}
28
+ # put constraint check here and return the container directly ?
29
+ end
30
+ end
31
+
32
+ class UMLAttributeSetting < MMBase
33
+ has_one 'name', String
34
+ has_one 'value', String
35
+ end
36
+
37
+ class UMLAssociation < MMBase
38
+ end
39
+
40
+ class UMLAggregation < UMLAssociation
41
+ end
42
+
43
+ class UMLAssociationEnd < MMBase
44
+ has_one 'navigable' # boolean
45
+ has_one 'composite' # boolean
46
+ has_one 'role', String
47
+ def assoc
48
+ assocA || assocB
49
+ end
50
+ def otherEnd
51
+ return unless assoc
52
+ assoc.endA == self ? assoc.endB : assoc.endA
53
+ end
54
+ end
55
+
56
+ UMLPackage.one_to_many 'subpackages', UMLPackage, 'superpackage'
57
+ UMLPackage.one_to_many 'objects', UMLObject, 'package'
58
+
59
+ UMLObject.one_to_many 'assocEnds', UMLAssociationEnd, 'object'
60
+ UMLObject.one_to_many 'attributeSettings', UMLAttributeSetting, 'object'
61
+
62
+ UMLAssociation.one_to_one 'endA', UMLAssociationEnd, 'assocA'
63
+ UMLAssociation.one_to_one 'endB', UMLAssociationEnd, 'assocB'
64
+
65
+ end
@@ -0,0 +1,54 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/array_extensions'
5
+
6
+ class ArrayExtensionsTest < Test::Unit::TestCase
7
+
8
+ def test_element_methods
9
+ c = Struct.new("SomeClass",:name,:age)
10
+ a = []
11
+ a << c.new('MyName',33)
12
+ a << c.new('YourName',22)
13
+ assert_equal ["MyName", "YourName"], a >> :name
14
+ assert_raise NoMethodError do
15
+ a.name
16
+ end
17
+ assert_equal [33, 22], a>>:age
18
+ assert_raise NoMethodError do
19
+ a.age
20
+ end
21
+ # unfortunately, any method can be called on an empty array
22
+ assert_equal [], [].age
23
+ end
24
+
25
+ class MMBaseClass < RGen::MetamodelBuilder::MMBase
26
+ has_one 'name'
27
+ has_one 'age'
28
+ end
29
+
30
+ def test_with_mmbase
31
+ e1 = MMBaseClass.new
32
+ e1.name = "MyName"
33
+ e1.age = 33
34
+ e2 = MMBaseClass.new
35
+ e2.name = "YourName"
36
+ e2.age = 22
37
+ a = [e1, e2]
38
+ assert_equal ["MyName", "YourName"], a >> :name
39
+ assert_equal ["MyName", "YourName"], a.name
40
+ assert_equal [33, 22], a>>:age
41
+ assert_equal [33, 22], a.age
42
+ # put something into the array that is not an MMBase
43
+ a << "not a MMBase"
44
+ # the dot operator will tell that there is something not a MMBase
45
+ assert_raise StandardError do
46
+ a.age
47
+ end
48
+ # the >> operator will try to call the method anyway
49
+ assert_raise NoMethodError do
50
+ a >> :age
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,47 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/environment'
5
+
6
+ class EnvironmentTest < Test::Unit::TestCase
7
+
8
+ class Model
9
+ attr_accessor :name
10
+ end
11
+
12
+ class ModelSub < Model
13
+ end
14
+
15
+ def test_find
16
+ m1 = Model.new
17
+ m1.name = "M1"
18
+ m2 = ModelSub.new
19
+ m2.name = "M2"
20
+ m3 = "justAString"
21
+ env_in = RGen::Environment.new << m1 << m2 << m3
22
+
23
+ result = env_in.find(:class => Model, :name => "M1")
24
+ assert result.is_a?(Array)
25
+ assert_equal 1, result.size
26
+ assert_equal m1, result.first
27
+
28
+ result = env_in.find(:class => Model)
29
+ assert result.is_a?(Array)
30
+ assert_equal 2, result.size
31
+ assert_equal m1, result[0]
32
+ assert_equal m2, result[1]
33
+
34
+ result = env_in.find(:name => "M2")
35
+ assert result.is_a?(Array)
36
+ assert_equal 1, result.size
37
+ assert_equal m2, result[0]
38
+
39
+ result = env_in.find(:class => [Model, String])
40
+ assert result.is_a?(Array)
41
+ assert_equal 3, result.size
42
+ assert_equal m1, result[0]
43
+ assert_equal m2, result[1]
44
+ assert_equal m3, result[2]
45
+ end
46
+
47
+ end
@@ -0,0 +1,175 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/metamodel_builder'
5
+
6
+ class MetamodelBuilderTest < Test::Unit::TestCase
7
+
8
+ class HasOneTestClass < RGen::MetamodelBuilder::MMBase
9
+ has_one 'name'
10
+ has_one 'an_array', Array
11
+ end
12
+
13
+ def test_has_one
14
+ sc = HasOneTestClass.new
15
+ assert_respond_to sc, :name
16
+ assert_respond_to sc, :name=
17
+ sc.name = 'SomeName'
18
+ assert_equal 'SomeName', sc.name
19
+ sc.name = nil
20
+ assert_equal nil, sc.name
21
+
22
+ assert_respond_to sc, :an_array
23
+ assert_respond_to sc, :an_array=
24
+ aa = Array.new
25
+ sc.an_array = aa
26
+ assert_equal aa, sc.an_array
27
+
28
+ assert_raise StandardError do
29
+ sc.an_array = "a string"
30
+ end
31
+ end
32
+
33
+ class HasManyTestClass < RGen::MetamodelBuilder::MMBase
34
+ has_many 'string', String
35
+ end
36
+
37
+ def test_has_many
38
+ o = HasManyTestClass.new
39
+ o.addString("s1")
40
+ o.addString("s2")
41
+ assert_equal ["s1","s2"], o.string
42
+ # make sure we get a copy
43
+ o.string.clear
44
+ assert_equal ["s1","s2"], o.string
45
+ o.removeString("s3")
46
+ assert_equal ["s1","s2"], o.string
47
+ o.removeString("s2")
48
+ assert_equal ["s1"], o.string
49
+ assert_raise StandardError do
50
+ o.addString(:notastring)
51
+ end
52
+ end
53
+
54
+ class OneClass < RGen::MetamodelBuilder::MMBase
55
+ end
56
+ class ManyClass < RGen::MetamodelBuilder::MMBase
57
+ end
58
+ OneClass.one_to_many 'manyClasses', ManyClass, 'oneClass'
59
+
60
+ def test_one_to_many
61
+ oc = OneClass.new
62
+ assert_respond_to oc, :manyClasses
63
+ assert oc.manyClasses.empty?
64
+
65
+ mc = ManyClass.new
66
+ assert_respond_to mc, :oneClass
67
+ assert_respond_to mc, :oneClass=
68
+ assert_nil mc.oneClass
69
+
70
+ # put the OneClass into the ManyClass
71
+ mc.oneClass = oc
72
+ assert_equal oc, mc.oneClass
73
+ assert oc.manyClasses.include?(mc)
74
+
75
+ # remove the OneClass from the ManyClass
76
+ mc.oneClass = nil
77
+ assert_equal nil, mc.oneClass
78
+ assert !oc.manyClasses.include?(mc)
79
+
80
+ # put the ManyClass into the OneClass
81
+ oc.addManyClasses mc
82
+ assert oc.manyClasses.include?(mc)
83
+ assert_equal oc, mc.oneClass
84
+
85
+ # remove the ManyClass from the OneClass
86
+ oc.removeManyClasses mc
87
+ assert !oc.manyClasses.include?(mc)
88
+ assert_equal nil, mc.oneClass
89
+ end
90
+
91
+ class AClassOO < RGen::MetamodelBuilder::MMBase
92
+ end
93
+ class BClassOO < RGen::MetamodelBuilder::MMBase
94
+ end
95
+ AClassOO.one_to_one 'bClass', BClassOO, 'aClass'
96
+
97
+ def test_one_to_one
98
+ ac = AClassOO.new
99
+ assert_respond_to ac, :bClass
100
+ assert_respond_to ac, :bClass=
101
+ assert_nil ac.bClass
102
+
103
+ bc = BClassOO.new
104
+ assert_respond_to bc, :aClass
105
+ assert_respond_to bc, :aClass=
106
+ assert_nil bc.aClass
107
+
108
+ # put the AClass into the BClass
109
+ bc.aClass = ac
110
+ assert_equal ac, bc.aClass
111
+ assert_equal bc, ac.bClass
112
+
113
+ # remove the AClass from the BClass
114
+ bc.aClass = nil
115
+ assert_equal nil, bc.aClass
116
+ assert_equal nil, ac.bClass
117
+
118
+ # put the BClass into the AClass
119
+ ac.bClass = bc
120
+ assert_equal bc, ac.bClass
121
+ assert_equal ac, bc.aClass
122
+
123
+ # remove the BClass from the AClass
124
+ ac.bClass = nil
125
+ assert_equal nil, ac.bClass
126
+ assert_equal nil, bc.aClass
127
+ end
128
+
129
+ class AClassMM < RGen::MetamodelBuilder::MMBase
130
+ end
131
+ class BClassMM < RGen::MetamodelBuilder::MMBase
132
+ end
133
+ AClassMM.many_to_many 'bClasses', BClassMM, 'aClasses'
134
+
135
+ def test_many_to_many
136
+
137
+ ac = AClassMM.new
138
+ assert_respond_to ac, :bClasses
139
+ assert ac.bClasses.empty?
140
+
141
+ bc = BClassMM.new
142
+ assert_respond_to bc, :aClasses
143
+ assert bc.aClasses.empty?
144
+
145
+ # put the AClass into the BClass
146
+ bc.addAClasses ac
147
+ assert bc.aClasses.include?(ac)
148
+ assert ac.bClasses.include?(bc)
149
+
150
+ # put something else into the BClass
151
+ assert_raise StandardError do
152
+ bc.addAClasses :notaaclass
153
+ end
154
+
155
+ # remove the AClass from the BClass
156
+ bc.removeAClasses ac
157
+ assert !bc.aClasses.include?(ac)
158
+ assert !ac.bClasses.include?(bc)
159
+
160
+ # put the BClass into the AClass
161
+ ac.addBClasses bc
162
+ assert ac.bClasses.include?(bc)
163
+ assert bc.aClasses.include?(ac)
164
+
165
+ # put something else into the AClass
166
+ assert_raise StandardError do
167
+ ac.addBClasses :notabclass
168
+ end
169
+
170
+ # remove the BClass from the AClass
171
+ ac.removeBClasses bc
172
+ assert !ac.bClasses.include?(bc)
173
+ assert !bc.aClasses.include?(ac)
174
+ end
175
+ end