KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > tree > AbstractMatchingEngine


1 /*
2  * Created on 24-Jul-2005
3  *
4
5  */

6 package com.jofti.tree;
7
8
9
10 import java.util.Map JavaDoc;
11 import java.util.Stack JavaDoc;
12
13 import com.jofti.btree.ValueObject;
14 import com.jofti.core.INameSpaceAware;
15 import com.jofti.core.IParsedQuery;
16 import com.jofti.core.IPredicate;
17 import com.jofti.exception.JoftiException;
18 import com.jofti.parser.AttributeValueParser;
19 import com.jofti.parser.CommonLexerTokenTypes;
20 import com.jofti.parser.Operator;
21 import com.jofti.parser.StackPredicate;
22 import com.jofti.util.FastStack;
23 import com.jofti.util.ObjectProcedureAdapter;
24 import com.jofti.util.OpenHashMap;
25
26 /**
27  * @author Steve Woodcock
28  *
29  
30  */

31 public abstract class AbstractMatchingEngine implements MatchingEngine {
32
33
34     
35
36     // move these to be parser constants at some point
37
protected static final int OR = CommonLexerTokenTypes.OR;
38     protected static final int AND = CommonLexerTokenTypes.AND;
39     
40     
41     protected AttributeValueParser attributeValueParser = new AttributeValueParser();;
42     
43
44     
45     
46     
47     
48 protected Map JavaDoc addAllOpen(final OpenHashMap large, final OpenHashMap smaller){
49       // large.ensureCapacity(large.size()+smaller.size());
50
smaller.forEachPair( new ObjectProcedureAdapter(){
51             public boolean apply(Object JavaDoc key, Object JavaDoc value){
52                 if (!large.containsKey(key)){
53                     large.put(key, value);
54                 }
55                 return true;
56             }
57         });
58
59         return large;
60     }
61     
62     
63 protected Map JavaDoc retainAllOpen(final OpenHashMap large, final OpenHashMap smaller){
64         
65         smaller.forEachPair( new ObjectProcedureAdapter(){
66             public boolean apply(Object JavaDoc key, Object JavaDoc value){
67                 if (!large.containsKey(key)){
68                     smaller.remove(key);
69                 }
70                 return true;
71             }
72         });
73
74         return smaller;
75     }
76
77     protected Map JavaDoc andResults(Map JavaDoc map1, Map JavaDoc map2){
78         if (map1.size() > map2.size()){
79             return retainAllOpen((OpenHashMap)map1, (OpenHashMap)map2);
80         }else{
81             return retainAllOpen((OpenHashMap)map2, (OpenHashMap)map1);
82         }
83     }
84
85     
86     protected Map JavaDoc orResults(Map JavaDoc map1, Map JavaDoc map2){
87             if (map1.size() > map2.size()){
88                 return addAllOpen((OpenHashMap)map1, (OpenHashMap)map2);
89             }else{
90                 return addAllOpen((OpenHashMap)map2, (OpenHashMap)map1);
91             }
92         }
93         
94     // we use a hash join here as we assume the results all fit into main memory
95
protected Map JavaDoc resultJunction(Map JavaDoc map1, Operator op, Map JavaDoc map2){
96             
97         
98                 switch (op.getOperator()) {
99                     case OR:
100                         if (map1.size() ==0) {
101                             return map2;
102                         }else if (map2.size() ==0){
103                             return map1;
104                         }
105                         return orResults(map1,map2);
106                     case AND:
107                         if ((map1.size() ==0 || map2.size() ==0)){
108                             return new OpenHashMap(1);
109                         }
110                         return andResults(map1,map2);
111                     default:
112                         return new OpenHashMap(1);
113                 }
114             
115         }
116         
117         
118         protected Map JavaDoc processPredicates(Stack JavaDoc predicates, Class JavaDoc className, Object JavaDoc nameSpace, Map JavaDoc aliasMap,TreeIndex index, Map JavaDoc namedParameters) throws JoftiException{
119             
120             Map JavaDoc firstResults = null;
121             Map JavaDoc returnResults =null;
122             IPredicate first =null;
123             
124              FastStack predicateStack = null;
125              if (predicates.size() == 1){
126                 first = (IPredicate)predicates.peek();
127              }
128              else{
129                 predicateStack = new FastStack();
130                  predicateStack.addAll(predicates);
131                  first = (IPredicate)predicateStack.pop();
132              }
133             
134   
135             
136             if (first.getType() ==1){
137                 firstResults = processPredicates(((StackPredicate)first).getPredicateStack(), className, nameSpace, aliasMap,index, namedParameters);
138             }else{
139                 firstResults = runPredicate(first, className, nameSpace,aliasMap,index, namedParameters);
140             }
141             
142         
143             if (predicateStack == null || predicateStack.size() ==0){
144                 returnResults = firstResults;
145             }else if (predicateStack.size() %2 == 0 && predicateStack.size() != 0){
146                 returnResults = processRemainder(firstResults, predicateStack, className, nameSpace,aliasMap, index, namedParameters);
147             }else if (predicateStack.size() %2 == 1){
148                 throw new JoftiException("we seem to have a hanging operator or predicate " );
149             }
150                 // we do not care
151
return returnResults;
152             
153         
154         }
155         
156         protected Map JavaDoc processQuery(IParsedQuery query,TreeIndex index) throws JoftiException{
157             
158     
159             // then get the predicates
160

161             Stack JavaDoc predicates = query.getPredicates();
162             
163             Object JavaDoc nameSpace = null;
164             if (((INameSpaceAware)query).getNameSpace() != null){
165                 nameSpace =((INameSpaceAware)query).getNameSpace();
166             }
167             // wif stack is empty then we need to do a range query for the whole entry
168

169              if (predicates.isEmpty()){
170                 
171                 // we need to get all results for the index and then merge them together as ors
172
// return processNoPredicates(query.getResultFieldsMap(), nameSpace, index);
173
throw new JoftiException("At least one predicate in where clause is required in Query");
174               }
175             // first one should always be a predicate
176
Map JavaDoc results = processPredicates(predicates, query.getClassName(), nameSpace,query.getAliasMap(),index, query.getNamedValueMap());
177             
178             
179             return results;
180         }
181         
182         
183
184         
185         protected Map JavaDoc processRemainder(Map JavaDoc results, FastStack predicates, Class JavaDoc className,Object JavaDoc nameSpace, Map JavaDoc aliasMap,TreeIndex index, Map JavaDoc namedParameters ) throws JoftiException{
186             while (predicates.size() %2 == 0 && predicates.size() != 0){
187                 Operator op= (Operator)predicates.pop();
188                  IPredicate second= (IPredicate) predicates.pop();
189                  Map JavaDoc secondResults =null;
190                 if (second.getType() ==1){
191                     secondResults = processPredicates(((StackPredicate)second).getPredicateStack(), className, nameSpace, aliasMap,index,namedParameters);
192                 }else{
193                     secondResults = runPredicate(second, className, nameSpace,aliasMap,index, namedParameters);
194                 }
195                 results = resultJunction(results, op, secondResults);
196             }
197             return results;
198         }
199         
200         protected Map JavaDoc runPredicate(IPredicate pred, Class JavaDoc className, Object JavaDoc nameSpace, Map JavaDoc aliasMap,TreeIndex index, Map JavaDoc namedParameters) throws JoftiException{
201             Class JavaDoc name =null;
202             Object JavaDoc tempAlias =null;
203             if (pred.getAlias() != null){
204                 tempAlias =name = (Class JavaDoc)aliasMap.get(pred.getAlias());
205             }else{
206                 name = className;
207             }
208             String JavaDoc attribute =null;
209             if (!(AttributeValueParser.VALUE.equalsIgnoreCase(pred.getField())) &&
210                     (!index.getIntrospector().getPrimitiveClasses().contains(name.toString()))){
211                 attribute = pred.getField();
212             }
213             
214
215             try {
216                 
217                 return performQuery(pred.getOperator(), name, nameSpace, attribute, pred.getValue(), index, namedParameters, tempAlias);
218             } catch (Throwable JavaDoc t){
219                 if (t instanceof JoftiException){
220                     throw (JoftiException)t;
221                 }else{
222                     throw new JoftiException(t);
223                 }
224             }
225         }
226
227         // wraps null value
228
protected Comparable JavaDoc wrapNull(Comparable JavaDoc value){
229             if (value == null){
230                 return ValueObject.MIN_COMAPARBLE_VALUE;
231             }
232             return value;
233         }
234
235         /**
236          * @param pred
237          * @param index
238          * @param name
239          * @param attribute
240          * @return
241          * @throws JoftiException
242          */

243         
244     
245         
246         // construct a value from the supplied parameter map
247

248         
249         
250     
251         
252     
253         
254      
255         
256         protected void testNull(Object JavaDoc obj) throws JoftiException{
257             if (obj == null){
258                 throw new JoftiException("value null not permitted in query");
259             }
260         }
261         protected abstract Map JavaDoc performQuery(int operator, Class JavaDoc className, Object JavaDoc nameSpace,String JavaDoc attribute, Object JavaDoc value, TreeIndex index, Map JavaDoc namedParameters, Object JavaDoc alias) throws JoftiException;
262
263 }
264
Popular Tags