rgen 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -98,3 +98,15 @@
98
98
 
99
99
  * Fixed metamodel builder bug: _register at one-side did not unregister from the element referenced by the old value
100
100
  * Added helper class for building simple model comparators
101
+
102
+ =0.5.2 ( )
103
+
104
+ * Added has_many_attr to metamodel builder, support for "many" attributes
105
+ * Added JSON support (json instantiator and serializer)
106
+ * Added QualifiedNameResolver instantiation helper
107
+ * Added reference proxy support
108
+ * Added more generic access methods on metaclasses
109
+ * Added ReferenceResolver resolver mixin
110
+ * Fixed ecore xml instantiator and serializer to handle references to builtin datatypes correctly
111
+ * Fixed bug in ecore xml serializer to not output references which are opposites of containment references
112
+
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Martin Thiede
1
+ Copyright (c) 2010 Martin Thiede
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -3,8 +3,8 @@ require 'rake/rdoctask'
3
3
 
4
4
  RGenGemSpec = Gem::Specification.new do |s|
5
5
  s.name = %q{rgen}
6
- s.version = "0.5.1"
7
- s.date = %q{2009-11-10}
6
+ s.version = "0.5.2"
7
+ s.date = %q{2010-06-13}
8
8
  s.summary = %q{Ruby Modelling and Generator Framework}
9
9
  s.email = %q{martin dot thiede at gmx de}
