hutch-xamplr 1.1.2 → 1.1.4

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