activefacts-generators 1.8.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,23 +8,23 @@ module ActiveFacts
8
8
  module Generators
9
9
  module OOTraits
10
10
  module ObjectType
11
- # Map the ObjectType name to an OO class name
12
- def oo_type_name
13
- name.words.capcase
14
- end
11
+ # Map the ObjectType name to an OO class name
12
+ def oo_type_name
13
+ name.words.capcase
14
+ end
15
15
 
16
- # Map the OO class name to a default role name
17
- def oo_default_role_name
16
+ # Map the OO class name to a default role name
17
+ def oo_default_role_name
18
18
  name.words.snakecase
19
- end
19
+ end
20
20
  end
21
21
 
22
22
  module Role
23
- def oo_role_definition
23
+ def oo_role_definition
24
24
  return if fact_type.entity_type
25
25
 
26
26
  if fact_type.all_role.size == 1
27
- return " maybe :#{preferred_role_name}\n"
27
+ return " maybe :#{preferred_role_name}\n"
28
28
  elsif fact_type.all_role.size != 2
29
29
  # Shouldn't come here, except perhaps for an invalid model
30
30
  return # ternaries and higher are always objectified
@@ -55,8 +55,8 @@ module ActiveFacts
55
55
  counterpart_role_method = one_to_one ? role_method : "all_"+role_method
56
56
  # puts "---"+role.role_name if role.role_name
57
57
  if counterpart_role_name != counterpart_type.oo_default_role_name and
58
- role_method == self.object_type.oo_default_role_name
59
- # debugger
58
+ role_method == self.object_type.oo_default_role_name
59
+ # debugger
60
60
  counterpart_role_method += "_as_#{counterpart_role_name}"
61
61
  end
62
62
 
@@ -64,10 +64,10 @@ module ActiveFacts
64
64
  role_name = nil if role_name == object_type.oo_default_role_name
65
65
 
66
66
  as_binary(counterpart_role_name, counterpart_type, is_mandatory, one_to_one, nil, role_name, counterpart_role_method)
67
- end
67
+ end
68
68
  end
69
69
 
70
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
70
+ include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
71
71
  end
72
72
  end
73
73
  end
@@ -8,26 +8,26 @@ module ActiveFacts
8
8
  module Generators #:nodoc:
9
9
  module OrderedTraits
10
10
  module DumpedFlag
11
- attr_reader :ordered_dumped
11
+ attr_reader :ordered_dumped
12
12
 
13
- def ordered_dumped!
14
- @ordered_dumped = true
15
- end
13
+ def ordered_dumped!
14
+ @ordered_dumped = true
15
+ end
16
16
  end
17
17
 
18
18
  module ObjectType
19
- include DumpedFlag
19
+ include DumpedFlag
20
20
  end
21
21
 
22
22
  module FactType
23
- include DumpedFlag
23
+ include DumpedFlag
24
24
  end
25
25
 
26
26
  module Constraint
27
- include DumpedFlag
27
+ include DumpedFlag
28
28
  end
29
29
 
30
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
30
+ include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
31
31
  end
32
32
  end
33
33
  end
@@ -8,24 +8,24 @@ module ActiveFacts
8
8
  module Generators
9
9
  module RubyTraits
10
10
  module Vocabulary
11
- def prelude
12
- if @mapping == 'sql'
13
- require 'activefacts/rmap'
14
- @tables = self.tables
15
- end
16
-
17
- "require 'activefacts/api'\n" +
18
- (@mapping == 'sql' ? "require 'activefacts/rmap'\n" : '') +
19
- "\nmodule ::#{self.name}\n\n"
20
- end
21
-
22
- def finale
23
- "end"
24
- end
11
+ def prelude
12
+ if @mapping == 'sql'
13
+ require 'activefacts/rmap'
14
+ @tables = self.tables
15
+ end
16
+
17
+ "require 'activefacts/api'\n" +
18
+ (@mapping == 'sql' ? "require 'activefacts/rmap'\n" : '') +
19
+ "\nmodule ::#{self.name.words.capcase}\n\n"
20
+ end
21
+
22
+ def finale
23
+ "end"
24
+ end
25
25
  end
26
26
 
27
27
  module ObjectType
28
- def absorbed_roles
28
+ def absorbed_roles
29
29
  all_role.
30
30
  select do |role|
31
31
  role.fact_type.all_role.size <= 2 &&
@@ -33,41 +33,41 @@ module ActiveFacts
33
33
  end.
34
34
  sort_by do |role|
35
35
  r = role.fact_type.all_role.select{|r2| r2 != role}[0] || role
36
- r.preferred_role_name(self) + ':' + role.preferred_role_name(r.object_type)
36
+ r.preferred_role_name(self) + ':' + role.preferred_role_name(r.object_type)
37
37
  end
38
- end
39
-
40
- # Map the ObjectType name to a Ruby class name
41
- def ruby_type_name
42
- oo_type_name
43
- end
44
-
45
- # Map the Ruby class name to a default role name
46
- def ruby_default_role_name
47
- oo_default_role_name
48
- end
49
-
50
-
51
- def ruby_type_reference
52
- if !ordered_dumped
53
- '"'+name.gsub(/ /,'')+'"'
54
- else
55
- role_reference = name.gsub(/ /,'')
56
- end
57
- end
38
+ end
39
+
40
+ # Map the ObjectType name to a Ruby class name
41
+ def ruby_type_name
42
+ oo_type_name
43
+ end
44
+
45
+ # Map the Ruby class name to a default role name
46
+ def ruby_default_role_name
47
+ oo_default_role_name
48
+ end
49
+
50
+
51
+ def ruby_type_reference
52
+ if !ordered_dumped
53
+ '"'+name.gsub(/ /,'')+'"'
54
+ else
55
+ role_reference = name.gsub(/ /,'')
56
+ end
57
+ end
58
58
  end
59
59
 
60
60
  module Role
61
61
  def preferred_role_name(is_for = nil, &name_builder)
62
62
 
