activefacts-generators 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +30 -0
  8. data/Rakefile +6 -0
  9. data/activefacts-generators.gemspec +26 -0
  10. data/lib/activefacts/dependency_analyser.rb +182 -0
  11. data/lib/activefacts/generators/absorption.rb +71 -0
  12. data/lib/activefacts/generators/composition.rb +119 -0
  13. data/lib/activefacts/generators/cql.rb +715 -0
  14. data/lib/activefacts/generators/diagrams/json.rb +340 -0
  15. data/lib/activefacts/generators/help.rb +64 -0
  16. data/lib/activefacts/generators/helpers/inject.rb +16 -0
  17. data/lib/activefacts/generators/helpers/oo.rb +162 -0
  18. data/lib/activefacts/generators/helpers/ordered.rb +605 -0
  19. data/lib/activefacts/generators/helpers/rails.rb +57 -0
  20. data/lib/activefacts/generators/html/glossary.rb +462 -0
  21. data/lib/activefacts/generators/metadata/json.rb +204 -0
  22. data/lib/activefacts/generators/null.rb +32 -0
  23. data/lib/activefacts/generators/rails/models.rb +247 -0
  24. data/lib/activefacts/generators/rails/schema.rb +217 -0
  25. data/lib/activefacts/generators/ruby.rb +134 -0
  26. data/lib/activefacts/generators/sql/mysql.rb +281 -0
  27. data/lib/activefacts/generators/sql/server.rb +274 -0
  28. data/lib/activefacts/generators/stats.rb +70 -0
  29. data/lib/activefacts/generators/text.rb +29 -0
  30. data/lib/activefacts/generators/traits/datavault.rb +241 -0
  31. data/lib/activefacts/generators/traits/oo.rb +73 -0
  32. data/lib/activefacts/generators/traits/ordered.rb +33 -0
  33. data/lib/activefacts/generators/traits/ruby.rb +210 -0
  34. data/lib/activefacts/generators/transform/datavault.rb +303 -0
  35. data/lib/activefacts/generators/transform/surrogate.rb +215 -0
  36. data/lib/activefacts/registry.rb +11 -0
  37. metadata +176 -0
