activefacts-compositions 1.9.6 → 1.9.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dd27f8a8f6a05f883483391f31e2a026b9a52b4
4
- data.tar.gz: cc0355b8f29a879c654d7e36e542a95045e71994
3
+ metadata.gz: c3f30aa198a18c360d4fee63de36a3764df7d799
4
+ data.tar.gz: 28db19dcd307a9ab3ab1e7a50fada7023651d6e6
5
5
  SHA512:
6
- metadata.gz: 2dc13c0b861580a23517fe1fe50f6dd4d8b88a42fb7ee15827119992c090172386efb984855a7ecf81f97a682e3439201f718bd1ae7fcb7aeeb3420317c86230
7
- data.tar.gz: 45854d64978972f11839794e6c6fe0cd38a0e09c0c13f66081e9a0580cd4d01503350f144946dd22174b06530c0394b72632f5ac0fa660ba1ddf706e036bcb55
6
+ metadata.gz: 0b179e371a8f8b47a308d5790c6a21e4dec2c490eb7bd76da9bab58a0c8ae201fbf50c27a6a6b882e3395a9118b75ab16568353e076a17be1fd5197c4b78ae2f
7
+ data.tar.gz: cb28e3eb273607b31fb7e55fa2e826a5cc965764345a4b80c8096531d33be0dc97e05b7103424b5afd9bee1bc68d7fb9d51341a87967909eba52eaddd1964ed7
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.rej
13
13
  *.orig
14
14
  *.diff
15
+ actual
data/Rakefile CHANGED
@@ -21,3 +21,36 @@ task :bump do
21
21
  )
22
22
  end
23
23
  end
24
+
25
+ desc "Display differences between expected and actual from the last test run"
26
+ task :actual do
27
+ system <<-END
28
+ for actual in `find spec -type d -name actual`
29
+ do
30
+ base=`dirname "$actual"`
31
+ files="`ls $base/actual/* 2>/dev/null`"
32
+ if [ x"$files" != x"" ]
33
+ then
34
+ echo "=================================== $base ==================================="
35
+ diff -rub $base/expected/ $base/actual |grep -v '^Only in .*expected'
36
+ fi
37
+ done
38
+ END
39
+ end
40
+
41
+ desc "Accept the last actual test output, making it expected for the next test run"
42
+ task :accept do
43
+ system <<-END
44
+ for actual_dir in `find spec -type d -name actual`
45
+ do
46
+ base=`dirname "$actual_dir"`
47
+ expected=`cd "$base/expected"; git ls-files`
48
+ actual=`cd "$base/actual"; ls $expected 2>/dev/null`
49
+ if [ x"$actual" != x"" ]
50
+ then
51
+ echo "Accepting $actual"
52
+ (cd "$base/actual"; mv $actual ../expected)
53
+ fi
54
+ done
55
+ END
56
+ end
@@ -19,14 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", ">= 1.10", "~> 1.10.6"
22
+ spec.add_development_dependency "bundler", ">= 1.11"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec", "~> 3.3"
25
25
 
26
26
  spec.add_development_dependency "activefacts", "~> 1", ">= 1.8"
27
27
 
28
- spec.add_runtime_dependency("activefacts-api", "~> 1", ">= 1.9.5")
29
- spec.add_runtime_dependency("activefacts-metamodel", "~> 1", ">= 1.9.6")
28
+ spec.add_runtime_dependency("activefacts-api", "~> 1", ">= 1.9.11")
29
+ spec.add_runtime_dependency("activefacts-metamodel", "~> 1", ">= 1.9.10")
30
30
  spec.add_runtime_dependency "tracing", "~> 2", ">= 2.0.6"
31
31
 
32
32
  spec.add_runtime_dependency "activefacts-cql", "~> 1", ">= 1.8"
@@ -5,111 +5,168 @@
5
5
  # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
6
  #
