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 +1 -1
- data/examples/random-people-shared-addresses/xampl-gen.rb +1 -1
- data/lib/xamplr/graphml-out.rb +470 -0
- data/lib/xamplr/persistence.rb +5 -0
- data/lib/xamplr/persister.rb +12 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb +4 -0
- data/lib/xamplr/xampl-generator.rb +5 -1
- data/lib/xamplr/yEd-sample.graphml +300 -0
- metadata +4 -6
- data/examples/random-people-shared-addresses/results.write.BASELINE +0 -298
- data/examples/random-people-shared-addresses/results.write.NEW_ATTR_ENCODING +0 -294
- data/examples/read-testing/results.read.BASELINE +0 -6
- data/examples/read-testing/results.read.FAST +0 -5
data/VERSION.yml
CHANGED
@@ -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
|