rgen 0.2.0

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 (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