7
7
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
8
- require 'bundler/setup' # Set up gems listed in the Gemfile.
9
8
  $:.unshift File.dirname(File.expand_path(__FILE__))+"/../lib"
10
9
 
10
+ require 'pathname'
11
11
  require 'activefacts/loadable'
12
12
  require 'activefacts/metamodel'
13
13
  require 'activefacts/compositions'
14
14
  require 'activefacts/generator'
15
15
 
16
- # Parse options into a hash, and values for each option into a hash
17
- options = {}
18
- while ARGV[0] =~ /^-/
19
- option, value = ARGV.shift.split(/=/, 2)
20
- options[option.sub(/^-*/,'')] =
21
- (value =~ /,/ ? value.split(',') : Array(value)).
22
- inject({}){|h,s| k, v = s.split(/=/, 2); h[k] = v || true; h }
23
- end
16
+ class SchemaCompositor
17
+ attr_reader :options
18
+ attr_reader :compositors
19
+ attr_reader :generators
24
20
 
25
- # Load and enumerate all available compositors:
26
- compositions_path = "activefacts/compositions"
27
- Loadable.new(compositions_path).
28
- enumerate.
29
- select do |filename|
30
- begin
31
- require(pathname = compositions_path+"/"+filename)
32
- rescue LoadError => e
33
- rescue Exception => e
34
- puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
21
+ # Parse options into a hash, and values for each option into a hash
22
+ def initialize argv
23
+ @options = {}
24
+ while argv[0] =~ /^-/
25
+ option, value = argv.shift.split(/=/, 2)
26
+ @options[option.sub(/^-*/,'')] =
27
+ (value =~ /,/ ? value.split(',') : Array(value)).
28
+ inject({}){|h,s| k, v = s.split(/=/, 2); h[k] = v || true; h }
29
+ end
35
30
  end
36
- end
37
31
 
38
- # Load and enumerate all available generators
39
- generators_path = "activefacts/generator"
40
- Loadable.new(generators_path).
41
- enumerate.
42
- select do |filename|
43
- begin
44
- require(pathname = generators_path+"/"+filename)
45
- rescue LoadError => e
46
- rescue Exception => e
47
- puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
32
+ # Load and enumerate all available modules in this path
33
+ def enumerate_available path
34
+ Loadable.new(path).
35
+ enumerate.
36
+ select do |filename|
37
+ begin
38
+ require(pathname = path+"/"+filename)
39
+ rescue LoadError => e
40
+ rescue Exception => e
41
+ $stderr.puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
42
+ end
43
+ end
48
44
  end
49
- end
50
45
 
51
- if options['help']
52
- puts "Available compositors:\n\t#{ActiveFacts::Compositions.compositors.keys.sort*"\n\t"}\n\n"
53
- puts "Available generators:\n\t#{ActiveFacts::Generators.generators.keys.sort*"\n\t"}\n\n"
54
- exit
55
- end
56
-
57
- # Arrange the requested compositors and generators:
58
- compositors = []
59
- generators = []
60
- options.clone.each do |option, mode|
61
- if action = ActiveFacts::Compositions.compositors[option]
62
- options.delete(option)
63
- compositors << [action, mode]
64
- elsif action = ActiveFacts::Generators.generators[option]
65
- options.delete(option)
66
- generators << [action, mode]
67
- end
68
- if mode && mode['help']
69
- puts "REVISIT: Help for #{option} is not yet available"
46
+ def arrange_actions
47
+ # Arrange the requested compositors and generators:
48
+ @compositors = []
49
+ @generators = []
50
+ @options.clone.each do |option, mode|
51
+ if action = ActiveFacts::Compositions.compositors[option]
52
+ options.delete(option)
53
+ check_options(action, mode)
54
+ @compositors << [action, mode]
55
+ elsif action = ActiveFacts::Generators.generators[option]
56
+ options.delete(option)
57
+ check_options(action, mode)
58
+ @generators << [action, mode]
59
+ else
60
+ $stderr.puts "Action --#{option} is not recognised"
61
+ exit 1
62
+ end
63
+ if mode && mode['help']
64
+ puts "Help for #{option} is not yet available"
65
+ end
66
+ end
70
67
  end