63
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
64
- # Subtype and Supertype roles default to TitleCase names, and have no role_name to worry about:
65
- return (name_builder || proc {|names| names.titlecase}).call(object_type.name.words)
66
- end
63
+ if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
64
+ # Subtype and Supertype roles default to TitleCase names, and have no role_name to worry about:
65
+ return (name_builder || proc {|names| names.titlecase}).call(object_type.name.words)
66
+ end
67
67
 
68
- name_builder ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
68
+ name_builder ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
69
69
 
70
- # Handle an objectified unary role:
70
+ # Handle an objectified unary role:
71
71
  if is_for && fact_type.entity_type == is_for && fact_type.all_role.size == 1
72
72
  return name_builder.call(object_type.name.words)
73
73
  end
@@ -80,131 +80,131 @@ module ActiveFacts
80
80
 
81
81
  if fact_type.all_role.size == 1
82
82
  return name_builder.call(
83
- role_name ?
84
- role_name.snakewords :
85
- reading.text.gsub(/ *\{0\} */,' ').gsub(/[- ]+/,'_').words
86
- )
83
+ role_name ?
84
+ role_name.words.snakewords :
85
+ reading.text.gsub(/ *\{0\} */,' ').gsub(/[- ]+/,'_').words
86
+ )
87
87
  end
88
88
 
89
- if role_name && role_name != ""
90
- role_words = [role_name]
91
- else
92
- role_words = []
89
+ if role_name && role_name != ""
90
+ role_words = [role_name]
91
+ else
92
+ role_words = []
93
93
 
94
- la = preferred_role_ref.leading_adjective
95
- role_words += la.words.snakewords if la && la != ""
94
+ la = preferred_role_ref.leading_adjective
95
+ role_words += la.words.snakewords if la && la != ""
96
96
 
97
- role_words += object_type.name.words.snakewords
97
+ role_words += object_type.name.words.snakewords
98
98
 
99
- ta = preferred_role_ref.trailing_adjective
100
- role_words += ta.words.snakewords if ta && ta != ""
101
- end
99
+ ta = preferred_role_ref.trailing_adjective
100
+ role_words += ta.words.snakewords if ta && ta != ""
101
+ end
102
102
 
103
103
  # n = role_words.map{|w| w.gsub(/([a-z])([A-Z]+)/,'\1_\2').downcase}*"_"
104
- n = role_words*'_'
104
+ n = role_words*'_'
105
105
  # trace "\tresult=#{n}"
106
106
  return name_builder.call(n.gsub(' ','_').split(/_/))
107
107
  end
108
108
 
109
- def as_binary(role_name, role_player, mandatory = nil, one_to_one = nil, readings = nil, other_role_name = nil, other_method_name = nil)
110
- ruby_role_name = ":"+role_name.words.snakecase
111
-
112
- # Find whether we need the name of the other role player, and whether it's defined yet:
113
- implied_role_name = role_player.name.gsub(/ /,'').sub(/^[a-z]/) {|i| i.upcase}
114
- if role_name.camelcase != implied_role_name
115
- # Only use Class name if it's not implied by the rolename
116
- role_reference = ":class => "+role_player.ruby_type_reference
117
- end
118
-
119
- other_role_name = ":counterpart => :"+other_role_name.gsub(/ /,'_') if other_role_name
120
-
121
- if vr = role_value_constraint
122
- value_restriction = ":restrict => #{vr}"
123
- end
124
-
125
- options = [
126
- ruby_role_name,
127
- role_reference,
128
- mandatory ? ":mandatory => true" : nil,
129
- readings,
130
- other_role_name,
131
- value_restriction
132
- ].compact
133
-
134
- debugger if ruby_role_name == 'astronomicalobject'
135
-
136
- line = " #{one_to_one ? "one_to_one" : "has_one" } #{options*', '} "
137
- if other_method_name
138
- line += " "*(48-line.length) if line.length < 48
139
- line += "\# See #{role_player.name.gsub(/ /,'')}.#{other_method_name}"
140
- end
141
- line+"\n"
142
- end
143
-
144
- def ruby_role_definition
145
- oo_role_definition
146
- end
109
+ def as_binary(role_name, role_player, mandatory = nil, one_to_one = nil, readings = nil, other_role_name = nil, other_method_name = nil)
110
+ ruby_role_name = ":"+role_name.words.snakecase
111
+
112
+ # Find whether we need the name of the other role player, and whether it's defined yet:
113
+ implied_role_name = role_player.name.gsub(/ /,'').sub(/^[a-z]/) {|i| i.upcase}
114
+ if role_name.camelcase != implied_role_name
115
+ # Only use Class name if it's not implied by the rolename
116
+ role_reference = ":class => "+role_player.ruby_type_reference
117
+ end
118
+
119
+ other_role_name = ":counterpart => :"+other_role_name.gsub(/ /,'_') if other_role_name
120
+
121
+ if vr = role_value_constraint
122
+ value_restriction = ":restrict => #{vr}"
123
+ end
124
+
125
+ options = [
126
+ ruby_role_name,
127
+ role_reference,
128
+ mandatory ? ":mandatory => true" : nil,
129
+ readings,
130
+ other_role_name,
131
+ value_restriction
132
+ ].compact
133
+
134
+ debugger if ruby_role_name == 'astronomicalobject'
135
+
136
+ line = " #{one_to_one ? "one_to_one" : "has_one" } #{options*', '} "
137
+ if other_method_name
138
+ line += " "*(48-line.length) if line.length < 48
139
+ line += "\# See #{role_player.name.gsub(/ /,'')}.#{other_method_name}"
140
+ end
141
+ line+"\n"
142
+ end
143
+
144
+ def ruby_role_definition
145
+ oo_role_definition
146
+ end
147
147
  end
148
148
 
149
149
  module ValueType
