I have an xml file which contains conditions to be checked against a metadata JSON and value data JSON input.
Sample metadata JSON input can be
{
"max_cash":789,
"min_cash":12,
"start_date":"28 Oct 2018",
"end_date":"02 Dec 2018",
"allowed_cities":"3,4,5,6"
}
Sample value data JSON can be
{
"cash":34,
"order_date":"03 Nov 2018",
"city_id":"5,4"
}
Each condition can form an expression and has following attribute
- param_holder - this is left term of expression. Its just a key whose value is in metadata JSON.
- param_value_holder - this is right term of expression. Its just a key whose value is in value data JSON.
- operator - which operator to be performed on left and right term. For example <,>,<=,>=,<>,==,CONTAINS, NOT_CONTAINS, CONTAINS_AT_LEAST_ONE etc.
- param_type - data type of left and right term . For example NUMBER, DATE, TIME, STRING, LIST.
Sample xml looks like this
<condtion id="1" param_type="NUMBER" param_holder="max_cash" operator=">=" param_value_holder="cash" next_condition="2"></condtion>
<condtion id="2" param_type="NUMBER" param_holder="min_cash" operator="<=" param_value_holder="cash" next_condition="3"></condtion>
<condtion id="3" param_type="DATE" param_holder="start_date" operator="<=" param_value_holder="order_date" next_condition="4"></condtion>
<condtion id="4" param_type="DATE" param_holder="end_date" operator=">=" param_value_holder="order_date" next_condition="5"></condtion>
<condtion id="5" param_type="LIST" param_holder="allowed_cities" operator="CONTAINS" param_value_holder="city_id" next_condition="-1">
I am working with JAVA, and almost everything here is dynamic which can be added , modified and removed anytime. In future there might by some more operators, data types etc. I am looking for a solution where people can add any conditions without re deploying the code. Code deployment should be done only if metadata JSON changes. I read about ANTLR and it think it will over killing the solution and creation and maintenance of grammar and parser is overhead for a developer. I came up with another solution with Factory Pattern, where Operator Factory takes input as operator and returns respective Operator object which further takes left term, right term and param type as parameter and evaluated the condition based on specific param type.
public abstract class Operator {
public abstract boolean evaluate(String leftTerm, String rightTerm, String param_type) throws ParseException;
}
public class GTEOperator extends Operator {
@Override
public boolean evaluate(String leftTerm, String rightTerm, String param_type) throws ParseException {
switch (param_type)
{
case "DATE":
return new SimpleDateFormat().parse(leftTerm).after(new SimpleDateFormat().parse(rightTerm));
case "NUMBER":
return Integer.parseInt(leftTerm) >=Integer.parseInt(rightTerm);
default:
return true;
}
}
}
public class ContainsOperator extends Operator {
@Override
public boolean evaluate(String leftTerm, String rightTerm, String param_type) throws ParseException {
return Arrays.asList(leftTerm.split(",")).contains(rightTerm);
}
}
This solution is not dynamic and involves a lot of code rewrite. Can some one help me with a better, extensible and object oriented approach.
Aucun commentaire:
Enregistrer un commentaire