71
- end
72
68
 
73
- # Process each input file:
74
- ARGV.each do |arg|
75
- filename, input_options = *arg.split(/=/, 2)
69
+ def process_files argv
70
+ # Process each input file:
71
+ argv.each do |arg|
72
+ filename, input_options = *arg.split(/=/, 2)
76
73
 
77
- # Load the correct file type input method
78
- pathname, basename, extension = * /(?:(.*)[\/\\])?(.*)\.([^.]*)$/.match(filename).captures
79
- input_handler = "activefacts/input/#{extension}"
80
- require input_handler
74
+ # Load the correct file type input method
75
+ pathname, basename, extension = * /(?:(.*)[\/\\])?(.*)\.([^.]*)$/.match(filename).captures
76
+ input_handler = "activefacts/input/#{extension}"
77
+ require input_handler
81
78
 
82
- input_class = extension.upcase
83
- input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
84
- raise "Expected #{input_handler} to define #{input_class}" unless input_klass
79
+ input_class = extension.upcase
80
+ input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
81
+ raise "Expected #{input_handler} to define #{input_class}" unless input_klass
85
82
 
86
- # Read the input file:
87
- vocabulary =
88
- if input_klass
89
- begin
90
- input_klass.readfile(filename, *input_options)
91
- rescue => e
92
- $stderr.puts "#{e.message}"
93
- if trace :exception
94
- $stderr.puts "\t#{e.backtrace*"\n\t"}"
95
- else
96
- $stderr.puts "\t#{e.backtrace[0]}"
83
+ # Read the input file:
84
+ vocabulary =
85
+ if input_klass
86
+ begin
87
+ input_klass.readfile(filename, *input_options)
88
+ rescue => e
89
+ $stderr.puts "#{e.message}"
90
+ if trace :exception
91
+ $stderr.puts "\t#{e.backtrace*"\n\t"}"
92
+ else
93
+ $stderr.puts "\t#{e.backtrace[0]}"
94
+ end
95
+ exit 1
96
+ end
97
+ end
98
+ exit 0 unless vocabulary
99
+ vocabulary.finalise unless vocabulary == true
100
+
101
+ # Run each compositor
102
+ @compositors.each do |compositor_klass, mode|
103
+ compositor = compositor_klass.new(vocabulary.constellation, basename, mode||{})
104
+ compositor.generate
105
+
106
+ # Run each generator
107
+ @generators.each do |generator, mode|
108
+ output = generator.new(compositor.composition, mode||{}).generate
109
+ puts output if output
97
110
  end
98
- exit 1
99
111
  end
100
112
  end
101
- exit 0 unless vocabulary
102
- vocabulary.finalise unless vocabulary == true
103
-
104
- # Run each compositor
105
- compositors.each do |compositor_klass, mode|
106
- compositor = compositor_klass.new(vocabulary.constellation, basename, mode||{})
107
- compositor.generate
108
-
109
- # Run each generator
110
- generators.each do |generator, mode|
111
- output = generator.new(compositor.composition, mode||{}).generate
112
- puts output if output
113
+ end
114
+
115
+ def action_name action
116
+ action.name.sub(/ActiveFacts::[^:]+::/,'').gsub(/::/,'/').downcase
117
+ end
118
+
119
+ def display_options action, stream = $stdout
120
+ options = action.options
121
+ name = action.name.sub(/ActiveFacts::[^:]+::/,'').gsub(/::/,'/').downcase
122
+ if options.empty?
123
+ stream.puts "There are no options for --#{action_name action}"
124
+ else
125
+ stream.puts "Options for --#{name} (say e.g. --#{action_name action}=option1=value,option2)"
126
+ options.keys.sort.each do |key|
127
+ type, description = *options[key]
128
+ tag =
129
+ key.to_s +
130
+ case type
131
+ when NilClass,'Boolean', TrueClass
132
+ ''
133
+ when Numeric
134
+ ' num'
135
+ when Pathname
136
+ ' file'
137
+ else
138
+ ' str'
139
+ end
140
+
141
+ stream.puts "\t#{tag}#{' '*(24-tag.size)}#{description}"
142
+ end
113
143
  end