@@ -0,0 +1,605 @@
1
+ #
2
+ # ActiveFacts Generators.
3
+ # Generation support superclass that sequences entity types to avoid forward references.
4
+ #
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ require 'activefacts/api'
8
+ require 'activefacts/generators/helpers/inject'
9
+ require 'activefacts/generators/traits/ordered'
10
+
11
+ module ActiveFacts
12
+ module Generators #:nodoc:
13
+ module Helpers #:nodoc:
14
+ class OrderedDumper #:nodoc:
15
+ # Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
16
+ def initialize(vocabulary, *options)
17
+ @vocabulary = vocabulary
18
+ @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
19
+ options.each{|option| set_option(option) }
20
+ end
21
+
22
+ def set_option(option)
23
+ end
24
+
25
+ def puts(*a)
26
+ @out.puts *a
27
+ end
28
+
29
+ def print(*a)
30
+ @out.print *a
31
+ end
32
+
33
+ def generate(out = $>)
34
+ @out = out
35
+ vocabulary_start
36
+ units_dump
37
+ value_types_dump
38
+ entity_types_dump
39
+ fact_types_dump
40
+ constraints_dump
41
+ vocabulary_end
42
+ end
43
+
44
+ def units_dump
45
+ done_banner = false
46
+ units = @vocabulary.all_unit.to_a.sort_by{|u| u.name.gsub(/ /,'')}
47
+ while units.size > 0
48
+ i = 0
49
+ while i < units.size
50
+ unit = units[i]
51
+ i += 1
52
+
53
+ # Skip this one if the precursors haven't yet been dumped:
54
+ next if unit.all_derivation_as_derived_unit.detect{|d| units.include?(d.base_unit) }
55
+
56
+ # Even if we skip, we're done with this unit
57
+ units.delete(unit)
58
+ i -= 1
59
+
60
+ # Skip value-type derived units
61
+ next if unit.name =~ /\^/
62
+
63
+ if !done_banner
64
+ done_banner = true
65
+ units_banner
66
+ end
67
+ unit_dump(unit)
68
+ end
69
+ end
70
+ units_end if done_banner
71
+ end
72
+
73
+ def value_type_fork(o)
74
+ if o.name == "_ImplicitBooleanValueType"
75
+ # do nothing
76
+ elsif
77
+ !o.supertype # No supertype, i.e. a base type
78
+ o.all_role.size == 0 && # No roles
79
+ !o.is_independent && # not independent
80
+ !o.value_constraint && # No value constraints
81
+ o.concept.all_context_note_as_relevant_concept.size == 0 && # No context notes
82
+ o.all_instance.size == 0 # No instances
83
+ data_type_dump(o)
84
+ else
85
+ super_type_name = o.supertype ? o.supertype.name : o.name
86
+ length = (l = o.length) && l > 0 ? "#{l}" : nil
87
+ scale = (s = o.scale) && s > 0 ? "#{s}" : nil
88
+ facets = { :length => length, :scale => scale }
89
+ value_type_dump(o, super_type_name, facets)
90
+ end
91
+ end
92
+
93
+ def value_types_dump
94
+ done_banner = false
95
+ @vocabulary.all_object_type.sort_by{|o| o.name.gsub(/ /,'')}.each{|o|
96
+ next unless o.is_a?(ActiveFacts::Metamodel::ValueType)
97
+
98
+ value_type_banner unless done_banner
99
+ done_banner = true
100
+
101
+ value_type_chain_dump(o)
102
+ # @object_types_dumped[o] = true
103
+ o.ordered_dumped!
104
+ }
105
+ value_type_end if done_banner
106
+ end
107
+
108
+ # Ensure that supertype gets dumped first
109
+ def value_type_chain_dump(o)
110
+ return if o.ordered_dumped
111
+ value_type_chain_dump(o.supertype) if (o.supertype && !o.supertype.ordered_dumped)
112
+ value_type_fork(o)
113
+ o.ordered_dumped!
114
+ end
115
+
116
+ # Try to dump entity types in order of name, but we need
117
+ # to dump ETs before they're referenced in preferred ids
118
+ # if possible (it's not always, there may be loops!)
119
+ def entity_types_dump
120
+ # Build hash tables of precursors and followers to use:
121
+ @precursors, @followers = *build_entity_dependencies
122
+
123
+ done_banner = false
124
+ sorted = @vocabulary.all_object_type.select{|o|
125
+ o.is_a?(ActiveFacts::Metamodel::EntityType) # and !o.fact_type
126
+ }.sort_by{|o| o.name.gsub(/ /,'')}
127
+ panic = nil
128
+ while true do
129
+ count_this_pass = 0
130
+ skipped_this_pass = 0
131
+ sorted.each{|o|
132
+ next if o.ordered_dumped # Already done
133
+
134
+ trace :ordered, "Panicing to dump #{panic.name}" if panic
135
+ # Can we do this yet?
136
+ remaining_precursors = Array(@precursors[o])-[o]
137
+ if (o != panic and # We don't *have* to do it (panic mode)
138
+ remaining_precursors.size > 0) # precursors - still blocked
139
+ trace :ordered, "Can't dump #{o.name} despite panic for #{panic.name}, it still needs #{remaining_precursors.map(&:name)*', '}" if panic
140
+ skipped_this_pass += 1
141
+ next
142
+ end
143
+ trace :ordered, "Dumping #{o.name} in panic mode, even though it still needs #{remaining_precursors.map(&:name)*', '}" if panic
144
+
145
+ entity_type_banner unless done_banner
146
+ done_banner = true
147
+
148
+ # We're going to emit o - remove it from precursors of others:
149
+ (@followers[o]||[]).each{|f|
150
+ @precursors[f] -= [o]
151
+ }
152
+ count_this_pass += 1
153
+ panic = nil
154
+
155
+ if (o.fact_type)
156
+ fact_type_dump_with_dependents(o.fact_type)
157
+ released_fact_types_dump(o)
158
+ else
159
+ entity_type_dump(o)
160
+ released_fact_types_dump(o)
161
+ end
162
+
163
+ entity_type_group_end
164
+ }
165
+
166
+ # Check that we made progress if there's any to make:
167
+ if count_this_pass == 0 && skipped_this_pass > 0
168
+ =begin
169
+ if panic # We were already panicing... what to do now?
170
+ # This won't happen again unless the above code is changed to decide it can't dump "panic".
171
+ bad = sorted.select do |o|
172
+ o.is_a?(ActiveFacts::Metamodel::EntityType) &&
173
+ !o.ordered_dumped &&
174
+ (Array(@precursors[o])-[o]).size > 0 &&
175
+ (Array(@followers[o])-[o]).size > 0
176
+ end
177
+
178
+ raise "Unresolvable cycle of forward references: " +
179
+ bad.map { |o| o.name }*', ' +
180
+ ":\n\t" +
181
+ (
182
+ bad.map do |o|
183
+ o.name +
184
+ " depends on " +
185
+ (@precursors[o].uniq.map{|p| p.name}.sort*', ')
186
+ end
187
+ ) * "\n\t" +
188
+ "\n"
189
+ =end
190
+ # else
191
+ # Find the object that has the most followers and no fwd-ref'd supertypes:
192
+ # This selection might be better if we allow PI roles to be fwd-ref'd...
193
+ panic = sorted.
194
+ select{|o| !o.ordered_dumped }.
195
+ sort_by{|o|
196
+ f = (@followers[o] || []) - [o];
197
+ o.supertypes.detect{|s| !s.ordered_dumped } ? 0 : -f.size
198
+ }[0]
199
+ trace :ordered, "Panic mode, selected #{panic.name} next"
200
+ # end
201
+ end
202
+
203
+ break if skipped_this_pass == 0 # All done.
204
+
205
+ end
206
+ end
207
+
208
+ def identified_by(o, pi)
209
+ # Different adjectives might be used for different readings.
210
+ # Here, we must find the role_ref containing the adjectives that we need for each identifier,
211
+ # which will be attached to the uniqueness constraint on this object in the binary FT that
212
+ # attaches that identifying role.
213
+ identifying_role_refs = pi.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
214
+
215
+ # We need to get the adjectives for the roles from the identifying fact's preferred readings:
216
+ identifying_facts = ([o.fact_type]+identifying_role_refs.map{|rr| rr.role.fact_type }).compact.uniq
217
+
218
+ identification = identified_by_roles_and_facts(o, identifying_role_refs, identifying_facts)
219
+
220
+ identification
221
+ end
222
+
223
+ def describe_fact_type(fact_type, highlight = nil)
224
+ (fact_type.entity_type ? fact_type.entity_type.name : "")+
225
+ describe_roles(fact_type.all_role, highlight)
226
+ end
227
+
228
+ def describe_roles(roles, highlight = nil)
229
+ "("+
230
+ roles.map{|role| role.object_type.name + (role == highlight ? "*" : "")}*", "+
231
+ ")"
232
+ end
233
+
234
+ def describe_role_sequence(role_sequence)
235
+ "("+
236
+ role_sequence.all_role_ref.map{|role_ref| role_ref.role.object_type.name }*", "+
237
+ ")"
238
+ end
239
+
240
+ # This returns an array of two hash tables each keyed by an EntityType.
241
+ # The values of each hash entry are the precursors and followers (respectively) of that entity.
242
+ def build_entity_dependencies
243
+ @vocabulary.all_object_type.inject([{},{}]) { |a, o|
244
+ if o.is_a?(ActiveFacts::Metamodel::EntityType)
245
+ precursor = a[0]
246
+ follower = a[1]
247
+ blocked = false
248
+ pi = o.preferred_identifier
249
+ if pi
250
+ pi.role_sequence.all_role_ref.each{|rr|
251
+ role = rr.role
252
+ player = role.object_type
253
+ # REVISIT: If we decide to emit value types on demand, need to remove this:
254
+ next unless player.is_a?(ActiveFacts::Metamodel::EntityType)
255
+ # player is a precursor of o
256
+ (precursor[o] ||= []) << player if (player != o)
257
+ (follower[player] ||= []) << o if (player != o)
258
+ }
259
+ end
260
+ if o.fact_type
261
+ o.fact_type.all_role.each do |role|
262
+ next unless role.object_type.is_a?(ActiveFacts::Metamodel::EntityType)
263
+ (precursor[o] ||= []) << role.object_type
264
+ (follower[role.object_type] ||= []) << o
265
+ end
266
+ end
267
+
268
+ # Supertypes are precursors too:
269
+ subtyping = o.all_type_inheritance_as_supertype
270
+ next a if subtyping.size == 0
271
+ subtyping.each{|ti|
272
+ # debug ti.class.roles.verbalise; trace "all_type_inheritance_as_supertype"; exit
273
+ s = ti.subtype
274
+ (precursor[s] ||= []) << o
275
+ (follower[o] ||= []) << s
276
+ }
277
+ # REVISIT: Need to use this to order ValueTypes after their supertypes
278
+ # else
279
+ # o.all_value_type_as_supertype.each { |s|
280
+ # (precursor[s] ||= []) << o
281
+ # (follower[o] ||= []) << s
282
+ # }
283
+ end
284
+ a
285
+ }
286
+ end
287
+
288
+ # Dump all fact types for which all precursors (of which "o" is one) have been emitted:
289
+ def released_fact_types_dump(o)
290
+ roles = o.all_role
291
+ begin
292
+ progress = false
293
+ roles.map(&:fact_type).uniq.select{|fact_type|
294
+ # The fact type hasn't already been dumped but all its role players have
295
+ !fact_type.ordered_dumped &&
296
+ !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType) &&
297
+ !fact_type.all_role.detect{|r| !r.object_type.ordered_dumped } &&
298
+ !fact_type.entity_type &&
299
+ derivation_precursors_complete(fact_type)
300
+ # REVISIT: A derived fact type must not be dumped before its dependent fact types have
301
+ }.sort_by{|fact_type|
302
+ fact_type_key(fact_type)
303
+ }.each{|fact_type|
304
+ fact_type_dump_with_dependents(fact_type)
305
+ # Objectified Fact Types may release additional fact types
306
+ roles += fact_type.entity_type.all_role.sort_by{|role| role.ordinal} if fact_type.entity_type
307
+ progress = true
308
+ }
309
+ end while progress
310
+ end
311
+
312
+ def derivation_precursors_complete(fact_type)
313
+ pr = fact_type.preferred_reading
314
+ return true unless jr = pr.role_sequence.all_role_ref.to_a[0].play
315
+ query = jr.variable.query
316
+ return false if query.all_step.detect{|js| !js.fact_type.ordered_dumped }
317
+ return false if query.all_variable.detect{|jn| !jn.object_type.ordered_dumped }
318
+ true
319
+ end
320
+
321
+ def skip_fact_type(f)
322
+ return true if f.is_a?(ActiveFacts::Metamodel::TypeInheritance)
323
+ return false if f.entity_type && !f.entity_type.ordered_dumped
324
+
325
+ # REVISIT: There might be constraints we have to merge into the nested entity or subtype.
326
+ # These will come up as un-handled constraints:
327
+ # Dump this fact type only if it contains a presence constraint we've missed:
328
+ pcs = @presence_constraints_by_fact[f]
329
+ pcs && pcs.size > 0 && !pcs.detect{|c| !c.ordered_dumped }
330
+ end
331
+
332
+ # Dump one fact type.
333
+ # Include as many as possible internal constraints in the fact type readings.
334
+ def fact_type_dump_with_dependents(fact_type)
335
+ fact_type.ordered_dumped!
336
+ return if skip_fact_type(fact_type)
337
+
338
+ if (et = fact_type.entity_type) &&
339
+ (pi = et.preferred_identifier) &&
340
+ pi.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type != fact_type }
341
+ # trace "Dumping objectified FT #{et.name} as an entity, non-fact PI"
342
+ entity_type_dump(et)
343
+ released_fact_types_dump(et)
344
+ return
345
+ end
346
+
347
+ # trace "#{fact_type.name} has readings:\n\t#{fact_type.readings.map(&:name)*"\n\t"}"
348
+ # trace "Dumping #{fact_type.concept.guid} as a fact type"
349
+
350
+ # Fact types that aren't nested have no names
351
+ name = fact_type.entity_type && fact_type.entity_type.name
352
+
353
+ fact_type_dump(fact_type, name)
354
+
355
+ # REVISIT: Go through the residual constraints and re-process appropriate readings to show them
356
+
357
+ #CJH: Necessary?
358
+ fact_type.ordered_dumped!
359
+ fact_type.entity_type.ordered_dumped! if fact_type.entity_type
360
+ end
361
+
362
+ # Dump fact types.
363
+ def fact_types_dump
364
+ # REVISIT: Uniqueness on the LHS of a binary can be coded using "distinct"
365
+
366
+ # The only fact types that can be remaining are those involving only value types,
367
+ # since we dumped every fact type as soon as all relevant entities were dumped.
368
+ # Iterate over all fact types of all value types, looking for these strays.
369
+
370
+ done_banner = false
371
+ fact_collection = @vocabulary.constellation.FactType
372
+ fact_collection.keys.select{|fact_id|
373
+ fact_type = fact_collection[fact_id] and
374
+ !fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) and
375
+ !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType) and
376
+ !fact_type.ordered_dumped and
377
+ !skip_fact_type(fact_type) and
378
+ !fact_type.all_role.detect{|r| r.object_type.is_a?(ActiveFacts::Metamodel::EntityType) }
379
+ }.sort_by{|fact_id|
380
+ fact_type = fact_collection[fact_id]
381
+ fact_type_key(fact_type)
382
+ }.each{|fact_id|
383
+ fact_type = fact_collection[fact_id]
384
+
385
+ fact_type_banner unless done_banner
386
+ done_banner = true
387
+ fact_type_dump_with_dependents(fact_type)
388
+ }
389
+
390
+ # REVISIT: Find out why some fact types are missed during entity dumping:
391
+ @vocabulary.constellation.FactType.values.select{|fact_type|
392
+ !fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) &&
393
+ !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
394
+ }.sort_by{|fact_type|
395
+ fact_type_key(fact_type)
396
+ }.each{|fact_type|
397
+ next if fact_type.ordered_dumped
398
+ # trace "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.object_type.name}*", "})"
399
+ fact_type_banner unless done_banner
400
+ done_banner = true
401
+ fact_type_dump_with_dependents(fact_type)
402
+ }
403
+
404
+ fact_type_end if done_banner
405
+ end
406
+
407
+ def fact_instances_dump
408
+ @vocabulary.fact_types.each{|f|
409
+ # Dump the instances:
410
+ f.facts.each{|i|
411
+ raise "REVISIT: Not dumping fact instances"
412
+ trace "\t\t"+i.to_s
413
+ }
414
+ }
415
+ end
416
+
417
+ # Arrange for objectified fact types to appear in order of name, after other fact types.
418
+ # Facts are ordered alphabetically by the names of their role players,
419
+ # then by preferred_reading (subtyping fact types have no preferred_reading).
420
+ def fact_type_key(fact_type)
421
+ role_names =
422
+ if (pr = fact_type.preferred_reading)
423
+ pr.role_sequence.
424
+ all_role_ref.
425
+ sort_by{|role_ref| role_ref.ordinal}.
426
+ map{|role_ref| [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" } +
427
+ [pr.text]
428
+ else
429
+ fact_type.all_role.map{|role| role.object_type.name }
430
+ end
431
+
432
+ (fact_type.entity_type ? [fact_type.entity_type.name] : [""]) + role_names
433
+ end
434
+
435
+ def role_ref_key(role_ref)
436
+ [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" +
437
+ " in " +
438
+ role_ref.role.fact_type.preferred_reading.expand
439
+ end
440
+
441
+ def constraint_sort_key(c)
442
+ case c
443
+ when ActiveFacts::Metamodel::RingConstraint
444
+ [ 1,
445
+ c.ring_type,
446
+ c.role.object_type.name,
447
+ c.other_role.object_type.name,
448
+ c.name||""
449
+ ]
450
+ when ActiveFacts::Metamodel::SetExclusionConstraint
451
+ [ 2+(c.is_mandatory ? 0 : 1),
452
+ c.all_set_comparison_roles.map{|scrs|
453
+ scrs.role_sequence.all_role_ref.map{|rr|
454
+ role_ref_key(rr)
455
+ }
456
+ },
457
+ c.name||""
458
+ ]
459
+ when ActiveFacts::Metamodel::SetEqualityConstraint
460
+ [ 4,
461
+ c.all_set_comparison_roles.map{|scrs|
462
+ scrs.role_sequence.all_role_ref.map{|rr|
463
+ role_ref_key(rr)
464
+ }
465
+ },
466
+ c.name||""
467
+ ]
468
+ when ActiveFacts::Metamodel::SubsetConstraint
469
+ [ 5,
470
+ [c.superset_role_sequence, c.subset_role_sequence].map{|rs|
471
+ rs.all_role_ref.map{|rr|
472
+ role_ref_key(rr)
473
+ }
474
+ },
475
+ c.name||""
476
+ ]
477
+ when ActiveFacts::Metamodel::PresenceConstraint
478
+ [ 6,
479
+ c.role_sequence.all_role_ref.map{|rr|
480
+ role_ref_key(rr)
481
+ },
482
+ c.name||""
483
+ ]
484
+ end
485
+ end
486
+
487
+ def constraints_dump
488
+ heading = false
489
+ @vocabulary.
490
+ all_constraint.
491
+ reject{|c| c.ordered_dumped}.
492
+ sort_by{ |c| constraint_sort_key(c) }.
493
+ each do |c|
494
+ # Skip some PresenceConstraints:
495
+ if c.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
496
+ # Skip uniqueness constraints that cover all roles of a fact type, they're implicit
497
+ fact_types = c.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq
498
+ if fact_types.size == 1 &&
499
+ !c.role_sequence.all_role_ref.detect{|rr| rr.play } &&
500
+ c.max_frequency == 1 && # Uniqueness
501
+ fact_types[0].all_role.size == c.role_sequence.all_role_ref.size
502
+ next
503
+ end
504
+
505
+ # Skip internal PresenceConstraints over TypeInheritances:
506
+ next if c.role_sequence.all_role_ref.size == 1 &&
507
+ fact_types[0].is_a?(ActiveFacts::Metamodel::TypeInheritance)
508
+ end
509
+
510
+ constraint_banner unless heading
511
+ heading = true
512
+
513
+ # Skip presence constraints on value types:
514
+ # next if ActiveFacts::PresenceConstraint === c &&
515
+ # ActiveFacts::ValueType === c.object_type
516
+ constraint_dump(c)
517
+ end
518
+ constraint_end if heading
519
+ end
520
+
521
+ def vocabulary_start
522
+ trace "Should override vocabulary_start"
523
+ end
524
+
525
+ def vocabulary_end
526
+ trace "Should override vocabulary_end"
527
+ end
528
+
529
+ def units_banner
530
+ end
531
+
532
+ def units_end
533
+ end
534
+
535
+ def unit_dump unit
536
+ end
537
+
538
+ def value_type_banner
539
+ trace "Should override value_type_banner"
540
+ end
541
+
542
+ def value_type_end
543
+ trace "Should override value_type_end"
544
+ end
545
+
546
+ def data_type_dump(o)
547
+ trace "Should override data_type_dump"
548
+ end
549
+
550
+ def value_type_dump(o, super_type_name, facets)
551
+ trace "Should override value_type_dump"
552
+ end
553
+
554
+ def entity_type_banner
555
+ trace "Should override entity_type_banner"
556
+ end
557
+
558
+ def entity_type_group_end
559
+ trace "Should override entity_type_group_end"
560
+ end
561
+
562
+ def non_subtype_dump(o, pi)
563
+ trace "Should override non_subtype_dump"
564
+ end
565
+
566
+ def subtype_dump(o, supertypes, pi = nil)
567
+ trace "Should override subtype_dump"
568
+ end
569
+
570
+ def append_ring_to_reading(reading, ring)
571
+ trace "Should override append_ring_to_reading"
572
+ end
573
+
574
+ def fact_type_banner
575
+ trace "Should override fact_type_banner"
576
+ end
577
+
578
+ def fact_type_end
579
+ trace "Should override fact_type_end"
580
+ end
581
+
582
+ def fact_type_dump(fact_type, name)
583
+ trace "Should override fact_type_dump"
584
+ end
585
+
586
+ def constraint_banner
587
+ trace "Should override constraint_banner"
588
+ end
589
+
590
+ def constraint_end
591
+ trace "Should override constraint_end"
592
+ end
593
+
594
+ def constraint_dump(c)
595
+ trace "Should override constraint_dump"
596
+ end
597
+
598
+ end
599
+
600
+ def dump(vocabulary, out = $>)
601
+ OrderedDumper.new(vocabulary).dump(out)
602
+ end
603
+ end
604
+ end
605
+ end