150
- def ruby_definition
151
- return if name == "_ImplicitBooleanValueType"
152
-
153
- ruby_length = length && length > 0 ? ":length => #{length}" : nil
154
- ruby_scale = scale && scale > 0 ? ":scale => #{scale}" : nil
155
- params = [ruby_length,ruby_scale].compact * ", "
156
-
157
- base_type = supertype || self
158
- base_type_name = base_type.ruby_type_name
159
- ruby_name = ruby_type_name
160
- if base_type_name == ruby_name
161
- base_type_name = '::'+base_type_name
162
- end
163
-
164
- " class #{ruby_name} < #{base_type_name}\n" +
165
- " value_type #{params}\n" +
166
- #emit_mapping self if is_table
167
- (value_constraint ?
168
- " restrict #{value_constraint.all_allowed_range_sorted.map{|ar| ar.to_s}*", "}\n" :
169
- ""
170
- ) +
171
- (unit ?
172
- " \# REVISIT: #{ruby_name} is in units of #{unit.name}\n" :
173
- ""
174
- ) +
175
- absorbed_roles.map do |role|
176
- role.ruby_role_definition
177
- end.
178
- compact*"" +
179
- " end\n\n"
180
- end
150
+ def ruby_definition
151
+ return if name == "_ImplicitBooleanValueType"
152
+
153
+ ruby_length = length && length > 0 ? ":length => #{length}" : nil
154
+ ruby_scale = scale && scale > 0 ? ":scale => #{scale}" : nil
155
+ params = [ruby_length,ruby_scale].compact * ", "
156
+
157
+ base_type = supertype || self
158
+ base_type_name = base_type.ruby_type_name
159
+ ruby_name = ruby_type_name
160
+ if base_type_name == ruby_name
161
+ base_type_name = '::'+base_type_name
162
+ end
163
+
164
+ " class #{ruby_name} < #{base_type_name}\n" +
165
+ " value_type #{params}\n" +
166
+ #emit_mapping self if is_table
167
+ (value_constraint ?
168
+ " restrict #{value_constraint.all_allowed_range_sorted.map{|ar| ar.to_s}*", "}\n" :
169
+ ""
170
+ ) +
171
+ (unit ?
172
+ " \# REVISIT: #{ruby_name} is in units of #{unit.name}\n" :
173
+ ""
174
+ ) +
175
+ absorbed_roles.map do |role|
176
+ role.ruby_role_definition
177
+ end.
178
+ compact*"" +
179
+ " end\n\n"
180
+ end
181
181
  end
182
182
 
183
183
  module FactType
184
184
  # An objectified fact type has internal roles that are always "has_one":
185
185
  def fact_roles
186
- raise "Fact #{describe} type is not objectified" unless entity_type
186
+ raise "Fact #{describe} type is not objectified" unless entity_type
187
187
  all_role.sort_by do |role|
188
- role.preferred_role_name(entity_type)
189
- end.
190
- map do |role|
191
- role_name = role.preferred_role_name(entity_type)
192
- one_to_one = role.all_role_ref.detect{|rr|
193
- rr.role_sequence.all_role_ref.size == 1 &&
194
- rr.role_sequence.all_presence_constraint.detect{|pc|
195
- pc.max_frequency == 1
196
- }
197
- }
198
- counterpart_role_method = (one_to_one ? "" : "all_") +
199
- entity_type.oo_default_role_name +
200
- (role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : '')
201
- role.as_binary(role_name, role.object_type, true, one_to_one, nil, nil, counterpart_role_method)
202
- end.
203
- join('')
204
- end
188
+ role.preferred_role_name(entity_type)
189
+ end.
190
+ map do |role|
191
+ role_name = role.preferred_role_name(entity_type)
192
+ one_to_one = role.all_role_ref.detect{|rr|
193
+ rr.role_sequence.all_role_ref.size == 1 &&
194
+ rr.role_sequence.all_presence_constraint.detect{|pc|
195
+ pc.max_frequency == 1
196
+ }
197
+ }
198
+ counterpart_role_method = (one_to_one ? "" : "all_") +
199
+ entity_type.oo_default_role_name +
200
+ (role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : '')
201
+ role.as_binary(role_name, role.object_type, true, one_to_one, nil, nil, counterpart_role_method)
202
+ end.
203
+ join('')
204
+ end
205
205
  end
206
206
 
207
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
207
+ include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
208
208
  end
209
209
  end
210
210
  end
@@ -9,43 +9,43 @@ module ActiveFacts
9
9
  module Generators
10
10
  module ScalaTraits
11
11
  module Vocabulary
12
- def scala_prelude
13
- title_name = name.words.titlecase
14
-
15
- "package model\n"+
16
- "\n"+
17
- "import scala.language.implicitConversions\n" +
18
- "\n" +
19
- "object #{title_name} extends LocalStorageConstellation with #{title_name}\n" +
20
- "\n" +
21
- "trait #{title_name} extends Model {\n" +
22
- # REVISIT: I think this next line should be model, not metaModel
23
- " val metaModel = new #{title_name}Model()\n" +
24
- "\n"
25
- end
26
-
27
- def scala_prelude_metamodel
28
- title_name = name.words.titlecase
29
- "class #{title_name}Model extends FBMModel with LocalStorageConstellation {\n" +
30
- " implicit val constellation: Constellation = this\n"
31
- end
32
-
33
- def scala_finale
34
- "}\n"+
35
- "\n"
36
- end
12
+ def scala_prelude
13
+ title_name = name.words.titlecase
14
+
15
+ "package model\n"+
16
+ "\n"+
17
+ "import scala.language.implicitConversions\n" +
18
+ "\n" +
19
+ "object #{title_name} extends LocalStorageConstellation with #{title_name}\n" +
20
+ "\n" +
21
+ "trait #{title_name} extends Model {\n" +
22
+ # REVISIT: I think this next line should be model, not metaModel
23
+ " val metaModel = new #{title_name}Model()\n" +
24
+ "\n"
25
+ end
26
+
27
+ def scala_prelude_metamodel
28
+ title_name = name.words.titlecase
29
+ "class #{title_name}Model extends FBMModel with LocalStorageConstellation {\n" +
30
+ " implicit val constellation: Constellation = this\n"
31
+ end
32
+
33
+ def scala_finale
34
+ "}\n"+
35
+ "\n"
36
+ end
37
37
  end
38
38
 
39
39
  module ObjectType