114
144
  end
145
+
146
+ # Ensure that the options provided are supported by the action
147
+ def check_options action, mode
148
+ if mode['help']
149
+ display_options(action)
150
+ exit
151
+ end
152
+ options = action.options
153
+ unsupported = mode.keys.select{|k| !options.has_key?(k.to_sym)}
154
+ return if unsupported.empty?
155
+ $stderr.puts "Action --#{action_name action} does not support #{unsupported.size >1 ? 'these options' : 'this option'}: #{unsupported*', '}"
156
+ display_options(action, $stderr)
157
+ exit 1
158
+ end
115
159
  end
160
+
161
+ sc = SchemaCompositor.new(ARGV)
162
+ sc.enumerate_available('activefacts/compositions')
163
+ sc.enumerate_available('activefacts/generator')
164
+ if sc.options['help']
165
+ puts "Available compositors:\n\t#{ActiveFacts::Compositions.compositors.keys.sort*"\n\t"}\n\n"
166
+ puts "Available generators:\n\t#{ActiveFacts::Generators.generators.keys.sort*"\n\t"}\n\n"
167
+ puts "To get help for a particular action, follow it by =help, e.g. --relational=help"
168
+ exit
169
+ end
170
+
171
+ sc.arrange_actions
172
+ sc.process_files ARGV
@@ -1,7 +1,7 @@
1
1
  ### Composition
2
2
  # ActiveFacts Compositions, Binary Compositor.
3
3
  #
4
- # Fans of RDF will like this one.
4
+ # Fans of RDF will like this one.
5
5
  #
6
6
  # Copyright (c) 2015 Clifford Heath. Read the LICENSE file.
7
7
  #
@@ -10,23 +10,27 @@ require "activefacts/compositions"
10
10
  module ActiveFacts
11
11
  module Compositions
12
12
  class Binary < Compositor
13
+ def self.options
14
+ {}
15
+ end
16
+
13
17
  def generate
14
- super
18
+ super
15
19
 
16
- trace :binary!, "Constructing Binary Composition" do
17
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
18
- mapping = @binary_mappings[object_type]
19
- mapping.re_rank
20
- composite = @constellation.Composite(mapping, composition: @composition)
21
- end
22
- end
20
+ trace :binary!, "Constructing Binary Composition" do
21
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
22
+ mapping = @binary_mappings[object_type]
23
+ mapping.re_rank
24
+ composite = @constellation.Composite(mapping, composition: @composition)
25
+ end
26
+ end
23
27
 
24
- trace :binary!, "Full binary composition" do
25
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
26
- mapping = @binary_mappings[object_type]
27
- mapping.show_trace
28
- end
29
- end
28
+ trace :binary!, "Full binary composition" do
29
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
30
+ mapping = @binary_mappings[object_type]
31
+ mapping.show_trace
32
+ end
33
+ end
30
34
 
31
35
  end
32
36
  end
@@ -1,13 +1,13 @@
1
1
  #
2
2
  # ActiveFacts Compositions, Fundamental Compositor
3
3
  #
4
- # All Compositors derive from this one, which can calculate the basic binary bi-directional mapping
4
+ # All Compositors derive from this one, which can calculate the basic binary bi-directional mapping
5
5
  #
