tla-sbuilder 0.2.2 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +150 -116
- data/VERSION +1 -1
- data/lib/cli/cli-customer.rb +23 -3
- data/lib/cli/cli-pet.rb +66 -12
- data/lib/cli/cli-text.rb +127 -8
- data/lib/cli/cli.rb +49 -6
- data/lib/sbuilder.rb +26 -3
- data/lib/sbuilder/constants.rb +165 -6
- data/lib/sbuilder/controller.rb +943 -169
- data/lib/sbuilder/controller_utils.rb +122 -0
- data/lib/sbuilder/default-sbuilder.yaml +38 -44
- data/lib/sbuilder/domain.rb +160 -36
- data/lib/sbuilder/domain_cardinality.rb +1 -1
- data/lib/sbuilder/domain_range.rb +102 -0
- data/lib/sbuilder/domain_type.rb +150 -0
- data/lib/sbuilder/domain_value.rb +21 -13
- data/lib/sbuilder/exception.rb +16 -0
- data/lib/sbuilder/extension_loader.rb +67 -686
- data/lib/sbuilder/extension_loader_deprecated_step_extensions.rb +711 -0
- data/lib/sbuilder/extension_loader_step_generator.rb +876 -0
- data/lib/sbuilder/facade/{api_loader.rb → api_loader_facade.rb} +176 -45
- data/lib/sbuilder/facade/api_loader_plugin.rb +6 -32
- data/lib/sbuilder/facade/api_loader_plugin_mixer.rb +35 -0
- data/lib/sbuilder/facade/facade_constants.rb +23 -0
- data/lib/sbuilder/facade/loader_plugin_root.rb +56 -0
- data/lib/sbuilder/facade/param_set_root.rb +55 -0
- data/lib/sbuilder/facade/snippet_loader_facade.rb +600 -0
- data/lib/sbuilder/facade/snippet_loader_plugin.rb +76 -0
- data/lib/sbuilder/facade/snippet_loader_plugin_mixer.rb +56 -0
- data/lib/sbuilder/factory.rb +224 -45
- data/lib/sbuilder/model.rb +125 -45
- data/lib/sbuilder/mustache/template.rb +107 -58
- data/lib/sbuilder/mustache/template_reader.rb +56 -46
- data/lib/sbuilder/mustache/template_reader_context.rb +64 -234
- data/lib/sbuilder/mustache/template_resolve.rb +103 -0
- data/lib/sbuilder/mustache/template_root.rb +71 -0
- data/lib/sbuilder/param_set.rb +30 -15
- data/lib/sbuilder/param_set_db.rb +1 -1
- data/lib/sbuilder/param_set_def.rb +6 -1
- data/lib/sbuilder/param_set_def_func.rb +39 -0
- data/lib/sbuilder/param_set_if.rb +45 -10
- data/lib/sbuilder/param_set_loader_swagger.rb +56 -26
- data/lib/sbuilder/param_set_step.rb +1 -1
- data/lib/sbuilder/param_sets.rb +2 -1
- data/lib/sbuilder/parameter.rb +9 -3
- data/lib/sbuilder/parameter_container.rb +1 -1
- data/lib/sbuilder/parameter_dom.rb +17 -5
- data/lib/sbuilder/parameter_ref.rb +39 -10
- data/lib/sbuilder/parser/parser_facade.rb +310 -0
- data/lib/sbuilder/resolver.rb +11 -6
- data/lib/sbuilder/resolver_loader.rb +1 -1
- data/lib/sbuilder/resolver_loader_yaml.rb +1 -1
- data/lib/sbuilder/resolver_rule.rb +1 -1
- data/lib/sbuilder/resolver_rule_match.rb +10 -4
- data/lib/sbuilder/resolver_rule_ref.rb +1 -1
- data/lib/sbuilder/setup_loader.rb +49 -0
- data/lib/sbuilder/setup_loader_env.rb +478 -0
- data/lib/sbuilder/setup_loader_pref.rb +56 -0
- data/lib/sbuilder/snippet_loader_simple.rb +125 -0
- data/lib/sbuilder/spec/api_loader.rb +34 -0
- data/lib/sbuilder/spec/api_loader_facade.rb +169 -32
- data/lib/sbuilder/spec/loader_plugin.rb +98 -0
- data/lib/sbuilder/spec/snippet_loader.rb +228 -0
- data/lib/sbuilder/symbol_table.rb +279 -0
- data/lib/utils/{cache_lines.rb → fileio.rb} +8 -1
- data/lib/utils/logger.rb +2 -1
- data/lib/utils/powerset.rb +13 -0
- data/lib/utils/validate.rb +38 -0
- data/mustache/cfg/const_def.mustache +2 -0
- data/mustache/cfg/macro_run.mustache +1 -4
- data/mustache/data-model-header.mustache +1 -0
- data/mustache/definition_types.mustache +34 -4
- data/mustache/domains.mustache +1 -1
- data/mustache/domains_assign.mustache +1 -1
- data/mustache/infrastructure-service-init.mustache +1 -1
- data/mustache/interface_processes.mustache +16 -10
- data/mustache/interface_types.mustache +37 -11
- data/mustache/operator-infrastructure-service.mustache +1 -1
- data/mustache/resources/schedule_operator_new_step.tla +8 -0
- data/mustache/resources/schedule_process_macro.tla +37 -0
- data/mustache/resources/schedule_process_procedure.tla +22 -0
- data/mustache/resources/schedule_throw.tla +16 -0
- data/mustache/setup/domains_run.mustache +8 -2
- data/mustache/setup/operator_run.mustache +0 -4
- data/mustache/setup/steps_run.mustache +4 -3
- data/mustache/setup/steps_run_parameterBind.mustache +14 -6
- data/mustache/setup/steps_run_parameterExact.mustache +7 -3
- data/mustache/state_type_invariant-infrastructure-service.mustache +9 -4
- data/mustache/tla/const_def.mustache +1 -1
- data/mustache/tla/macro_run.mustache +7 -1
- data/mustache/tla/module_header.mustache +1 -1
- data/mustache/tla/operator_run.mustache +8 -5
- data/mustache/tla/plc_define_run.mustache +45 -36
- data/mustache/tla/plc_run_state.mustache +12 -5
- data/src-extend/extend/extend_assumptions.mustache +3 -0
- data/src-extend/extend/extend_const.mustache +3 -0
- data/src-extend/extend/extend_implementation.mustache +3 -0
- data/src-extend/extend/extend_invariant.mustache +3 -0
- data/src-extend/extend/extend_macros.mustache +3 -0
- data/src-extend/extend/extend_operations.mustache +3 -0
- data/src-extend/extend/extend_state.mustache +3 -0
- data/src/pet/extend/extend_assumptions.mustache +4 -0
- data/src/pet/extend/extend_implementation.mustache +3 -0
- data/src/pet/extend/extend_invariant.mustache +3 -0
- data/src/pet/extend/extend_macros.mustache +3 -0
- data/src/pet/extend/extend_operations.mustache +4 -0
- data/src/pet/extend/extend_state.mustache +3 -0
- data/src/pet/interface +5 -5
- data/src/pet/interface_delete_pet.tla +1 -1
- data/src/pet/interface_get_pet.tla +1 -1
- data/src/pet/interface_post_pet.tla +4 -2
- data/src/pet/interface_post_tag.tla +1 -1
- data/src/pet/interface_put_tag.tla +1 -1
- data/tla-sbuilder.gemspec +3 -3
- metadata +44 -19
- data/mustache/name_definition_type.mustache +0 -5
- data/mustache/name_domain.mustache +0 -5
- data/mustache/name_domain_value.mustache +0 -5
- data/mustache/name_domain_value_prefix.mustache +0 -5
- data/mustache/name_interface_response_type.mustache +0 -6
- data/mustache/name_interface_type.mustache +0 -6
- data/mustache/name_parameter_type.mustache +0 -6
- data/mustache/name_process.mustache +0 -6
- data/mustache/state_type_invariant.mustache +0 -17
- data/mustache/state_variables.mustache +0 -20
- data/src-extend/extend/extend_invariant_cfg.mustache +0 -7
@@ -0,0 +1,102 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
|
3
|
+
class DomainRange < Domain
|
4
|
+
|
5
|
+
PROGNAME = nil # progname for logger default class name
|
6
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
7
|
+
|
8
|
+
# @attr [Integer] rangeStart
|
9
|
+
attr_reader :rangeStart
|
10
|
+
|
11
|
+
# @attr [Integer] rangeEnd
|
12
|
+
attr_reader :rangeEnd
|
13
|
+
|
14
|
+
|
15
|
+
# ------------------------------------------------------------------
|
16
|
+
# @!group Constructor & configure
|
17
|
+
|
18
|
+
|
19
|
+
def initialize( options = {} )
|
20
|
+
super( options )
|
21
|
+
@logger = getLogger( PROGNAME, options )
|
22
|
+
@logger.debug( "#{__method__} initialized" )
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Set domain +rangeStart+ .. +rangeEnd+
|
28
|
+
#
|
29
|
+
# @param [Integer] rangeStart
|
30
|
+
# @param [Integer] rangeEnd
|
31
|
+
def setRange( rangeStart, rangeEnd )
|
32
|
+
@rangeStart = rangeStart
|
33
|
+
@rangeEnd = rangeEnd
|
34
|
+
end
|
35
|
+
|
36
|
+
# @!endgroup
|
37
|
+
|
38
|
+
# ------------------------------------------------------------------
|
39
|
+
# @!group Override from base class
|
40
|
+
|
41
|
+
##
|
42
|
+
# Range does not include Nil in domain set.
|
43
|
+
#
|
44
|
+
# @return [Boolean] false overrides default
|
45
|
+
def includeNil
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Integer] {rangeEnd} - {rangeStart} + 1
|
50
|
+
def cardinality
|
51
|
+
rangeEnd - rangeStart + 1
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param i [Integer|String] domain entry to access
|
55
|
+
# @return {rangeStart} + i
|
56
|
+
def domain_entry( i )
|
57
|
+
|
58
|
+
# Convert to integer - if possible
|
59
|
+
i = Integer(i ) unless i.is_a?( Integer )
|
60
|
+
|
61
|
+
# Valid range index?
|
62
|
+
if i<rangeStart || i>rangeEnd
|
63
|
+
msg = <<-EOS
|
64
|
+
Error in domain range #{i}
|
65
|
+
|
66
|
+
Valid domain index: #{rangeStart}..#{rangeEnd}
|
67
|
+
EOS
|
68
|
+
@logger.error "#{__method__}: #{msg}"
|
69
|
+
raise DomainException, msg
|
70
|
+
end
|
71
|
+
|
72
|
+
i
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [ val ] no change (because integers should not be wrapped
|
76
|
+
def stringize( val )
|
77
|
+
val
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Array] of intergers [{rangeStart}..{rangeEnd}]
|
81
|
+
def render_values
|
82
|
+
(rangeStart..rangeEnd).to_a
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Range overrides default implementation for 'domain', and return
|
87
|
+
# valid index for 'domain_entry'.
|
88
|
+
#
|
89
|
+
# @Return [Integer..Integer] range to access 'domain_entry' of
|
90
|
+
# (maybe extentended) domain
|
91
|
+
def domain_range
|
92
|
+
rangeStart..rangeEnd
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# @!endgroup
|
97
|
+
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
|
3
|
+
class DomainType < Domain
|
4
|
+
|
5
|
+
PROGNAME = nil # progname for logger default class name
|
6
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
7
|
+
|
8
|
+
TYPE_DEFS = {
|
9
|
+
'Int' => {
|
10
|
+
:tlaBaseType => true,
|
11
|
+
},
|
12
|
+
|
13
|
+
'BOOLEAN' => {
|
14
|
+
:cardinality => 2,
|
15
|
+
:domain_range => 0..1,
|
16
|
+
:tlaBaseType => true,
|
17
|
+
:map => {
|
18
|
+
0 => 'FALSE',
|
19
|
+
1 => 'TRUE',
|
20
|
+
true => 'TRUE',
|
21
|
+
false => 'FALSE',
|
22
|
+
'TRUE' => 'TRUE',
|
23
|
+
'FALSE' => 'FALSE',
|
24
|
+
}
|
25
|
+
},
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
# @attr [Integer] type e.g. Integer
|
30
|
+
attr_reader :type
|
31
|
+
|
32
|
+
|
33
|
+
# ------------------------------------------------------------------
|
34
|
+
# @!group Constructor & configure
|
35
|
+
|
36
|
+
|
37
|
+
def initialize( options = {} )
|
38
|
+
super( options )
|
39
|
+
@logger = getLogger( PROGNAME, options )
|
40
|
+
@logger.debug( "#{__method__} initialized" )
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Set domain +type+
|
46
|
+
#
|
47
|
+
# @param [String] type
|
48
|
+
def setType( typeIn )
|
49
|
+
|
50
|
+
if TYPE_DEFS.keys.include?( typeIn )
|
51
|
+
@type = typeIn
|
52
|
+
else
|
53
|
+
|
54
|
+
msg=<<-EOS
|
55
|
+
Invalid type '#{typeIn}'
|
56
|
+
|
57
|
+
Valid types: #{TYPE_DEFS.keys.join(',')}
|
58
|
+
EOS
|
59
|
+
@logger.error "#{__method__}: #{msg}"
|
60
|
+
raise DomainException, msg
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!endgroup
|
67
|
+
|
68
|
+
# ------------------------------------------------------------------
|
69
|
+
# @!group Override from base class
|
70
|
+
|
71
|
+
##
|
72
|
+
# Just type, no nils counted here
|
73
|
+
#
|
74
|
+
# @return [Boolean] false overrides default
|
75
|
+
def includeNil
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# It is safe to call +cardinality+, +domain_values+,
|
81
|
+
# +numberOfElements+, +render_values+, ...
|
82
|
+
#
|
83
|
+
# @return true, extension may override
|
84
|
+
#
|
85
|
+
def tlaBaseType
|
86
|
+
return TYPE_DEFS[type][:tlaBaseType] if TYPE_DEFS[type][:tlaBaseType]
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [Integer] {rangeEnd} - {rangeStart} + 1
|
91
|
+
def cardinality
|
92
|
+
return TYPE_DEFS[type][:cardinality] if TYPE_DEFS[type][:cardinality]
|
93
|
+
msg = <<-EOS
|
94
|
+
Cardinality not applicable for #{self.class} type #{type}
|
95
|
+
EOS
|
96
|
+
@logger.error "#{__method__}, #{msg}"
|
97
|
+
raise DomainException, msg
|
98
|
+
end
|
99
|
+
|
100
|
+
# @param i [Integer|String] domain entry to access
|
101
|
+
# @return {rangeStart} + i
|
102
|
+
def domain_entry( i )
|
103
|
+
if TYPE_DEFS[type][:map] then
|
104
|
+
ret = TYPE_DEFS[type][:map][i]
|
105
|
+
if ret.nil?
|
106
|
+
msg = <<-EOS
|
107
|
+
Invalid value entry #{i} for #{self.class} type #{type}
|
108
|
+
|
109
|
+
Valid values #{TYPE_DEFS[type][:map].keys.join(',')}
|
110
|
+
EOS
|
111
|
+
@logger.error "#{__method__}, #{msg}"
|
112
|
+
raise DomainException, msg
|
113
|
+
end
|
114
|
+
ret
|
115
|
+
else
|
116
|
+
i
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [ val ] no change (because integers should not be wrapped
|
121
|
+
def stringize( val )
|
122
|
+
val
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Domain values is the set +type+
|
127
|
+
#
|
128
|
+
# @return [String] type
|
129
|
+
def render_values
|
130
|
+
return type
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Not possible for type domain.
|
135
|
+
def domain_range
|
136
|
+
return TYPE_DEFS[type][:domain_range] if TYPE_DEFS[type][:domain_range]
|
137
|
+
msg = <<-EOS
|
138
|
+
domain_range not applicable for #{self.class} type #{type}
|
139
|
+
EOS
|
140
|
+
@logger.error "#{__method__}, #{msg}"
|
141
|
+
raise DomainException, msg
|
142
|
+
end
|
143
|
+
|
144
|
+
# @!endgroup
|
145
|
+
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
@@ -7,8 +7,8 @@ module Sbuilder
|
|
7
7
|
|
8
8
|
# ------------------------------------------------------------------
|
9
9
|
# mixer
|
10
|
-
PROGNAME =
|
11
|
-
include Sbuilder::Utils::MyLogger
|
10
|
+
PROGNAME = nil # progname for logger default class name
|
11
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
12
12
|
|
13
13
|
|
14
14
|
def initialize( options = {} )
|
@@ -29,22 +29,30 @@ module Sbuilder
|
|
29
29
|
|
30
30
|
|
31
31
|
# @param i [integer|string] domain entry to access
|
32
|
-
# @return value in location `i-1` ie. indexing from 1,2,3,.. when i:integer
|
32
|
+
# @return [String] value in location `i-1` ie. indexing from 1,2,3,.. when i:integer
|
33
33
|
# value with the given name when i:string
|
34
34
|
def domain_entry( i )
|
35
35
|
case i
|
36
36
|
when Integer
|
37
|
-
|
37
|
+
if i<1 || i>cardinality
|
38
|
+
msg = <<-EOS
|
39
|
+
Error in domain index #{i}
|
40
|
+
|
41
|
+
Valid domain index: 1..#{cardinality}
|
42
|
+
EOS
|
43
|
+
raise DomainException.new, msg
|
44
|
+
end
|
45
|
+
@values[i-1]
|
38
46
|
when String
|
39
47
|
ret = @values.select { |val| val == i }.first
|
40
48
|
if ret.nil?
|
41
49
|
raise DomainException.new <<-EOS
|
42
|
-
Unknown domain entry #{i}
|
50
|
+
Unknown domain entry '#{i}'
|
43
51
|
|
44
52
|
Known domain entries: #{values.join(',')}
|
45
53
|
EOS
|
46
54
|
end
|
47
|
-
|
55
|
+
ret
|
48
56
|
else
|
49
57
|
raise DomainException.new <<-EOS
|
50
58
|
Unknown type #{i.class} in 'domain_entry' #{name}.
|
@@ -53,14 +61,14 @@ module Sbuilder
|
|
53
61
|
EOS
|
54
62
|
end
|
55
63
|
end
|
56
|
-
|
57
64
|
|
58
|
-
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
|
66
|
+
# ##
|
67
|
+
# # @return [Array] entries as an array of strings for entries in domain - overides super
|
68
|
+
# def render_values
|
69
|
+
# @logger.debug( "#{__method__}: name: #{name}: added domain values #{values.join(',')}" )
|
70
|
+
# @values.map { |v| stringize( v ) }
|
71
|
+
# end
|
64
72
|
|
65
73
|
# ------------------------------------------------------------------
|
66
74
|
# build
|
data/lib/sbuilder/exception.rb
CHANGED
@@ -31,6 +31,22 @@ module Sbuilder
|
|
31
31
|
|
32
32
|
class FactoryException < SbuilderException
|
33
33
|
end
|
34
|
+
|
35
|
+
class FacadeException < SbuilderException
|
36
|
+
end
|
37
|
+
|
38
|
+
class DeprecatedException < SbuilderException
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class SymbolTableException < SbuilderException
|
43
|
+
end
|
44
|
+
|
45
|
+
class StepGeneratorException < SbuilderException
|
46
|
+
end
|
47
|
+
|
48
|
+
class ValidateException < SbuilderException
|
49
|
+
end
|
34
50
|
|
35
51
|
|
36
52
|
end
|
@@ -1,28 +1,25 @@
|
|
1
|
+
|
2
|
+
require_relative( './extension_loader_deprecated_step_extensions.rb')
|
3
|
+
|
1
4
|
module Sbuilder
|
2
5
|
|
3
6
|
class ExtensionLoader
|
4
7
|
|
8
|
+
# @attr [Sbuilder::Controller] controller
|
5
9
|
attr_accessor :controller # get sets when load starts
|
10
|
+
|
11
|
+
# @attr [String] setupName being loaded
|
12
|
+
attr_reader :setupName
|
6
13
|
|
7
14
|
# ------------------------------------------------------------------
|
8
15
|
# mixer
|
9
|
-
PROGNAME =
|
16
|
+
PROGNAME = nil # progname for logger defaults class name
|
10
17
|
include Sbuilder::Utils::MyLogger # mix logger
|
11
|
-
|
12
|
-
@@extensionDefProperties = ['domain-extension', 'interface-extension', 'step-extension']
|
13
|
-
|
14
|
-
@@extensionDoaminProperties = ['domain', 'cardinality']
|
15
|
-
|
16
|
-
@@extensionValuesProperties = ['domain', 'values']
|
17
18
|
|
18
|
-
|
19
|
-
@@validStepExtension_allowed = @@validStepExtension_required + ["input", "bindExact", "inputs"]
|
19
|
+
include Sbuilder::ExtensionLoader_Deprecated_Step_Extensions
|
20
20
|
|
21
|
-
@@validStepExtension_input = [ "input" ]
|
22
|
-
|
23
|
-
|
24
21
|
# ------------------------------------------------------------------
|
25
|
-
#
|
22
|
+
# @!group contruct & configure
|
26
23
|
|
27
24
|
def initialize( options = {} )
|
28
25
|
@logger = getLogger( PROGNAME, options )
|
@@ -30,6 +27,14 @@ module Sbuilder
|
|
30
27
|
self
|
31
28
|
end
|
32
29
|
|
30
|
+
##
|
31
|
+
# configure name of setup when loader constructed
|
32
|
+
def setupName=( name )
|
33
|
+
@setupName = name
|
34
|
+
end
|
35
|
+
|
36
|
+
# @!endgroup
|
37
|
+
|
33
38
|
# ------------------------------------------------------------------
|
34
39
|
# model - is found using contorller
|
35
40
|
def model
|
@@ -55,78 +60,52 @@ module Sbuilder
|
|
55
60
|
loadExtensions( domains_hash )
|
56
61
|
end
|
57
62
|
|
58
|
-
|
59
63
|
# iterate domains
|
60
64
|
def loadExtensions( extensionsArr )
|
61
65
|
extensionsArr && extensionsArr.each do |extensionDef|
|
62
66
|
raise ExtensionException.new "Invalid extension definition #{extensionDef}" unless (extensionDef.keys.length == 1)
|
63
|
-
validateProperties( extensionDef, [], @@extensionDefProperties )
|
67
|
+
# validateProperties( extensionDef, [], @@extensionDefProperties )
|
64
68
|
key = extensionDef.keys.first
|
65
69
|
case key
|
66
70
|
when 'domain-extension'
|
67
71
|
extensionDef[key].each do |domainDef|
|
68
|
-
|
69
|
-
extendDomainWithCardinality( domainDef )
|
70
|
-
else
|
71
|
-
extendDomainWithValues( domainDef )
|
72
|
-
end
|
72
|
+
controller.dispatchExtendDomain( domainDef )
|
73
73
|
end
|
74
74
|
when 'interface-extension'
|
75
|
-
extensionDef[key]
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
msg = deprecatedInterfaceExtension( extensionDef[key] )
|
76
|
+
@logger.error "#{__method__} #{msg}"
|
77
|
+
raise DeprecatedException.new( msg )
|
78
|
+
# extensionDef[key].each do |interfaceExtesionDef|
|
79
|
+
# extendInterface( interfaceExtesionDef )
|
80
|
+
# end
|
81
|
+
# when 'step-extension'
|
82
|
+
# extensionDef[key].each do |stepExtensionDef|
|
83
|
+
# extendStep( stepExtensionDef )
|
84
|
+
# end
|
82
85
|
else
|
83
|
-
|
86
|
+
ldr = factory.getSetupLoader( key, controller, setupName )
|
87
|
+
ldr.load( extensionDef[key] )
|
88
|
+
# raise ExtensionException.new "Unknown extension type #{key} in #{extensionDef}"
|
84
89
|
end
|
85
90
|
end
|
86
91
|
end
|
87
92
|
|
88
|
-
# validate 'defintionHash' all 'required'/only 'allowed' props set
|
89
|
-
private def validateProperties( defintionHash, required, allowed=nil )
|
90
|
-
|
91
|
-
allowed = required unless allowed
|
92
|
-
|
93
|
-
missingProps = required - defintionHash.keys
|
94
|
-
raise ExtensionException.new "Missing properties #{missingProps} in #{defintionHash} - required #{required}" if missingProps.any?
|
95
|
-
|
96
|
-
invalidProps = defintionHash.keys - allowed
|
97
|
-
raise ExtensionException.new "Unknown properties #{invalidProps} in #{defintionHash} - allowed #{allowed}" if invalidProps.any?
|
98
|
-
|
99
|
-
end
|
100
|
-
# ------------------------------------------------------------------
|
101
|
-
# extend one domain with cardinality
|
102
|
-
def extendDomainWithValues( domainDef )
|
103
|
-
@logger.info( "#{__method__} domainDef=#{domainDef}" )
|
104
|
-
validateProperties( domainDef, @@extensionValuesProperties )
|
105
|
-
|
106
|
-
# create & configure
|
107
|
-
domain = factory.createDomain( Sbuilder::Constants::TYPE_VALUE_DOMAIN )
|
108
|
-
domain.setName( domainDef['domain'] )
|
109
|
-
domainDef['values'].each { |value| domain.addValue( value ) }
|
110
93
|
|
111
|
-
# pass to model via controller
|
112
|
-
controller.extendDomain( domain )
|
113
|
-
|
114
|
-
end
|
115
94
|
|
116
95
|
# ------------------------------------------------------------------
|
96
|
+
# @!group Domain extensions
|
97
|
+
|
98
|
+
|
99
|
+
##
|
100
|
+
# extend domain with values
|
101
|
+
|
102
|
+
##
|
117
103
|
# extend one domain with cardinality
|
118
|
-
|
119
|
-
|
120
|
-
validateProperties( domainDef, @@extensionDoaminProperties )
|
121
|
-
|
122
|
-
# create & configure
|
123
|
-
domain = factory.createDomain( Sbuilder::Constants::TYPE_CARDINALITY_DOMAIN )
|
124
|
-
domain.setName( domainDef['domain'] )
|
125
|
-
domain.setCardinality( domainDef['cardinality'] )
|
104
|
+
|
105
|
+
|
126
106
|
|
127
|
-
|
128
|
-
|
129
|
-
end
|
107
|
+
# @!endgroup
|
108
|
+
|
130
109
|
|
131
110
|
# ------------------------------------------------------------------
|
132
111
|
# extend interface
|
@@ -135,644 +114,46 @@ module Sbuilder
|
|
135
114
|
controller.extendInterface( interfaceExtensionDef )
|
136
115
|
end
|
137
116
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
def extendStep( stepExtensionDef )
|
143
|
-
@logger.info( "#{__method__} stepExtensionDef=#{stepExtensionDef}" )
|
144
|
-
|
145
|
-
validateProperties( stepExtensionDef, @@validStepExtension_required, @@validStepExtension_allowed )
|
146
|
-
|
147
|
-
# access paramSet for interface being extenedd && assert that it also exists
|
148
|
-
interface = controller.getInterface( stepExtensionDef['interface'] )
|
149
|
-
|
150
|
-
# create new param-set && configure it
|
151
|
-
stepParamSet = controller.createParamSet( Sbuilder::Constants::PARAM_SET_STEPS )
|
152
|
-
stepParamSet.setInterfaceReference( interface )
|
153
|
-
stepParamSet.setBindExact( stepExtensionDef["bindExact"] )
|
154
|
-
|
155
|
-
# iterate stepParamSet['inputs']/stepParamSet['input'] to create
|
156
|
-
# mustacheTemplateData & add use 'stepParamSet.addInput' add it
|
157
|
-
# to 'stepParamSet'
|
158
|
-
extendStep_Inputs( interface, stepParamSet, stepExtensionDef )
|
159
|
-
|
160
|
-
# pass extension for controller - to delegate to model
|
161
|
-
controller.extendStep( stepParamSet )
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
def extendStep_Inputs( interface, stepParamSet, stepExtensionDef )
|
166
|
-
|
167
|
-
raise ExtensionException.new <<-EOS if stepExtensionDef['input'] && stepExtensionDef['inputs']
|
168
|
-
Property 'input' cannot be defined together with 'inputs' in #{stepExtensionDef.to_yaml}
|
169
|
-
|
170
|
-
Use
|
171
|
-
|
172
|
-
inputs:
|
173
|
-
- input:
|
174
|
-
...
|
175
|
-
- input:
|
176
|
-
...
|
117
|
+
def deprecatedInterfaceExtension( extensionDefs )
|
118
|
+
<<-EOS
|
119
|
+
Extension 'interface-extension' is deprecated -
|
120
|
+
use snippets configuration in sbuilder.yaml instead.
|
177
121
|
|
178
|
-
|
122
|
+
For example:
|
179
123
|
|
180
|
-
|
181
|
-
|
124
|
+
snippets:
|
125
|
+
- className: Sbuilder::SnippetLoaderSimple
|
126
|
+
snippets:
|
127
|
+
metatype: service_implementation
|
128
|
+
appName: ...
|
129
|
+
name: ...
|
182
130
|
EOS
|
183
|
-
|
184
|
-
raise ExtensionException.new <<-EOS if stepExtensionDef['inputs'] && stepExtensionDef['bindExact'] != true
|
185
|
-
Property 'inputs' cannot be defined unless 'bindExact' true.
|
186
|
-
|
187
|
-
Error in in #{stepExtensionDef.to_yaml}
|
188
|
-
|
189
|
-
EOS
|
190
|
-
|
191
|
-
|
192
|
-
# process either 'inputs' or 'input'
|
193
|
-
stepExtensionDefInputs = stepExtensionDef['inputs'] ? stepExtensionDef['inputs'] : [ { 'input' => stepExtensionDef['input'] } ]
|
194
|
-
|
195
|
-
# loop
|
196
|
-
stepExtensionDefInputs.each do |stepExtensionDefInput|
|
197
|
-
|
198
|
-
# single case: create 'mustacheTemplateData' and add it to
|
199
|
-
# 'stepParamSet'
|
200
|
-
begin
|
201
|
-
|
202
|
-
validateProperties( stepExtensionDefInput, @@validStepExtension_input )
|
203
|
-
|
204
|
-
mustacheTemplateData = extendStep_Input( interface, stepParamSet, stepExtensionDefInput['input'] )
|
205
|
-
stepParamSet.addInput( mustacheTemplateData )
|
206
|
-
|
207
|
-
rescue ExtensionException => ee
|
208
|
-
msg = "Error #{ee} caused by #{ee.backtrace.join("\n")} when extending interface '#{stepExtensionDef['interface']}'\n\n"
|
209
|
-
@logger.error( "#{__method__} #{msg}" )
|
210
|
-
raise ExtensionException.new( msg )
|
211
|
-
end
|
212
|
-
|
213
|
-
end # iterate
|
214
|
-
|
215
|
-
end # def extendStep_Inputs( interface, stepParamSet, stepExtensionDef )
|
216
|
-
|
217
|
-
|
218
|
-
# expand one input to a mustache template
|
219
|
-
def extendStep_Input( interface, stepParamSet, stepExtensionDefInputs )
|
220
|
-
|
221
|
-
# convert input paramters for the interface to datastructure, which
|
222
|
-
# can passed to template rendering
|
223
|
-
mustacheTemplateData = extendStepInputs( interface, stepExtensionDefInputs )
|
224
|
-
|
225
|
-
# add missing sub-documents in 'stepExtensionDef'
|
226
|
-
expandedStepExtensionDef = expandStepInputForDefaults( interface, stepExtensionDefInputs )
|
227
|
-
|
228
|
-
# add _default values for parameters not defined
|
229
|
-
# NB: expandedStepExtensionDef = stepExtensionDef['input']
|
230
|
-
mustacheTemplateData = extendStepDefaults( interface, expandedStepExtensionDef, mustacheTemplateData )
|
231
|
-
|
232
|
-
# assign unique number to hash element in 'mustacheTemplateData'
|
233
|
-
mustacheTemplateData = extendNumbering( mustacheTemplateData )
|
234
|
-
|
235
|
-
# added to stepParameterSet
|
236
|
-
return mustacheTemplateData
|
237
|
-
|
238
|
-
end
|
239
|
-
|
240
|
-
|
241
|
-
# 'expandedInputs' includes all 'interaface' fields (recurisively)
|
242
|
-
def expandStepInputForDefaults( interface, stepExtensionInputs )
|
243
|
-
|
244
|
-
# make a deeeep copy
|
245
|
-
# puts( "expandStepInputForDefaults: stepExtensionInputs=#{stepExtensionInputs.to_yaml}\n\n" )
|
246
|
-
expandedInputs = Marshal.load( Marshal.dump( stepExtensionInputs ))
|
247
|
-
|
248
|
-
# recurse 'interface' and ensure that 'expandedInputs' structure
|
249
|
-
# corresponds 'interface' structure
|
250
|
-
expandStepInputForDefaultsRecursion( interface, expandedInputs )
|
251
|
-
|
252
|
-
# puts( "expandStepInputForDefaults: expandedInputs=#{expandedInputs.to_yaml}\n\n" )
|
253
|
-
return expandedInputs
|
254
|
-
|
255
|
-
end
|
256
|
-
|
257
|
-
# recurs 'paramSet' in synch with 'stepExtensionDef': for each
|
258
|
-
# non-leaf paramter (i.e. a a parameter referencing to an other
|
259
|
-
# paramset) ensure that 'stepExtensionDef' also this entry
|
260
|
-
def expandStepInputForDefaultsRecursion( paramSet, stepExtensionInput )
|
261
|
-
|
262
|
-
@logger.debug( "#{__method__} paramSet=#{paramSet}, stepExtensionInput=#{stepExtensionInput}, stepExtensionInput.nil?=#{stepExtensionInput.nil?}" )
|
263
|
-
|
264
|
-
# when no 'input' on 'step-extension'
|
265
|
-
stepExtensionInput = {} if stepExtensionInput.nil?
|
266
|
-
|
267
|
-
paramSet.parameters.each do |parameter|
|
268
|
-
if parameter.isReference && stepExtensionInput.is_a?( Hash ) then
|
269
|
-
# add empty input parameter (if not defined) for records (ie. Hashe).
|
270
|
-
# rows are not expanded (we do not know many we should add)
|
271
|
-
# stepExtensionInput[parameter.name] = initRecord( parameter.name ) unless stepExtensionInput.has_key?( parameter.name )
|
272
|
-
stepExtensionInput[parameter.name] = {} unless stepExtensionInput.has_key?( parameter.name )
|
273
|
-
# recurse referenced 'paramSet' together with 'stepExtensionDef'
|
274
|
-
expandStepInputForDefaultsRecursion( parameter.getResolvedReference( model ), stepExtensionInput[parameter.name] )
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
# ------------------------------------------------------------------
|
280
|
-
# recurse 'stepExtensionInputs' and use it to set default values
|
281
|
-
# in 'mustacheTemplateData' structure.
|
282
|
-
|
283
|
-
def extendStepDefaults( interface, stepExtensionInputs, mustacheTemplateData )
|
284
|
-
# puts "extendStepDefaults - starting"
|
285
|
-
# recrurse 'stepExtensionInputs' and yield 'rows' && 'records'
|
286
|
-
recurseStepDefaults( stepExtensionInputs ) do |type, keys, indexes, stepExtensionInput, defaultValues|
|
287
|
-
# puts "type=#{type}, keys=#{keys}, indexes=#{indexes}, stepExtensionInput=#{stepExtensionInput}, defaultValues=#{defaultValues}"
|
288
|
-
|
289
|
-
# configuration in model
|
290
|
-
interfaceParameters = locateParameter( interface, keys )
|
291
|
-
|
292
|
-
# what we have expanded so far - using 'stepExtensionInputs'
|
293
|
-
templateData = locateTemplateData( mustacheTemplateData, keys, indexes )
|
294
|
-
|
295
|
-
# default value is on the top of the stack
|
296
|
-
# defaultValue = defaultValues.last
|
297
|
-
# defaultValue is the last non-nil value on stack 'defaultValues'
|
298
|
-
defaultValue = defaultValues.reverse.find { |v| !v.nil? }
|
299
|
-
|
300
|
-
next unless defaultValue
|
301
|
-
|
302
|
-
# create an entry in 'mustacheTemplateData' if path 'keys'/'indexes' no configuration
|
303
|
-
# in 'step-extension' 'input'
|
304
|
-
templateData = addTemplateData( mustacheTemplateData, keys, indexes ) unless templateData
|
305
|
-
expandDefaults( interfaceParameters, defaultValue, templateData )
|
306
|
-
|
307
|
-
# case type
|
308
|
-
# when "row"
|
309
|
-
# next unless defaultValue
|
310
|
-
# # access data row 'index'
|
311
|
-
# index = indexes.last
|
312
|
-
# # expandDefaults( interfaceParameters, defaultValue, templateData['rows'][index] )
|
313
|
-
# puts "row-expansion templateData=#{templateData}"
|
314
|
-
# expandDefaults( interfaceParameters, defaultValue, templateData )
|
315
|
-
# when "record"
|
316
|
-
# # possibly no default value defined
|
317
|
-
# next unless defaultValue
|
318
|
-
# expandDefaults( interfaceParameters, defaultValue, templateData )
|
319
|
-
# else
|
320
|
-
# # should not happen
|
321
|
-
# raise "Unknown type #{type}"
|
322
|
-
# end
|
323
|
-
end
|
324
|
-
# empty is returnet as boolean false
|
325
|
-
mustacheTemplateData = false if mustacheTemplateData == {}
|
326
|
-
|
327
|
-
mustacheTemplateData
|
328
|
-
end # def extendStepDefaults
|
329
|
-
|
330
|
-
# recurse 'stepExtensionInputs' and yield
|
331
|
-
# - record|row, [keys], parameterDef
|
332
|
-
def recurseStepDefaults( stepExtensionInputs, keys=[], indexes=[], defaultValues=nil, &block )
|
333
|
-
# puts "recurseStepDefaults(enter) stepExtensionInputs=#{stepExtensionInputs}"
|
334
|
-
return unless stepExtensionInputs
|
335
|
-
# init defaultValues
|
336
|
-
defaultValues = [ stepExtensionInputs["_default"] ] unless defaultValues
|
337
|
-
if !keys.any? then
|
338
|
-
# puts "recurseStepDefaults(init) #{stepExtensionInputs}"
|
339
|
-
yield "record", keys, indexes, stepExtensionInputs, defaultValues
|
340
|
-
end
|
341
|
-
stepExtensionInputs.each do |parameterName, parameterDef|
|
342
|
-
if parameterDef.is_a?( Array ) then
|
343
|
-
parameterDef.each.with_index do |parameterDefRow,index|
|
344
|
-
defaultValues.push( parameterDefRow["_default"] )
|
345
|
-
# puts "recurseStepDefaults:(array) resolved-defaultValues=#{defaultValues} index=#{index}, for parameterDefRow=#{parameterDefRow}"
|
346
|
-
yield "row", keys + [parameterName], indexes + [index], parameterDefRow, defaultValues
|
347
|
-
recurseStepDefaults( parameterDefRow, keys + [parameterName], indexes + [index], defaultValues, &block)
|
348
|
-
defaultValues.pop
|
349
|
-
end
|
350
|
-
elsif parameterDef.is_a?( Hash ) then
|
351
|
-
defaultValues.push( parameterDef["_default"] )
|
352
|
-
# puts "recurseStepDefaults:(hash): resolved-defaultValues=#{defaultValues} keys=#{keys}, for parameterDef=#{parameterDef}"
|
353
|
-
yield "record", keys + [parameterName], indexes + [nil], parameterDef, defaultValues
|
354
|
-
recurseStepDefaults( parameterDef, keys + [parameterName], indexes + [nil], defaultValues, &block)
|
355
|
-
defaultValues.pop
|
356
|
-
else
|
357
|
-
# puts "recurseStepDefaults:(else): resolved-defaultValues=#{defaultValues} keys=#{keys}, for parameterDef=#{parameterDef}"
|
358
|
-
# leaf entry
|
359
|
-
end
|
360
|
-
|
361
|
-
end
|
362
|
-
|
363
|
-
end # def recurseStepDefaults
|
364
|
-
|
365
|
-
|
366
|
-
# add expanded parameters to 'templateData'
|
367
|
-
def expandDefaults( interfaceParameters, defaultValue, templateData )
|
368
|
-
|
369
|
-
# puts "\nexpandDefaults defaultValue=#{defaultValue} on '#{templateData}' missing from #{interfaceParameters}"
|
370
|
-
# return unless templateData
|
371
|
-
|
372
|
-
# array of 'parameter_name' fields found on templateData
|
373
|
-
definedParameters = templateData && templateData['columns'] ? templateData['columns'].map { |column| column[:parameter_name] } : []
|
374
|
-
|
375
|
-
# select parameters, which are not defined on 'templateData'
|
376
|
-
# (i.e. missing from 'definedParameters') append new entries in
|
377
|
-
# 'templateData' with 'defaultValue' expanded
|
378
|
-
|
379
|
-
parametersToBe( interfaceParameters ).select do |param|
|
380
|
-
|
381
|
-
# puts "expandDefaults param=#{param} of #{param.class}"
|
382
|
-
# select for expsion
|
383
|
-
# if NOT already defined i.e. NOT in definedParameters
|
384
|
-
# if CARDNIALITY defined (ie. paramter_dom object)
|
385
|
-
|
386
|
-
!definedParameters.include?( param[:parameter_name] ) && !param[:cardinality].nil?
|
387
|
-
|
388
|
-
end.each do |param|
|
389
|
-
# one more added - modify comm
|
390
|
-
templateData['columns'].last["_comma"] = ',' if templateData && templateData['columns'] && templateData['columns'].length > 0
|
391
|
-
|
392
|
-
# puts "added fied #{param[:parameter_name]}"
|
393
|
-
# create default entry
|
394
|
-
expadedElement = {
|
395
|
-
:parameter_name => param[:parameter_name],
|
396
|
-
"_comma" => '',
|
397
|
-
"rows" => false,
|
398
|
-
"columns" => false,
|
399
|
-
}
|
400
|
-
|
401
|
-
expadedElement = expandDefaultValue( expadedElement, defaultValue, param )
|
402
|
-
# ensure that 'columns' array exists (espeically case when
|
403
|
-
# only _default defined in step extension)
|
404
|
-
templateData['columns'] = [] unless templateData && templateData['columns']
|
405
|
-
templateData['columns'] << expadedElement
|
406
|
-
|
407
|
-
end # apped new entries to 'templateData'
|
408
|
-
|
409
|
-
templateData
|
410
|
-
|
411
|
-
end
|
412
|
-
|
413
|
-
# retrurn array of hashes(:parameter_name, :cardinality, :domain_prefix)
|
414
|
-
# on an interface parameters
|
415
|
-
def parametersToBe( interfaceParameters )
|
416
|
-
@logger.debug( "#{__method__} interfaceParameters=#{interfaceParameters}" )
|
417
|
-
parameters = interfaceParameters.parameters.map do |parameter|
|
418
|
-
# puts "parameter=#{parameter}"
|
419
|
-
{
|
420
|
-
:parameter_name => parameter.name,
|
421
|
-
:cardinality => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.cardinality : nil,
|
422
|
-
# :domain_prefix => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.domain_prefix : nil,
|
423
|
-
:domain_name => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.domain_name : nil,
|
424
|
-
}
|
425
|
-
|
426
|
-
end
|
427
|
-
return parameters
|
428
|
-
end
|
429
|
-
|
430
|
-
|
431
|
-
# update :domain_value (whewn 'defaultValue' is String), or :domain_element= #{param[:domain_prefix]}#{:domain_prefix}" otherwise
|
432
|
-
def expandDefaultValue( expadedElement, defaultValue, param )
|
433
|
-
|
434
|
-
# Case 'String'
|
435
|
-
return expadedElement.merge( { :domain_value => defaultValue, :domain_element => false }) if defaultValue.is_a?( String )
|
436
|
-
|
437
|
-
# Case 'Interger'
|
438
|
-
# puts "expandDefaultValue param=#{param}"
|
439
|
-
if defaultValue.is_a?( Integer ) then
|
440
|
-
raise ExtensionException.new <<-EOS if defaultValue > param[:cardinality]
|
441
|
-
Cardinality of the default exceeds the cardinality of the parameter domain
|
442
|
-
|
443
|
-
cardinality of default : #{defaultValue}
|
444
|
-
cardinality on domain : #{param[:cardinality]}
|
445
|
-
name of parameter : #{param[:parameter_name]}
|
446
|
-
domain name : #{param[:domain_name]}
|
447
|
-
|
448
|
-
EOS
|
449
|
-
return expadedElement.merge( { :domain_element => getDomainElement( param, defaultValue ), :domain_value => false } )
|
450
|
-
end
|
451
|
-
|
452
|
-
# else - unknown value
|
453
|
-
raise raise ExtensionException.new <<-EOS
|
454
|
-
Unknown type #{defaultValue.class} for default #{defaultValue} value encountered.
|
455
|
-
|
456
|
-
Exteding paramter #{param}
|
457
|
-
EOS
|
458
131
|
end
|
459
132
|
|
460
|
-
def getDomainElement2( extededParameter, domainElement )
|
461
|
-
# puts( "extededParameter=#{extededParameter}, domainElement=#{domainElement}" )
|
462
|
-
return extededParameter.resolvedDomain.domain_entry( domainElement )
|
463
|
-
# "#{extededParameter.resolvedDomain.name}_#{domainElement}"
|
464
|
-
end
|
465
|
-
def getDomainElement( param, defaultValue )
|
466
|
-
# ret = "#{param[:domain_prefix]}#{defaultValue}"
|
467
|
-
ret = model.getDomain(param[:domain_name]).domain_entry( defaultValue )
|
468
|
-
# puts( "getDomainElement: param=#{param}, defaultValue=#{defaultValue} --> #{ret}" )
|
469
|
-
return ret
|
470
133
|
|
471
|
-
|
472
|
-
|
473
|
-
# ------------------------------------------------------------------
|
474
|
-
# number elements
|
475
|
-
|
476
|
-
# assign '_first' element for hash within 'mustacheTemplateData'
|
477
|
-
#
|
478
|
-
# @param mustacheTemplateData [Hash]
|
479
|
-
# @return [Hash] 'mustacheTemplateData' with record elements numbered
|
480
|
-
def extendNumbering( mustacheTemplateData )
|
481
|
-
|
482
|
-
recurseHash( mustacheTemplateData ) do |h,k,v,i|
|
483
|
-
v["_index"] = i
|
484
|
-
end
|
485
|
-
return mustacheTemplateData
|
486
|
-
end
|
487
|
-
|
488
|
-
# recurse hash, and yield 'hash', 'key', 'value', 'index' for each
|
489
|
-
# entry within the hash structure, which is_a?(Hash).
|
134
|
+
# # ------------------------------------------------------------------
|
135
|
+
# # @!group Utilities
|
490
136
|
|
491
|
-
def recurseHash( hash, &block )
|
492
|
-
|
493
|
-
hash && hash.each_with_index do |(k,v),index|
|
494
|
-
if v.is_a?( Hash ) then
|
495
|
-
yield hash, k, v, index
|
496
|
-
recurseHash( v, &block)
|
497
|
-
elsif v.is_a?( Array ) then
|
498
|
-
v.each_with_index do |array_element,i|
|
499
|
-
if array_element.is_a?(Hash)
|
500
|
-
yield hash, k, array_element, i
|
501
|
-
recurseHash( array_element, &block)
|
502
|
-
end
|
503
|
-
end
|
504
|
-
end
|
505
|
-
end
|
506
|
-
end
|
507
|
-
|
508
|
-
# ------------------------------------------------------------------
|
509
|
-
# recurse 'stepExtensionInputs' configuration and create a hash
|
510
|
-
# structure, which can be passed to mustache template
|
511
|
-
|
512
|
-
def extendStepInputs( interface, stepExtensionInputs )
|
513
|
-
@logger.debug( "#{__method__} stepExtensionInputs=#{stepExtensionInputs}" )
|
514
|
-
|
515
|
-
# recursion uses this as a stack
|
516
|
-
subDocumentStack = []
|
517
|
-
subDocumentStack.push( {} )
|
518
137
|
|
138
|
+
# # validate 'defintionHash' all 'required'/only 'allowed' props set
|
139
|
+
# private def validateProperties( defintionHash, required, allowed=nil )
|
519
140
|
|
520
|
-
|
521
|
-
# puts "#{act}, keys=#{keys},domainElement=#{domainElement}, #{row}"
|
522
|
-
|
523
|
-
# uses path [keys] in 'interface' to locate parameter to extend
|
524
|
-
extededParameter = locateParameter( interface, keys )
|
525
|
-
parameterName = keys.last
|
526
|
-
next if parameterName[0] == "_"
|
527
|
-
|
528
|
-
case act
|
529
|
-
when "="
|
530
|
-
@logger.debug( "#{__method__} extededParameter=#{extededParameter.name}, extededParameter.resolvedDomain=#{extededParameter.resolvedDomain}" )
|
531
|
-
input = {
|
532
|
-
:parameter_name => parameterName,
|
533
|
-
:domain_element => getDomainElement2(extededParameter, domainElement),
|
534
|
-
"rows" => false,
|
535
|
-
"columns" => false,
|
536
|
-
"_comma" => ','
|
537
|
-
}
|
538
|
-
# create new parameter && add it to the paramSet
|
539
|
-
raise ExtensionException.new <<-EOS if domainElement.is_a?( Integer ) && extededParameter.resolvedDomain.cardinality < domainElement
|
540
|
-
The cardinality on step exceeds the cardinality of the parameter domain
|
541
|
-
|
542
|
-
Name of parameter : #{extededParameter.name}
|
543
|
-
Name of parameter domain : #{extededParameter.resolvedDomain.name}
|
544
|
-
Cardinality of the parameter domain : #{extededParameter.resolvedDomain.cardinality}
|
545
|
-
Cardinality defined: #{domainElement}
|
546
|
-
|
547
|
-
EOS
|
548
|
-
|
549
|
-
subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
550
|
-
subDocumentStack.last["columns"] << input
|
551
|
-
when "["
|
552
|
-
input = initRecord( parameterName )
|
553
|
-
# {
|
554
|
-
# :parameter_name => parameterName,
|
555
|
-
# "rows" => false,
|
556
|
-
# "columns" => false,
|
557
|
-
# }
|
558
|
-
subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
559
|
-
subDocumentStack.last["columns"] << input
|
560
|
-
subDocumentStack.push( input )
|
561
|
-
when "]"
|
562
|
-
# end of sub-record
|
563
|
-
input = subDocumentStack.pop
|
564
|
-
# last element has no comma
|
565
|
-
input['columns'].last["_comma"] = '' if input['columns']
|
566
|
-
when "<<"
|
567
|
-
if row == 0 then
|
568
|
-
# start of array processing = start of row
|
569
|
-
input = initRecord( parameterName )
|
570
|
-
# {
|
571
|
-
# :parameter_name => parameterName,
|
572
|
-
# "rows" => false,
|
573
|
-
# "columns" => false,
|
574
|
-
# }
|
575
|
-
subDocumentStack.push( addColumn( subDocumentStack.last, input ))
|
576
|
-
|
577
|
-
# subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
578
|
-
# subDocumentStack.last["columns"] << input
|
579
|
-
# subDocumentStack.push( input )
|
580
|
-
else
|
581
|
-
# start a new row in an array
|
582
|
-
input = {
|
583
|
-
"rows" => false,
|
584
|
-
"columns" => false,
|
585
|
-
"_comma" => ",",
|
586
|
-
}
|
587
|
-
subDocumentStack.push( input )
|
588
|
-
end
|
589
|
-
|
590
|
-
when ">>"
|
591
|
-
if row == 0 then
|
592
|
-
# end of array
|
593
|
-
input = subDocumentStack.pop
|
594
|
-
input['rows'].last["_comma"] = '' if input['rows']
|
595
|
-
input['columns'].last["_comma"] = '' if input['columns']
|
596
|
-
|
597
|
-
else
|
598
|
-
input = subDocumentStack.pop
|
599
|
-
input['rows'].last["_comma"] = '' if input['rows']
|
600
|
-
input['columns'].last["_comma"] = '' if input['columns']
|
601
|
-
# puts "subDocumentStack=#{subDocumentStack}"
|
602
|
-
subDocumentStack.last["rows"] = [] unless subDocumentStack.last["rows"]
|
603
|
-
subDocumentStack.last["rows"] << input
|
604
|
-
end
|
605
|
-
else
|
606
|
-
raise "Unknown act #{act}"
|
607
|
-
end
|
608
|
-
end
|
609
|
-
|
610
|
-
raise "subDocumentStack should have been empty #{subDocumentStack}" unless subDocumentStack.length == 1
|
611
|
-
ret = subDocumentStack.first
|
612
|
-
|
613
|
-
# last element has no _comma always
|
614
|
-
ret['columns'].last["_comma"] = '' if ret['columns']
|
615
|
-
|
616
|
-
@logger.info( "#{__method__} return=#{ret}" )
|
617
|
-
return ret
|
141
|
+
# allowed = required unless allowed
|
618
142
|
|
619
|
-
|
620
|
-
|
621
|
-
# Recurse 'stepExtensionInputs' (i.e. hash under key 'step-extension' ).
|
622
|
-
# During recursion yield:
|
623
|
-
# = : reference parameter, domainElement
|
624
|
-
# [ : starts hash
|
625
|
-
# ] : end hash
|
626
|
-
# << : array
|
627
|
-
# >> : end array
|
628
|
-
def recurseStepInputs( stepExtensionInputs, keys=[], row=0, &block )
|
629
|
-
stepExtensionInputs.each do |parameterName, parameterDef|
|
630
|
-
begin
|
631
|
-
if parameterDef.is_a?( Array ) then
|
632
|
-
yield "<<", keys + [parameterName], nil, 0
|
633
|
-
parameterDef.each.with_index do |parameterDefRow,index|
|
634
|
-
yield "<<", keys + [parameterName], nil, index+1
|
635
|
-
recurseStepInputs( parameterDefRow, keys + [parameterName], index+1, &block )
|
636
|
-
yield ">>", keys + [parameterName], nil, index+1
|
637
|
-
end
|
638
|
-
yield ">>", keys + [parameterName], nil, 0
|
639
|
-
|
640
|
-
elsif parameterDef.is_a?( Hash ) then
|
641
|
-
yield "[", keys + [parameterName], nil, row
|
642
|
-
recurseStepInputs( parameterDef, keys + [parameterName], row, &block )
|
643
|
-
yield "]", keys + [parameterName], nil, row
|
644
|
-
else
|
645
|
-
# do not process "meta fields" e.g '_default'
|
646
|
-
yield "=", keys + [parameterName], parameterDef, row
|
647
|
-
end
|
648
|
-
rescue SbuilderException => e
|
649
|
-
msg = <<-EOS.gsub( /^\s*/, '' )
|
650
|
-
Error:
|
651
|
-
|
652
|
-
#{e.message}
|
143
|
+
# missingProps = required - defintionHash.keys
|
144
|
+
# raise ExtensionException.new "Missing properties #{missingProps} in #{defintionHash} - required #{required}" if missingProps.any?
|
653
145
|
|
146
|
+
# invalidProps = defintionHash.keys - allowed
|
147
|
+
# raise ExtensionException.new "Unknown properties #{invalidProps} in #{defintionHash} - allowed #{allowed}" if invalidProps.any?
|
654
148
|
|
655
|
-
|
149
|
+
# end
|
656
150
|
|
657
|
-
|
658
|
-
|
659
|
-
EOS
|
660
|
-
@logger.error( "#{__method__} #{msg}" )
|
661
|
-
raise Sbuilder::LoaderException.new, msg, e.backtrace
|
662
|
-
end
|
663
|
-
end
|
664
|
-
end # recurseStepInputs
|
151
|
+
# # @!endgroup
|
665
152
|
|
666
|
-
|
667
|
-
# uses path [keys] in 'interface' to locate parameter
|
668
|
-
def locateParameter( interface, keys )
|
669
|
-
extededParameter = interface
|
670
|
-
if keys.any?
|
671
|
-
extededParameter = keys.inject(interface) { |p,key|
|
672
|
-
# _default paramtes not real parameters
|
673
|
-
next if key == "_default"
|
674
|
-
p = p.locateParameter( key )
|
675
|
-
# resolve in model context - possible for paramter_ref
|
676
|
-
p = p.getResolvedReference( controller.model ) if p.respond_to?( :getResolvedReference )
|
677
|
-
p
|
678
|
-
}
|
679
|
-
@logger.debug( "#{__method__} keys #{keys}->extededParameter=#{extededParameter}" )
|
680
|
-
end
|
681
|
-
return extededParameter
|
682
|
-
end
|
683
|
-
|
684
|
-
# ensure that templateData element in ['keys'] and ['indexes']
|
685
|
-
# exists in 'mustacheTemplateData'.
|
686
|
-
def addTemplateData( mustacheTemplateData, keys, indexes )
|
687
|
-
|
688
|
-
templateData = mustacheTemplateData
|
689
|
-
prev = templateData
|
690
|
-
keys.each_with_index do |key,i|
|
691
|
-
index = indexes[i]
|
692
|
-
# puts "addTemplateData: key=#{key}, #{i}, index #{index}"
|
693
|
-
templateData = templateData['columns'].select{ |column| column[:parameter_name] == key }.first
|
694
|
-
if templateData.nil? then
|
695
|
-
templateData = initRecord( key )
|
696
|
-
addColumn( prev, templateData )
|
697
|
-
# puts "addTemplateData: added #{templateData} for key #{key} --> #{mustacheTemplateData}"
|
698
|
-
else
|
699
|
-
# puts "addTemplateData: exists #{templateData} for key #{key}"
|
700
|
-
end
|
701
|
-
|
702
|
-
prev = templateData
|
703
|
-
|
704
|
-
# # puts "data1=#{data}"
|
705
|
-
# if !index.nil? then
|
706
|
-
# templateData = templateData['rows'][index]
|
707
|
-
# # puts "data2=#{data}"
|
708
|
-
# end
|
709
|
-
end # iterate
|
710
|
-
|
711
|
-
return templateData
|
712
|
-
end
|
713
|
-
|
714
|
-
|
715
|
-
# uses path in [keys] and ['indexes'] to locate data 'mustacheTemplateData'.
|
716
|
-
def locateTemplateData( mustacheTemplateData, keys, indexes )
|
717
|
-
ret = mustacheTemplateData
|
718
|
-
i = 0
|
719
|
-
if keys.any?
|
720
|
-
ret = keys.inject(ret) { |data,key|
|
721
|
-
index = indexes[i]
|
722
|
-
i += 1
|
723
|
-
# puts "\n\nindex=#{index} of #{indexes}, i=#{i}, key=#{key} on '#{data}'"
|
724
|
-
break unless data
|
725
|
-
data = data['columns'].select{ |column| column[:parameter_name] == key }.first
|
726
|
-
# puts "data1=#{data}"
|
727
|
-
if !index.nil? then
|
728
|
-
data = data['rows'][index]
|
729
|
-
# puts "data2=#{data}"
|
730
|
-
end
|
731
|
-
|
732
|
-
# if index.nil? then
|
733
|
-
# else
|
734
|
-
# data = data['rows'][index]['columns'].select{ |column| column[:parameter_name] == key }.first
|
735
|
-
# end
|
736
|
-
data
|
737
|
-
}
|
738
|
-
end
|
739
|
-
return ret
|
740
|
-
end
|
741
|
-
|
742
|
-
# ------------------------------------------------------------------
|
743
|
-
# Build a hash structure, which can be passed to mustache template
|
744
153
|
|
745
|
-
# create record entry
|
746
|
-
private
|
747
|
-
def initRecord( parameterName )
|
748
|
-
{
|
749
|
-
:parameter_name => parameterName,
|
750
|
-
"rows" => false,
|
751
|
-
"columns" => false,
|
752
|
-
"_comma" => ",", # assume that comma get removed if -needed
|
753
|
-
}
|
754
|
-
end
|
755
|
-
|
756
|
-
def addColumn( columns, column )
|
757
|
-
# subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
758
|
-
# subDocumentStack.last["columns"] << input
|
759
|
-
# subDocumentStack.push( input )
|
760
|
-
columns['columns'] = [] unless columns['columns']
|
761
|
-
|
762
|
-
# la
|
763
|
-
columns['columns'].last["_comma"] = ',' if columns['columns'].length > 0
|
764
|
-
|
765
|
-
# no comma here
|
766
|
-
column["_comma"] = ''
|
767
154
|
|
768
|
-
columns['columns'] << column
|
769
|
-
return column
|
770
|
-
end
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
155
|
end # class ExtensionLoader
|
776
156
|
|
157
|
+
|
777
158
|
end # module
|
778
159
|
|