40
- # Map the ObjectType name to a Scala class name
41
- def scala_type_name
42
- oo_type_name
43
- end
40
+ # Map the ObjectType name to a Scala class name
41
+ def scala_type_name
42
+ oo_type_name
43
+ end
44
44
 
45
- # Map the Scala class name to a default role name
46
- def scala_default_role_name
47
- oo_default_role_name
48
- end
45
+ # Map the Scala class name to a default role name
46
+ def scala_default_role_name
47
+ oo_default_role_name
48
+ end
49
49
 
50
50
  def absorbed_roles
51
51
  all_role.
@@ -62,16 +62,16 @@ module ActiveFacts
62
62
 
63
63
  module Role
64
64
  def scala_preferred_role_name(is_for = nil, &name_builder)
65
- # REVISIT: Modify this to suit Scala
65
+ # REVISIT: Modify this to suit Scala
66
66
 
67
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
68
- # Subtype and Supertype roles default to TitleCase names, and have no role_name to worry about:
69
- return (name_builder || proc {|names| names.titlecase}).call(object_type.name.words)
70
- end
67
+ if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
68
+ # Subtype and Supertype roles default to TitleCase names, and have no role_name to worry about:
69
+ return (name_builder || proc {|names| names.titlecase}).call(object_type.name.words)
70
+ end
71
71
 
72
- name_builder ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
72
+ name_builder ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
73
73
 
74
- # Handle an objectified unary role:
74
+ # Handle an objectified unary role:
75
75
  if is_for && fact_type.entity_type == is_for && fact_type.all_role.size == 1
76
76
  return name_builder.call(object_type.name.words)
77
77
  end
@@ -84,304 +84,304 @@ module ActiveFacts
84
84
 
85
85
  if fact_type.all_role.size == 1
86
86
  return name_builder.call(
87
- role_name ?
88
- role_name.snakewords :
89
- reading.text.gsub(/ *\{0\} */,' ').gsub(/[- ]+/,'_').words
90
- )
87
+ role_name ?
88
+ role_name.snakewords :
89
+ reading.text.gsub(/ *\{0\} */,' ').gsub(/[- ]+/,'_').words
90
+ )
91
91
  end
92
92
 
93
- if role_name && role_name != ""
94
- role_words = [role_name]
95
- else
96
- role_words = []
93
+ if role_name && role_name != ""
94
+ role_words = [role_name]
95
+ else
96
+ role_words = []
97
97
 
98
- la = preferred_role_ref.leading_adjective
99
- role_words += la.words.snakewords if la && la != ""
98
+ la = preferred_role_ref.leading_adjective
99
+ role_words += la.words.snakewords if la && la != ""
100
100
 
101
- role_words += object_type.name.words.snakewords
101
+ role_words += object_type.name.words.snakewords
102
102
 
103
- ta = preferred_role_ref.trailing_adjective
104
- role_words += ta.words.snakewords if ta && ta != ""
105
- end
103
+ ta = preferred_role_ref.trailing_adjective
104
+ role_words += ta.words.snakewords if ta && ta != ""
105
+ end
106
106
 
107
107
  # n = role_words.map{|w| w.gsub(/([a-z])([A-Z]+)/,'\1_\2').downcase}*"_"
108
- n = role_words*'_'
108
+ n = role_words*'_'
109
109
  # trace "\tresult=#{n}"
110
110
  return name_builder.call(n.gsub(' ','_').split(/_/))
111
111
  end
112
112
 
113
- def scala_role_definition
114
- return if fact_type.entity_type
115
-
116
- if fact_type.all_role.size == 1
117
- scala_role_name = scala_preferred_role_name.words.camelcase
118
- return " val #{scala_role_name}: Boolean"
119
- elsif fact_type.all_role.size != 2
120
- # Shouldn't come here, except perhaps for an invalid model
121
- return # ternaries and higher are always objectified
122
- end
123
-
124
- return if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
125
-
126
- other_role = fact_type.all_role.select{|r| r != self}[0]
127
- other_role_name = other_role.scala_preferred_role_name
128
- scala_role_name = other_role_name.words.camelcase
129
- other_type_name = other_role.object_type.name.words.titlecase
130
-
131
- if is_functional
132
- if is_mandatory
133
- # Define a getter for a mandatory value:
134
- " val #{scala_role_name}: #{other_type_name}"
135
- if !fact_type.is_existential
136
- " def #{scala_role_name}_=(_value: #{other_type_name}) = { #{scala_role_name} = _value }"
137
- end
138
- else
139
- # Define a getter for an optional value:
140
- # REVISIT: The role number here depends on the metamodel ordering of the fact type roles.
141
- # This likely should follow the role order of the preferred reading, from which the fact name is derived.
142
- # The code here collows the order of definition of the roles in the fact type,
143
- # which might not be the same as the order of the preferred reading:
144
- fact_name = fact_type.scala_name.titlecase
145
- role_number = fact_type.all_role_in_order.index(other_role)+1
146
-
147
- " def #{scala_role_name}: Option[#{other_type_name}] = {\n" +
148
- " constellation.getBinaryFact(metaModel.#{fact_name.words.camelcase}, this).map(x => {\n" +
149
- " x.head.asInstanceOf[FBMModel.BinaryFact].rolePlayers._#{role_number}.asInstanceOf[#{other_type_name}]\n" +
150
- " })\n" +
151
- " }\n" +
152
- if !fact_type.is_existential
153
- # Define a setter for an optional value:
154
- " def #{scala_role_name}_=(value: Option[#{other_type_name}]) = {\n" +
155
- " value match {\n" +
156
- " case None =>\n" +
157
- " case Some(m) => constellation.assertBinaryFact(#{fact_name.words.titlecase}(this, m))\n" +
158
- " }\n" +
159
- " }"
160
- else
161
- ''
162
- end
163
- end
164
- elsif other_role.object_type.fact_type
165
- # An objectified fact type
166
- <<"END"
113
+ def scala_role_definition
114
+ return if fact_type.entity_type
115
+
116
+ if fact_type.all_role.size == 1
117
+ scala_role_name = scala_preferred_role_name.words.camelcase
118
+ return " val #{scala_role_name}: Boolean"
119
+ elsif fact_type.all_role.size != 2
120
+ # Shouldn't come here, except perhaps for an invalid model
121
+ return # ternaries and higher are always objectified
122
+ end
123
+
124
+ return if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
125
+
126
+ other_role = fact_type.all_role.select{|r| r != self}[0]
127
+ other_role_name = other_role.scala_preferred_role_name
128
+ scala_role_name = other_role_name.words.camelcase
129
+ other_type_name = other_role.object_type.name.words.titlecase
130
+
131
+ if is_functional
132
+ if is_mandatory
133
+ # Define a getter for a mandatory value:
134
+ " val #{scala_role_name}: #{other_type_name}"
135
+ if !fact_type.is_existential
136
+ " def #{scala_role_name}_=(_value: #{other_type_name}) = { #{scala_role_name} = _value }"
137
+ end
138
+ else
139
+ # Define a getter for an optional value:
140
+ # REVISIT: The role number here depends on the metamodel ordering of the fact type roles.
141
+ # This likely should follow the role order of the preferred reading, from which the fact name is derived.
142
+ # The code here collows the order of definition of the roles in the fact type,
143
+ # which might not be the same as the order of the preferred reading:
144
+ fact_name = fact_type.scala_name.titlecase
145
+ role_number = fact_type.all_role_in_order.index(other_role)+1
146
+
147
+ " def #{scala_role_name}: Option[#{other_type_name}] = {\n" +
148
+ " constellation.getBinaryFact(metaModel.#{fact_name.words.camelcase}, this).map(x => {\n" +
149
+ " x.head.asInstanceOf[FBMModel.BinaryFact].rolePlayers._#{role_number}.asInstanceOf[#{other_type_name}]\n" +
150
+ " })\n" +
151
+ " }\n" +
152
+ if !fact_type.is_existential
153
+ # Define a setter for an optional value:
154
+ " def #{scala_role_name}_=(value: Option[#{other_type_name}]) = {\n" +
155
+ " value match {\n" +
156
+ " case None =>\n" +
157
+ " case Some(m) => constellation.assertBinaryFact(#{fact_name.words.titlecase}(this, m))\n" +
158
+ " }\n" +
159
+ " }"
160
+ else
161
+ ''
162
+ end
163
+ end
164
+ elsif other_role.object_type.fact_type
165
+ # An objectified fact type
166
+ <<"END"
167
167
  def all#{scala_role_name.words.titlecase}(implicit constellation: Constellation): Seq[#{other_type_name}] = {