6
- # The term "reference" used here means either an Absorption
7
- # (one direction of a binary fact type relating two object types),
8
- # or an Indicator (for a unary fact type).
6
+ # The term "reference" used here means either an Absorption
7
+ # (one direction of a binary fact type relating two object types),
8
+ # or an Indicator (for a unary fact type).
9
9
  #
10
- # n-ary fact types and other objectified fact types are factored out by using the associated LinkFactTypes.
10
+ # n-ary fact types and other objectified fact types are factored out by using the associated LinkFactTypes.
11
11
  #
12
12
  # Copyright (c) 2015 Clifford Heath. Read the LICENSE file.
13
13
  #
@@ -15,141 +15,142 @@ require "activefacts/metamodel"
15
15
 
16
16
  module ActiveFacts
17
17
  module Compositions
18
- private
19
- MM = ActiveFacts::Metamodel
20
18
  class Compositor
21
19
  attr_reader :options, :name, :composition
22
20
 
21
+ def self.options
22
+ {}
23
+ end
24
+
23
25
  def initialize constellation, name, options = {}
24
- @constellation = constellation
25
- @name = name
26
- @options = options
27
- $stderr.puts "Unknown options: #{options.inspect}" unless options.empty?
26
+ @constellation = constellation
27
+ @name = name
28
+ @options = options
28
29
  end
29
30
 
30
31
  # Generate all Mappings into @binary_mappings for a binary composition of all ObjectTypes in this constellation
31
32
  def generate
32
- # Retract an existing composition by this name
33
- if existing = @constellation.Name[[@name]] and
34
- @composition = existing.composition
35
- @composition.all_composite.to_a.each{|composite| composite.retract}
36
- @composition.retract
37
- end
38
-
39
- @composition = @constellation.Composition(:new, :name => @name)
40
- preload_preferred_identifiers
41
- populate_references
33
+ # Retract an existing composition by this name
34
+ if existing = @constellation.Name[[@name]] and
35
+ @composition = existing.composition
36
+ @composition.all_composite.to_a.each{|composite| composite.retract}
37
+ @composition.retract
38
+ end
39
+
40
+ @composition = @constellation.Composition(:new, :name => @name)
41
+ preload_preferred_identifiers
42
+ populate_references
42
43
  end
43
44
 
44
45
  private
45
46
  # Preferred identifiers are cached, but the process produces trace output
46
47
  # that appears in the "tutti" mode used in testing. This precludes that.
47
48
  def preload_preferred_identifiers
48
- @constellation.EntityType.map{|k, et| et.preferred_identifier }
49
+ @constellation.EntityType.map{|k, et| et.preferred_identifier }
49
50
  end
50
51
 
51
52
  def populate_reference object_type, role
