parse_decision 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +71 -0
- data/bin/parse_decision +126 -0
- data/lib/parse_decision/config.rb +90 -0
- data/lib/parse_decision/controller.rb +142 -0
- data/lib/parse_decision/parsedecisiontask.rb +31 -0
- data/lib/parse_decision/parser.rb +194 -0
- data/lib/parse_decision/pd_context.rb +148 -0
- data/lib/parse_decision/plugin/application.rb +48 -0
- data/lib/parse_decision/plugin/plugin.rb +56 -0
- data/lib/parse_decision/plugin/ppm_xpath.rb +70 -0
- data/lib/parse_decision/plugin/pre_decision_guideline.rb +177 -0
- data/lib/parse_decision/plugin/product.rb +176 -0
- data/lib/parse_decision/plugin/product_xpath.rb +52 -0
- data/lib/parse_decision/plugin/web_product.rb +179 -0
- data/lib/parse_decision/plugin.rb +50 -0
- data/lib/parse_decision/version.rb +5 -0
- data/lib/parse_decision.rb +59 -0
- data/parse_decision.gemspec +27 -0
- data/rakefile.rb +58 -0
- data/spec/context_spec.rb +21 -0
- data/spec/data/multiproduct.decision.txt +1481 -0
- data/spec/data/prod.decision.txt +3957 -0
- data/spec/data/reference/multiproduct/001-APP.xml +1 -0
- data/spec/data/reference/multiproduct/001-Mod-Forbear-PRODUCT.xml +357 -0
- data/spec/data/reference/multiproduct/001-Mod-Forgive-PRODUCT.xml +361 -0
- data/spec/data/reference/multiproduct/001-Mod-RateTerm-PRODUCT.xml +353 -0
- data/spec/data/reference/multiproduct/001-Mod-SAM-PRODUCT.xml +365 -0
- data/spec/data/reference/product/001-APP.xml +1 -0
- data/spec/data/reference/product/001-Validation-Rules.xml +536 -0
- data/spec/data/reference/product/002-APP.xml +1 -0
- data/spec/data/reference/product/002-FAPIILoanModification-PRODUCT.xml +1770 -0
- data/spec/data/reference/web/001-APP.xml +1 -0
- data/spec/data/reference/web/001-Product01-PRODUCT.xml +1088 -0
- data/spec/data/reference/web/002-APP.xml +1 -0
- data/spec/data/reference/web/002-Product01-PRODUCT.xml +15 -0
- data/spec/data/reference/workflow/001-APP.xml +1 -0
- data/spec/data/reference/workflow/001-WF-DataClearing-Pre-Rules.xml +37 -0
- data/spec/data/reference/workflow-2/001-APP.xml +1 -0
- data/spec/data/reference/workflow-2/001-WF-ProdSel-Post-Rules.xml +699 -0
- data/spec/data/test.rb +13 -0
- data/spec/data/validation.decision.txt +1199 -0
- data/spec/data/web.decision.txt +1128 -0
- data/spec/data/wf.decision.txt +43 -0
- data/spec/data/wf2.decision.txt +705 -0
- data/spec/parser_spec.rb +308 -0
- data/spec/plugin_app_spec.rb +40 -0
- data/spec/plugin_ppmxpath_spec.rb +74 -0
- data/spec/plugin_predecision_spec.rb +81 -0
- data/spec/plugin_product_spec.rb +117 -0
- data/spec/plugin_productxpath_spec.rb +76 -0
- data/spec/plugin_spec.rb +54 -0
- data/spec/spec_helper.rb +81 -0
- data/test/data/2.2.decision-multiple.txt +1391 -0
- data/test/data/2.2.decision.txt +1128 -0
- data/test/data/2.decision.txt +1481 -0
- data/test/plugins/test_plugin_predecisionguideline.rb +120 -0
- data/test/plugins/test_plugin_product.rb +120 -0
- data/test/test_config.rb +90 -0
- data/test/test_context.rb +103 -0
- data/test/test_parse_webdecision.rb +121 -0
- data/test/test_parser.rb +69 -0
- data/test/test_parser_parse.rb +110 -0
- metadata +225 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: parser.rb
|
3
|
+
# Purpose:: Main Model object for ParseDecision utility
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 03/12/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
require 'ktcommon/ktpath'
|
11
|
+
require 'ktcommon/ktcmdline'
|
12
|
+
require 'parse_decision/plugin'
|
13
|
+
require 'pathname'
|
14
|
+
|
15
|
+
#$LOG.level = Logger::ERROR
|
16
|
+
|
17
|
+
##############################################################################
|
18
|
+
# Everything is contained in Module ParseDecision
|
19
|
+
module ParseDecision
|
20
|
+
|
21
|
+
##########################################################################
|
22
|
+
# The Parser class runs the show. This class is called by the controller object
|
23
|
+
class Parser
|
24
|
+
|
25
|
+
|
26
|
+
def initialize()
|
27
|
+
$LOG.debug "Parser::initialize"
|
28
|
+
@cfg = Config.new.load
|
29
|
+
@plugins = [Plugin::Application.new,
|
30
|
+
Plugin::PpmXpath.new,
|
31
|
+
Plugin::PreDecisionGuideline.new,
|
32
|
+
Plugin::ProductXpath.new,
|
33
|
+
Plugin::Product.new,
|
34
|
+
]
|
35
|
+
@context = PDContext.new
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Return the application's version string.
|
40
|
+
def version()
|
41
|
+
return ParseDecision::VERSION
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Validate the configuration.
|
46
|
+
def validateCfg(cfg)
|
47
|
+
|
48
|
+
if(!(cfg.key?(:file) && (nil != cfg[:file])))
|
49
|
+
puts "Missing --file option."
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
if(!(cfg.key?(:outdir) && (nil != cfg[:outdir])) )
|
53
|
+
puts "Missing --outdir option."
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
@context.file = cfg[:file]
|
58
|
+
@context.outdir = cfg[:outdir]
|
59
|
+
|
60
|
+
if(cfg.key?(:srcdir) && cfg[:srcdir] != nil)
|
61
|
+
@context.srcdir = cfg[:srcdir]
|
62
|
+
end
|
63
|
+
|
64
|
+
if(cfg.key?(:verbose) && cfg[:verbose] != nil)
|
65
|
+
@context.verbose = cfg[:verbose]
|
66
|
+
end
|
67
|
+
|
68
|
+
return true
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def parse(srcpath, destpath)
|
74
|
+
path = Pathname.new srcpath
|
75
|
+
destpath = Pathname.pwd if destpath.nil?
|
76
|
+
parseCfg({ file: path.basename.to_s,
|
77
|
+
srcdir: path.dirname.to_s, outdir: destpath.to_s })
|
78
|
+
end
|
79
|
+
|
80
|
+
# Parse files based on the configuration.
|
81
|
+
def parseCfg(cfg)
|
82
|
+
$LOG.debug "Parser::parseCfg( cfg )"
|
83
|
+
|
84
|
+
if( !validateCfg(cfg) )
|
85
|
+
puts "ERROR: Invalid options."
|
86
|
+
return
|
87
|
+
end
|
88
|
+
|
89
|
+
if( !File.exists?(@context.file) )
|
90
|
+
@context.file = File.join( @context.srcdir, @context.file )
|
91
|
+
if( !File.exists?(@context.file) )
|
92
|
+
puts "ERROR: unable to locate src file: #{@context.file}"
|
93
|
+
return
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if( !File.exists?(@context.outdir) )
|
98
|
+
FileUtils.mkdir_p( @context.outdir )
|
99
|
+
puts "Output dir created: #{@context.outdir}" if @context.verbose
|
100
|
+
end
|
101
|
+
|
102
|
+
parseFile(@context.file)
|
103
|
+
|
104
|
+
# Copy the decision log to the output dir.
|
105
|
+
FileUtils.cp(@context.file, @context.outdir)
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# Parse an XML decision file.
|
110
|
+
def parseFile(fname)
|
111
|
+
$LOG.debug "Parser::parseFile( #{fname} )"
|
112
|
+
puts "Parsing file: #{fname}" if @context.verbose
|
113
|
+
|
114
|
+
# Determine the mode and configure plugins based on the file data.
|
115
|
+
configureForFileMode(fname)
|
116
|
+
|
117
|
+
line_count = 1
|
118
|
+
# Open the file and read line by line
|
119
|
+
df = File.open(fname).each do |ln|
|
120
|
+
puts line_count.to_s if $DEBUG
|
121
|
+
line_count += 1
|
122
|
+
@plugins.each do |plug|
|
123
|
+
puts " --> #{plug.class}" if $DEBUG
|
124
|
+
break if ( true == plug.execute(@context, ln))
|
125
|
+
end # plugins.each
|
126
|
+
end # do file
|
127
|
+
|
128
|
+
puts "Lines parsed: #{line_count}" if @context.verbose
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def configureForFileMode(fname)
|
133
|
+
$LOG.debug "Parser::configureForFileMode( #{fname} )"
|
134
|
+
|
135
|
+
mode = :default
|
136
|
+
fileTypeFound = false
|
137
|
+
|
138
|
+
# Open the file and read line by line looking for indications of which mode to use.
|
139
|
+
df = File.open(fname).each do |ln|
|
140
|
+
# Search for 'normal' decision file.
|
141
|
+
if(ln.include?("<PARAMS>"))
|
142
|
+
fileTypeFound = true
|
143
|
+
puts "Decision file type = :default (not webdecision)" if @context.verbose
|
144
|
+
break
|
145
|
+
end
|
146
|
+
|
147
|
+
# Search for web decision file.
|
148
|
+
if(ln.include?("Next Decision"))
|
149
|
+
fileTypeFound = true
|
150
|
+
mode = :webdecision
|
151
|
+
puts "Decision file type = :webdecision" if @context.verbose
|
152
|
+
break
|
153
|
+
end
|
154
|
+
|
155
|
+
# Exit file search if mode has been determined.
|
156
|
+
if(true == fileTypeFound)
|
157
|
+
break
|
158
|
+
end
|
159
|
+
end # do file
|
160
|
+
|
161
|
+
# If the file is a web decision, reset the plugins.
|
162
|
+
if(mode == :webdecision)
|
163
|
+
@context.parseMode = mode
|
164
|
+
@plugins = [Plugin::Application.new,
|
165
|
+
Plugin::WebProduct.new,
|
166
|
+
]
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
def parseFileWithSwitch(arg)
|
173
|
+
$LOG.debug "Parser::parseFileWithSwitch( #{arg} )"
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def parseFileWithCmdLineArg(arg)
|
178
|
+
$LOG.debug "Parser::parseFileWithCmdLineArg( #{arg} )"
|
179
|
+
end
|
180
|
+
|
181
|
+
# Set directory where generated files are placed.
|
182
|
+
def setOutdir(dir)
|
183
|
+
@context.outdir = dir
|
184
|
+
end
|
185
|
+
|
186
|
+
def noCmdLineArg()
|
187
|
+
$LOG.debug "Parser::noCmdLineArg"
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
end # class Parser
|
192
|
+
|
193
|
+
|
194
|
+
end # module ParseDecision
|
@@ -0,0 +1,148 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: pd_context.rb
|
3
|
+
# Purpose:: Context object used by all plugins
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 03/12/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
require 'ktcommon/ktpath'
|
11
|
+
require 'ktcommon/ktcmdline'
|
12
|
+
require 'parse_decision/plugin'
|
13
|
+
require 'pathname'
|
14
|
+
|
15
|
+
#$LOG.level = Logger::ERROR
|
16
|
+
|
17
|
+
##############################################################################
|
18
|
+
# Everything is contained in Module ParseDecision
|
19
|
+
module ParseDecision
|
20
|
+
|
21
|
+
##########################################################################
|
22
|
+
# Context class holds all info and state about the current parsing process
|
23
|
+
class PDContext
|
24
|
+
|
25
|
+
attr_reader :outdir
|
26
|
+
attr_reader :srcdir
|
27
|
+
attr_reader :file
|
28
|
+
attr_reader :verbose
|
29
|
+
attr_reader :index
|
30
|
+
attr_reader :state
|
31
|
+
attr_reader :parseMode
|
32
|
+
|
33
|
+
|
34
|
+
def initialize()
|
35
|
+
$LOG.debug "PDContext::initialize"
|
36
|
+
@outdir = nil
|
37
|
+
@srcdir = "."
|
38
|
+
@file = nil
|
39
|
+
@verbose = false
|
40
|
+
@index = 0
|
41
|
+
@parseMode = :default # :webdecision
|
42
|
+
@data = nil # Hash to store plugin data in
|
43
|
+
|
44
|
+
@availableStates = {}
|
45
|
+
@availableStates[:default] = [:app, :appPpmXpath, :preDecisionGdl, :productXpath, :productXml, :productPpms, :productRules, ]
|
46
|
+
@availableStates[:webdecision] = [:app, :gdlRules, :productRules, :decisionResponse, :preDecisionGdl, ]
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Return the data hash, creating it if needed.
|
51
|
+
def data()
|
52
|
+
@data ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Return data from hash.
|
57
|
+
def [](sym)
|
58
|
+
return data[sym]
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Return data from hash.
|
63
|
+
def []=(sym, val)
|
64
|
+
return data[sym] = val
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# Return array of current available states.
|
69
|
+
def availableStates()
|
70
|
+
return @availableStates[@parseMode]
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# Set the parse mode.
|
75
|
+
def parseMode=(mode)
|
76
|
+
@parseMode = mode if [:default, :webdecision].include?(mode)
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Set the output dir path.
|
81
|
+
def outdir=(dir)
|
82
|
+
@outdir = File.rubypath(dir) unless nil == dir
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# Set source file and dir path
|
87
|
+
def src_file=(file)
|
88
|
+
fp = Pathname.new(file)
|
89
|
+
@srcdir = fp.dirname.to_s
|
90
|
+
@file = fp.basename.to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
# Set the source dir path.
|
94
|
+
def srcdir=(dir)
|
95
|
+
@srcdir = File.rubypath(dir) unless nil == dir
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Set the name of file to parse.
|
100
|
+
def file=(filename)
|
101
|
+
@file = File.rubypath(filename) unless nil == filename
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Turn on verbose mode.
|
106
|
+
def verbose=(verbose)
|
107
|
+
@verbose = verbose
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# Return the full output path including the filename.
|
112
|
+
def outputPath(filename)
|
113
|
+
raise "outdir missing" unless !@outdir.nil?
|
114
|
+
outputPath = File.join(@outdir, filename)
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def state=(nextState)
|
119
|
+
raise "Invalid target state: #{nextState.to_s}" unless availableStates.include? nextState
|
120
|
+
|
121
|
+
@state = nextState
|
122
|
+
puts "STATE: #{nextState.to_s}" if $DEBUG
|
123
|
+
end
|
124
|
+
|
125
|
+
def nextIndex()
|
126
|
+
@index += 1
|
127
|
+
end
|
128
|
+
|
129
|
+
def indexStr()
|
130
|
+
return "%03d" % @index
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def createValidName(inname)
|
135
|
+
return nil if nil == inname
|
136
|
+
|
137
|
+
outname = inname.gsub(/[\s\/\\?*#+]/,'') # Remove illegal chars (replace with underscore).
|
138
|
+
outname.gsub!(/_+/,"_") # Replace consecutive uscores with single uscore.
|
139
|
+
outname.gsub!(/\./,"-") # Replace period with dash.
|
140
|
+
outname.gsub!(/[\(\)\$]/,"") # Remove L & R Parens, dollar signs.
|
141
|
+
outname.gsub!(/\%/,"Perc") # Replace '%' with Perc.
|
142
|
+
|
143
|
+
outname
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
end # module ParseDecision
|
@@ -0,0 +1,48 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: plugin.rb
|
3
|
+
# Purpose:: Plugin objects for ParseDecision utility
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 04/17/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
##############################################################################
|
11
|
+
module ParseDecision
|
12
|
+
|
13
|
+
##############################################################################
|
14
|
+
module Plugin
|
15
|
+
|
16
|
+
## #######################################################################
|
17
|
+
# Application XML plugin
|
18
|
+
class Application < Plugin
|
19
|
+
def initialize()
|
20
|
+
$LOG.debug "Application::initialize"
|
21
|
+
@fnameTemplate = "@INDEX@-APP.xml"
|
22
|
+
@searchStr = "<DECISION_REQUEST><APPLICATION"
|
23
|
+
@searchStr = "<APPLICATION " # Note that the space at end is required.
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute(context, ln)
|
27
|
+
#$LOG.debug "Application::execute"
|
28
|
+
if(ln.include?(@searchStr))
|
29
|
+
context.nextIndex
|
30
|
+
context.state = :app
|
31
|
+
outfile = apply_template(@fnameTemplate, "@INDEX@", context.indexStr)
|
32
|
+
puts "" if context.verbose
|
33
|
+
puts "= = = = = = = = = = = = = = = = = = = = = = = = = = = =" if context.verbose
|
34
|
+
puts "" if context.verbose
|
35
|
+
puts "Creating Application XML file: #{outfile}" if context.verbose
|
36
|
+
File.open(context.outputPath(outfile), "w") do |f|
|
37
|
+
write_to_file(f,ln)
|
38
|
+
end
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end # class Application
|
44
|
+
|
45
|
+
|
46
|
+
end # module Plugin
|
47
|
+
|
48
|
+
end # module ParseDecision
|
@@ -0,0 +1,56 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: plugin.rb
|
3
|
+
# Purpose:: Plugin objects for ParseDecision utility
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 04/17/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
##############################################################################
|
11
|
+
module ParseDecision
|
12
|
+
|
13
|
+
##############################################################################
|
14
|
+
module Plugin
|
15
|
+
|
16
|
+
## #######################################################################
|
17
|
+
# Base class for all plugins
|
18
|
+
class Plugin
|
19
|
+
def initialize()
|
20
|
+
$LOG.debug "Plugin::initialize"
|
21
|
+
end
|
22
|
+
|
23
|
+
def apply_template(template, pattern, replacement)
|
24
|
+
output = template.gsub(pattern, replacement)
|
25
|
+
end
|
26
|
+
|
27
|
+
def apply_templates(template, repPatterns)
|
28
|
+
output = template
|
29
|
+
repPatterns.each do |p,r|
|
30
|
+
output = output.gsub(p, r)
|
31
|
+
end # repPatterns.each
|
32
|
+
output
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute(context, ln)
|
36
|
+
$LOG.debug "Plugin::execute"
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_to_file(f,data)
|
41
|
+
if(data.class == Array)
|
42
|
+
data.each do |ln|
|
43
|
+
f.write ln
|
44
|
+
end
|
45
|
+
else
|
46
|
+
f.write data
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end # class Plugin
|
52
|
+
|
53
|
+
|
54
|
+
end # module Plugin
|
55
|
+
|
56
|
+
end # module ParseDecision
|
@@ -0,0 +1,70 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: plugin.rb
|
3
|
+
# Purpose:: Plugin objects for ParseDecision utility
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 04/17/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
##############################################################################
|
11
|
+
module ParseDecision
|
12
|
+
|
13
|
+
##############################################################################
|
14
|
+
module Plugin
|
15
|
+
|
16
|
+
## #######################################################################
|
17
|
+
# PPM XPath plugin
|
18
|
+
class PpmXpath < Plugin
|
19
|
+
def initialize()
|
20
|
+
$LOG.debug "PpmXpath::initialize"
|
21
|
+
@fnameTemplate = "@INDEX@-APP-PPMXPATH.xml"
|
22
|
+
@searchStr1 = "*APP XPATH xml*"
|
23
|
+
@searchStr2 = "<PPXPATH>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute(context, ln)
|
27
|
+
#$LOG.debug "PpmXpath::execute"
|
28
|
+
#require 'pry'; binding.pry
|
29
|
+
case context.state
|
30
|
+
when :app
|
31
|
+
return is_ppm_xpath context, ln
|
32
|
+
|
33
|
+
when :appPpmXpath
|
34
|
+
return store_xpath_content context, ln
|
35
|
+
|
36
|
+
else
|
37
|
+
return false
|
38
|
+
end # case
|
39
|
+
end
|
40
|
+
|
41
|
+
def is_ppm_xpath(context,ln)
|
42
|
+
if ln.include?(@searchStr1)
|
43
|
+
context.state = :appPpmXpath
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
def store_xpath_content(context, ln)
|
50
|
+
if ln.include?(@searchStr2)
|
51
|
+
context.state = :app
|
52
|
+
outfile = apply_template(@fnameTemplate, "@INDEX@", context.indexStr)
|
53
|
+
puts "Creating App XML XPath file: #{outfile}" if context.verbose
|
54
|
+
File.open(context.outputPath(outfile), "w") do |f|
|
55
|
+
write_to_file(f,ln)
|
56
|
+
end
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
# This is probably an empty line.
|
61
|
+
# Return true since we're in the xpath state and there is no need for
|
62
|
+
# any other plugin to handle this line.
|
63
|
+
return true
|
64
|
+
end
|
65
|
+
end # class PpmXpath
|
66
|
+
|
67
|
+
|
68
|
+
end # module Plugin
|
69
|
+
|
70
|
+
end # module ParseDecision
|
@@ -0,0 +1,177 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# File:: plugin.rb
|
3
|
+
# Purpose:: Plugin objects for ParseDecision utility
|
4
|
+
#
|
5
|
+
# Author:: Jeff McAffee 04/17/2010
|
6
|
+
# Copyright:: Copyright (c) 2010, kTech Systems LLC. All rights reserved.
|
7
|
+
# Website:: http://ktechsystems.com
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
##############################################################################
|
11
|
+
module ParseDecision
|
12
|
+
|
13
|
+
##############################################################################
|
14
|
+
module Plugin
|
15
|
+
|
16
|
+
## #######################################################################
|
17
|
+
# Pre-Decision Guideline XML plugin
|
18
|
+
class PreDecisionGuideline < Plugin
|
19
|
+
|
20
|
+
attr_reader :ppmData
|
21
|
+
attr_reader :outfile
|
22
|
+
|
23
|
+
def initialize()
|
24
|
+
$LOG.debug "PreDecisionGuideline::initialize"
|
25
|
+
@fnameTemplate = "@INDEX@-@GDL@-Rules.xml"
|
26
|
+
@searchStrPpms = "<PARAMS><_DATA_SET"
|
27
|
+
@searchStrGdl = "<Guideline "
|
28
|
+
@searchStrGdl2 = "******Guideline*"
|
29
|
+
@searchStrGdlEnd = "<Decision GuidelineId"
|
30
|
+
@searchRulesEnd = "</Decision>"
|
31
|
+
@ppmData = ""
|
32
|
+
@ruleData = []
|
33
|
+
|
34
|
+
@openTag = "<@TAG@_DATA>\n"
|
35
|
+
@closeTag = "</@TAG@_DATA>\n"
|
36
|
+
@actualCloseTag = ""
|
37
|
+
@lineCount = 0
|
38
|
+
@chunkSize = 1000
|
39
|
+
@outfile = "PreDecision"
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute(context, ln)
|
43
|
+
#$LOG.debug "PreDecisionGuideline::execute"
|
44
|
+
|
45
|
+
case context.state
|
46
|
+
when :app
|
47
|
+
return check_for_ppms_or_rule_start context, ln
|
48
|
+
|
49
|
+
when :preDecisionGdl
|
50
|
+
return process_rule_data context, ln
|
51
|
+
|
52
|
+
else
|
53
|
+
return false
|
54
|
+
end # case
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_for_ppms_or_rule_start(context, ln)
|
58
|
+
if ln.include?(@searchStrPpms)
|
59
|
+
@ppmData = ln
|
60
|
+
# XML Tidy doesn't like underscores at the beginning attribute names, take care of it here.
|
61
|
+
@ppmData.gsub!(/_DATA_SET/, "DATA_SET")
|
62
|
+
@ppmData.gsub!(/_Name/, "Name")
|
63
|
+
@ppmData.gsub!(/_Value/, "Value")
|
64
|
+
return true
|
65
|
+
end
|
66
|
+
|
67
|
+
if ln.include?(@searchStrGdl) || ln.include?(@searchStrGdl2)
|
68
|
+
context.state = :preDecisionGdl
|
69
|
+
@ruleData.clear
|
70
|
+
open_discard_element
|
71
|
+
@ruleData << ln
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
def open_discard_element
|
79
|
+
# The log can contain a lot of junk here. This prevents it from being a valid
|
80
|
+
# XML doc. To account for this, we'll create a DISCARD element for easy folding
|
81
|
+
# and put everything into an HTML comment block.
|
82
|
+
|
83
|
+
# We need to track when discarding is on, so we only turn it off once.
|
84
|
+
@discarding = true
|
85
|
+
|
86
|
+
@ruleData << "<DISCARD_BY_PARSER>\n"
|
87
|
+
@ruleData << "<!-- " # The leading element tag is not valid XML (no quotes around attrib params).
|
88
|
+
end
|
89
|
+
|
90
|
+
def close_discard_element
|
91
|
+
# Only output the closing element if discarding is actually on.
|
92
|
+
# This could get called multiple times after discarding has been turned off.
|
93
|
+
if !@discarding.nil? && @discarding
|
94
|
+
@discarding = false
|
95
|
+
@ruleData << "-->\n" # The leading element tag is not valid XML (no quotes around attrib params).
|
96
|
+
@ruleData << "</DISCARD_BY_PARSER>\n"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def process_rule_data(context, ln)
|
101
|
+
# Create the rules data file if the Guideline end tag is found
|
102
|
+
if ln.include?(@searchStrGdlEnd)
|
103
|
+
close_discard_element
|
104
|
+
setup_rules_file context, ln
|
105
|
+
return true
|
106
|
+
end
|
107
|
+
|
108
|
+
# Close the rules data file if the rules end tag is found
|
109
|
+
if ln.include?(@searchRulesEnd)
|
110
|
+
close_out_rules_file context, ln
|
111
|
+
context.state = :app
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
|
115
|
+
# Haven't found the start or end of the rules here,
|
116
|
+
# we must be somewhere in the middle.
|
117
|
+
# Store the data so it can be written to file later.
|
118
|
+
write_rules_data context, ln
|
119
|
+
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
|
123
|
+
def setup_rules_file(context, ln)
|
124
|
+
@ruleData << ln
|
125
|
+
|
126
|
+
# Default guideline name
|
127
|
+
gdlName = "PreDecision"
|
128
|
+
|
129
|
+
# String#match acts weird so using RegEx/MatchData here.
|
130
|
+
m = /\sGuidelineName="([^"]+)/.match(ln)
|
131
|
+
if m[1].length > 1
|
132
|
+
gdlName = m[1]
|
133
|
+
gdlName = context.createValidName(gdlName)
|
134
|
+
end
|
135
|
+
|
136
|
+
@outfile = apply_templates(@fnameTemplate, {"@INDEX@"=>context.indexStr, "@GDL@"=>gdlName})
|
137
|
+
|
138
|
+
# Store the closing tag for later.
|
139
|
+
@actualCloseTag = apply_template(@closeTag, "@TAG@", gdlName)
|
140
|
+
|
141
|
+
puts "Creating Gdl Rules file: #{@outfile}" if context.verbose
|
142
|
+
|
143
|
+
File.open(context.outputPath(@outfile), "w") do |f|
|
144
|
+
write_to_file(f, apply_template(@openTag, "@TAG@", gdlName))
|
145
|
+
write_to_file(f,@ppmData)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def close_out_rules_file(context, ln)
|
150
|
+
@ruleData << ln
|
151
|
+
|
152
|
+
File.open(context.outputPath(@outfile), "a") do |f|
|
153
|
+
write_to_file(f,@ruleData)
|
154
|
+
write_to_file(f, @actualCloseTag)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def write_rules_data(context, ln)
|
159
|
+
@ruleData << ln
|
160
|
+
@lineCount += 1
|
161
|
+
|
162
|
+
if(@lineCount > @chunkSize)
|
163
|
+
puts "Writing rule data chunk." if context.verbose
|
164
|
+
File.open(context.outputPath(@outfile), "a") do |f|
|
165
|
+
write_to_file(f,@ruleData)
|
166
|
+
end
|
167
|
+
@lineCount = 0
|
168
|
+
@ruleData.clear
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end # class PreDecisionGuideline
|
173
|
+
|
174
|
+
|
175
|
+
end # module Plugin
|
176
|
+
|
177
|
+
end # module ParseDecision
|