168
- constellation.getObjectifiedFact(metaModel.#{scala_role_name.words.camelcase}, this).getOrElse(Nil).flatMap(x => x match {
169
- case o: #{other_type_name} => Some(o)
170
- case _ => None
171
- })
168
+ constellation.getObjectifiedFact(metaModel.#{scala_role_name.words.camelcase}, this).getOrElse(Nil).flatMap(x => x match {
169
+ case o: #{other_type_name} => Some(o)
170
+ case _ => None
171
+ })
172
172
  }
173
173
  END
174
- else
175
- <<"END"
174
+ else
175
+ <<"END"
176
176
  /*
177
177
  def all#{scala_role_name.words.titlecase}(implicit constellation: Constellation): Seq[#{other_type_name}] = {
178
- constellation.getFact(metaModel.#{scala_role_name.words.camelcase}, this).getOrElse(Nil).flatMap(x => x match {
179
- # REVISIT: This is incorrect; we want to return the other role player in the fact
180
- case o: #{other_type_name} => Some(o)
181
- case _ => None
182
- })
178
+ constellation.getFact(metaModel.#{scala_role_name.words.camelcase}, this).getOrElse(Nil).flatMap(x => x match {
179
+ # REVISIT: This is incorrect; we want to return the other role player in the fact
180
+ case o: #{other_type_name} => Some(o)
181
+ case _ => None
182
+ })
183
183
  }
184
184
  */
185
185
  END
186
- end
187
- end
186
+ end
187
+ end
188
188
  end
189
189
 
190
190
  module ValueType
191
- DataTypeMap = {
192
- "Signed Integer" => "Int",
193
- "Unsigned Integer" => "Int",
194
- "Real" => "Double",
195
- "Char" => "String",
196
- # REVISIT: More will be needed here.
197
- }
198
- LengthTypes = [ "String", "Decimal" ]
199
- ScaleTypes = [ "Decimal" ]
200
-
201
- def scala_definition(super_type_name, facets)
202
- vt_name = name.words.titlecase
203
- if d = DataTypeMap[super_type_name]
204
- super_type_name = d
205
- end
206
- super_type_title = super_type_name.words.titlecase
207
- super_type_camel = super_type_name.words.camelcase
208
-
209
- sometimes_optional = all_role.detect do |r|
210
- r.fact_type.all_role.size == 2 && (c = (r.fact_type.all_role.to_a-[r])[0]) and !c.is_mandatory
211
- end
212
-
213
- " case class #{vt_name}(value: #{super_type_title})(implicit val constellation: Constellation) extends FBMModel.ValueTypeValue[#{super_type_title}] {\n" +
214
- " val objectType = metaModel.#{vt_name.words.camelcase}\n" +
215
- # REVISIT: scala_type_params +
216
- # REVISIT: scala_value_restriction + # puts " restrict #{value_constraint.all_allowed_range_sorted.map{|ar| ar.to_s}*", "}\n" if value_constraint
217
- # REVISIT: scala_units + # puts " \# REVISIT: #{vt_name} is in units of #{unit.name}\n" if unit
218
- absorbed_roles.map do |role|
191
+ DataTypeMap = {
192
+ "Signed Integer" => "Int",
193
+ "Unsigned Integer" => "Int",
194
+ "Real" => "Double",
195
+ "Char" => "String",
196
+ # REVISIT: More will be needed here.
197
+ }
198
+ LengthTypes = [ "String", "Decimal" ]
199
+ ScaleTypes = [ "Decimal" ]
200
+
201
+ def scala_definition(super_type_name, facets)
202
+ vt_name = name.words.titlecase
203
+ if d = DataTypeMap[super_type_name]
204
+ super_type_name = d
205
+ end
206
+ super_type_title = super_type_name.words.titlecase
207
+ super_type_camel = super_type_name.words.camelcase
208
+
209
+ sometimes_optional = all_role.detect do |r|
210
+ r.fact_type.all_role.size == 2 && (c = (r.fact_type.all_role.to_a-[r])[0]) and !c.is_mandatory
211
+ end
212
+
213
+ " case class #{vt_name}(value: #{super_type_title})(implicit val constellation: Constellation) extends FBMModel.ValueTypeValue[#{super_type_title}] {\n" +
214
+ " val objectType = metaModel.#{vt_name.words.camelcase}\n" +
215
+ # REVISIT: scala_type_params +
216
+ # REVISIT: scala_value_restriction + # puts " restrict #{value_constraint.all_allowed_range_sorted.map{|ar| ar.to_s}*", "}\n" if value_constraint
217
+ # REVISIT: scala_units + # puts " \# REVISIT: #{vt_name} is in units of #{unit.name}\n" if unit
218
+ absorbed_roles.map do |role|
219
219
  role.scala_role_definition