52
- parent = @binary_mappings[role.object_type]
53
-
54
- return if role.fact_type.all_role.size > 2
55
- if role.fact_type.all_role.size != 1
56
- counterpart = role.counterpart
57
- rt = role_type(counterpart)
58
- if rt == :many_many
59
- raise "Fact type must be objectified: #{role.fact_type.default_reading}"
60
- end
61
-
62
- a = @constellation.Absorption(
63
- :new,
64
- name: role_name(counterpart),
65
- parent: parent,
66
- object_type: counterpart.object_type,
67
- parent_role: role,
68
- child_role: counterpart
69
- )
70
- # Populate the absorption/reverse_absorption (putting the "many" or optional side as reverse)
71
- if r = @component_by_fact[role.fact_type]
72
- # Second occurrence of this fact type, set the direction:
73
- if a.is_preferred_direction
74
- a.reverse_absorption = r
75
- else # Set this as the reverse absorption
76
- a.forward_absorption = r
77
- end
78
- else
79
- # First occurrence of this fact type
80
- @component_by_fact[role.fact_type] = a
81
- end
82
- else # It's an indicator
83
- a = @constellation.Indicator(
84
- :new,
85
- name: role.name,
86
- parent: parent,
87
- role: role
88
- )
89
- @component_by_fact[role.fact_type] = a # For completeness, in case a subclass uses it
90
- end
91
- trace :binarize, "Populating #{a.inspect}"
53
+ parent = @binary_mappings[role.object_type]
54
+
55
+ return if role.fact_type.all_role.size > 2
56
+ if role.fact_type.all_role.size != 1
57
+ counterpart = role.counterpart
58
+ rt = role_type(counterpart)
59
+ if rt == :many_many
60
+ raise "Fact type must be objectified: #{role.fact_type.default_reading}"
61
+ end
62
+
63
+ a = @constellation.Absorption(
64
+ :new,
65
+ name: role_name(counterpart),
66
+ parent: parent,
67
+ object_type: counterpart.object_type,
68
+ parent_role: role,
69
+ child_role: counterpart
70
+ )
71
+ # Populate the absorption/reverse_absorption (putting the "many" or optional side as reverse)
72
+ if r = @component_by_fact[role.fact_type]
73
+ # Second occurrence of this fact type, set the direction:
74
+ if a.is_preferred_direction
75
+ a.reverse_absorption = r
76
+ else # Set this as the reverse absorption
77
+ a.forward_absorption = r
78
+ end
79
+ else
80
+ # First occurrence of this fact type
81
+ @component_by_fact[role.fact_type] = a
82
+ end
83
+ else # It's an indicator
84
+ a = @constellation.Indicator(
85
+ :new,
86
+ name: role.name,
87
+ parent: parent,
88
+ role: role
89
+ )
90
+ @component_by_fact[role.fact_type] = a # For completeness, in case a subclass uses it
91
+ end
92
+ trace :binarize, "Populating #{a.inspect}"
92
93
  end
93
94
 
94
95
  def populate_references
95
- # A table of Mappings by object type, with a default Mapping for each:
96
- @binary_mappings = Hash.new do |h, object_type|
97
- h[object_type] = @constellation.Mapping(
98
- :new,
99
- name: object_type.name,
100
- object_type: object_type
101
- )
102
- end
103
- @component_by_fact = {}
104
-
105
- @constellation.ObjectType.each do |key, object_type|
106
- trace :binarize, "Populating possible absorptions for #{object_type.name}" do
107
- @binary_mappings[object_type] # Ensure we create the top Mapping even if it has no references
108
-
109
- object_type.all_role.each do |role|
110
- # Exclude base roles in objectified fact types (unless unary); just use link fact types
111
- next if role.fact_type.entity_type && role.fact_type.all_role.size != 1
112
- next if role.variable # REVISIT: Continue to ignore roles in derived fact types?
113
- populate_reference object_type, role
114
- end
115
- if object_type.is_a?(ActiveFacts::Metamodel::ValueType)
116
- # This requires a change in the metamodel to use TypeInheritance for ValueTypes
117
- if object_type.supertype
118
- trace :binarize, "REVISIT: Eliding supertype #{object_type.supertype.name} for #{object_type.name}"
119
- end
120
- object_type.all_value_type_as_supertype.each do |subtype|
121
- trace :binarize, "REVISIT: Eliding subtype #{subtype.name} for #{object_type.name}"
122
- end
123
- end
124
- end
125
- end
96
+ # A table of Mappings by object type, with a default Mapping for each:
97
+ @binary_mappings = Hash.new do |h, object_type|
98
+ h[object_type] = @constellation.Mapping(
99
+ :new,
100
+ name: object_type.name,
101
+ object_type: object_type
102
+ )
103
+ end
104
+ @component_by_fact = {}
105
+
106
+ @constellation.ObjectType.each do |key, object_type|
107
+ trace :binarize, "Populating possible absorptions for #{object_type.name}" do
108
+ @binary_mappings[object_type] # Ensure we create the top Mapping even if it has no references
109
+
110
+ object_type.all_role.each do |role|
111
+ # Exclude base roles in objectified fact types (unless unary); just use link fact types
112
+ next if role.fact_type.entity_type && role.fact_type.all_role.size != 1
113
+ next if role.variable # REVISIT: Continue to ignore roles in derived fact types?
114
+ populate_reference object_type, role
115
+ end
116
+ if object_type.is_a?(ActiveFacts::Metamodel::ValueType)
117
+ # This requires a change in the metamodel to use TypeInheritance for ValueTypes
118
+ if object_type.supertype
119
+ trace :binarize, "REVISIT: Eliding supertype #{object_type.supertype.name} for #{object_type.name}"
120
+ end
121
+ object_type.all_value_type_as_supertype.each do |subtype|
122
+ trace :binarize, "REVISIT: Eliding subtype #{subtype.name} for #{object_type.name}"
123
+ end
124
+ end
125
+ end
126
+ end
126
127
  end
