1 | /* |
2 | * Copyright (c) 2005-2012, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. |
3 | * |
4 | * WSO2 Inc. licenses this file to you under the Apache License, |
5 | * Version 2.0 (the "License"); you may not use this file except |
6 | * in compliance with the License. |
7 | * You may obtain a copy of the License at |
8 | * |
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, |
12 | * software distributed under the License is distributed on an |
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | * KIND, either express or implied. See the License for the |
15 | * specific language governing permissions and limitations |
16 | * under the License. |
17 | */ |
18 | package org.wso2.siddhi.core.util.parser; |
19 | |
20 | import org.wso2.siddhi.core.statemachine.pattern.AndPatternState; |
21 | import org.wso2.siddhi.core.statemachine.pattern.CountPatternState; |
22 | import org.wso2.siddhi.core.statemachine.pattern.LogicPatternState; |
23 | import org.wso2.siddhi.core.statemachine.pattern.OrPatternState; |
24 | import org.wso2.siddhi.core.statemachine.pattern.PatternState; |
25 | import org.wso2.siddhi.core.statemachine.sequence.CountSequenceState; |
26 | import org.wso2.siddhi.core.statemachine.sequence.OrSequenceState; |
27 | import org.wso2.siddhi.core.statemachine.sequence.SequenceState; |
28 | import org.wso2.siddhi.core.util.statemachine.AndState; |
29 | import org.wso2.siddhi.core.util.statemachine.CountState; |
30 | import org.wso2.siddhi.core.util.statemachine.LogicState; |
31 | import org.wso2.siddhi.core.util.statemachine.OrState; |
32 | import org.wso2.siddhi.core.util.statemachine.State; |
33 | import org.wso2.siddhi.core.util.statemachine.StateNumber; |
34 | import org.wso2.siddhi.query.api.stream.SingleStream; |
35 | import org.wso2.siddhi.query.api.stream.pattern.PatternStream; |
36 | import org.wso2.siddhi.query.api.stream.pattern.element.CountElement; |
37 | import org.wso2.siddhi.query.api.stream.pattern.element.FollowedByElement; |
38 | import org.wso2.siddhi.query.api.stream.pattern.element.LogicalElement; |
39 | import org.wso2.siddhi.query.api.stream.pattern.element.PatternElement; |
40 | import org.wso2.siddhi.query.api.stream.sequence.element.NextElement; |
41 | import org.wso2.siddhi.query.api.stream.sequence.element.OrElement; |
42 | import org.wso2.siddhi.query.api.stream.sequence.element.RegexElement; |
43 | import org.wso2.siddhi.query.api.stream.sequence.element.SequenceElement; |
44 | |
45 | import java.util.ArrayList; |
46 | import java.util.List; |
47 | |
48 | public class StateParser { |
49 | |
50 | //Pattern |
51 | |
52 | public static List<PatternState> convertToPatternStateList(List<State> stateList) { |
53 | List<PatternState> patternStateList = new ArrayList<PatternState>(stateList.size()); |
54 | for (int i = 0, stateListSize = stateList.size(); i < stateListSize; i++) { |
55 | State state = stateList.get(i); |
56 | PatternState patternState; |
57 | if (state instanceof AndState) { |
58 | patternState = (new AndPatternState(state.getStateNumber(), state.getSingleStream())); |
59 | } else if (state instanceof OrState) { |
60 | patternState = (new OrPatternState(state.getStateNumber(), state.getSingleStream())); |
61 | } else if (state instanceof CountState) { |
62 | patternState = (new CountPatternState(state.getStateNumber(), state.getSingleStream(), ((CountState) state).getMin(), ((CountState) state).getMax())); |
63 | } else { |
64 | patternState = (new PatternState(state.getStateNumber(), state.getSingleStream())); |
65 | } |
66 | patternState.setStateNumber(i); |
67 | patternState.setFirst(state.isFirst()); |
68 | patternState.setLast(state.isLast()); |
69 | patternStateList.add(patternState); |
70 | } |
71 | for (int i = 0, stateListSize = stateList.size(); i < stateListSize; i++) { |
72 | State state = stateList.get(i); |
73 | PatternState patternState = patternStateList.get(i); |
74 | if (state.getNext() != -1) { |
75 | patternState.setNextState(patternStateList.get(state.getNext())); |
76 | } |
77 | if (state.getNextEvery() != -1) { |
78 | patternState.setNextEveryState(patternStateList.get(state.getNextEvery())); |
79 | } |
80 | if (state instanceof LogicState) { |
81 | ((LogicPatternState) patternStateList.get(i)).setPartnerState(patternStateList.get(((LogicState) state).getPartnerNumber())); |
82 | } |
83 | } |
84 | return patternStateList; |
85 | } |
86 | |
87 | |
88 | public static List<State> identifyStates(PatternElement patternElement) { |
89 | List<State> stateList = identifyStates(patternElement, new ArrayList<State>(), new StateNumber(0), new ArrayList<Integer>(), true); |
90 | //setting first state |
91 | State firstState = stateList.get(0); |
92 | firstState.setFirst(true); |
93 | if (firstState instanceof LogicState) { |
94 | stateList.get(((LogicState) firstState).getPartnerNumber()).setFirst(true); |
95 | } |
96 | //setting last state |
97 | State lastState = stateList.get(stateList.size() - 1); |
98 | lastState.setLast(true); |
99 | if (lastState instanceof LogicState) { |
100 | stateList.get(((LogicState) lastState).getPartnerNumber()).setLast(true); |
101 | } |
102 | |
103 | |
104 | return stateList; |
105 | } |
106 | |
107 | |
108 | private static List<State> identifyStates(PatternElement patternElement, List<State> stateList, |
109 | StateNumber stateNumber, List<Integer> perv, |
110 | boolean topLevel) { |
111 | |
112 | if (patternElement instanceof SingleStream) { |
113 | stateList.add(new State(stateNumber.getNumber(), ((SingleStream) patternElement))); |
114 | addStateAsNext(stateList, stateNumber, perv); |
115 | stateNumber.increment(); |
116 | perv.clear(); |
117 | perv.add(stateNumber.getNumber() - 1); |
118 | } else if (patternElement instanceof LogicalElement) { |
119 | if (((LogicalElement) patternElement).getType() == LogicalElement.Type.OR) { |
120 | stateList.add(new OrState(stateNumber.getNumber(), ((LogicalElement) patternElement).getSingleStream1(), stateNumber.getNumber() + 1)); |
121 | addStateAsNext(stateList, stateNumber, perv); |
122 | stateNumber.increment(); |
123 | stateList.add(new OrState(stateNumber.getNumber(), ((LogicalElement) patternElement).getSingleStream2(), stateNumber.getNumber() - 1)); |
124 | //addStateAsNext(stateList, stateNumber, perv); |
125 | stateNumber.increment(); |
126 | } else {//AND |
127 | stateList.add(new AndState(stateNumber.getNumber(), ((LogicalElement) patternElement).getSingleStream1(), stateNumber.getNumber() + 1)); |
128 | addStateAsNext(stateList, stateNumber, perv); |
129 | stateNumber.increment(); |
130 | stateList.add(new AndState(stateNumber.getNumber(), ((LogicalElement) patternElement).getSingleStream2(), stateNumber.getNumber() - 1)); |
131 | //addStateAsNext(stateList, stateNumber, perv); |
132 | stateNumber.increment(); |
133 | } |
134 | perv.clear(); |
135 | perv.add(stateNumber.getNumber() - 1); |
136 | perv.add(stateNumber.getNumber() - 2); |
137 | } else if (patternElement instanceof CountElement) { |
138 | stateList.add(new CountState(stateNumber.getNumber(), ((CountElement) patternElement).getSingleStream(), ((CountElement) patternElement).getMinCount(), ((CountElement) patternElement).getMaxCount())); |
139 | addStateAsNext(stateList, stateNumber, perv); |
140 | stateNumber.increment(); |
141 | perv.clear(); |
142 | perv.add(stateNumber.getNumber() - 1); |
143 | } else if (patternElement instanceof FollowedByElement) { |
144 | identifyStates(((FollowedByElement) patternElement).getPatternElement(), stateList, stateNumber, perv, topLevel); |
145 | identifyStates(((FollowedByElement) patternElement).getFollowedByPatternElement(), stateList, stateNumber, perv, topLevel); |
146 | } else if (patternElement instanceof PatternStream) { |
147 | int firstEveryStateNumber = stateNumber.getNumber(); |
148 | if (!topLevel) { |
149 | System.err.println("Every inside Every is not allowed !!"); |
150 | } |
151 | identifyStates(((PatternStream) patternElement).getPatternElement(), stateList, stateNumber, perv, false); |
152 | |
153 | State lastState = stateList.get(stateList.size() - 1); |
154 | State lastStatePartner = null; |
155 | if (lastState instanceof LogicState) { |
156 | lastStatePartner = stateList.get(((LogicState) lastState).getPartnerNumber()); |
157 | } |
158 | if (stateList.get(firstEveryStateNumber) instanceof LogicState) { |
159 | lastState.setNextEvery(firstEveryStateNumber); |
160 | // lastState.addNextEvery(firstEveryStateNumber + 1); |
161 | if (lastStatePartner != null) { |
162 | lastStatePartner.setNextEvery(firstEveryStateNumber); |
163 | // lastStatePartner.addNext(firstEveryStateNumber + 1); |
164 | } |
165 | } else { |
166 | lastState.setNextEvery(firstEveryStateNumber); |
167 | if (lastStatePartner != null) { |
168 | lastStatePartner.setNextEvery(firstEveryStateNumber); |
169 | } |
170 | } |
171 | } else { |
172 | System.err.println("Error! " + patternElement); |
173 | } |
174 | |
175 | return stateList; |
176 | } |
177 | |
178 | //Sequence |
179 | |
180 | public static List<SequenceState> convertToSequenceStateList(List<State> stateList) { |
181 | List<SequenceState> sequenceStateList = new ArrayList<SequenceState>(stateList.size()); |
182 | for (int i = 0, stateListSize = stateList.size(); i < stateListSize; i++) { |
183 | State state = stateList.get(i); |
184 | SequenceState sequenceState; |
185 | if (state instanceof OrState) { |
186 | sequenceState = (new OrSequenceState(state.getStateNumber(), state.getSingleStream())); |
187 | } else if (state instanceof CountState) { |
188 | sequenceState = (new CountSequenceState(state.getStateNumber(), state.getSingleStream(), ((CountState) state).getMin(), ((CountState) state).getMax())); |
189 | } else { |
190 | sequenceState = (new SequenceState(state.getStateNumber(), state.getSingleStream())); |
191 | } |
192 | sequenceState.setStateNumber(i); |
193 | sequenceState.setFirst(state.isFirst()); |
194 | sequenceState.setLast(state.isLast()); |
195 | sequenceStateList.add(sequenceState); |
196 | } |
197 | for (int i = 0, stateListSize = stateList.size(); i < stateListSize; i++) { |
198 | State state = stateList.get(i); |
199 | SequenceState sequenceState = sequenceStateList.get(i); |
200 | if (state.getNext() != -1) { |
201 | sequenceState.setNextState(sequenceStateList.get(state.getNext())); |
202 | } |
203 | |
204 | if (state instanceof OrState) { |
205 | ((OrSequenceState) sequenceStateList.get(i)).setPartnerState(sequenceStateList.get(((LogicState) state).getPartnerNumber())); |
206 | } |
207 | } |
208 | return sequenceStateList; |
209 | } |
210 | |
211 | |
212 | public static List<State> identifyStates(SequenceElement sequenceElement) { |
213 | List<State> stateList = identifyStates(sequenceElement, new ArrayList<State>(), new StateNumber(0), new ArrayList<Integer>()); |
214 | //setting first state |
215 | State firstState = stateList.get(0); |
216 | firstState.setFirst(true); |
217 | if (firstState instanceof LogicState) { |
218 | stateList.get(((LogicState) firstState).getPartnerNumber()).setFirst(true); |
219 | } |
220 | //setting last state |
221 | State lastState = stateList.get(stateList.size() - 1); |
222 | lastState.setLast(true); |
223 | if (lastState instanceof LogicState) { |
224 | stateList.get(((LogicState) lastState).getPartnerNumber()).setLast(true); |
225 | } |
226 | |
227 | |
228 | return stateList; |
229 | } |
230 | |
231 | |
232 | private static List<State> identifyStates(SequenceElement sequenceElement, |
233 | List<State> stateList, |
234 | StateNumber stateNumber, List<Integer> perv) { |
235 | |
236 | if (sequenceElement instanceof SingleStream) { |
237 | stateList.add(new State(stateNumber.getNumber(), ((SingleStream) sequenceElement))); |
238 | addStateAsNext(stateList, stateNumber, perv); |
239 | stateNumber.increment(); |
240 | perv.clear(); |
241 | perv.add(stateNumber.getNumber() - 1); |
242 | } else if (sequenceElement instanceof OrElement) { |
243 | stateList.add(new OrState(stateNumber.getNumber(), ((OrElement) sequenceElement).getSingleStream1(), stateNumber.getNumber() + 1)); |
244 | addStateAsNext(stateList, stateNumber, perv); |
245 | stateNumber.increment(); |
246 | stateList.add(new OrState(stateNumber.getNumber(), ((OrElement) sequenceElement).getSingleStream2(), stateNumber.getNumber() - 1)); |
247 | //addStateAsNext(stateList, stateNumber, perv); |
248 | stateNumber.increment(); |
249 | |
250 | perv.clear(); |
251 | perv.add(stateNumber.getNumber() - 1); |
252 | perv.add(stateNumber.getNumber() - 2); |
253 | } else if (sequenceElement instanceof RegexElement) { |
254 | stateList.add(new CountState(stateNumber.getNumber(), ((RegexElement) sequenceElement).getSingleStream(), ((RegexElement) sequenceElement).getMinCount(), ((RegexElement) sequenceElement).getMaxCount())); |
255 | addStateAsNext(stateList, stateNumber, perv); |
256 | stateNumber.increment(); |
257 | perv.clear(); |
258 | perv.add(stateNumber.getNumber() - 1); |
259 | } else if (sequenceElement instanceof NextElement) { |
260 | identifyStates(((NextElement) sequenceElement).getSequenceElement(), stateList, stateNumber, perv); |
261 | identifyStates(((NextElement) sequenceElement).getNextSequenceElement(), stateList, stateNumber, perv); |
262 | } else { |
263 | System.err.println("Error! " + sequenceElement); |
264 | } |
265 | |
266 | return stateList; |
267 | } |
268 | |
269 | //General |
270 | |
271 | private static void addStateAsNext(List<State> stateList, StateNumber stateNumber, |
272 | List<Integer> perv) { |
273 | for (int prevState : perv) { |
274 | stateList.get(prevState).setNext(stateNumber.getNumber()); |
275 | } |
276 | } |
277 | } |