tla-sbuilder 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +328 -0
- data/VERSION +1 -0
- data/bin/sbuilder.rb +5 -0
- data/lib/cli/cli-customer.rb +420 -0
- data/lib/cli/cli-example.rb +92 -0
- data/lib/cli/cli-pet.rb +767 -0
- data/lib/cli/cli-text.rb +226 -0
- data/lib/cli/cli.rb +298 -0
- data/lib/sbuilder.rb +52 -0
- data/lib/sbuilder/constants.rb +72 -0
- data/lib/sbuilder/controller.rb +798 -0
- data/lib/sbuilder/default-sbuilder.yaml +372 -0
- data/lib/sbuilder/domain.rb +124 -0
- data/lib/sbuilder/domain_cardinality.rb +37 -0
- data/lib/sbuilder/domain_value.rb +81 -0
- data/lib/sbuilder/exception.rb +27 -0
- data/lib/sbuilder/extension_loader.rb +721 -0
- data/lib/sbuilder/factory.rb +234 -0
- data/lib/sbuilder/model.rb +356 -0
- data/lib/sbuilder/mustache/template.rb +125 -0
- data/lib/sbuilder/mustache/template_reader.rb +206 -0
- data/lib/sbuilder/mustache/template_reader_context.rb +371 -0
- data/lib/sbuilder/param_set.rb +132 -0
- data/lib/sbuilder/param_set_db.rb +20 -0
- data/lib/sbuilder/param_set_def.rb +57 -0
- data/lib/sbuilder/param_set_if.rb +68 -0
- data/lib/sbuilder/param_set_loader.rb +77 -0
- data/lib/sbuilder/param_set_loader_swagger.rb +424 -0
- data/lib/sbuilder/param_set_step.rb +62 -0
- data/lib/sbuilder/param_sets.rb +54 -0
- data/lib/sbuilder/parameter.rb +97 -0
- data/lib/sbuilder/parameter_container.rb +72 -0
- data/lib/sbuilder/parameter_dom.rb +70 -0
- data/lib/sbuilder/parameter_ref.rb +71 -0
- data/lib/sbuilder/resolver.rb +78 -0
- data/lib/sbuilder/resolver_loader.rb +79 -0
- data/lib/sbuilder/resolver_loader_yaml.rb +103 -0
- data/lib/sbuilder/resolver_rule.rb +36 -0
- data/lib/sbuilder/resolver_rule_match.rb +55 -0
- data/lib/sbuilder/resolver_rule_ref.rb +37 -0
- data/lib/utils/hash_inject.rb +12 -0
- data/lib/utils/logger.rb +80 -0
- data/lib/utils/netio.rb +58 -0
- data/lib/utils/string_inject.rb +10 -0
- data/lib/utils/version.rb +13 -0
- data/mustache/cfg/const_def.mustache +8 -0
- data/mustache/cfg/const_run.mustache +3 -0
- data/mustache/cfg/invariant-infrastructure-service.mustache +4 -0
- data/mustache/cfg/macro_run.mustache +6 -0
- data/mustache/cfg/module_footer.mustache +0 -0
- data/mustache/cfg/module_header.mustache +7 -0
- data/mustache/data-model-dump.mustache +19 -0
- data/mustache/data-model-footer.mustache +5 -0
- data/mustache/data-model-header.mustache +16 -0
- data/mustache/definition_types.mustache +40 -0
- data/mustache/domains.mustache +20 -0
- data/mustache/domains_assign.mustache +22 -0
- data/mustache/domains_run.mustache +21 -0
- data/mustache/extend/extend_assumptions.mustache +7 -0
- data/mustache/extend/extend_const.mustache +5 -0
- data/mustache/extend/extend_implementation.mustache +9 -0
- data/mustache/extend/extend_invariant.mustache +7 -0
- data/mustache/extend/extend_invariant_cfg.mustache +7 -0
- data/mustache/extend/extend_macros.mustache +19 -0
- data/mustache/extend/extend_operations.mustache +9 -0
- data/mustache/extend/extend_state.mustache +9 -0
- data/mustache/infrastructure-service-init.mustache +36 -0
- data/mustache/infrastructure-service-variables.mustache +10 -0
- data/mustache/interface_processes.mustache +38 -0
- data/mustache/interface_stubs_dummy.mustache +13 -0
- data/mustache/interface_types.mustache +52 -0
- data/mustache/markdown-header.mustache +24 -0
- data/mustache/markdown-toc.mustache +13 -0
- data/mustache/name_definition_type.mustache +5 -0
- data/mustache/name_domain.mustache +5 -0
- data/mustache/name_domain_value.mustache +5 -0
- data/mustache/name_domain_value_prefix.mustache +5 -0
- data/mustache/name_interface_response_type.mustache +6 -0
- data/mustache/name_interface_type.mustache +6 -0
- data/mustache/name_parameter_definition.mustache +5 -0
- data/mustache/name_parameter_type.mustache +6 -0
- data/mustache/name_process.mustache +6 -0
- data/mustache/name_type_invariant.mustache +5 -0
- data/mustache/name_variable.mustache +6 -0
- data/mustache/operator-infrastructure-service.mustache +13 -0
- data/mustache/possibility/module_extends.mustache +1 -0
- data/mustache/possibility/module_footer.mustache +1 -0
- data/mustache/possibility/module_header.mustache +8 -0
- data/mustache/possibility/possibility_definition.mustache +12 -0
- data/mustache/possibility/possibility_directive.mustache +1 -0
- data/mustache/possibility/possility_setup.mustache +28 -0
- data/mustache/setup/module_footer.mustache +1 -0
- data/mustache/setup/module_header.mustache +9 -0
- data/mustache/setup/operator_run.mustache +7 -0
- data/mustache/setup/operator_tick.mustache +2 -0
- data/mustache/setup/steps_run.mustache +22 -0
- data/mustache/setup/steps_run_bind_rule.mustache +51 -0
- data/mustache/setup/steps_run_bind_set.mustache +37 -0
- data/mustache/setup/steps_run_parameterBind.mustache +80 -0
- data/mustache/setup/steps_run_parameterExact.mustache +79 -0
- data/mustache/state_type_invariant-infrastructure-service.mustache +49 -0
- data/mustache/state_type_invariant.mustache +17 -0
- data/mustache/state_type_invariant_cfg.mustache +18 -0
- data/mustache/state_variables.mustache +20 -0
- data/mustache/tla/const_def.mustache +5 -0
- data/mustache/tla/const_run.mustache +3 -0
- data/mustache/tla/macro-infrastructure-service.mustache +14 -0
- data/mustache/tla/macro_run.mustache +40 -0
- data/mustache/tla/module_footer.mustache +2 -0
- data/mustache/tla/module_header.mustache +9 -0
- data/mustache/tla/operator_run.mustache +8 -0
- data/mustache/tla/operators-infrastructure-service.mustache +12 -0
- data/mustache/tla/plc_define_footer.mustache +1 -0
- data/mustache/tla/plc_define_header.mustache +1 -0
- data/mustache/tla/plc_define_run.mustache +59 -0
- data/mustache/tla/plc_footer.mustache +2 -0
- data/mustache/tla/plc_header.mustache +2 -0
- data/mustache/tla/plc_run_state.mustache +12 -0
- data/mustache/tla/plc_tail.mustache +8 -0
- data/mustache/tla/plc_translation.mustache +2 -0
- data/resources/schema/json_schema/draft-04.json +150 -0
- data/resources/schema/swagger/2.0/schema.json +1591 -0
- data/src-extend/README +2 -0
- data/src-extend/extend/extend_assumptions.mustache +7 -0
- data/src-extend/extend/extend_const.mustache +5 -0
- data/src-extend/extend/extend_implementation.mustache +9 -0
- data/src-extend/extend/extend_invariant.mustache +11 -0
- data/src-extend/extend/extend_invariant_cfg.mustache +7 -0
- data/src-extend/extend/extend_macros.mustache +19 -0
- data/src-extend/extend/extend_operations.mustache +9 -0
- data/src-extend/extend/extend_state.mustache +9 -0
- data/src-extend/extend_app/assumption +20 -0
- data/src-extend/extend_app/correctness +19 -0
- data/src-extend/extend_app/correctness.cfg +9 -0
- data/src-extend/extend_app/infrastructure +25 -0
- data/src-extend/extend_app/interface +11 -0
- data/src-extend/extend_app/operator +18 -0
- data/src-extend/extend_app/possibility +16 -0
- data/src-extend/extend_app/service +33 -0
- data/src-extend/extend_app/state +16 -0
- data/src-extend/extend_app/transaction +22 -0
- data/src/pet/assumption +29 -0
- data/src/pet/assumption_address_domains.tla +12 -0
- data/src/pet/assumption_domains.tla +16 -0
- data/src/pet/assumption_generic.tla +8 -0
- data/src/pet/assumption_id_domains.tla +2 -0
- data/src/pet/assumption_owner_domains.tla +14 -0
- data/src/pet/assumption_pet_domains.tla +16 -0
- data/src/pet/assumption_tag_domains.tla +13 -0
- data/src/pet/correctness +24 -0
- data/src/pet/correctness.cfg +9 -0
- data/src/pet/correctness_coherent_owner_address.tla +6 -0
- data/src/pet/correctness_pet_name.tla +4 -0
- data/src/pet/correctness_ref_tag.tla +13 -0
- data/src/pet/correctness_type_invariants.tla +12 -0
- data/src/pet/correctness_unique_pet.tla +3 -0
- data/src/pet/correctness_unique_tag.tla +3 -0
- data/src/pet/docs/Petstore.md +117 -0
- data/src/pet/extend/extend_assumptions.mustache +7 -0
- data/src/pet/extend/extend_implementation.mustache +9 -0
- data/src/pet/extend/extend_invariant.mustache +11 -0
- data/src/pet/extend/extend_invariant_cfg.mustache +7 -0
- data/src/pet/extend/extend_macros.mustache +19 -0
- data/src/pet/extend/extend_operations.mustache +9 -0
- data/src/pet/extend/extend_state.mustache +9 -0
- data/src/pet/infrastructure +25 -0
- data/src/pet/infrastructure_id_get.tla +24 -0
- data/src/pet/interface +12 -0
- data/src/pet/interface_delete_pet.tla +5 -0
- data/src/pet/interface_get_pet.tla +4 -0
- data/src/pet/interface_post_pet.tla +5 -0
- data/src/pet/interface_post_tag.tla +5 -0
- data/src/pet/interface_put_tag.tla +3 -0
- data/src/pet/operator +30 -0
- data/src/pet/operator_find_tag_by_owner_name.tla +1 -0
- data/src/pet/operator_get_pet.tla +4 -0
- data/src/pet/operator_get_pet_by_tag.tla +4 -0
- data/src/pet/operator_get_tag.tla +10 -0
- data/src/pet/operator_new_owner.tla +3 -0
- data/src/pet/operator_new_pet.tla +13 -0
- data/src/pet/operator_new_tag.tla +3 -0
- data/src/pet/operator_next_pet_id.tla +3 -0
- data/src/pet/operator_responses.tla +8 -0
- data/src/pet/operator_tag_exists.tla +2 -0
- data/src/pet/operator_tag_owner_validated.tla +2 -0
- data/src/pet/operator_tag_referenced.tla +4 -0
- data/src/pet/operator_valid_owner.tla +17 -0
- data/src/pet/operator_valid_pet.tla +6 -0
- data/src/pet/operator_valid_tag.tla +5 -0
- data/src/pet/possibility +18 -0
- data/src/pet/possibility_at_least_two_tags.tla +12 -0
- data/src/pet/possibility_invalid_tag_address.tla +8 -0
- data/src/pet/service +35 -0
- data/src/pet/service_pet_delete.tla +11 -0
- data/src/pet/service_pet_get.tla +27 -0
- data/src/pet/service_pet_post.tla +78 -0
- data/src/pet/service_tag_post.tla +53 -0
- data/src/pet/service_tag_put.tla +82 -0
- data/src/pet/state +16 -0
- data/src/pet/state_infra.tla +6 -0
- data/src/pet/state_pet.tla +5 -0
- data/src/pet/state_tag_id.tla +2 -0
- data/src/pet/transaction +23 -0
- data/src/pet/transaction_delete_pet.tla +13 -0
- data/src/pet/transaction_enter_pet.tla +13 -0
- data/src/pet/transaction_enter_tag.tla +56 -0
- data/src/pet/transaction_error.tla +23 -0
- data/tla-sbuilder.gemspec +43 -0
- metadata +353 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
class DomainCardinality < Domain
|
5
|
+
|
6
|
+
attr_reader :cardinality
|
7
|
+
|
8
|
+
# ------------------------------------------------------------------
|
9
|
+
# mixer
|
10
|
+
PROGNAME = "CardDomain" # progname for logger
|
11
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
12
|
+
|
13
|
+
|
14
|
+
def initialize( options = {} )
|
15
|
+
super( options )
|
16
|
+
@logger = getLogger( PROGNAME, options )
|
17
|
+
@logger.info( "#{__method__} initialized" )
|
18
|
+
|
19
|
+
# default values one
|
20
|
+
@cardinality = 1
|
21
|
+
end
|
22
|
+
|
23
|
+
# ------------------------------------------------------------------
|
24
|
+
# build
|
25
|
+
def setCardinality( cardinality )
|
26
|
+
@cardinality = cardinality
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
|
2
|
+
module Sbuilder
|
3
|
+
|
4
|
+
class DomainValue < Domain
|
5
|
+
|
6
|
+
attr_reader :values
|
7
|
+
|
8
|
+
# ------------------------------------------------------------------
|
9
|
+
# mixer
|
10
|
+
PROGNAME = "ValueDomain" # progname for logger
|
11
|
+
include Sbuilder::Utils::MyLogger # mix logger
|
12
|
+
|
13
|
+
|
14
|
+
def initialize( options = {} )
|
15
|
+
super( options )
|
16
|
+
@logger = getLogger( PROGNAME, options )
|
17
|
+
@logger.info( "#{__method__} initialized" )
|
18
|
+
|
19
|
+
# default values one
|
20
|
+
@values = []
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# ------------------------------------------------------------------
|
25
|
+
# cardinality overriden
|
26
|
+
def cardinality
|
27
|
+
@values.size
|
28
|
+
end
|
29
|
+
|
30
|
+
|
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
|
33
|
+
# value with the given name when i:string
|
34
|
+
def domain_entry( i )
|
35
|
+
case i
|
36
|
+
when Integer
|
37
|
+
@values[i-1]
|
38
|
+
when String
|
39
|
+
ret = @values.select { |val| val == i }.first
|
40
|
+
if ret.nil?
|
41
|
+
raise DomainException.new <<-EOS
|
42
|
+
Unknown domain entry #{i}
|
43
|
+
|
44
|
+
Known domain entries: #{values.join(',')}
|
45
|
+
EOS
|
46
|
+
end
|
47
|
+
return ret
|
48
|
+
else
|
49
|
+
raise DomainException.new <<-EOS
|
50
|
+
Unknown type #{i.class} in 'domain_entry' #{name}.
|
51
|
+
|
52
|
+
Support only for Integer, String
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# ------------------------------------------------------------------
|
59
|
+
# return array of strings for entries in domain - overides super
|
60
|
+
def domain_entries
|
61
|
+
@logger.debug( "#{__method__} #{name}: added domain_entries #{values.join(',')}" )
|
62
|
+
values
|
63
|
+
end
|
64
|
+
|
65
|
+
# ------------------------------------------------------------------
|
66
|
+
# build
|
67
|
+
|
68
|
+
def addValue( value )
|
69
|
+
@logger.debug( "#{__method__} #{name}: added value #{value}" )
|
70
|
+
@values << value
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
|
3
|
+
class TemplateReaderException < Exception
|
4
|
+
end
|
5
|
+
|
6
|
+
|
7
|
+
class ResolverException < Exception
|
8
|
+
end
|
9
|
+
|
10
|
+
class ExtensionException < Exception
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
class DomainException < Exception
|
15
|
+
end
|
16
|
+
|
17
|
+
class ControllerException < Exception
|
18
|
+
end
|
19
|
+
|
20
|
+
class ModelException < Exception
|
21
|
+
end
|
22
|
+
|
23
|
+
class LoaderException < Exception
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,721 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
|
3
|
+
class ExtensionLoader
|
4
|
+
|
5
|
+
attr_accessor :controller # get sets when load starts
|
6
|
+
|
7
|
+
# ------------------------------------------------------------------
|
8
|
+
# mixer
|
9
|
+
PROGNAME = "ExtensionLoader" # progname for logger
|
10
|
+
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
|
+
@@validStepExtension_required = ["interface" ]
|
19
|
+
@@validStepExtension_allowed = @@validStepExtension_required + ["input", "bindExact", "inputs"]
|
20
|
+
|
21
|
+
@@validStepExtension_input = [ "input" ]
|
22
|
+
|
23
|
+
|
24
|
+
# ------------------------------------------------------------------
|
25
|
+
# constructore
|
26
|
+
|
27
|
+
def initialize( options = {} )
|
28
|
+
@logger = getLogger( PROGNAME, options )
|
29
|
+
@logger.info( "#{__method__} initialized" )
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# ------------------------------------------------------------------
|
34
|
+
# model - is found using contorller
|
35
|
+
def model
|
36
|
+
controller.model
|
37
|
+
end
|
38
|
+
|
39
|
+
def factory
|
40
|
+
controller.factory
|
41
|
+
end
|
42
|
+
|
43
|
+
# ------------------------------------------------------------------
|
44
|
+
# load
|
45
|
+
def load( filePath, controller )
|
46
|
+
@logger.info( "#{__method__} filePath=#{filePath}" )
|
47
|
+
@controller = controller
|
48
|
+
doLoad( filePath )
|
49
|
+
end
|
50
|
+
|
51
|
+
def doLoad( fileUri )
|
52
|
+
|
53
|
+
yaml = Sbuilder::Utils::NetIo.read_lines( fileUri )
|
54
|
+
domains_hash = YAML.load( yaml )
|
55
|
+
loadExtensions( domains_hash )
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# iterate domains
|
60
|
+
def loadExtensions( extensionsArr )
|
61
|
+
extensionsArr && extensionsArr.each do |extensionDef|
|
62
|
+
raise ExtensionException.new "Invalid extension definition #{extensionDef}" unless (extensionDef.keys.length == 1)
|
63
|
+
validateProperties( extensionDef, [], @@extensionDefProperties )
|
64
|
+
key = extensionDef.keys.first
|
65
|
+
case key
|
66
|
+
when 'domain-extension'
|
67
|
+
extensionDef[key].each do |domainDef|
|
68
|
+
if !domainDef['cardinality'].nil? then
|
69
|
+
extendDomainWithCardinality( domainDef )
|
70
|
+
else
|
71
|
+
extendDomainWithValues( domainDef )
|
72
|
+
end
|
73
|
+
end
|
74
|
+
when 'interface-extension'
|
75
|
+
extensionDef[key].each do |interfaceExtesionDef|
|
76
|
+
extendInterface( interfaceExtesionDef )
|
77
|
+
end
|
78
|
+
when 'step-extension'
|
79
|
+
extensionDef[key].each do |stepExtensionDef|
|
80
|
+
extendStep( stepExtensionDef )
|
81
|
+
end
|
82
|
+
else
|
83
|
+
raise ExtensionException.new "Unknown extension type #{key} in #{extensionDef}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
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
|
+
|
111
|
+
# pass to model via controller
|
112
|
+
controller.extendDomain( domain )
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
# ------------------------------------------------------------------
|
117
|
+
# extend one domain with cardinality
|
118
|
+
def extendDomainWithCardinality( domainDef )
|
119
|
+
@logger.info( "#{__method__} domainDef=#{domainDef}" )
|
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'] )
|
126
|
+
|
127
|
+
# pass to model via controller
|
128
|
+
controller.extendDomain( domain )
|
129
|
+
end
|
130
|
+
|
131
|
+
# ------------------------------------------------------------------
|
132
|
+
# extend interface
|
133
|
+
def extendInterface( interfaceExtensionDef )
|
134
|
+
@logger.info( "#{__method__} interfaceExtensionDef=#{interfaceExtensionDef}" )
|
135
|
+
controller.extendInterface( interfaceExtensionDef )
|
136
|
+
end
|
137
|
+
|
138
|
+
# ------------------------------------------------------------------
|
139
|
+
# extend steps: recurse 'stepExtensionDef' and create a hash, which
|
140
|
+
# can passed to mustache templates
|
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
|
+
...
|
177
|
+
|
178
|
+
or for a single input
|
179
|
+
|
180
|
+
input:
|
181
|
+
....
|
182
|
+
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
|
+
# added to stepParameterSet
|
233
|
+
return mustacheTemplateData
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
# 'expandedInputs' includes all 'interaface' fields (recurisively)
|
239
|
+
def expandStepInputForDefaults( interface, stepExtensionInputs )
|
240
|
+
|
241
|
+
# make a deeeep copy
|
242
|
+
# puts( "expandStepInputForDefaults: stepExtensionInputs=#{stepExtensionInputs.to_yaml}\n\n" )
|
243
|
+
expandedInputs = Marshal.load( Marshal.dump( stepExtensionInputs ))
|
244
|
+
|
245
|
+
# recurse 'interface' and ensure that 'expandedInputs' structure
|
246
|
+
# corresponds 'interface' structure
|
247
|
+
expandStepInputForDefaultsRecursion( interface, expandedInputs )
|
248
|
+
|
249
|
+
# puts( "expandStepInputForDefaults: expandedInputs=#{expandedInputs.to_yaml}\n\n" )
|
250
|
+
return expandedInputs
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
# recurs 'paramSet' in synch with 'stepExtensionDef': for each
|
255
|
+
# non-leaf paramter (i.e. a a parameter referencing to an other
|
256
|
+
# paramset) ensure that 'stepExtensionDef' also this entry
|
257
|
+
def expandStepInputForDefaultsRecursion( paramSet, stepExtensionInput )
|
258
|
+
|
259
|
+
@logger.debug( "#{__method__} paramSet=#{paramSet}, stepExtensionInput=#{stepExtensionInput}, stepExtensionInput.nil?=#{stepExtensionInput.nil?}" )
|
260
|
+
|
261
|
+
# when no 'input' on 'step-extension'
|
262
|
+
stepExtensionInput = {} if stepExtensionInput.nil?
|
263
|
+
|
264
|
+
paramSet.parameters.each do |parameter|
|
265
|
+
if parameter.isReference && stepExtensionInput.is_a?( Hash ) then
|
266
|
+
# add empty input parameter (if not defined) for records (ie. Hashe).
|
267
|
+
# rows are not expanded (we do not know many we should add)
|
268
|
+
# stepExtensionInput[parameter.name] = initRecord( parameter.name ) unless stepExtensionInput.has_key?( parameter.name )
|
269
|
+
stepExtensionInput[parameter.name] = {} unless stepExtensionInput.has_key?( parameter.name )
|
270
|
+
# recurse referenced 'paramSet' together with 'stepExtensionDef'
|
271
|
+
expandStepInputForDefaultsRecursion( parameter.getResolvedReference( model ), stepExtensionInput[parameter.name] )
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# ------------------------------------------------------------------
|
277
|
+
# recurse 'stepExtensionInputs' and use it to set default values
|
278
|
+
# in 'mustacheTemplateData' structure.
|
279
|
+
|
280
|
+
def extendStepDefaults( interface, stepExtensionInputs, mustacheTemplateData )
|
281
|
+
# puts "extendStepDefaults - starting"
|
282
|
+
# recrurse 'stepExtensionInputs' and yield 'rows' && 'records'
|
283
|
+
recurseStepDefaults( stepExtensionInputs ) do |type, keys, indexes, stepExtensionInput, defaultValues|
|
284
|
+
# puts "type=#{type}, keys=#{keys}, indexes=#{indexes}, stepExtensionInput=#{stepExtensionInput}, defaultValues=#{defaultValues}"
|
285
|
+
|
286
|
+
# configuration in model
|
287
|
+
interfaceParameters = locateParameter( interface, keys )
|
288
|
+
|
289
|
+
# what we have expanded so far - using 'stepExtensionInputs'
|
290
|
+
templateData = locateTemplateData( mustacheTemplateData, keys, indexes )
|
291
|
+
|
292
|
+
# default value is on the top of the stack
|
293
|
+
# defaultValue = defaultValues.last
|
294
|
+
# defaultValue is the last non-nil value on stack 'defaultValues'
|
295
|
+
defaultValue = defaultValues.reverse.find { |v| !v.nil? }
|
296
|
+
|
297
|
+
next unless defaultValue
|
298
|
+
|
299
|
+
# create an entry in 'mustacheTemplateData' if path 'keys'/'indexes' no configuration
|
300
|
+
# in 'step-extension' 'input'
|
301
|
+
templateData = addTemplateData( mustacheTemplateData, keys, indexes ) unless templateData
|
302
|
+
expandDefaults( interfaceParameters, defaultValue, templateData )
|
303
|
+
|
304
|
+
# case type
|
305
|
+
# when "row"
|
306
|
+
# next unless defaultValue
|
307
|
+
# # access data row 'index'
|
308
|
+
# index = indexes.last
|
309
|
+
# # expandDefaults( interfaceParameters, defaultValue, templateData['rows'][index] )
|
310
|
+
# puts "row-expansion templateData=#{templateData}"
|
311
|
+
# expandDefaults( interfaceParameters, defaultValue, templateData )
|
312
|
+
# when "record"
|
313
|
+
# # possibly no default value defined
|
314
|
+
# next unless defaultValue
|
315
|
+
# expandDefaults( interfaceParameters, defaultValue, templateData )
|
316
|
+
# else
|
317
|
+
# # should not happen
|
318
|
+
# raise "Unknown type #{type}"
|
319
|
+
# end
|
320
|
+
end
|
321
|
+
# empty is returnet as boolean false
|
322
|
+
mustacheTemplateData = false if mustacheTemplateData == {}
|
323
|
+
|
324
|
+
mustacheTemplateData
|
325
|
+
end # def extendStepDefaults
|
326
|
+
|
327
|
+
# recurse 'stepExtensionInputs' and yield
|
328
|
+
# - record|row, [keys], parameterDef
|
329
|
+
def recurseStepDefaults( stepExtensionInputs, keys=[], indexes=[], defaultValues=nil, &block )
|
330
|
+
# puts "recurseStepDefaults(enter) stepExtensionInputs=#{stepExtensionInputs}"
|
331
|
+
return unless stepExtensionInputs
|
332
|
+
# init defaultValues
|
333
|
+
defaultValues = [ stepExtensionInputs["_default"] ] unless defaultValues
|
334
|
+
if !keys.any? then
|
335
|
+
# puts "recurseStepDefaults(init) #{stepExtensionInputs}"
|
336
|
+
yield "record", keys, indexes, stepExtensionInputs, defaultValues
|
337
|
+
end
|
338
|
+
stepExtensionInputs.each do |parameterName, parameterDef|
|
339
|
+
if parameterDef.is_a?( Array ) then
|
340
|
+
parameterDef.each.with_index do |parameterDefRow,index|
|
341
|
+
defaultValues.push( parameterDefRow["_default"] )
|
342
|
+
# puts "recurseStepDefaults:(array) resolved-defaultValues=#{defaultValues} index=#{index}, for parameterDefRow=#{parameterDefRow}"
|
343
|
+
yield "row", keys + [parameterName], indexes + [index], parameterDefRow, defaultValues
|
344
|
+
recurseStepDefaults( parameterDefRow, keys + [parameterName], indexes + [index], defaultValues, &block)
|
345
|
+
defaultValues.pop
|
346
|
+
end
|
347
|
+
elsif parameterDef.is_a?( Hash ) then
|
348
|
+
defaultValues.push( parameterDef["_default"] )
|
349
|
+
# puts "recurseStepDefaults:(hash): resolved-defaultValues=#{defaultValues} keys=#{keys}, for parameterDef=#{parameterDef}"
|
350
|
+
yield "record", keys + [parameterName], indexes + [nil], parameterDef, defaultValues
|
351
|
+
recurseStepDefaults( parameterDef, keys + [parameterName], indexes + [nil], defaultValues, &block)
|
352
|
+
defaultValues.pop
|
353
|
+
else
|
354
|
+
# puts "recurseStepDefaults:(else): resolved-defaultValues=#{defaultValues} keys=#{keys}, for parameterDef=#{parameterDef}"
|
355
|
+
# leaf entry
|
356
|
+
end
|
357
|
+
|
358
|
+
end
|
359
|
+
|
360
|
+
end # def recurseStepDefaults
|
361
|
+
|
362
|
+
|
363
|
+
# add expanded parameters to 'templateData'
|
364
|
+
def expandDefaults( interfaceParameters, defaultValue, templateData )
|
365
|
+
|
366
|
+
# puts "\nexpandDefaults defaultValue=#{defaultValue} on '#{templateData}' missing from #{interfaceParameters}"
|
367
|
+
# return unless templateData
|
368
|
+
|
369
|
+
# array of 'parameter_name' fields found on templateData
|
370
|
+
definedParameters = templateData && templateData['columns'] ? templateData['columns'].map { |column| column[:parameter_name] } : []
|
371
|
+
|
372
|
+
# select parameters, which are not defined on 'templateData'
|
373
|
+
# (i.e. missing from 'definedParameters') append new entries in
|
374
|
+
# 'templateData' with 'defaultValue' expanded
|
375
|
+
|
376
|
+
parametersToBe( interfaceParameters ).select do |param|
|
377
|
+
|
378
|
+
# puts "expandDefaults param=#{param} of #{param.class}"
|
379
|
+
# select for expsion
|
380
|
+
# if NOT already defined i.e. NOT in definedParameters
|
381
|
+
# if CARDNIALITY defined (ie. paramter_dom object)
|
382
|
+
|
383
|
+
!definedParameters.include?( param[:parameter_name] ) && !param[:cardinality].nil?
|
384
|
+
|
385
|
+
end.each do |param|
|
386
|
+
# one more added - modify comm
|
387
|
+
templateData['columns'].last["_comma"] = ',' if templateData && templateData['columns'] && templateData['columns'].length > 0
|
388
|
+
|
389
|
+
# puts "added fied #{param[:parameter_name]}"
|
390
|
+
# create default entry
|
391
|
+
expadedElement = {
|
392
|
+
:parameter_name => param[:parameter_name],
|
393
|
+
"_comma" => '',
|
394
|
+
"rows" => false,
|
395
|
+
"columns" => false,
|
396
|
+
}
|
397
|
+
|
398
|
+
expadedElement = expandDefaultValue( expadedElement, defaultValue, param )
|
399
|
+
# ensure that 'columns' array exists (espeically case when
|
400
|
+
# only _default defined in step extension)
|
401
|
+
templateData['columns'] = [] unless templateData && templateData['columns']
|
402
|
+
templateData['columns'] << expadedElement
|
403
|
+
|
404
|
+
end # apped new entries to 'templateData'
|
405
|
+
|
406
|
+
templateData
|
407
|
+
|
408
|
+
end
|
409
|
+
|
410
|
+
# retrurn array of hashes(:parameter_name, :cardinality, :domain_prefix)
|
411
|
+
# on an interface parameters
|
412
|
+
def parametersToBe( interfaceParameters )
|
413
|
+
@logger.debug( "#{__method__} interfaceParameters=#{interfaceParameters}" )
|
414
|
+
parameters = interfaceParameters.parameters.map do |parameter|
|
415
|
+
# puts "parameter=#{parameter}"
|
416
|
+
{
|
417
|
+
:parameter_name => parameter.name,
|
418
|
+
:cardinality => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.cardinality : nil,
|
419
|
+
# :domain_prefix => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.domain_prefix : nil,
|
420
|
+
:domain_name => parameter.respond_to?( :resolvedDomain) ? parameter.resolvedDomain.domain_name : nil,
|
421
|
+
}
|
422
|
+
|
423
|
+
end
|
424
|
+
return parameters
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
# update :domain_value (whewn 'defaultValue' is String), or :domain_element= #{param[:domain_prefix]}#{:domain_prefix}" otherwise
|
429
|
+
def expandDefaultValue( expadedElement, defaultValue, param )
|
430
|
+
|
431
|
+
# Case 'String'
|
432
|
+
return expadedElement.merge( { :domain_value => defaultValue, :domain_element => false }) if defaultValue.is_a?( String )
|
433
|
+
|
434
|
+
# Case 'Interger'
|
435
|
+
# puts "expandDefaultValue param=#{param}"
|
436
|
+
if defaultValue.is_a?( Integer ) then
|
437
|
+
raise ExtensionException.new <<-EOS if defaultValue > param[:cardinality]
|
438
|
+
Cardinality of the default exceeds the cardinality of the parameter domain
|
439
|
+
|
440
|
+
cardinality of default : #{defaultValue}
|
441
|
+
cardinality on domain : #{param[:cardinality]}
|
442
|
+
name of parameter : #{param[:parameter_name]}
|
443
|
+
domain name : #{param[:domain_name]}
|
444
|
+
|
445
|
+
EOS
|
446
|
+
return expadedElement.merge( { :domain_element => getDomainElement( param, defaultValue ), :domain_value => false } )
|
447
|
+
end
|
448
|
+
|
449
|
+
# else - unknown value
|
450
|
+
raise raise ExtensionException.new <<-EOS
|
451
|
+
Unknown type #{defaultValue.class} for default #{defaultValue} value encountered.
|
452
|
+
|
453
|
+
Exteding paramter #{param}
|
454
|
+
EOS
|
455
|
+
end
|
456
|
+
|
457
|
+
def getDomainElement2( extededParameter, domainElement )
|
458
|
+
# puts( "extededParameter=#{extededParameter}, domainElement=#{domainElement}" )
|
459
|
+
return extededParameter.resolvedDomain.domain_entry( domainElement )
|
460
|
+
# "#{extededParameter.resolvedDomain.name}_#{domainElement}"
|
461
|
+
end
|
462
|
+
def getDomainElement( param, defaultValue )
|
463
|
+
# ret = "#{param[:domain_prefix]}#{defaultValue}"
|
464
|
+
ret = model.getDomain(param[:domain_name]).domain_entry( defaultValue )
|
465
|
+
# puts( "getDomainElement: param=#{param}, defaultValue=#{defaultValue} --> #{ret}" )
|
466
|
+
return ret
|
467
|
+
|
468
|
+
end
|
469
|
+
|
470
|
+
# ------------------------------------------------------------------
|
471
|
+
# recurse 'stepExtensionInputs' configuration and create a hash
|
472
|
+
# structure, which can be passed to mustache template
|
473
|
+
|
474
|
+
def extendStepInputs( interface, stepExtensionInputs )
|
475
|
+
@logger.debug( "#{__method__} stepExtensionInputs=#{stepExtensionInputs}" )
|
476
|
+
|
477
|
+
# recursion uses this as a stack
|
478
|
+
subDocumentStack = []
|
479
|
+
subDocumentStack.push( {} )
|
480
|
+
|
481
|
+
|
482
|
+
stepExtensionInputs && recurseStepInputs( stepExtensionInputs ) do |act,keys,domainElement,row|
|
483
|
+
# puts "#{act}, keys=#{keys},domainElement=#{domainElement}, #{row}"
|
484
|
+
|
485
|
+
# uses path [keys] in 'interface' to locate parameter to extend
|
486
|
+
extededParameter = locateParameter( interface, keys )
|
487
|
+
parameterName = keys.last
|
488
|
+
next if parameterName[0] == "_"
|
489
|
+
|
490
|
+
case act
|
491
|
+
when "="
|
492
|
+
@logger.debug( "#{__method__} extededParameter=#{extededParameter.name}, extededParameter.resolvedDomain=#{extededParameter.resolvedDomain}" )
|
493
|
+
input = {
|
494
|
+
:parameter_name => parameterName,
|
495
|
+
:domain_element => getDomainElement2(extededParameter, domainElement),
|
496
|
+
"rows" => false,
|
497
|
+
"columns" => false,
|
498
|
+
"_comma" => ','
|
499
|
+
}
|
500
|
+
# create new parameter && add it to the paramSet
|
501
|
+
raise ExtensionException.new <<-EOS if domainElement.is_a?( Integer ) && extededParameter.resolvedDomain.cardinality < domainElement
|
502
|
+
The cardinality on step exceeds the cardinality of the parameter domain
|
503
|
+
|
504
|
+
Name of parameter : #{extededParameter.name}
|
505
|
+
Name of parameter domain : #{extededParameter.resolvedDomain.name}
|
506
|
+
Cardinality of the parameter domain : #{extededParameter.resolvedDomain.cardinality}
|
507
|
+
Cardinality defined: #{domainElement}
|
508
|
+
|
509
|
+
EOS
|
510
|
+
|
511
|
+
subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
512
|
+
subDocumentStack.last["columns"] << input
|
513
|
+
when "["
|
514
|
+
input = initRecord( parameterName )
|
515
|
+
# {
|
516
|
+
# :parameter_name => parameterName,
|
517
|
+
# "rows" => false,
|
518
|
+
# "columns" => false,
|
519
|
+
# }
|
520
|
+
subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
521
|
+
subDocumentStack.last["columns"] << input
|
522
|
+
subDocumentStack.push( input )
|
523
|
+
when "]"
|
524
|
+
# end of sub-record
|
525
|
+
input = subDocumentStack.pop
|
526
|
+
# last element has no comma
|
527
|
+
input['columns'].last["_comma"] = '' if input['columns']
|
528
|
+
when "<<"
|
529
|
+
if row == 0 then
|
530
|
+
# start of array processing = start of row
|
531
|
+
input = initRecord( parameterName )
|
532
|
+
# {
|
533
|
+
# :parameter_name => parameterName,
|
534
|
+
# "rows" => false,
|
535
|
+
# "columns" => false,
|
536
|
+
# }
|
537
|
+
subDocumentStack.push( addColumn( subDocumentStack.last, input ))
|
538
|
+
|
539
|
+
# subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
540
|
+
# subDocumentStack.last["columns"] << input
|
541
|
+
# subDocumentStack.push( input )
|
542
|
+
else
|
543
|
+
# start a new row in an array
|
544
|
+
input = {
|
545
|
+
"rows" => false,
|
546
|
+
"columns" => false,
|
547
|
+
"_comma" => ",",
|
548
|
+
}
|
549
|
+
subDocumentStack.push( input )
|
550
|
+
end
|
551
|
+
|
552
|
+
when ">>"
|
553
|
+
if row == 0 then
|
554
|
+
# end of array
|
555
|
+
input = subDocumentStack.pop
|
556
|
+
input['rows'].last["_comma"] = '' if input['rows']
|
557
|
+
input['columns'].last["_comma"] = '' if input['columns']
|
558
|
+
|
559
|
+
else
|
560
|
+
input = subDocumentStack.pop
|
561
|
+
input['rows'].last["_comma"] = '' if input['rows']
|
562
|
+
input['columns'].last["_comma"] = '' if input['columns']
|
563
|
+
# puts "subDocumentStack=#{subDocumentStack}"
|
564
|
+
subDocumentStack.last["rows"] = [] unless subDocumentStack.last["rows"]
|
565
|
+
subDocumentStack.last["rows"] << input
|
566
|
+
end
|
567
|
+
else
|
568
|
+
raise "Unknown act #{act}"
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
raise "subDocumentStack should have been empty #{subDocumentStack}" unless subDocumentStack.length == 1
|
573
|
+
ret = subDocumentStack.first
|
574
|
+
|
575
|
+
# last element has no _comma always
|
576
|
+
ret['columns'].last["_comma"] = '' if ret['columns']
|
577
|
+
|
578
|
+
@logger.info( "#{__method__} return=#{ret}" )
|
579
|
+
return ret
|
580
|
+
|
581
|
+
end # def extendStepInputs( interface, stepExtensionInputs )
|
582
|
+
|
583
|
+
# Recurse 'stepExtensionInputs' (i.e. hash under key 'step-extension' ).
|
584
|
+
# During recursion yield:
|
585
|
+
# = : reference parameter, domainElement
|
586
|
+
# [ : starts hash
|
587
|
+
# ] : end hash
|
588
|
+
# << : array
|
589
|
+
# >> : end array
|
590
|
+
def recurseStepInputs( stepExtensionInputs, keys=[], row=0, &block )
|
591
|
+
stepExtensionInputs.each do |parameterName, parameterDef|
|
592
|
+
if parameterDef.is_a?( Array ) then
|
593
|
+
yield "<<", keys + [parameterName], nil, 0
|
594
|
+
parameterDef.each.with_index do |parameterDefRow,index|
|
595
|
+
yield "<<", keys + [parameterName], nil, index+1
|
596
|
+
recurseStepInputs( parameterDefRow, keys + [parameterName], index+1, &block )
|
597
|
+
yield ">>", keys + [parameterName], nil, index+1
|
598
|
+
end
|
599
|
+
yield ">>", keys + [parameterName], nil, 0
|
600
|
+
|
601
|
+
elsif parameterDef.is_a?( Hash ) then
|
602
|
+
yield "[", keys + [parameterName], nil, row
|
603
|
+
recurseStepInputs( parameterDef, keys + [parameterName], row, &block )
|
604
|
+
yield "]", keys + [parameterName], nil, row
|
605
|
+
else
|
606
|
+
# do not process "meta fields" e.g '_default'
|
607
|
+
yield "=", keys + [parameterName], parameterDef, row
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end # recurseStepInputs
|
611
|
+
|
612
|
+
|
613
|
+
# uses path [keys] in 'interface' to locate parameter
|
614
|
+
def locateParameter( interface, keys )
|
615
|
+
extededParameter = interface
|
616
|
+
if keys.any?
|
617
|
+
extededParameter = keys.inject(interface) { |p,key|
|
618
|
+
# _default paramtes not real parameters
|
619
|
+
next if key == "_default"
|
620
|
+
p = p.locateParameter( key )
|
621
|
+
# resolve in model context - possible for paramter_ref
|
622
|
+
p = p.getResolvedReference( controller.model ) if p.respond_to?( :getResolvedReference )
|
623
|
+
p
|
624
|
+
}
|
625
|
+
@logger.debug( "#{__method__} keys #{keys}->extededParameter=#{extededParameter}" )
|
626
|
+
end
|
627
|
+
return extededParameter
|
628
|
+
end
|
629
|
+
|
630
|
+
# ensure that templateData element in ['keys'] and ['indexes']
|
631
|
+
# exists in 'mustacheTemplateData'.
|
632
|
+
def addTemplateData( mustacheTemplateData, keys, indexes )
|
633
|
+
|
634
|
+
templateData = mustacheTemplateData
|
635
|
+
prev = templateData
|
636
|
+
keys.each_with_index do |key,i|
|
637
|
+
index = indexes[i]
|
638
|
+
# puts "addTemplateData: key=#{key}, #{i}, index #{index}"
|
639
|
+
templateData = templateData['columns'].select{ |column| column[:parameter_name] == key }.first
|
640
|
+
if templateData.nil? then
|
641
|
+
templateData = initRecord( key )
|
642
|
+
addColumn( prev, templateData )
|
643
|
+
# puts "addTemplateData: added #{templateData} for key #{key} --> #{mustacheTemplateData}"
|
644
|
+
else
|
645
|
+
# puts "addTemplateData: exists #{templateData} for key #{key}"
|
646
|
+
end
|
647
|
+
|
648
|
+
prev = templateData
|
649
|
+
|
650
|
+
# # puts "data1=#{data}"
|
651
|
+
# if !index.nil? then
|
652
|
+
# templateData = templateData['rows'][index]
|
653
|
+
# # puts "data2=#{data}"
|
654
|
+
# end
|
655
|
+
end # iterate
|
656
|
+
|
657
|
+
return templateData
|
658
|
+
end
|
659
|
+
|
660
|
+
|
661
|
+
# uses path in [keys] and ['indexes'] to locate data 'mustacheTemplateData'.
|
662
|
+
def locateTemplateData( mustacheTemplateData, keys, indexes )
|
663
|
+
ret = mustacheTemplateData
|
664
|
+
i = 0
|
665
|
+
if keys.any?
|
666
|
+
ret = keys.inject(ret) { |data,key|
|
667
|
+
index = indexes[i]
|
668
|
+
i += 1
|
669
|
+
# puts "\n\nindex=#{index} of #{indexes}, i=#{i}, key=#{key} on '#{data}'"
|
670
|
+
break unless data
|
671
|
+
data = data['columns'].select{ |column| column[:parameter_name] == key }.first
|
672
|
+
# puts "data1=#{data}"
|
673
|
+
if !index.nil? then
|
674
|
+
data = data['rows'][index]
|
675
|
+
# puts "data2=#{data}"
|
676
|
+
end
|
677
|
+
|
678
|
+
# if index.nil? then
|
679
|
+
# else
|
680
|
+
# data = data['rows'][index]['columns'].select{ |column| column[:parameter_name] == key }.first
|
681
|
+
# end
|
682
|
+
data
|
683
|
+
}
|
684
|
+
end
|
685
|
+
return ret
|
686
|
+
end
|
687
|
+
|
688
|
+
# ------------------------------------------------------------------
|
689
|
+
# Build a hash structure, which can be passed to mustache template
|
690
|
+
|
691
|
+
# create record entry
|
692
|
+
private
|
693
|
+
def initRecord( parameterName )
|
694
|
+
{
|
695
|
+
:parameter_name => parameterName,
|
696
|
+
"rows" => false,
|
697
|
+
"columns" => false,
|
698
|
+
"_comma" => "",
|
699
|
+
}
|
700
|
+
end
|
701
|
+
|
702
|
+
def addColumn( columns, column )
|
703
|
+
# subDocumentStack.last["columns"] = [] unless subDocumentStack.last["columns"]
|
704
|
+
# subDocumentStack.last["columns"] << input
|
705
|
+
# subDocumentStack.push( input )
|
706
|
+
columns['columns'] = [] unless columns['columns']
|
707
|
+
|
708
|
+
# la
|
709
|
+
columns['columns'].last["_comma"] = ',' if columns['columns'].length > 0
|
710
|
+
|
711
|
+
columns['columns'] << column
|
712
|
+
return column
|
713
|
+
end
|
714
|
+
|
715
|
+
|
716
|
+
|
717
|
+
|
718
|
+
end # class ExtensionLoader
|
719
|
+
|
720
|
+
end # module
|
721
|
+
|