10
10
  s.homepage = %q{http://ruby-gen.org}
@@ -60,15 +60,15 @@
60
60
  <% end %>
61
61
 
62
62
  <% define 'Attribute', :for => EAttribute do |rootp| %>
63
- <% if upperBound == 1%>
64
- has_attr '<%= name %>', <%nows%>
63
+ <% if upperBound == 1%>has_attr<% else %>has_many_attr<% end %> '<%= name %>', <%nows%>
65
64
  <% if eType.is_a?(EEnum) %><%nows%>
66
65
  <%= eType.qualifiedClassifierName(rootp) %><%nows%>
67
66
  <% else %><%nows%>
68
67
  <%= eType && eType.instanceClass.to_s %><%nows%>
69
68
  <% end %><%nows%>
70
69
  <% for p in RGen::MetamodelBuilder::AttributeDescription.propertySet %>
71
- <% unless p == :name || p == :upperBound || RGen::MetamodelBuilder::AttributeDescription.default_value(p) == getGeneric(p) %>
70
+ <% unless p == :name || (p == :upperBound && (upperBound == 1 || upperBound == -1)) ||
71
+ RGen::MetamodelBuilder::AttributeDescription.default_value(p) == getGeneric(p) %>
72
72
  , :<%=p%> => <%nows%>
73
73
  <% if getGeneric(p).is_a?(String) %>
74
74
  "<%= getGeneric(p) %>"<%nows%>
@@ -80,7 +80,6 @@
80
80
  <% end %>
81
81
  <% end %>
82
82
  <%ws%><% expand 'annotations::Annotations' %><%nl%>
83
- <% end %>
84
83
  <% end %>
85
84
 
86
85
  <% define 'EnumTypes', :for => EPackage do %>
@@ -170,4 +169,4 @@
170
169
  <% else %><% nows %>
171
170
  RGen::MetamodelBuilder::MMBase
172
171
  <% end %>
173
- <% end %>
172
+ <% end %>
@@ -115,30 +115,39 @@ class ECoreXMLInstantiator < AbstractXMLInstantiator
115
115
  desc.split(/\s+/).collect do |r|
116
116
  if r =~ /^#\/\d*\/([\w\/]+)/
117
117
  find_in_context(context, $1.split('/'))
118
+ elsif r =~ /#\/\/(\w+)$/
119
+ case $1
120
+ when "EString"; RGen::ECore::EString
121
+ when "EInt"; RGen::ECore::EInt
122
+ when "EBoolean"; RGen::ECore::EBoolean
123
+ when "EFloat"; RGen::ECore::EFloat
124
+ when "EJavaObject"; RGen::ECore::EJavaObject
125
+ when "EJavaClass"; RGen::ECore::EJavaClass
126
+ end
118
127
  end
119
- end.compact
128
+ end.compact
129
+ end
130
+
131
+ def find_in_context(context, desc_elements)
132
+ if context.is_a?(EPackage)
133
+ r = (context.eClassifiers + context.eSubpackages).find{|c| c.name == desc_elements.first}
134
+ elsif context.is_a?(EClass)
135
+ r = context.eStructuralFeatures.find{|s| s.name == desc_elements.first}
136
+ else
137
+ raise StandardError.new("Don't know how to find #{desc_elements.join('/')} in context #{context}")
120
138
  end
121
-
122
- def find_in_context(context, desc_elements)
123
- if context.is_a?(EPackage)
124
- r = (context.eClassifiers + context.eSubpackages).find{|c| c.name == desc_elements.first}
125
- elsif context.is_a?(EClass)
126
- r = context.eStructuralFeatures.find{|s| s.name == desc_elements.first}
139
+ if r
140
+ if desc_elements.size > 1
141
+ find_in_context(r, desc_elements[1..-1])
127
142
  else
128
- raise StandardError.new("Don't know how to find #{desc_elements.join('/')} in context #{context}")
143
+ r
129
144
  end
130
- if r
131
- if desc_elements.size > 1
132
- find_in_context(r, desc_elements[1..-1])
133
- else
134
- r
135
- end
136
- else
137
- log WARN, "Can not follow path, element #{desc_elements.first} not found within #{context}(#{context.name})"
138
- end
139
- end
140
-
141
- def log(level, msg)
142
- puts %w(INFO WARN ERROR)[level] + ": " + msg if level >= @loglevel
145
+ else
146
+ log WARN, "Can not follow path, element #{desc_elements.first} not found within #{context}(#{context.name})"
143
147
  end
144
- end
148
+ end
149
+
150
+ def log(level, msg)
151
+ puts %w(INFO WARN ERROR)[level] + ": " + msg if level >= @loglevel
152
+ end
153
+ end
@@ -0,0 +1,79 @@
1
+ require 'rgen/instantiator/qualified_name_resolver'
2
+ require 'rgen/instantiator/json_parser'
3
+
4
+ module RGen
5
+
6
+ module Instantiator
7
+
8
+ class JsonInstantiator
9
+
10
+ def initialize(env, mm, options={})
11
+ @env = env
12
+ @mm = mm
13
+ @options = options
14
+ @unresolvedReferences = []
15
+ @parser = JsonParser.new(self)
16
+ end
17
+
18
+ # creates the elements described by the json string +str+
19
+ # returns an array of ReferenceResolver::UnresolvedReference
20
+ # describing the references which could not be resolved
21
+ def instantiate(str)
22
+ root = @parser.parse(str)
23
+ resolver = QualifiedNameResolver.new(root, @options)
24
+ resolver.resolveReferences(@unresolvedReferences)
25
+ end
26
+
27
+ def createObject(hash)
28
+ className = hash["_class"]
29
+ raise "no class information" unless className
30
+ clazz = @mm.const_get(className)
31
+ raise "class not found: #{className}" unless clazz
32
+ hash.delete("_class")
33
+ urefs = []
34
+ hash.keys.each do |k|
35
+ f = eFeature(k, clazz)
36
+ hash[k] = [hash[k]] if f.many && !hash[k].is_a?(Array)
37
+ if f.is_a?(RGen::ECore::EReference) && !f.containment
38
+ if f.many
39
+ idents = hash[k]
40
+ hash[k] = idents.collect do |i|
41
+ proxy = RGen::MetamodelBuilder::MMProxy.new(i)
42
+ urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy)
43
+ proxy
44
+ end
45
+ else
46
+ ident = hash[k]
47
+ ident = ident.first if ident.is_a?(Array)
48
+ proxy = RGen::MetamodelBuilder::MMProxy.new(ident)
49
+ hash[k] = proxy
50
+ urefs << ReferenceResolver::UnresolvedReference.new(nil, k, proxy)
51
+ end
52
+ elsif f.eType.is_a?(RGen::ECore::EEnum)
53
+ hash[k] = hash[k].to_sym
54
+ elsif f.eType.instanceClassName == "Float"
55
+ hash[k] = hash[k].to_f
56
+ end
57
+ end
58
+ obj = @env.new(clazz, hash)
59
+ urefs.each do |r|
60
+ r.element = obj
61
+ @unresolvedReferences << r
62
+ end
63
+ obj
64
+ end
65
+
66
+ private
67
+
68
+ def eFeature(name, clazz)
69
+ @eFeature ||= {}
70
+ @eFeature[clazz] ||= {}
71
+ @eFeature[clazz][name] ||= clazz.ecore.eAllStructuralFeatures.find{|f| f.name == name}
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+
@@ -0,0 +1,326 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by racc 1.4.5
4
+ # from racc grammer file "json_parser.y".
5
+ #
6
+
7
+ require 'racc/parser'
8
+
9
+
10
+
11
+ module RGen
12
+
13
+ module Instantiator
14
+
15
+
16
+ class JsonParser < Racc::Parser
17
+
18
+ module_eval <<'..end json_parser.y modeval..ide42306a0dd', 'json_parser.y', 38
19
+
20
+ ParserToken = Struct.new(:line, :file, :value)
21
+
22
+ def initialize(instantiator)
23
+ @instantiator = instantiator
24
+ end
25
+
26
+ def parse(str, file=nil)
27
+ @q = []
28
+ line = 1
29
+
30
+ until str.empty?
31
+ case str
32
+ when /\A\n/
33
+ str = $'
34
+ line +=1
35
+ when /\A\s+/
36
+ str = $'
37
+ when /\A([-+]?\d+\.\d+)/
38
+ str = $'
39
+ @q << [:FLOAT, ParserToken.new(line, file, $1)]
40
+ when /\A([-+]?\d+)/
41
+ str = $'
42
+ @q << [:INTEGER, ParserToken.new(line, file, $1)]
43
+ when /\A"((?:[^"\\]|\\"|\\\\|\\[^"\\])*)"/
44
+ str = $'
45
+ sval = $1
46
+ sval.gsub!('\\\\','\\')
47
+ sval.gsub!('\\"','"')
48
+ @q << [:STRING, ParserToken.new(line, file, sval)]
49
+ when /\A(\{|\}|\[|\]|,|:|true|false)/
50
+ str = $'
51
+ @q << [$1, ParserToken.new(line, file, $1)]
52
+ else
53
+ raise "parse error in line #{line} on "+str[0..20].inspect+"..."
54
+ end
55
+ end
56
+ @q.push [false, ParserToken.new(line, file, '$end')]
57
+ do_parse
58
+ end
59
+
60
+ def next_token
61
+ r = @q.shift
62
+ r
63
+ end
64
+
65
+ ..end json_parser.y modeval..ide42306a0dd
66
+
67
+ ##### racc 1.4.5 generates ###
68
+
69
+ racc_reduce_table = [
70
+ 0, 0, :racc_error,
71
+ 1, 14, :_reduce_1,
72
+ 3, 16, :_reduce_2,
73
+ 2, 16, :_reduce_3,
74
+ 1, 17, :_reduce_4,
75
+ 3, 17, :_reduce_5,
76
+ 3, 18, :_reduce_6,
77
+ 2, 18, :_reduce_7,
78
+ 1, 19, :_reduce_8,
79
+ 3, 19, :_reduce_9,
80
+ 3, 20, :_reduce_10,
81
+ 1, 15, :_reduce_11,
82
+ 1, 15, :_reduce_12,
83
+ 1, 15, :_reduce_13,
84
+ 1, 15, :_reduce_14,
85
+ 1, 15, :_reduce_15,
86
+ 1, 15, :_reduce_16,
87
+ 1, 15, :_reduce_17 ]
88
+
89
+ racc_reduce_n = 18
90
+
91
+ racc_shift_n = 29
92
+
93
+ racc_action_table = [
94
+ 3, 16, 17, 7, 22, 8, 21, 10, 11, 1,
95
+ 2, 3, 12, 23, 7, 24, 8, 25, 10, 11,
96
+ 1, 2, 3, 20, 15, 7, 17, 8, nil, 10,
97
+ 11, 1, 2, 3, nil, nil, 7, nil, 8, nil,
98
+ 10, 11, 1, 2 ]
99
+
100
+ racc_action_check = [
101
+ 0, 7, 7, 0, 15, 0, 14, 0, 0, 0,
102
+ 0, 3, 3, 17, 3, 18, 3, 19, 3, 3,
103
+ 3, 3, 20, 13, 4, 20, 25, 20, nil, 20,
104
+ 20, 20, 20, 23, nil, nil, 23, nil, 23, nil,
105
+ 23, 23, 23, 23 ]
106
+
107
+ racc_action_pointer = [
108
+ -2, nil, nil, 9, 24, nil, nil, -5, nil, nil,
109
+ nil, nil, nil, 19, 3, 4, nil, 5, 9, 13,
110
+ 20, nil, nil, 31, nil, 19, nil, nil, nil ]
111
+
112
+ racc_action_default = [
113
+ -18, -16, -17, -18, -18, -1, -11, -18, -13, -12,
114
+ -14, -15, -3, -4, -18, -18, -7, -18, -18, -8,
115
+ -18, -2, 29, -18, -6, -18, -5, -10, -9 ]
116
+
117
+ racc_goto_table = [
118
+ 5, 18, 4, 14, nil, nil, nil, nil, nil, nil,
119
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 28,
120
+ 26, nil, nil, 27 ]
121
+
122
+ racc_goto_check = [
123
+ 2, 6, 1, 4, nil, nil, nil, nil, nil, nil,
124
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 6,
125
+ 4, nil, nil, 2 ]
126
+
127
+ racc_goto_pointer = [
128
+ nil, 2, 0, nil, 0, nil, -6, nil ]
129
+
130
+ racc_goto_default = [
131
+ nil, nil, 13, 6, nil, 9, nil, 19 ]
132
+
133
+ racc_token_table = {
134
+ false => 0,
135
+ Object.new => 1,
136
+ "[" => 2,
137
+ "]" => 3,
138
+ "," => 4,
139
+ "{" => 5,
140
+ "}" => 6,
141
+ :STRING => 7,
142
+ ":" => 8,
143
+ :INTEGER => 9,
144
+ :FLOAT => 10,
145
+ "true" => 11,
146
+ "false" => 12 }
147
+
148
+ racc_use_result_var = true
149
+
150
+ racc_nt_base = 13
151
+
152
+ Racc_arg = [
153
+ racc_action_table,
154
+ racc_action_check,
155
+ racc_action_default,
156
+ racc_action_pointer,
157
+ racc_goto_table,
158
+ racc_goto_check,
159
+ racc_goto_default,
160
+ racc_goto_pointer,
161
+ racc_nt_base,
162
+ racc_reduce_table,
163
+ racc_token_table,
164
+ racc_shift_n,
165
+ racc_reduce_n,
166
+ racc_use_result_var ]
167
+
168
+ Racc_token_to_s_table = [
169
+ '$end',
170
+ 'error',
171
+ '"["',
172
+ '"]"',
173
+ '","',
174
+ '"{"',
175
+ '"}"',
176
+ 'STRING',
177
+ '":"',
178
+ 'INTEGER',
179
+ 'FLOAT',
180
+ '"true"',
181
+ '"false"',
182
+ '$start',
183
+ 'json',
184
+ 'value',
185
+ 'array',
186
+ 'valueList',
187
+ 'object',
188
+ 'memberList',
189
+ 'member']
190
+
191
+ Racc_debug_parser = false
192
+
193
+ ##### racc system variables end #####
194
+
195
+ # reduce 0 omitted
196
+
197
+ module_eval <<'.,.,', 'json_parser.y', 4
198
+ def _reduce_1( val, _values, result )
199
+ result = val[0]
200
+ result
201
+ end
202
+ .,.,
203
+
204
+ module_eval <<'.,.,', 'json_parser.y', 6
205
+ def _reduce_2( val, _values, result )
206
+ result = val[1]
207
+ result
208
+ end
209
+ .,.,
210
+
211
+ module_eval <<'.,.,', 'json_parser.y', 7
212
+ def _reduce_3( val, _values, result )
213
+ result = []
214
+ result
215
+ end
216
+ .,.,
217
+
218
+ module_eval <<'.,.,', 'json_parser.y', 9
219
+ def _reduce_4( val, _values, result )
220
+ result = [ val[0] ]
221
+ result
222
+ end
223
+ .,.,
224
+
225
+ module_eval <<'.,.,', 'json_parser.y', 10
226
+ def _reduce_5( val, _values, result )
227
+ result = [ val[0] ] + val[2]
228
+ result
229
+ end
230
+ .,.,
231
+
232
+ module_eval <<'.,.,', 'json_parser.y', 12
233
+ def _reduce_6( val, _values, result )
234
+ result = @instantiator.createObject(val[1])
235
+ result
236
+ end
237
+ .,.,
238
+
239
+ module_eval <<'.,.,', 'json_parser.y', 13
240
+ def _reduce_7( val, _values, result )
241
+ result = nil
242
+ result
243
+ end
244
+ .,.,
245
+
246
+ module_eval <<'.,.,', 'json_parser.y', 15
247
+ def _reduce_8( val, _values, result )
248
+ result = val[0]
249
+ result
250
+ end
251
+ .,.,
252
+
253
+ module_eval <<'.,.,', 'json_parser.y', 16
254
+ def _reduce_9( val, _values, result )
255
+ result = val[0].merge(val[2])
256
+ result
257
+ end
258
+ .,.,
259
+
260
+ module_eval <<'.,.,', 'json_parser.y', 18
261
+ def _reduce_10( val, _values, result )
262
+ result = {val[0].value => val[2]}
263
+ result
264
+ end
265
+ .,.,
266
+
267
+ module_eval <<'.,.,', 'json_parser.y', 20
268
+ def _reduce_11( val, _values, result )
269
+ result = val[0]
270
+ result
271
+ end
272
+ .,.,
273
+
274
+ module_eval <<'.,.,', 'json_parser.y', 21
275
+ def _reduce_12( val, _values, result )
276
+ result = val[0]
277
+ result
278
+ end
279
+ .,.,
280
+
281
+ module_eval <<'.,.,', 'json_parser.y', 22
282
+ def _reduce_13( val, _values, result )
283
+ result = val[0].value
284
+ result
285
+ end
286
+ .,.,
287
+
288
+ module_eval <<'.,.,', 'json_parser.y', 23
289
+ def _reduce_14( val, _values, result )
290
+ result = val[0].value.to_i
291
+ result
292
+ end
293
+ .,.,
294
+
295
+ module_eval <<'.,.,', 'json_parser.y', 24
296
+ def _reduce_15( val, _values, result )
297
+ result = val[0].value.to_f
298
+ result
299
+ end
300
+ .,.,
301
+
302
+ module_eval <<'.,.,', 'json_parser.y', 25
303
+ def _reduce_16( val, _values, result )
304
+ result = true
305
+ result
306
+ end
307
+ .,.,
308
+
309
+ module_eval <<'.,.,', 'json_parser.y', 26
310
+ def _reduce_17( val, _values, result )
311
+ result = false
312
+ result
313
+ end
314
+ .,.,
315
+
316
+ def _reduce_none( val, _values, result )
317
+ result
318
+ end
319
+
320
+ end # class JsonParser
321
+
322
+
323
+ end
324
+
325
+ end
326
+