127
128
 
128
129
  def role_name role
129
- # if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) && role == role.fact_type.subtype_role
130
- # return "Is "+role.object_type.name
131
- # end
132
- role = role.base_role unless role.base_role.fact_type.all_role.size == 1
133
- String::Words.new(role.preferred_reference.role_name(nil)).capwords*' '
130
+ # if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) && role == role.fact_type.subtype_role
131
+ # return "Is "+role.object_type.name
132
+ # end
133
+ role = role.base_role unless role.base_role.fact_type.all_role.size == 1
134
+ String::Words.new(role.preferred_reference.role_name(nil)).capwords*' '
134
135
  end
135
136
 
136
137
  def role_type role
137
- fact_type = role.fact_type
138
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
139
- return role.object_type == fact_type.supertype ? :supertype : :subtype
140
- end
141
-
142
- return :unary if fact_type.all_role.size == 1
143
-
144
- if fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
145
- # Prevent an unnecessary from-1 search:
146
- from_1 = true
147
- # Change the to_1 search to detect a one-to-one:
148
- role = fact_type.implying_role
149
- fact_type = role.fact_type
150
- end
151
-
152
- # List the UCs on this fact type:
138
+ fact_type = role.fact_type
139
+ if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
140
+ return role.object_type == fact_type.supertype ? :supertype : :subtype
141
+ end
142
+
143
+ return :unary if fact_type.all_role.size == 1
144
+
145
+ if fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
146
+ # Prevent an unnecessary from-1 search:
147
+ from_1 = true
148
+ # Change the to_1 search to detect a one-to-one:
149
+ role = fact_type.implying_role
150
+ fact_type = role.fact_type
151
+ end
152
+
153
+ # List the UCs on this fact type:
153
154
  all_uniqueness_constraints =
154
155
  fact_type.all_role.map do |fact_role|
155
156
  fact_role.all_role_ref.map do |rr|
@@ -159,7 +160,7 @@ module ActiveFacts
159
160
  end
160
161
  end.flatten.uniq
161
162
 
162
- # It's to-1 if a UC exists over exactly this role:
163
+ # It's to-1 if a UC exists over exactly this role:
163
164
  to_1 =
164
165
  all_uniqueness_constraints.
165
166
  detect do |c|
@@ -186,16 +187,16 @@ module ActiveFacts
186
187
 
187
188
  # Display the primitive binary mapping:
188
189
  def show_references
189
- trace :composition, "Displaying the mappings:" do
190
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
191
- mapping = @binary_mappings[object_type]
192
- trace :composition, "#{object_type.name}" do
193
- mapping.all_member.each do |component|
194
- trace :composition, component.inspect
195
- end
196
- end
197
- end
198
- end
190
+ trace :composition, "Displaying the mappings:" do
191
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
192
+ mapping = @binary_mappings[object_type]
193
+ trace :composition, "#{object_type.name}" do
194
+ mapping.all_member.each do |component|
195
+ trace :composition, component.inspect
196
+ end
197
+ end
198
+ end
199
+ end
199
200
  end
200
201
 
201
202
  end