220
220
  end.
221
221
  compact*"\n" +
222
- " }\n" +
223
-
224
- # Add implicit casts for the underlying data type:
225
- " implicit def #{super_type_camel}2#{vt_name}(value: #{super_type_title})(implicit constellation: Constellation): #{vt_name} = #{vt_name}(value)\n" +
226
- if sometimes_optional
227
- " implicit def #{super_type_camel}2#{vt_name}Option(value: #{super_type_title})(implicit constellation: Constellation): Option[#{vt_name}] = Some(#{vt_name}(value))\n"
228
- else
229
- ""
230
- end +
231
- "\n"
232
- end
233
-
234
- def scala_metamodel(super_type_name, facets)
235
- vt_name = name.words.titlecase
236
- super_type_title = super_type_name.words.titlecase
237
- # REVISIT: Remove facets that do not apply to the Scala data types
238
- params = [
239
- LengthTypes.include?(super_type_name) ? facets[:length] : nil,
240
- ScaleTypes.include?(super_type_name) ? facets[:scale] : nil
241
- ].compact * ", "
242
-
243
- " val #{name.words.camelcase} = assertEntity(FBMModel.ValueType(FBMModel.DomainObjectTypeName(\"#{vt_name}\"), FBMModel.#{super_type_title}Type(#{params}), Nil))\n"
244
- end
222
+ " }\n" +
223
+
224
+ # Add implicit casts for the underlying data type:
225
+ " implicit def #{super_type_camel}2#{vt_name}(value: #{super_type_title})(implicit constellation: Constellation): #{vt_name} = #{vt_name}(value)\n" +
226
+ if sometimes_optional
227
+ " implicit def #{super_type_camel}2#{vt_name}Option(value: #{super_type_title})(implicit constellation: Constellation): Option[#{vt_name}] = Some(#{vt_name}(value))\n"
228
+ else
229
+ ""
230
+ end +
231
+ "\n"
232
+ end
233
+
234
+ def scala_metamodel(super_type_name, facets)
235
+ vt_name = name.words.titlecase
236
+ super_type_title = super_type_name.words.titlecase
237
+ # REVISIT: Remove facets that do not apply to the Scala data types
238
+ params = [
239
+ LengthTypes.include?(super_type_name) ? facets[:length] : nil,
240
+ ScaleTypes.include?(super_type_name) ? facets[:scale] : nil
241
+ ].compact * ", "
242
+
243
+ " val #{name.words.camelcase} = assertEntity(FBMModel.ValueType(FBMModel.DomainObjectTypeName(\"#{vt_name}\"), FBMModel.#{super_type_title}Type(#{params}), Nil))\n"
244
+ end
245
245
  end
246
246
 
247
247
  module EntityType
248
- def scala_object(title_name, id_names, id_types)
249
- " object #{title_name} {\n" +
250
- " def apply(" +
251
- (id_names.zip(id_types).map do |(name, type_name)|
252
- "#{name}: #{type_name}"
253
- end * ', '
254
- ) +
255
- ")(implicit constellation: Constellation) = {\n" +
256
-
257
- # Define the constant storage for the identifying role values:
258
- id_names.map do |name|
259
- " val _#{name} = #{name}"
260
- end*"\n" +
261
- " val _constellation = constellation\n" +
262
- " assertEntity(new #{title_name} {\n" +
263
- id_names.map do |name|
264
- " val #{name} = _#{name}"
265
- end*"\n" +
266
- " val constellation = _constellation\n" +
267
- " })\n" + # Ends new block and assertEntity
268
- " }\n" + # Ends apply()
269
- " }\n" + # Ends object{}
270
- "\n"
271
- end
272
-
273
- def scala_trait(title_name, primary_supertype, pis)
274
- s = 'override ' unless supertypes.empty?
275
-
276
- " trait #{title_name} extends #{primary_supertype ? primary_supertype.name.words.titlecase : 'FBMModel.Entity'} {\n" +
277
- " #{s}val objectType = metaModel.#{name.words.camelcase}\n" +
278
- (fact_type ? " // REVISIT: Here, we should use fact_roles_dump(fact_type)\n\n" : '') +
279
- absorbed_roles.map do |role|
248
+ def scala_object(title_name, id_names, id_types)
249
+ " object #{title_name} {\n" +
250
+ " def apply(" +
251
+ (id_names.zip(id_types).map do |(name, type_name)|
252
+ "#{name}: #{type_name}"
253
+ end * ', '
254
+ ) +
255
+ ")(implicit constellation: Constellation) = {\n" +
256
+
257
+ # Define the constant storage for the identifying role values:
258
+ id_names.map do |name|
259
+ " val _#{name} = #{name}"
260
+ end*"\n" +
261
+ " val _constellation = constellation\n" +
262
+ " assertEntity(new #{title_name} {\n" +
263
+ id_names.map do |name|
264
+ " val #{name} = _#{name}"
265
+ end*"\n" +
266
+ " val constellation = _constellation\n" +
267
+ " })\n" + # Ends new block and assertEntity
268
+ " }\n" + # Ends apply()
269
+ " }\n" + # Ends object{}
270
+ "\n"
271
+ end
272
+
273
+ def scala_trait(title_name, primary_supertype, pis)
274
+ s = 'override ' unless supertypes.empty?
275
+
276
+ " trait #{title_name} extends #{primary_supertype ? primary_supertype.name.words.titlecase : 'FBMModel.Entity'} {\n" +
277
+ " #{s}val objectType = metaModel.#{name.words.camelcase}\n" +
278
+ (fact_type ? " // REVISIT: Here, we should use fact_roles_dump(fact_type)\n\n" : '') +
279
+ absorbed_roles.map do |role|
280
280
  role.scala_role_definition
