1 6 package com.jofti.tree; 7 8 9 10 import java.util.Map ; 11 import java.util.Stack ; 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 31 public abstract class AbstractMatchingEngine implements MatchingEngine { 32 33 34 35 36 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 addAllOpen(final OpenHashMap large, final OpenHashMap smaller){ 49 smaller.forEachPair( new ObjectProcedureAdapter(){ 51 public boolean apply(Object key, Object 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 retainAllOpen(final OpenHashMap large, final OpenHashMap smaller){ 64 65 smaller.forEachPair( new ObjectProcedureAdapter(){ 66 public boolean apply(Object key, Object 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 andResults(Map map1, Map 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 orResults(Map map1, Map 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 protected Map resultJunction(Map map1, Operator op, Map 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 processPredicates(Stack predicates, Class className, Object nameSpace, Map aliasMap,TreeIndex index, Map namedParameters) throws JoftiException{ 119 120 Map firstResults = null; 121 Map 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 return returnResults; 152 153 154 } 155 156 protected Map processQuery(IParsedQuery query,TreeIndex index) throws JoftiException{ 157 158 159 161 Stack predicates = query.getPredicates(); 162 163 Object nameSpace = null; 164 if (((INameSpaceAware)query).getNameSpace() != null){ 165 nameSpace =((INameSpaceAware)query).getNameSpace(); 166 } 167 169 if (predicates.isEmpty()){ 170 171 throw new JoftiException("At least one predicate in where clause is required in Query"); 174 } 175 Map results = processPredicates(predicates, query.getClassName(), nameSpace,query.getAliasMap(),index, query.getNamedValueMap()); 177 178 179 return results; 180 } 181 182 183 184 185 protected Map processRemainder(Map results, FastStack predicates, Class className,Object nameSpace, Map aliasMap,TreeIndex index, Map 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 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 runPredicate(IPredicate pred, Class className, Object nameSpace, Map aliasMap,TreeIndex index, Map namedParameters) throws JoftiException{ 201 Class name =null; 202 Object tempAlias =null; 203 if (pred.getAlias() != null){ 204 tempAlias =name = (Class )aliasMap.get(pred.getAlias()); 205 }else{ 206 name = className; 207 } 208 String 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 t){ 219 if (t instanceof JoftiException){ 220 throw (JoftiException)t; 221 }else{ 222 throw new JoftiException(t); 223 } 224 } 225 } 226 227 protected Comparable wrapNull(Comparable value){ 229 if (value == null){ 230 return ValueObject.MIN_COMAPARBLE_VALUE; 231 } 232 return value; 233 } 234 235 243 244 245 246 248 249 250 251 252 253 254 255 256 protected void testNull(Object obj) throws JoftiException{ 257 if (obj == null){ 258 throw new JoftiException("value null not permitted in query"); 259 } 260 } 261 protected abstract Map performQuery(int operator, Class className, Object nameSpace,String attribute, Object value, TreeIndex index, Map namedParameters, Object alias) throws JoftiException; 262 263 } 264 | Popular Tags |