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,340 @@
1
+ #
2
+ # ActiveFacts Generators.
3
+ # Generate json output from a vocabulary, for loading into APRIMO
4
+ #
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ require 'json'
8
+ require 'digest/sha1'
9
+ require 'activefacts/registry'
10
+
11
+ module ActiveFacts
12
+ module Generators
13
+ module Diagrams
14
+ # Generate json output from a vocabulary, for loading into APRIMO.
15
+ # Invoke as
16
+ # afgen --diagrams/json <file>.cql=diagrams
17
+ class JSON
18
+ private
19
+ def initialize(vocabulary)
20
+ @vocabulary = vocabulary
21
+ @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
22
+ end
23
+
24
+ def puts(*a)
25
+ @out.puts *a
26
+ end
27
+
28
+ public
29
+ def generate(out = $>)
30
+ @out = out
31
+ uuids = {}
32
+
33
+ puts "{ model: '#{@vocabulary.name}',\n" +
34
+ "diagrams: [\n#{
35
+ @vocabulary.all_diagram.sort_by{|o| o.name.gsub(/ /,'')}.map do |d|
36
+ j = {:uuid => (uuids[d] ||= uuid_from_id(d)), :name => d.name}
37
+ " #{j.to_json}"
38
+ end*",\n"
39
+ }\n ],"
40
+
41
+ object_types = @vocabulary.all_object_type.sort_by{|o| o.name.gsub(/ /,'')}
42
+ puts " object_types: [\n#{
43
+ object_types.sort_by{|o|o.identifying_role_values.inspect}.map do |o|
44
+ uuids[o] ||= uuid_from_id(o)
45
+ ref_mode = nil
46
+ if o.is_a?(ActiveFacts::Metamodel::EntityType) and
47
+ p = o.preferred_identifier and
48
+ (rrs = p.role_sequence.all_role_ref).size == 1 and
49
+ (r = rrs.single.role).fact_type != o.fact_type and
50
+ r.object_type.is_a?(ActiveFacts::Metamodel::ValueType) and
51
+ !r.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
52
+ ref_mode = "#{r.object_type.name}"
53
+ ref_mode.sub!(%r{#{o.name} *}, '.')
54
+ end
55
+ j = {
56
+ :uuid => uuids[o],
57
+ :name => o.name,
58
+ :shapes => o.all_object_type_shape.sort_by{|s| [s.location.x, s.location.y]}.map do |shape|
59
+ x = { :diagram => uuids[shape.orm_diagram],
60
+ :is_expanded => shape.is_expanded,
61
+ :uuid => uuid_from_id(shape),
62
+ :x => shape.location.x,
63
+ :y => shape.location.y
64
+ }
65
+ x[:is_expanded] = true if ref_mode && shape.is_expanded # Don't show the reference mode
66
+ x
67
+ end
68
+ }
69
+ j[:ref_mode] = ref_mode if ref_mode
70
+ j[:independent] = true if o.is_independent
71
+
72
+ if o.is_a?(ActiveFacts::Metamodel::EntityType)
73
+ # Entity Type may be objectified, and may have supertypes:
74
+ if o.fact_type
75
+ uuid = (uuids[o.fact_type] ||= uuid_from_id(o.fact_type))
76
+ j[:objectifies] = uuid
77
+ j[:implicit] = true if o.concept.implication_rule
78
+ end
79
+ if o.all_type_inheritance_as_subtype.size > 0
80
+ j[:supertypes] = o.
81
+ all_type_inheritance_as_subtype.
82
+ sort_by{|ti| ti.provides_identification ? 0 : 1}.
83
+ map{|ti|
84
+ [ uuids[ti.supertype] ||= uuid_from_id(ti.supertype),
85
+ uuids[ti.supertype_role] = uuid_from_id(ti.supertype_role)
86
+ ]
87
+ }
88
+ end
89
+ else
90
+ # ValueType usually has a supertype:
91
+ if (o.supertype)
92
+ j[:supertype] = (uuids[o.supertype] ||= uuid_from_id(o.supertype))
93
+ end
94
+ end
95
+ # REVISIT: Place a ValueConstraint and shape
96
+ " #{j.to_json}"
97
+ end*",\n"
98
+ }\n ],"
99
+
100
+ fact_types = @vocabulary.constellation.
101
+ FactType.values.
102
+ reject{|ft|
103
+ ActiveFacts::Metamodel::LinkFactType === ft || ActiveFacts::Metamodel::TypeInheritance === ft
104
+ }
105
+ puts " fact_types: [\n#{
106
+ fact_types.sort_by{|f| f.identifying_role_values.inspect}.map do |f|
107
+ uuids[f] ||= uuid_from_id(f)
108
+ j = {:uuid => uuids[f]}
109
+
110
+ if f.entity_type
111
+ j[:objectified_as] = uuids[f.entity_type]
112
+ end
113
+
114
+ # Emit roles
115
+ roles = f.all_role.sort_by{|r| r.ordinal }
116
+ j[:roles] = roles.map do |role|
117
+ uuid = (uuids[role] ||= uuid_from_id(role))
118
+ # REVISIT: Internal Mandatory Constraints
119
+ # REVISIT: Place a ValueConstraint and shape
120
+ # REVISIT: Place a RoleName shape
121
+ {:uuid => uuid, :player => uuids[role.object_type]}
122
+ # N.B. The object_type shape to which this role is attached is not in the meta-model
123
+ # Attach to the closest instance on this diagram (if any)
124
+ end
125
+
126
+ # Emit readings. Each is a [role_order, text] pair
127
+ j[:readings] = f.all_reading.map do |r|
128
+ role_refs = r.role_sequence.all_role_ref_in_order
129
+ [
130
+ role_order(uuids, role_refs.map{|rr| rr.role}, roles),
131
+ r.text.gsub(/\{([0-9])\}/) do |insert|
132
+ role_ref = role_refs[$1.to_i]
133
+ la = role_ref.leading_adjective
134
+ la = nil if la == ''
135
+ ta = role_ref.trailing_adjective
136
+ ta = nil if ta == ''
137
+ (la ? la+'-' : '') +
138
+ (la && la.index(' ') ? ' ' : '') +
139
+ insert +
140
+ (ta && ta.index(' ') ? ' ' : '') +
141
+ (ta ? '-'+ta : '')
142
+ end
143
+ ]
144
+ end.sort_by{|(ro,text)| ro }.map do |(ro,text)|
145
+ [ ro, text ]
146
+ end
147
+
148
+ # Emit shapes
149
+ j[:shapes] = f.all_fact_type_shape.sort_by{|s| [s.location.x, s.location.y]}.map do |shape|
150
+ sj = {
151
+ :diagram => uuids[shape.orm_diagram],
152
+ :uuid => uuid_from_id(shape),
153
+ :x => shape.location.x,
154
+ :y => shape.location.y
155
+ }
156
+
157
+ # Add the role_order, if specified
158
+ if shape.all_role_display.size > 0
159
+ if shape.all_role_display.size != roles.size
160
+ raise "Invalid RoleDisplay for #{f.default_reading} in #{shape.orm_diagram.name} diagram"
161
+ end
162
+ ro = role_order(
163
+ uuids,
164
+ shape.all_role_display.sort_by{|rd| rd.ordinal }.map{|rd| rd.role },
165
+ roles
166
+ )
167
+ sj[:role_order] = ro if ro
168
+ end
169
+
170
+ # REVISIT: Place the ReadingShape
171
+
172
+ # Emit the location of the name, if objectified
173
+ if n = shape.objectified_fact_type_name_shape
174
+ sj[:name_shape] = {:x => n.location.x, :y => n.location.y}
175
+ end
176
+ sj
177
+ end
178
+
179
+ # Emit Internal Presence Constraints
180
+ f.internal_presence_constraints.to_a.sort_by{|ipc, z|
181
+ [ipc.is_preferred_identifier ? 0 : 1, ipc.is_mandatory ? 0 : 1, ipc.min_frequency || 0, ipc.max_frequency || 1_000]
182
+ }.each do |ipc|
183
+ uuid = (uuids[ipc] ||= uuid_from_id(ipc))
184
+
185
+ constraint = {
186
+ :uuid => uuid,
187
+ :min => ipc.min_frequency,
188
+ :max => ipc.max_frequency,
189
+ :is_preferred => ipc.is_preferred_identifier,
190
+ :mandatory => ipc.is_mandatory
191
+ }
192
+
193
+ # Get the role (or excluded role, for a UC)
194
+ roles = ipc.role_sequence.all_role_ref_in_order.map{|r| r.role}
195
+ if roles.size > 1 || (!ipc.is_mandatory && ipc.max_frequency == 1)
196
+ # This can be only a uniqueness constraint. Record the missing role, if any
197
+ role = (f.all_role.to_a - roles)[0]
198
+ constraint[:uniqueExcept] = uuids[role]
199
+ else
200
+ # An internal mandatory or frequency constraint applies to only one role.
201
+ # If it's also unique (max == 1), that applies on the counterpart role.
202
+ # You can also have a mandatory frequency constraint, but that applies on this role.
203
+ constraint[:role] = uuids[roles[0]]
204
+ end
205
+ (j[:constraints] ||= []) << constraint
206
+ end
207
+
208
+ # Add ring constraints
209
+ f.all_role_in_order.
210
+ map{|r| r.all_ring_constraint.to_a+r.all_ring_constraint_as_other_role.to_a }.
211
+ flatten.uniq.each do |ring|
212
+ (j[:constraints] ||= []) << {
213
+ :uuid => (uuids[ring] ||= uuid_from_id(ring)),
214
+ :shapes => ring.all_constraint_shape.sort_by{|s| [s.location.x, s.location.y]}.map do |shape|
215
+ { :diagram => uuids[shape.orm_diagram],
216
+ :uuid => uuid_from_id(shape),
217
+ :x => shape.location.x,
218
+ :y => shape.location.y
219
+ }
220
+ end,
221
+ :ringKind => ring.ring_type,
222
+ :roles => [uuids[ring.role], uuids[ring.other_role]]
223
+ # REVISIT: Deontic, enforcement
224
+ }
225
+ end
226
+
227
+ # REVISIT: RotationSetting
228
+
229
+ " #{j.to_json}"
230
+ end*",\n"
231
+ }\n ],"
232
+
233
+ constraints = @vocabulary.constellation.
234
+ Constraint.values
235
+ puts " constraints: [\n#{
236
+ constraints.sort_by{|c|c.identifying_role_values.inspect}.select{|c| !uuids[c]}.map do |c|
237
+ uuid = uuids[c] ||= uuid_from_id(c)
238
+ j = {
239
+ :uuid => uuid,
240
+ :type => c.class.basename,
241
+ :shapes => c.all_constraint_shape.sort_by{|s| [s.location.x, s.location.y]}.map do |shape|
242
+ { :diagram => uuids[shape.orm_diagram],
243
+ :uuid => uuid_from_id(shape),
244
+ :x => shape.location.x,
245
+ :y => shape.location.y
246
+ }
247
+ end
248
+ }
249
+
250
+ if (c.enforcement)
251
+ # REVISIT: Deontic constraint
252
+ end
253
+ if (c.concept.all_context_note_as_relevant_concept.size > 0)
254
+ # REVISIT: Context Notes
255
+ end
256
+
257
+ case c
258
+ when ActiveFacts::Metamodel::PresenceConstraint
259
+ j[:min_frequency] = c.min_frequency
260
+ j[:max_frequency] = c.max_frequency
261
+ j[:is_mandatory] = c.is_mandatory
262
+ j[:is_preferred_identifier] = c.is_preferred_identifier
263
+ rss = [c.role_sequence.all_role_ref_in_order.map(&:role)]
264
+
265
+ # Ignore internal presence constraints on TypeInheritance fact types
266
+ next nil if !c.role_sequence.all_role_ref.
267
+ detect{|rr|
268
+ !rr.role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
269
+ }
270
+
271
+ when ActiveFacts::Metamodel::RingConstraint
272
+ next nil # These are emitted with the corresponding fact type
273
+
274
+ when ActiveFacts::Metamodel::SetComparisonConstraint
275
+ rss = c.
276
+ all_set_comparison_roles.sort_by{|scr| scr.ordinal}.
277
+ map{|scr| scr.role_sequence.all_role_ref_in_order.map(&:role) }
278
+ if (ActiveFacts::Metamodel::SetExclusionConstraint === c)
279
+ j[:is_mandatory] = c.is_mandatory
280
+ end
281
+
282
+ when ActiveFacts::Metamodel::SubsetConstraint
283
+ rss = [c.subset_role_sequence, c.superset_role_sequence].
284
+ map{|rs| rs.all_role_ref_in_order.map(&:role) }
285
+
286
+ when ActiveFacts::Metamodel::ValueConstraint
287
+ next nil # REVISIT: Should have been handled elsewhere
288
+ if (c.role)
289
+ # Should have been handled as role.role_value_constraint
290
+ elsif (c.value_type)
291
+ # Should have been handled as object_type.value_constraint
292
+ end
293
+ j[:allowed_ranges] = c.all_allowed_range.map{|ar|
294
+ [ ar.value_range.minimum_bound, ar.value_range.maximum_bound ].
295
+ map{|b| [b.value.literal, b.value.unit.name, b.is_inclusive] }
296
+ }
297
+
298
+ else
299
+ raise "REVISIT: Constraint type not yet dumped to JSON"
300
+ end
301
+
302
+ # rss contains the constrained role sequences; map to uuids
303
+ j[:role_sequences] = rss.map{|rs|
304
+ rs.map do |role|
305
+ uuids[role]
306
+ end
307
+ }
308
+
309
+ " #{j.to_json}"
310
+ end.compact*",\n"
311
+ }\n ]"
312
+
313
+ puts "}"
314
+ end
315
+
316
+ def role_order(uuids, roles, order)
317
+ if (roles.size > 9)
318
+ roles.map{|r| uuids[r] }
319
+ else
320
+ roles.map{|r| order.index(r).to_s }*''
321
+ end
322
+ end
323
+
324
+ def uuid_from_id o
325
+ irvs = o.identifying_role_values.inspect
326
+ d = Digest::SHA1.digest irvs
327
+ # $stderr.puts "#{o.class.basename}: #{irvs}"
328
+ d[0,4].unpack("H8")[0]+'-'+
329
+ d[4,2].unpack("H4")[0]+'-'+
330
+ d[6,2].unpack("H4")[0]+'-'+
331
+ d[8,2].unpack("H4")[0]+'-'+
332
+ d[10,6].unpack("H6")[0]
333
+ end
334
+
335
+ end
336
+ end
337
+ end
338
+ end
339
+
340
+ ActiveFacts::Registry.generator('diagrams/json', ActiveFacts::Generators::Diagrams::JSON)
@@ -0,0 +1,64 @@
1
+ #
2
+ # ActiveFacts Generators.
3
+ # Provides help for afgen - from afgen --help
4
+ #
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ require 'activefacts/registry'
8
+
9
+ module ActiveFacts
10
+ module Generators
11
+ # Generate nothing from an ActiveFacts vocabulary. This is useful to check the file can be read ok.
12
+ # Invoke as
13
+ # afgen --null <file>.cql
14
+ class HELP
15
+ private
16
+ def initialize(vocabulary, *options)
17
+ generators = $:.
18
+ map{|path|
19
+ Dir[path+"/activefacts/generators/**/*.rb"].
20
+ reject{|p|
21
+ p =~ %r{/(transform|helpers)/}
22
+ }.
23
+ map{|p|
24
+ p.sub(%r{.*/activefacts/generators/}, '').sub(/\.rb/,'')
25
+ }
26
+ }
27
+ transformers = $:.
28
+ map{|path|
29
+ Dir[path+"/activefacts/generators/transform/**/*.rb"].
30
+ map{|p|
31
+ p.sub(%r{.*/activefacts/generators/}, '').sub(/\.rb/,'')
32
+ }
33
+ }
34
+
35
+ puts %Q{
36
+ Usage: afgen [ --transformer[=options] ... ] [ --generator[=options] ... ] file.inp[=options]
37
+ options are comma-separated lists. Use =help to get more information.
38
+
39
+ Available generators are:
40
+ #{generators.flatten.uniq.sort.join("\n\t")
41
+ }
42
+
43
+ Available transformers are:
44
+ #{transformers.flatten.uniq.sort.join("\n\t")
45
+ }
46
+
47
+ inp is the name of a file input handler. Available input handlers are:
48
+ #{$:.map{|path|
49
+ Dir[path+"/activefacts/input/**.rb"].map{|p|
50
+ p.sub(%r{.*/}, '').sub(/\.rb/,'')
51
+ }
52
+ }.flatten.uniq.sort.join("\n\t")
53
+ }
54
+ }
55
+ end
56
+
57
+ public
58
+ def generate(out = $>)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ ActiveFacts::Registry.generator('help', ActiveFacts::Generators::HELP)
@@ -0,0 +1,16 @@
1
+ require 'activefacts/metamodel'
2
+
3
+ module ActiveFacts
4
+ module TraitInjector
5
+ def self.included other
6
+ overlap = Metamodel.constants & other.constants
7
+ overlap.each do |const|
8
+ mix_into = Metamodel.const_get(const)
9
+ mix_in = other.const_get(const)
10
+ mix_into.instance_exec {
11
+ include(mix_in)
12
+ }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,162 @@
1
+ #
2
+ # ActiveFacts Generators.
3
+ # Base class for generators of class libraries in any object-oriented language that supports the ActiveFacts API.
4
+ #
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ require 'activefacts/metamodel'
8
+ require 'activefacts/generators/helpers/ordered'
9
+ require 'activefacts/generators/traits/oo'
10
+
11
+ module ActiveFacts
12
+ module Generators
13
+
14
+ module Helpers
15
+ # Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
16
+ class OO < OrderedDumper #:nodoc:
17
+ def constraints_dump
18
+ # Stub, not needed.
19
+ end
20
+
21
+ def value_type_banner
22
+ end
23
+
24
+ def value_type_end
25
+ end
26
+
27
+ def entity_type_dump(o)
28
+ o.ordered_dumped!
29
+ pi = o.preferred_identifier
30
+
31
+ supers = o.supertypes
32
+ if (supers.size > 0)
33
+ # Ignore identification by a supertype:
34
+ pi = nil if pi && pi.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) }
35
+ subtype_dump(o, supers, pi)
36
+ else
37
+ non_subtype_dump(o, pi)
38
+ end
39
+ pi.ordered_dumped! if pi
40
+ end
41
+
42
+ # Dump the roles for an object type (excluding the roles of a fact type which is objectified)
43
+ def roles_dump(o)
44
+ o.all_role.
45
+ select{|role|
46
+ role.fact_type.all_role.size <= 2 &&
47
+ !role.fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
48
+ }.
49
+ sort_by{|role|
50
+ other_role = role.fact_type.all_role.select{|r2| r2 != role}[0] || role
51
+ other_role.preferred_role_name(o) + ':' + role.preferred_role_name(other_role.object_type)
52
+ }.each{|role|
53
+ role_dump(role)
54
+ }
55
+ end
56
+
57
+ def role_dump(role)
58
+ fact_type = role.fact_type
59
+ if fact_type.all_role.size == 1
60
+ unary_dump(role, role.preferred_role_name)
61
+ return
62
+ end
63
+ return if role.fact_type.entity_type
64
+
65
+ if fact_type.all_role.size != 2
66
+ # Shouldn't come here, except perhaps for an invalid model
67
+ return # ternaries and higher are always objectified
68
+ end
69
+
70
+ # REVISIT: TypeInheritance
71
+ if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
72
+ # trace "Ignoring role #{role} in #{fact_type}, subtype fact type"
73
+ # REVISIT: What about secondary subtypes?
74
+ # REVISIT: What about dumping the relational mapping when using separate tables?
75
+ return
76
+ end
77
+
78
+ return unless role.is_functional
79
+
80
+ other_role = fact_type.all_role.select{|r| r != role}[0]
81
+ other_role_name = other_role.preferred_role_name
82
+ other_player = other_role.object_type
83
+
84
+ # It's a one_to_one if there's a uniqueness constraint on the other role:
85
+ one_to_one = other_role.is_functional
86
+ return if one_to_one &&
87
+ !other_role.object_type.ordered_dumped
88
+
89
+ # Find role name:
90
+ role_method = role.preferred_role_name
91
+ other_role_method = one_to_one ? role_method : "all_"+role_method
92
+ # puts "---"+role.role_name if role.role_name
93
+ if other_role_name != other_player.oo_default_role_name and
94
+ role_method == role.object_type.oo_default_role_name
95
+ # debugger
96
+ other_role_method += "_as_#{other_role_name}"
97
+ end
98
+
99
+ role_name = role_method
100
+ role_name = nil if role_name == role.object_type.oo_default_role_name
101
+
102
+ b = role.ruby_role_definition
103
+ puts b
104
+
105
+ # binary_dump(role, other_role_name, other_player, role.is_mandatory, one_to_one, nil, role_name, other_role_method)
106
+ end
107
+
108
+ def skip_fact_type(f)
109
+ # REVISIT: There might be constraints we have to merge into the nested entity or subtype. These will come up as un-handled constraints.
110
+ !f.entity_type ||
111
+ f.is_a?(ActiveFacts::Metamodel::TypeInheritance)
112
+ end
113
+
114
+ # An objectified fact type has internal roles that are always "has_one":
115
+ def fact_roles_dump(fact_type)
116
+ fact_type.all_role.sort_by{|role|
117
+ role.preferred_role_name(fact_type.entity_type)
118
+ }.each{|role|
119
+ role_name = role.preferred_role_name(fact_type.entity_type)
120
+ one_to_one = role.is_unique
121
+ as = role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : ""
122
+ # debugger if as != ''
123
+ raise "Fact #{fact_type.describe} type is not objectified" unless fact_type.entity_type
124
+ other_role_method = (one_to_one ? "" : "all_") +
125
+ fact_type.entity_type.oo_default_role_name +
126
+ as
127
+ binary_dump(role, role_name, role.object_type, true, one_to_one, nil, nil, other_role_method)
128
+ }
129
+ end
130
+
131
+ def entity_type_banner
132
+ end
133
+
134
+ def entity_type_group_end
135
+ end
136
+
137
+ def append_ring_to_reading(reading, ring)
138
+ # REVISIT: trace "Should override append_ring_to_reading"
139
+ end
140
+
141
+ def fact_type_banner
142
+ end
143
+
144
+ def fact_type_end
145
+ end
146
+
147
+ def constraint_banner
148
+ # trace "Should override constraint_banner"
149
+ end
150
+
151
+ def constraint_end
152
+ # trace "Should override constraint_end"
153
+ end
154
+
155
+ def constraint_dump(c)
156
+ # trace "Should override constraint_dump"
157
+ end
158
+
159
+ end
160
+ end
161
+ end
162
+ end