281
281
  end.
282
282
  compact*"\n" +
283
- " #{s}val identifier: Seq[Seq[FBMModel.Identifier[_]]] = Seq(#{
284
- pis.map do |pi|
285
- 'Seq(' +
286
- pi.role_sequence.all_role_ref_in_order.map do |id_role_ref|
287
- id_role_ref.role.object_type.name.words.camelcase
288
- end*', ' +
289
- ')'
290
- end*', '
291
- })\n" +
292
- " }\n" + # Ends trait{}
293
- "\n"
294
- end
295
-
296
- def scala_metamodel(title_name)
297
- pi = preferred_identifier
298
- # The following finds the closest non-inheritance identifier
299
- #while pi.role_sequence.all_role_ref.size == 1 and
300
- # (role = pi.role_sequence.all_role_ref.single.role).fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
301
- # pi = role.fact_type.supertype_role.object_type.preferred_identifier
302
- #end
303
- identifying_parameters =
304
- pi.role_sequence.all_role_ref_in_order.map{|rr| rr.role.object_type.name.words.camelcase }*', '
305
-
306
- supertypes_list =
307
- if supertypes.empty?
308
- 'Nil'
309
- else
310
- "List(#{supertypes.map{|s| s.name.words.camelcase}*', '})"
311
- end
312
- " val #{name.words.camelcase} = assertEntity(FBMModel.EntityType(FBMModel.DomainObjectTypeName(\"#{title_name}\"), #{supertypes_list}, Seq(#{identifying_parameters})))\n"
313
- end
314
-
315
- def scala_shared(o, supertypes, pi = nil)
316
- if supertypes
317
- primary_supertype = o && (o.identifying_supertype || o.supertypes[0])
318
- end
319
- title_name = o.name.words.titlecase
320
-
321
- id_roles, pis = *all_identifying_roles(o)
322
- id_names = id_role_names(o, id_roles)
323
- id_types = id_role_types(id_roles)
324
- identification = pi ? identified_by(o, pi) : nil
325
-
326
- # REVISIT: We don't want an object for abstract classes,
327
- # i.e. where subtypes have a disjoint mandatory constraint
328
- entity_object(title_name, id_names, id_types)
329
-
330
- entity_trait(o, title_name, primary_supertype, pis)
331
-
332
- entity_model(o, title_name)
333
- end
334
-
335
- def id_role_names id_roles
336
- id_roles.map do |role|
337
- # Ignore identification through a supertype
338
- next if role.fact_type.kind_of?(ActiveFacts::Metamodel::TypeInheritance)
339
- role.scala_preferred_role_name(self).words.camelcase
340
- end.compact
341
- end
342
-
343
- def id_role_types id_roles
344
- id_roles.map do |role|
345
- next if role.fact_type.kind_of?(ActiveFacts::Metamodel::TypeInheritance)
346
- if !role.fact_type.entity_type && role.fact_type.all_role.size == 1
347
- "Boolean"
348
- else
349
- role.object_type.name.words.titlecase
350
- end
351
- end.compact
352
- end
353
-
354
- def scala_objectification
355
- # REVISIT: This disregards any supertypes and their identifiers
283
+ " #{s}val identifier: Seq[Seq[FBMModel.Identifier[_]]] = Seq(#{
284
+ pis.map do |pi|
285
+ 'Seq(' +
286
+ pi.role_sequence.all_role_ref_in_order.map do |id_role_ref|
287
+ id_role_ref.role.object_type.name.words.camelcase
288
+ end*', ' +
289
+ ')'
290
+ end*', '
291
+ })\n" +
292
+ " }\n" + # Ends trait{}
293
+ "\n"
294
+ end
295
+
296
+ def scala_metamodel(title_name)
297
+ pi = preferred_identifier
298
+ # The following finds the closest non-inheritance identifier
299
+ #while pi.role_sequence.all_role_ref.size == 1 and
300
+ # (role = pi.role_sequence.all_role_ref.single.role).fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
301
+ # pi = role.fact_type.supertype_role.object_type.preferred_identifier
302
+ #end
303
+ identifying_parameters =
304
+ pi.role_sequence.all_role_ref_in_order.map{|rr| rr.role.object_type.name.words.camelcase }*', '
305
+
306
+ supertypes_list =
307
+ if supertypes.empty?
308
+ 'Nil'
309
+ else
310
+ "List(#{supertypes.map{|s| s.name.words.camelcase}*', '})"
311
+ end
312
+ " val #{name.words.camelcase} = assertEntity(FBMModel.EntityType(FBMModel.DomainObjectTypeName(\"#{title_name}\"), #{supertypes_list}, Seq(#{identifying_parameters})))\n"
313
+ end
314
+
315
+ def scala_shared(o, supertypes, pi = nil)
316
+ if supertypes
317
+ primary_supertype = o && (o.identifying_supertype || o.supertypes[0])
318
+ end
319
+ title_name = o.name.words.titlecase
320
+
321
+ id_roles, pis = *all_identifying_roles(o)
322
+ id_names = id_role_names(o, id_roles)
323
+ id_types = id_role_types(id_roles)
324
+ identification = pi ? identified_by(o, pi) : nil
325
+
326
+ # REVISIT: We don't want an object for abstract classes,
327
+ # i.e. where subtypes have a disjoint mandatory constraint
328
+ entity_object(title_name, id_names, id_types)
329
+
330
+ entity_trait(o, title_name, primary_supertype, pis)
331
+
332
+ entity_model(o, title_name)
333
+ end
334
+
335
+ def id_role_names id_roles
336
+ id_roles.map do |role|
337
+ # Ignore identification through a supertype
338
+ next if role.fact_type.kind_of?(ActiveFacts::Metamodel::TypeInheritance)
339
+ role.scala_preferred_role_name(self).words.camelcase
340
+ end.compact
341
+ end
342
+
343
+ def id_role_types id_roles
344
+ id_roles.map do |role|
345
+ next if role.fact_type.kind_of?(ActiveFacts::Metamodel::TypeInheritance)
346
+ if !role.fact_type.entity_type && role.fact_type.all_role.size == 1
347
+ "Boolean"
348
+ else
349
+ role.object_type.name.words.titlecase
350
+ end
351
+ end.compact
352
+ end
353
+
354
+ def scala_objectification
355
+ # REVISIT: This disregards any supertypes and their identifiers
356
356
  # primary_supertype = o && (o.identifying_supertype || o.supertypes[0])
