001: package com.jofti.tree;
002:
003: import java.util.Collection;
004: import java.util.Iterator;
005: import java.util.LinkedHashMap;
006: import java.util.Map;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010:
011: import com.jofti.btree.BTOperations;
012: import com.jofti.cache.adapter.NameSpaceWrapper;
013: import com.jofti.exception.JoftiException;
014: import com.jofti.exception.PropertyNotIndexedException;
015: import com.jofti.manager.IndexManagerImpl;
016: import com.jofti.parser.CommonLexerTokenTypes;
017: import com.jofti.parser.sql.SQLQueryParserTokenTypes;
018: import com.jofti.query.namespace.MatchNSInQuery;
019: import com.jofti.query.namespace.MatchNSLargerQuery;
020: import com.jofti.query.namespace.MatchNSNotQuery;
021: import com.jofti.query.namespace.MatchNSQuery;
022: import com.jofti.query.namespace.MatchNSRangeQuery;
023: import com.jofti.query.namespace.MatchNSSmallerQuery;
024: import com.jofti.util.OpenHashMap;
025:
026: /**
027: * @author Steve Woodcock (steve@jofti.com)
028: *
029:
030: */
031: public class NameSpacedTreeMatcherEngine extends AbstractMatchingEngine {
032:
033: private static Log log = LogFactory.getLog(IndexManagerImpl.class);
034:
035: /* (non-Javadoc)
036: * @see com.jofti.engine.IQueryEngine#query(com.jofti.api.IndexQuery)
037: */
038:
039: protected Map constructReturnMap(Collection col) {
040: LinkedHashMap map = new LinkedHashMap(col.size());
041: int size = col.size();
042: Iterator it = col.iterator();
043: for (int i = 0; i < size; i++) {
044:
045: map.put(it.next(), null);
046: }
047: return map;
048: }
049:
050: protected Map matchNameSpace(MatchNSQuery query, TreeIndex index)
051: throws JoftiException {
052:
053: // we need to find the dimension from the name here
054: int dimension = index.introspector
055: .getKeyDimension(NameSpaceWrapper.class);
056: return BTOperations.match(index.tree, (Comparable) query
057: .getNameSpaceWrapper(), dimension, query.alias);
058:
059: }
060:
061: protected Map matchProperty(MatchNSQuery query, TreeIndex index)
062: throws JoftiException {
063:
064: // we need to find the dimension from the name here
065:
066: int dimension = 0;
067: try {
068: if (query.getPropertyName() == null) {
069: dimension = index.introspector.getDimension(query
070: .getValue().getClass().getName(), null);
071: } else {
072: dimension = index.introspector.getDimension(query
073: .getClassName(), query.getPropertyName());
074: }
075: } catch (PropertyNotIndexedException e) {
076: //no property match found
077: return new OpenHashMap(1);
078: } catch (JoftiException e) {
079: throw e;
080: }
081:
082: //log.info("Looking for property " + propertyName + " with index " + dimension);
083: return BTOperations.match(index.tree,
084: wrapNull(query.getValue()), dimension, query.alias);
085:
086: }
087:
088: protected Map matchIsProperty(MatchNSQuery query, TreeIndex index)
089: throws JoftiException {
090:
091: // we need to find the dimension from the name here
092:
093: int dimension = 0;
094: try {
095: if (query.getPropertyName() == null) {
096:
097: dimension = index.introspector.getDimension(query
098: .getClassName(), null);
099: } else {
100: dimension = index.introspector.getDimension(query
101: .getClassName(), query.getPropertyName());
102: }
103: } catch (PropertyNotIndexedException e) {
104: //no property match found
105: return new OpenHashMap(1);
106: } catch (JoftiException e) {
107: throw e;
108: }
109:
110: //log.info("Looking for property " + propertyName + " with index " + dimension);
111: return BTOperations.match(index.tree, wrapNull(null),
112: dimension, query.alias);
113:
114: }
115:
116: protected Map matchProperty(MatchNSInQuery query, TreeIndex index)
117: throws JoftiException {
118:
119: // we need to find the dimension from the name here
120:
121: int dimension = 0;
122: try {
123: if (query.getValues() == null
124: || query.getValues()[0] == null) {
125: return new OpenHashMap(1);
126: }
127: if (query.getPropertyName() == null) {
128:
129: dimension = index.introspector.getDimension(query
130: .getValues()[0].getClass(), null);
131: } else {
132: dimension = index.introspector.getDimension(query
133: .getClassName(), query.getPropertyName());
134: }
135: } catch (PropertyNotIndexedException e) {
136: //no property match found
137: return new OpenHashMap(1);
138: } catch (JoftiException e) {
139: throw e;
140: }
141:
142: return BTOperations.match(index.tree, query.getValues(),
143: dimension, query.alias);
144: //log.info("Looking for property " + propertyName + " with index " + dimension);
145:
146: }
147:
148: /**
149: * @param cache
150: * @param col
151: * @return
152: * @throws JoftiException
153: */
154:
155: protected Map matchPropertyRange(MatchNSRangeQuery query,
156: TreeIndex index) throws JoftiException {
157:
158: // we need to find the dimension from the name here
159: // we need to find the dimension from the name here
160: if (query.getStartValue() != null
161: && query.getEndValue() != null) {
162: if (!((query.getStartValue().getClass().equals(query
163: .getEndValue().getClass())))) {
164: throw new JoftiException(
165: "Classes for property range query must be the same. start:"
166: + query.getStartValue().getClass()
167: + " end:"
168: + query.getEndValue().getClass());
169: }
170: if (query.getStartValue().compareTo(query.getEndValue()) > 0) {
171: if (log.isDebugEnabled()) {
172: log.info("Range search: start range "
173: + query.getStartValue()
174: + " is greater then end range "
175: + query.getEndValue()
176: + " returning empty results");
177: }
178: return new OpenHashMap(1);
179: }
180: }
181: int dimension = 0;
182: Class className = null;
183: try {
184:
185: if (query.getClassName() == null) {
186: if (query.getStartValue() != null) {
187: className = query.getStartValue().getClass();
188: } else if (query.getEndValue() != null) {
189: className = query.getEndValue().getClass();
190: }
191: } else {
192: className = query.getClassName();
193: }
194: dimension = index.introspector.getDimension(className,
195: query.getPropertyName());
196: } catch (PropertyNotIndexedException e) {
197: //no property match found
198: return new OpenHashMap(1);
199: } catch (JoftiException e) {
200: throw e;
201: }
202:
203: //we need to change this to do the checks on nameSpace
204: return BTOperations.range(index.tree, query.getStartValue(),
205: query.getEndValue(), dimension, query.isInclusive(),
206: query.alias);
207:
208: }
209:
210: /* (non-Javadoc)
211: * @see com.jofti.tree.AbstractMatchingEngine#performQuery(int, java.lang.String, java.lang.String, java.lang.Comparable, com.jofti.tree.TreeIndex)
212: */
213: protected Map performQuery(int operator, Class className,
214: Object nameSpace, String attribute, Object value,
215: TreeIndex index, Map namedParameters, Object alias)
216: throws JoftiException {
217: Map temp = null;
218: switch (operator) {
219:
220: case SQLQueryParserTokenTypes.ASSIGNEQUAL:
221: Comparable comp = attributeValueParser.constructValue(
222: (String) value, index.introspector, className,
223: attribute, namedParameters);
224: temp = matchProperty(new MatchNSQuery(className, nameSpace,
225: attribute, comp, alias), index);
226: break;
227: case SQLQueryParserTokenTypes.IS:
228: comp = attributeValueParser.constructForIsNot(
229: (String) value, namedParameters);
230: temp = matchIsProperty(new MatchNSQuery(className,
231: nameSpace, attribute, comp, alias), index);
232: break;
233: case SQLQueryParserTokenTypes.GREATERTHAN:
234: ;
235: comp = attributeValueParser.constructValue((String) value,
236: index.introspector, className, attribute,
237: namedParameters);
238: temp = matchPropertyRange(new MatchNSLargerQuery(className,
239: nameSpace, attribute, comp, false, alias), index);
240: break;
241: case SQLQueryParserTokenTypes.GREATERTHANOREQUALTO1:
242: ;
243: case SQLQueryParserTokenTypes.GREATERTHANOREQUALTO2:
244: comp = attributeValueParser.constructValue((String) value,
245: index.introspector, className, attribute,
246: namedParameters);
247: temp = matchPropertyRange(new MatchNSLargerQuery(className,
248: nameSpace, attribute, comp, alias), index);
249: break;
250: case SQLQueryParserTokenTypes.LESSTHANOREQUALTO1:
251: ;
252: case SQLQueryParserTokenTypes.LESSTHANOREQUALTO2:
253: ;
254: comp = attributeValueParser.constructValue((String) value,
255: index.introspector, className, attribute,
256: namedParameters);
257: temp = matchPropertyRange(new MatchNSSmallerQuery(
258: className, nameSpace, attribute, comp, alias),
259: index);
260: break;
261: case SQLQueryParserTokenTypes.LESSTHAN:
262: comp = attributeValueParser.constructValue((String) value,
263: index.introspector, className, attribute,
264: namedParameters);
265: temp = matchPropertyRange(
266: new MatchNSSmallerQuery(className, nameSpace,
267: attribute, comp, false, alias), index);
268: break;
269: case SQLQueryParserTokenTypes.NOTEQUAL1:
270: ;
271: case SQLQueryParserTokenTypes.NOTEQUAL2:
272: comp = attributeValueParser.constructValue((String) value,
273: index.introspector, className, attribute,
274: namedParameters);
275: temp = matchNotProperty(new MatchNSNotQuery(className,
276: nameSpace, attribute, comp, alias), index);
277: break;
278: case SQLQueryParserTokenTypes.NOT:
279: comp = attributeValueParser.constructForIsNot(
280: (String) value, namedParameters);
281: temp = matchNotProperty(new MatchNSNotQuery(className,
282: nameSpace, attribute, comp, alias), index);
283: break;
284: case SQLQueryParserTokenTypes.LIKE:
285: Comparable[] tempVals = attributeValueParser.processVals(
286: (String) value, namedParameters);
287: temp = matchPropertyRange(new MatchNSRangeQuery(className,
288: nameSpace, attribute, tempVals[0], tempVals[1],
289: alias), index);
290: break;
291: case CommonLexerTokenTypes.IN:
292: tempVals = attributeValueParser.constructArrayValue(value,
293: index.introspector, className, attribute,
294: namedParameters);
295: temp = matchProperty(new MatchNSInQuery(className,
296: nameSpace, attribute, tempVals, alias), index);
297: break;
298: default:
299: break;
300: }
301: return temp;
302: }
303:
304: protected Map matchNotProperty(MatchNSNotQuery query,
305: TreeIndex index) throws JoftiException {
306:
307: // we need to find the dimension from the name here
308:
309: int dimension = 0;
310: try {
311: if (query.getPropertyName() == null) {
312: dimension = index.introspector.getDimension(query
313: .getClassName(), null);
314: } else {
315: dimension = index.introspector.getDimension(query
316: .getClassName(), query.getPropertyName());
317: }
318: } catch (PropertyNotIndexedException e) {
319: //no property match found
320: return new OpenHashMap(1);
321: } catch (JoftiException e) {
322: throw e;
323: }
324:
325: return BTOperations.notEqual(index.tree, wrapNull(query
326: .getValue()), dimension, query.alias);
327:
328: }
329:
330: }
|