-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathRuleParser.scala
More file actions
197 lines (157 loc) · 6.07 KB
/
RuleParser.scala
File metadata and controls
197 lines (157 loc) · 6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package com.databricks.labs.validation
import io.circe.{Decoder, Json, parser}
import com.databricks.labs.validation.utils.Structures.Bounds
import org.apache.spark.sql.functions.col
import scala.io.Source
sealed trait RuleParser{
/**
* Define trait to enable extension of generic Rule Parser to provide a body support multiple input types
* */
val parserType:String
/** Identifier to be implemented by child class specifying format it supports*/
def readRules(filePath:String):String
/** @param filePath The specific path where the json file containing the rules reside */
def parseRules(rules:String):Array[Rule]
/** @param rules input object of genric Type T containing the parsed rules
* returns Array of Individual Rules specified in JSON object*/
}
class JsonRuleParser extends RuleParser {
/**
* Implementation of RuleParser to support external rules in JSON Format
*
*
* */
override final val parserType ="jsonParser"
def parseRules(rules:String):Array[Rule] = {
if (rules == null) {
val jsonRules = parser.decode[Array[Rule]](rules).right.get
jsonRules
}
else{
val jsonRules = parser.decode[Array[Rule]](readRules()).right.get
jsonRules
}
}
def readRules(filePath:String="rules.json"):String = {
val jsonRuleString: String = Source.fromResource(filePath).mkString
jsonRuleString
}
/**
* Implicit decoder types needed by CIRCE lib to parse individual json items to be parsed to the supported Rule objects
* */
private val _boundsDecoder:Decoder[Bounds]={
boundCursor =>
for {
lower <- boundCursor.get[Double]("lower")
upper <- boundCursor.get[Double]("upper")
lowerInclusive <- boundCursor.getOrElse[Boolean]("lowerInclusive")(false)
upperInclusive <- boundCursor.getOrElse[Boolean]("upperInclusive")(false)
} yield Bounds(lower , upper , lowerInclusive , upperInclusive )
}
private val _ruleDecoder1:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
bounds <- ruleCursor.get[Bounds]("Bounds")
} yield Rule(ruleName, column ,bounds)
}
private val _ruleDecoder2:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
} yield Rule(ruleName, column)
}
private val _ruleDecoder3:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validExpr <- ruleCursor.get[String]("validExpr").map(x => col(x))
} yield Rule(ruleName , column ,validExpr)
}
private val _ruleDecoder4:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Double]]("validNumerics")
invertMatch <- ruleCursor.get[Boolean]("invertMatch")
} yield Rule(ruleName , column ,validNumerics,invertMatch)
}
private val _ruleDecoder5a:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Double]]("validNumerics")
} yield Rule(ruleName , column ,validNumerics)
}
private val _ruleDecoder5b:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Long]]("validNumerics")
} yield Rule(ruleName , column ,validNumerics)
}
private val _ruleDecoder5c:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Int]]("validNumerics")
} yield Rule(ruleName , column ,validNumerics)
}
private val _ruleDecoder5d1:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Double]]("validNumerics")
invertMatch <- ruleCursor.getOrElse[Boolean]("invertMatch")(false)
} yield Rule(ruleName , column ,validNumerics, invertMatch)
}
private val _ruleDecoder5d2:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validNumerics <- ruleCursor.get[Array[Int]]("validNumerics")
invertMatch <- ruleCursor.getOrElse[Boolean]("invertMatch")(false)
} yield Rule(ruleName , column ,validNumerics, invertMatch)
}
private val _ruleDecoder6:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validString <- ruleCursor.get[Array[String]]("validString")
ignoreCase <- ruleCursor.getOrElse[Boolean]("ignoreCase")(false)
invertMatch <- ruleCursor.getOrElse[Boolean]("invertMatch")(false)
} yield Rule(ruleName , column ,validString,ignoreCase,invertMatch)
}
private val _ruleDecoder7:Decoder[Rule]={
ruleCursor =>
for {
ruleName <- ruleCursor.get[String]("ruleName")
column <- ruleCursor.get[String]("column").map(x => col(x))
validString <- ruleCursor.get[Array[String]]("validString")
} yield Rule(ruleName , column ,validString)
}
implicit val boundsDecoder: Decoder[Bounds] = _boundsDecoder
implicit val ruleDecoder: Decoder[Rule] = {
_ruleDecoder3 or
_ruleDecoder4 or
_ruleDecoder5a or
_ruleDecoder5b or
_ruleDecoder5c or
_ruleDecoder5d1 or
_ruleDecoder5d2 or
_ruleDecoder6 or
_ruleDecoder7 or
_ruleDecoder1 or
_ruleDecoder2
}
}