hutch-xamplr 1.1.2 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 1
3
- :patch: 2
3
+ :patch: 4
4
4
  :major: 1
@@ -30,7 +30,7 @@ if $0 == __FILE__ then
30
30
  :filenames => filenames,
31
31
  :directory => directory)
32
32
 
33
- #puts generator.print_elements("./generated-elements.xml")
33
+ puts generator.print_elements("./generated-elements.xml")
34
34
  exit!
35
35
  end
36
36
  end
@@ -0,0 +1,470 @@
1
+ require 'fileutils'
2
+ require 'set'
3
+
4
+ module XamplGenerator
5
+
6
+ class GraphMLOut
7
+
8
+ def initialize(elements_map)
9
+ @elements_map = elements_map
10
+ end
11
+
12
+ def devise_filename(filename)
13
+ bn = File.basename(filename)
14
+ ext = File.extname(bn)
15
+ bn = bn[0..(bn.size - ext.size - 1)]
16
+ fn = "#{bn}.graphml"
17
+ end
18
+
19
+ def generate_class_nodes(element, include_mixins)
20
+
21
+ node = @element_to_node_map[element.nstag]
22
+
23
+ class_name = "#{ element.package }::#{ element.class_name }"
24
+ mixin_name = "#{ element.package }::#{ element.class_name }"
25
+
26
+ if element.persisted then
27
+ write_entity_node(node, class_name, element.kind)
28
+ else
29
+ write_internal_node(node, class_name, element.kind)
30
+ end
31
+
32
+ if include_mixins then
33
+ mixin_node = @mixed_in[element.nstag]
34
+ #puts "#{ element.nstag } => #{ node }, mixin: [#{ mixin_node }]"
35
+ if mixin_node then
36
+ write_mixin_node(mixin_node, class_name)
37
+ end
38
+ end
39
+ # puts "NODE #{ node } #{ class_name }"
40
+ # puts "NODE #{ mixin_node } #{ mixin_name }"
41
+ end
42
+
43
+ def generate_edges(element, include_mixins)
44
+ # for each child, generate an entity-ref or internal-ref edge
45
+ # for each child, generate a mixin-ref edge
46
+
47
+ return if ignore_package(element.package)
48
+
49
+ element.child_element_child.each do | celement |
50
+ next if ignore_package(celement.package)
51
+
52
+ cnstag = "{{#{ celement.namespace }}}#{ celement.element_name }"
53
+
54
+ referenced_element = @ns_to_element_map[ cnstag ]
55
+ next unless referenced_element
56
+
57
+ this_node = @element_to_node_map[ element.nstag ]
58
+
59
+ other_node = @element_to_node_map[ cnstag ]
60
+ other_mixin = @mixed_in[ cnstag ]
61
+
62
+ if referenced_element.persisted then
63
+ @current_edge += 1
64
+ write_entity_ref_edge(@current_edge, this_node, other_node)
65
+ # puts "ER EDGE #{ @current_edge }, #{ this_node } --> #{ other_node } :: #{ element.class_name } --> #{ referenced_element.class_name }"
66
+ else
67
+ @current_edge += 1
68
+ write_internal_ref_edge(@current_edge, this_node, other_node)
69
+ # puts "IR EDGE #{ @current_edge }, #{ this_node } --> #{ other_node } :: #{ element.class_name } --> #{ referenced_element.class_name }"
70
+ end
71
+ if include_mixins then
72
+ @current_edge += 1
73
+ write_mixin_ref_edge(@current_edge, this_node, other_mixin)
74
+ # puts "MI EDGE #{ @current_edge }, #{ this_node } --> #{ other_mixin } :: #{ element.class_name } --> #{ referenced_element.class_name }"
75
+ end
76
+ end
77
+ end
78
+
79
+ def ignore_package(package)
80
+ return true if @excluded_packages.member?(package)
81
+ return false if @included_packages.nil?
82
+ return true unless @included_packages.member?(package)
83
+ return false
84
+ end
85
+
86
+ # def ignore_package(package)
87
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} pkg: [#{ package }], exclude: #{ @excluded_packages.inspect }, include: #{ @included_packages.inspect }"
88
+ # r = ignore_package_work(package)
89
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} ignore? #{ r }"
90
+ # r
91
+ # end
92
+
93
+ #def write_graph_ml(filename, excluded_packages=[ 'C2', 'NavRelationships', 'App' ], included_packages=nil, include_mixins=false)
94
+ def write_graph_ml(filename, excluded_packages=[ ], included_packages=nil, include_mixins=true)
95
+
96
+ #puts "#{File.basename(__FILE__)}:#{__LINE__} no graphml yet"
97
+ #return
98
+
99
+ filename = devise_filename(filename)
100
+
101
+ @excluded_packages = Set.new(excluded_packages)
102
+ @included_packages = included_packages ? Set.new(included_packages) : nil
103
+
104
+ @element_to_node_map = {}
105
+ @ns_to_element_map = {}
106
+ @element_to_child_element_map = {}
107
+ @mixed_in = {}
108
+
109
+ nodes = 0
110
+ edges = 0
111
+ mixins = 0
112
+
113
+ @elements_map.each_value do |elements|
114
+ elements.element_child.each do |element|
115
+ next if ignore_package(element.package)
116
+ nodes += 1
117
+
118
+ @element_to_node_map[element.nstag] = nodes
119
+ @ns_to_element_map[element.nstag] = element
120
+ @element_to_child_element_map[element.nstag] = map = {}
121
+
122
+ element.child_element_child.each do | celement |
123
+ edges += 1
124
+ cnstag = "{{#{ celement.namespace }}}#{ celement.element_name }"
125
+ map[cnstag] = edges
126
+ unless @mixed_in.include?(cnstag) then
127
+ mixins += 1
128
+ @mixed_in[cnstag] = mixins
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ @mixed_in.each do | k, v |
135
+ @mixed_in[k] = v + nodes
136
+ end
137
+
138
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} #{ @element_to_node_map.inspect }"
139
+
140
+ @reference_edges = edges
141
+
142
+ File.open(filename, "w") do | out |
143
+ @out = out
144
+
145
+ if include_mixins then
146
+ write_graphml_start(nodes + mixins, 2 * edges)
147
+ else
148
+ write_graphml_start(nodes, edges)
149
+ end
150
+ @elements_map.each_value do |elements|
151
+ elements.element_child.each do |element|
152
+ generate_class_nodes(element, include_mixins)
153
+ end
154
+ end
155
+
156
+ @current_edge = 0
157
+ @elements_map.each_value do |elements|
158
+ elements.element_child.each do |element|
159
+ generate_edges(element, include_mixins)
160
+ end
161
+ end
162
+ write_graphml_end
163
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} EDGES:: predicted: #{ 2 * edges }, actual: #{ @current_edge }"
164
+ end
165
+ return nil
166
+ end
167
+
168
+ def write_entity_node(node, class_name, kind)
169
+ @out << <<EOS
170
+ <node id="n#{ node }">
171
+ <data key="d0">
172
+ <y:UMLClassNode>
173
+ <y:Geometry height="102.0"
174
+ width="111.0"
175
+ x="-5.5"
176
+ y="174.0"/>
177
+ <y:Fill color="#99CCFF"
178
+ transparent="false"/>
179
+ <y:BorderStyle color="#000000"
180
+ type="line"
181
+ width="2.0"/>
182
+ <y:NodeLabel alignment="center"
183
+ autoSizePolicy="content"
184
+ fontFamily="Dialog"
185
+ fontSize="13"
186
+ fontStyle="bold"
187
+ hasBackgroundColor="false"
188
+ hasLineColor="false"
189
+ height="19.310546875"
190
+ modelName="internal"
191
+ modelPosition="c"
192
+ textColor="#000000"
193
+ visible="true"
194
+ width="49.6904296875"
195
+ x="30.65478515625"
196
+ y="26.1328125">#{ class_name }
197
+ </y:NodeLabel>
198
+ <y:UML clipContent="true"
199
+ constraint=""
200
+ omitDetails="false"
201
+ stereotype="#{ kind }"
202
+ use3DEffect="false">
203
+ <!--y:AttributeLabel>bar
204
+ bar2</y:AttributeLabel>
205
+ <y:MethodLabel>foo()</y:MethodLabel-->
206
+ </y:UML>
207
+ </y:UMLClassNode>
208
+ </data>
209
+ <data key="d1">UMLClass</data>
210
+ </node>
211
+ EOS
212
+ end
213
+
214
+ def write_internal_node(node, class_name, kind)
215
+ @out << <<EOS
216
+ <node id="n#{ node }">
217
+ <data key="d0">
218
+ <y:UMLClassNode>
219
+ <y:Geometry height="102.0"
220
+ width="91.0"
221
+ x="4.5"
222
+ y="-1.0"/>
223
+ <y:Fill color="#CCFFCC"
224
+ transparent="false"/>
225
+ <y:BorderStyle color="#000000"
226
+ type="line"
227
+ width="1.0"/>
228
+ <y:NodeLabel alignment="center"
229
+ autoSizePolicy="content"
230
+ fontFamily="Dialog"
231
+ fontSize="13"
232
+ fontStyle="bold"
233
+ hasBackgroundColor="false"
234
+ hasLineColor="false"
235
+ height="19.310546875"
236
+ modelName="internal"
237
+ modelPosition="c"
238
+ textColor="#000000"
239
+ visible="true"
240
+ width="39.83251953125"
241
+ x="25.583740234375"
242
+ y="26.1328125">#{ class_name }
243
+ </y:NodeLabel>
244
+ <y:UML clipContent="true"
245
+ constraint=""
246
+ omitDetails="false"
247
+ stereotype="#{ kind }"
248
+ use3DEffect="false">
249
+ <!--y:AttributeLabel>bar</y:AttributeLabel>
250
+ <y:MethodLabel>foo()</y:MethodLabel-->
251
+ </y:UML>
252
+ </y:UMLClassNode>
253
+ </data>
254
+ <data key="d1">UMLClass</data>
255
+ </node>
256
+ EOS
257
+ end
258
+
259
+ def write_mixin_node(node, class_name)
260
+ @out << <<EOS
261
+ <node id="n#{ node }">
262
+ <data key="d0">
263
+ <y:UMLClassNode>
264
+ <y:Geometry height="102.0"
265
+ width="136.0"
266
+ x="-18.0"
267
+ y="349.0"/>
268
+ <y:Fill color="#FFCC99"
269
+ transparent="false"/>
270
+ <y:BorderStyle color="#000000"
271
+ type="line"
272
+ width="1.0"/>
273
+ <y:NodeLabel alignment="center"
274
+ autoSizePolicy="content"
275
+ fontFamily="Dialog"
276
+ fontSize="13"
277
+ fontStyle="bold"
278
+ hasBackgroundColor="false"
279
+ hasLineColor="false"
280
+ height="19.310546875"
281
+ modelName="internal"
282
+ modelPosition="c"
283
+ textColor="#000000"
284
+ visible="true"
285
+ width="110.818359375"
286
+ x="12.5908203125"
287
+ y="26.1328125">#{ class_name }
288
+ </y:NodeLabel>
289
+ <y:UML clipContent="true"
290
+ constraint=""
291
+ omitDetails="false"
292
+ stereotype="mixin"
293
+ use3DEffect="false">
294
+ <!--y:AttributeLabel></y:AttributeLabel>
295
+ <y:MethodLabel></y:MethodLabel-->
296
+ </y:UML>
297
+ </y:UMLClassNode>
298
+ </data>
299
+ <data key="d1">UMLClass</data>
300
+ </node>
301
+ EOS
302
+ end
303
+
304
+ def write_entity_ref_edge(edge, class_node, external_node)
305
+ @out << <<EOS
306
+ <edge id="e#{ edge }"
307
+ source="n#{ class_node }"
308
+ target="n#{ external_node }">
309
+ <data key="d2">
310
+ <y:PolyLineEdge>
311
+ <y:Path sx="0.0"
312
+ sy="0.0"
313
+ tx="0.0"
314
+ ty="0.0"/>
315
+ <y:LineStyle color="#000000"
316
+ type="line"
317
+ width="2.0"/>
318
+ <y:Arrows source="none"
319
+ target="short"/>
320
+ <y:EdgeLabel alignment="center"
321
+ distance="2.0"
322
+ fontFamily="Dialog"
323
+ fontSize="12"
324
+ fontStyle="plain"
325
+ hasBackgroundColor="false"
326
+ hasLineColor="false"
327
+ height="4.0"
328
+ modelName="six_pos"
329
+ modelPosition="tail"
330
+ preferredPlacement="anywhere"
331
+ ratio="0.5"
332
+ textColor="#000000"
333
+ visible="true"
334
+ width="4.0"
335
+ x="30.000732421875"
336
+ y="2.0"></y:EdgeLabel>
337
+ <y:BendStyle smoothed="false"/>
338
+ </y:PolyLineEdge>
339
+ </data>
340
+ <data key="d3">UMLuses</data>
341
+ </edge>
342
+ EOS
343
+ end
344
+
345
+ def write_internal_ref_edge(edge, class_node, internal_node)
346
+ @out << <<EOS
347
+ <edge id="e#{ edge }"
348
+ source="n#{ class_node }"
349
+ target="n#{ internal_node }">
350
+ <data key="d2">
351
+ <y:PolyLineEdge>
352
+ <y:Path sx="0.0"
353
+ sy="0.0"
354
+ tx="0.0"
355
+ ty="0.0"/>
356
+ <y:LineStyle color="#000000"
357
+ type="line"
358
+ width="1.0"/>
359
+ <y:Arrows source="none"
360
+ target="short"/>
361
+ <y:EdgeLabel alignment="center"
362
+ distance="2.0"
363
+ fontFamily="Dialog"
364
+ fontSize="12"
365
+ fontStyle="plain"
366
+ hasBackgroundColor="false"
367
+ hasLineColor="false"
368
+ height="4.0"
369
+ modelName="six_pos"
370
+ modelPosition="tail"
371
+ preferredPlacement="anywhere"
372
+ ratio="0.5"
373
+ textColor="#000000"
374
+ visible="true"
375
+ width="4.0"
376
+ x="2.0"
377
+ y="-38.529541015625"></y:EdgeLabel>
378
+ <y:BendStyle smoothed="false"/>
379
+ </y:PolyLineEdge>
380
+ </data>
381
+ <data key="d3">UMLuses</data>
382
+ </edge>
383
+ EOS
384
+ end
385
+
386
+ def write_mixin_ref_edge(edge, class_node, mixin_node)
387
+ @out << <<EOS
388
+ <edge id="e#{ edge }"
389
+ source="n#{ class_node }"
390
+ target="n#{ mixin_node }">
391
+ <data key="d2">
392
+ <y:PolyLineEdge>
393
+ <y:Path sx="0.0"
394
+ sy="0.0"
395
+ tx="0.0"
396
+ ty="0.0"/>
397
+ <y:LineStyle color="#000000"
398
+ type="line"
399
+ width="1.0"/>
400
+ <y:Arrows source="none"
401
+ target="white_delta"/>
402
+ <y:EdgeLabel alignment="center"
403
+ distance="2.0"
404
+ fontFamily="Dialog"
405
+ fontSize="12"
406
+ fontStyle="plain"
407
+ hasBackgroundColor="false"
408
+ hasLineColor="false"
409
+ height="4.0"
410
+ modelName="six_pos"
411
+ modelPosition="tail"
412
+ preferredPlacement="anywhere"
413
+ ratio="0.5"
414
+ textColor="#000000"
415
+ visible="true"
416
+ width="4.0"
417
+ x="2.0"
418
+ y="34.529541015625"></y:EdgeLabel>
419
+ <y:BendStyle smoothed="false"/>
420
+ </y:PolyLineEdge>
421
+ </data>
422
+ <data key="d3">UMLinherits</data>
423
+ </edge>
424
+ EOS
425
+ end
426
+
427
+ def write_graphml_start(nodes, edges)
428
+ @out << <<EOS
429
+ <?xml version="1.0" encoding="UTF-8"?>
430
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
431
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
432
+ xmlns:y="http://www.yworks.com/xml/graphml"
433
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd">
434
+ <key for="node"
435
+ id="d0"
436
+ yfiles.type="nodegraphics"/>
437
+ <key attr.name="description"
438
+ attr.type="string"
439
+ for="node"
440
+ id="d1"/>
441
+ <key for="edge"
442
+ id="d2"
443
+ yfiles.type="edgegraphics"/>
444
+ <key attr.name="description"
445
+ attr.type="string"
446
+ for="edge"
447
+ id="d3"/>
448
+ <key for="graphml"
449
+ id="d4"
450
+ yfiles.type="resources"/>
451
+ <graph edgedefault="directed"
452
+ id="G"
453
+ parse.edges="#{ edges }"
454
+ parse.nodes="#{ nodes }"
455
+ parse.order="free">
456
+ EOS
457
+ end
458
+
459
+ def write_graphml_end
460
+ @out << <<EOS
461
+ </graph>
462
+ <data key="d4">
463
+ <y:Resources/>
464
+ </data>
465
+ </graphml>
466
+ EOS
467
+ end
468
+
469
+ end
470
+ end