357
357
  # secondary_supertypes = o.supertypes-[primary_supertype]
358
358
 
359
- pi = preferred_identifier
360
- id_roles = []
361
- identifying_role_refs = pi.role_sequence.all_role_ref_in_order
362
- identifying_role_refs.each do |id_role_ref|
363
- id_roles << id_role_ref.role
364
- end
365
- id_names = id_role_names id_roles
366
- id_types = id_role_types id_roles
367
-
368
- " case class #{name.words.titlecase}(#{
369
- id_names.zip(id_types).map {|(n, t)|
370
- "#{n}: #{t}"
371
- }*', '
372
- }) extends FBMModel.ObjectifiedFact {\n" +
373
- " // REVISIT: Here, we should use fact_roles_dump(fact_type)\n" +
374
- absorbed_roles.map do |role|
359
+ pi = preferred_identifier
360
+ id_roles = []
361
+ identifying_role_refs = pi.role_sequence.all_role_ref_in_order
362
+ identifying_role_refs.each do |id_role_ref|
363
+ id_roles << id_role_ref.role
364
+ end
365
+ id_names = id_role_names id_roles
366
+ id_types = id_role_types id_roles
367
+
368
+ " case class #{name.words.titlecase}(#{
369
+ id_names.zip(id_types).map {|(n, t)|
370
+ "#{n}: #{t}"
371
+ }*', '
372
+ }) extends FBMModel.ObjectifiedFact {\n" +
373
+ " // REVISIT: Here, we should use fact_roles_dump(fact_type)\n" +
374
+ absorbed_roles.map do |role|
375
375
  role.scala_role_definition
376
376
  end.
377
377
  compact*"\n" +
378
- " }"
379
- end
378
+ " }"
379
+ end
380
380
 
381
- def scala_objectification_metamodel
382
- identifying_parameters = preferred_identifier.role_sequence.all_role_ref_in_order.map{|rr| rr.role.object_type.name.words.camelcase }*', '
383
- " val #{name.words.camelcase} = assertEntity(FBMModel.ObjectifiedType(FBMModel.DomainObjectTypeName(\"#{name.words.titlecase}\"), Nil, Seq(#{identifying_parameters})))\n"
384
- end
381
+ def scala_objectification_metamodel
382
+ identifying_parameters = preferred_identifier.role_sequence.all_role_ref_in_order.map{|rr| rr.role.object_type.name.words.camelcase }*', '
383
+ " val #{name.words.camelcase} = assertEntity(FBMModel.ObjectifiedType(FBMModel.DomainObjectTypeName(\"#{name.words.titlecase}\"), Nil, Seq(#{identifying_parameters})))\n"
384
+ end
385
385
  end
386
386
 
387
387
  module FactType
@@ -415,28 +415,28 @@ END
415
415
 
416
416
  # An objectified fact type has internal roles that are always "has_one":
417
417
  def fact_roles
418
- raise "Fact #{describe} type is not objectified" unless entity_type
418
+ raise "Fact #{describe} type is not objectified" unless entity_type
419
419
  all_role.sort_by do |role|
420
- role.scala_preferred_role_name(entity_type)
421
- end.
422
- map do |role|
423
- role_name = role.scala_preferred_role_name(entity_type)
424
- one_to_one = role.all_role_ref.detect{|rr|
425
- rr.role_sequence.all_role_ref.size == 1 &&
426
- rr.role_sequence.all_presence_constraint.detect{|pc|
427
- pc.max_frequency == 1
428
- }
429
- }
430
- counterpart_role_method = (one_to_one ? "" : "all_") +
431
- entity_type.oo_default_role_name +
432
- (role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : '')
433
- role.as_binary(role_name, role.object_type, true, one_to_one, nil, nil, counterpart_role_method)
434
- end.
435
- join('')
436
- end
420
+ role.scala_preferred_role_name(entity_type)
421
+ end.
422
+ map do |role|
423
+ role_name = role.scala_preferred_role_name(entity_type)
424
+ one_to_one = role.all_role_ref.detect{|rr|
425
+ rr.role_sequence.all_role_ref.size == 1 &&
426
+ rr.role_sequence.all_presence_constraint.detect{|pc|
427
+ pc.max_frequency == 1
428
+ }
429
+ }
430
+ counterpart_role_method = (one_to_one ? "" : "all_") +
431
+ entity_type.oo_default_role_name +
432
+ (role_name != role.object_type.oo_default_role_name ? "_as_#{role_name}" : '')
433
+ role.as_binary(role_name, role.object_type, true, one_to_one, nil, nil, counterpart_role_method)
434
+ end.
435
+ join('')
436
+ end
437
437
  end
438
438
 
439
- include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
439
+ include ActiveFacts::TraitInjector # Must be last in this module, after all submodules have been defined
440
440
  end
441
441
  end
442
442
  end