activefacts-generators 1.7.1

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