-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathWhereNode.java
179 lines (147 loc) · 5.96 KB
/
WhereNode.java
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
package me.huqiao.loganlyzer.querylanguage.statusnode;
import me.huqiao.loganlyzer.condition.Condition;
import me.huqiao.loganlyzer.condition.Conditions;
import me.huqiao.loganlyzer.enumtype.CompareType;
import me.huqiao.loganlyzer.enumtype.RelationType;
import me.huqiao.loganlyzer.orderby.OrderBy;
import me.huqiao.loganlyzer.querylanguage.LogQueryLanguageParserStateMachine;
import me.huqiao.loganlyzer.querylanguage.statemachine.AbstractNode;
import me.huqiao.loganlyzer.querylanguage.statemachine.StateMachine;
import me.huqiao.loganlyzer.querylanguage.statemachine.exception.FeedException;
import sun.misc.Compare;
import javax.management.relation.Relation;
import java.util.*;
import java.util.logging.Logger;
public class WhereNode extends AbstractNode<LogQueryLanguageParserStateMachine> {
static Logger log = Logger.getLogger(WhereNode.class.getName());
private RelationType relation;
private String prop;
private String compare;
private String pattern1;
private String pattern2;
//private Condition currentBag;
private Condition currentCondition;
/**
* 所有where条件和每一对括弧代表一个bagCondition
*/
private Stack<Condition> bagConditions = new Stack<Condition>();
private boolean isWordOverflow;
public WhereNode() {
super("where");
bagConditions.push(Conditions.and());//默认的全局condition
}
@Override
public void feed(String word, StateMachine<LogQueryLanguageParserStateMachine> stateMachine) throws FeedException {
if(word.equals("(")){
bagConditions.push(relation==RelationType.or ? Conditions.or() : Conditions.and());
relation = null;
}else if(word.equals(")")){
if(!bagConditions.isEmpty()){
//出栈,并且追加到前一个condition的child中
Condition condition = bagConditions.pop();
if(!bagConditions.isEmpty()){
if(condition.getRelationType()==RelationType.and) {
bagConditions.peek().and(condition);
}else{
bagConditions.peek().or(condition);
}
}
}else{
throw new FeedException("unexpected ')'");
}
}else if(isKeyWord(word)){
//where结束,word已经是下一个关键字了
endup(stateMachine);
isWordOverflow = true;
}else if(!getCurrentCondition().getChild().isEmpty() && relation == null){//非第一个条件,必须有relation
assertIsRelationWord(word);
relation = Enum.valueOf(RelationType.class,word);
}else if(prop == null){
assertNumber(word);
prop = word;
}else if(compare == null){
compare = word;
}else if(pattern1 == null && !compare.toLowerCase().equals("between")){
pattern1 = getInnerString(word);
makeCondition();
}else if(compare.toLowerCase().equals("between") && pattern2 == null){
pattern2 = getInnerString(word);
makeCondition();
}else{
}
}
private void assertIsRelationWord(String word) throws FeedException {
if(!word.toLowerCase().equals("and") && !word.toLowerCase().equals("or")){
throw new FeedException("Invalid value for comparision,expect for 'and' or 'or'");
}
}
private void makeCondition() throws FeedException {
CompareType compareType = compareTypeMap.get(compare);
System.out.println("get compare by :" + compare + ":" + compareType);
if(compareType == null){
throw new FeedException("not supported compare type:" +compare);
}
Condition condition = new Condition(prop,pattern1,compareType,pattern2);
if(relation == null || relation == RelationType.and){
getCurrentCondition().and(condition);
}else{
getCurrentCondition().or(condition);
}
log.info("make condition:" + condition);
clear();
}
private void clear(){
relation = null;
compare = null;
prop = null;
pattern1 = null;
pattern2 = null;
}
private boolean isClear(){
return relation == null &&
compare == null &&
prop == null &&
pattern1 == null &&
pattern2 == null;
}
@Override
public boolean isWordOverflow() {
return isWordOverflow;
}
/**
* 获取当前condition,即栈顶的记录
* @return
*/
public Condition getCurrentCondition(){
return bagConditions.peek();
}
public void endup(StateMachine<LogQueryLanguageParserStateMachine> stateMachine) throws FeedException{
//只有一种情况,
if(!isClear()){
throw new FeedException("uncompleted condition for where.");
}
stateMachine.get().getResult().setCondition(getCurrentCondition());
log.info("set CONDITION:" + getCurrentCondition());
saturated = true;
isWordOverflow = false;
}
static Map<String,CompareType> compareTypeMap = new HashMap<String, CompareType>();
static {
compareTypeMap.put(">=",CompareType.ge);
compareTypeMap.put("ge",CompareType.ge);
compareTypeMap.put("=",CompareType.eq);
compareTypeMap.put("eq",CompareType.eq);
compareTypeMap.put("!=",CompareType.ne);
compareTypeMap.put("ne",CompareType.ne);
compareTypeMap.put("<=",CompareType.le);
compareTypeMap.put("le",CompareType.le);
compareTypeMap.put("<",CompareType.lt);
compareTypeMap.put("lt",CompareType.lt);
compareTypeMap.put("between",CompareType.between);
compareTypeMap.put("contains",CompareType.contains);
compareTypeMap.put("like",CompareType.contains);
compareTypeMap.put("startwith",CompareType.startwith);
compareTypeMap.put("notcontains",CompareType.notcontains);
compareTypeMap.put("regex",CompareType.regex);
}
}