public Object visit(BBOX filter, Object notUsed) { if (filter instanceof BBOX3D && !fcs.supports(BBOX3D.class)) { postStack.push(filter); } else if (!fcs.supports(BBOX.class)) { postStack.push(filter); } else { preStack.push(filter); } return null; }
/** @see org.geotools.filter.FilterVisitor#visit(org.geotools.filter.FunctionExpression) */ public Object visit(Function expression, Object notUsed) { if (!fcs.supports(expression.getClass())) { postStack.push(expression); return null; } if (expression.getName() == null) { postStack.push(expression); return null; } int i = postStack.size(); int j = preStack.size(); for (int k = 0; k < expression.getParameters().size(); k++) { ((Expression) expression.getParameters().get(i)).accept(this, null); if (i < postStack.size()) { while (j < preStack.size()) preStack.pop(); postStack.pop(); postStack.push(expression); return null; } } while (j < preStack.size()) preStack.pop(); preStack.push(expression); return null; }
/** * @see FilterVisitor#visit(ExcludeFilter, Object) * @param filter the {@link Filter} to visit */ public void visit(ExcludeFilter filter) { if (fcs.supports(Filter.EXCLUDE)) { preStack.push(filter); } else { postStack.push(filter); } }
public Object visit(ExcludeFilter filter, Object notUsed) { if (fcs.supports(Filter.EXCLUDE)) { preStack.push(filter); } else { postStack.push(filter); } return null; }
public Object visit(Id filter, Object notUsed) { if (original == null) original = filter; if (!fcs.supports(filter)) { postStack.push(filter); } else { preStack.push(filter); } return null; }
private void visitMathExpression(BinaryExpression expression) { if (!fcs.supports(Add.class) && !fcs.supports(Subtract.class) && !fcs.supports(Multiply.class) && !fcs.supports(Divide.class)) { postStack.push(expression); return; } int i = postStack.size(); Expression leftValue = expression.getExpression1(); Expression rightValue = expression.getExpression2(); if (leftValue == null || rightValue == null) { postStack.push(expression); return; } leftValue.accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(expression); return; } rightValue.accept(this, null); if (i < postStack.size()) { preStack.pop(); // left postStack.pop(); postStack.push(expression); return; } preStack.pop(); // left side preStack.pop(); // right side preStack.push(expression); }
protected Object visit(BinaryTemporalOperator filter, Object data) { if (original == null) original = filter; // supports it as a group -- no need to check the type if (!fcs.supports(filter)) { postStack.push(filter); return null; } Expression leftValue = filter.getExpression1(); Expression rightValue = filter.getExpression2(); int i = postStack.size(); if (leftValue == null || rightValue == null) { postStack.push(filter); return null; } leftValue.accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(filter); return null; } rightValue.accept(this, null); if (i < postStack.size()) { preStack.pop(); // left postStack.pop(); postStack.push(filter); return null; } preStack.pop(); // left side preStack.pop(); // right side preStack.push(filter); return null; }
private void visitBinaryComparisonOperator(BinaryComparisonOperator filter) { if (original == null) original = filter; // supports it as a group -- no need to check the type if (!fcs.supports(FilterCapabilities.SIMPLE_COMPARISONS_OPENGIS)) { postStack.push(filter); return; } int i = postStack.size(); Expression leftValue = filter.getExpression1(); Expression rightValue = filter.getExpression2(); if (leftValue == null || rightValue == null) { postStack.push(filter); return; } leftValue.accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(filter); return; } rightValue.accept(this, null); if (i < postStack.size()) { preStack.pop(); // left postStack.pop(); postStack.push(filter); return; } preStack.pop(); // left side preStack.pop(); // right side preStack.push(filter); }
public Object visit(PropertyIsNull filter, Object notUsed) { if (original == null) original = filter; if (!fcs.supports(PropertyIsNull.class)) { postStack.push(filter); return null; } int i = postStack.size(); ((PropertyIsNull) filter).getExpression().accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(filter); } preStack.pop(); // null preStack.push(filter); return null; }
Object visitNullNil(Filter filter, Expression e) { if (original == null) original = filter; if (!fcs.supports(PropertyIsNull.class)) { postStack.push(filter); return null; } int i = postStack.size(); e.accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(filter); return null; } preStack.pop(); // null preStack.push(filter); return null; }
@Override protected FilterCapabilities createFilterCapabilities() { FilterCapabilities caps = new FilterCapabilities(); caps.addAll(SQLDialect.BASE_DBMS_CAPABILITIES); // adding the spatial filters support caps.addType(BBOX.class); caps.addType(Contains.class); caps.addType(Crosses.class); caps.addType(Disjoint.class); caps.addType(Equals.class); caps.addType(Intersects.class); caps.addType(Overlaps.class); caps.addType(Touches.class); caps.addType(Within.class); caps.addType(DWithin.class); caps.addType(Beyond.class); // temporal filters caps.addType(After.class); caps.addType(Before.class); caps.addType(Begins.class); caps.addType(BegunBy.class); caps.addType(During.class); caps.addType(TOverlaps.class); caps.addType(Ends.class); caps.addType(EndedBy.class); caps.addType(TEquals.class); return caps; }
private void visitLogicOperator(Filter filter) { if (original == null) original = filter; if (!fcs.supports(Not.class) && !fcs.supports(And.class) && !fcs.supports(Or.class)) { postStack.push(filter); return; } int i = postStack.size(); int j = preStack.size(); if (filter instanceof Not) { if (((Not) filter).getFilter() != null) { Filter next = ((Not) filter).getFilter(); next.accept(this, null); if (i < postStack.size()) { // since and can split filter into both pre and post parts // the parts have to be combined since ~(A^B) == ~A | ~B // combining is easy since filter==combined result however both post and pre stacks // must be cleared since both may have components of the filter popToSize(postStack, i); popToSize(preStack, j); postStack.push(filter); } else { popToSize(preStack, j); preStack.push(filter); } } } else { if (filter instanceof Or) { Filter orReplacement; try { orReplacement = translateOr((Or) filter); orReplacement.accept(this, null); } catch (IllegalFilterException e) { popToSize(preStack, j); postStack.push(filter); return; } if (postStack.size() > i) { popToSize(postStack, i); postStack.push(filter); return; } preStack.pop(); preStack.push(filter); } else { // it's an AND Iterator it = ((And) filter).getChildren().iterator(); while (it.hasNext()) { Filter next = (Filter) it.next(); next.accept(this, null); } // combine the unsupported and add to the top if (i < postStack.size()) { if (filter instanceof And) { Filter f = (Filter) postStack.pop(); while (postStack.size() > i) f = ff.and(f, (Filter) postStack.pop()); postStack.push(f); if (j < preStack.size()) { f = (Filter) preStack.pop(); while (preStack.size() > j) f = ff.and(f, (Filter) preStack.pop()); preStack.push(f); } } else { logger.warning("LogicFilter found which is not 'and, or, not"); popToSize(postStack, i); popToSize(preStack, j); postStack.push(filter); } } else { popToSize(preStack, j); preStack.push(filter); } } } }
private void visitBinarySpatialOperator(BinarySpatialOperator filter) { if (original == null) original = filter; Class[] spatialOps = new Class[] { Beyond.class, Contains.class, Crosses.class, Disjoint.class, DWithin.class, Equals.class, Intersects.class, Overlaps.class, Touches.class, Within.class }; for (int i = 0; i < spatialOps.length; i++) { if (spatialOps[i].isAssignableFrom(filter.getClass())) { if (!fcs.supports(spatialOps[i])) { postStack.push(filter); return; } else { // fcs supports this filter, no need to check the rest break; } } } // TODO check against tranasaction ? int i = postStack.size(); Expression leftGeometry, rightGeometry; leftGeometry = ((BinarySpatialOperator) filter).getExpression1(); rightGeometry = ((BinarySpatialOperator) filter).getExpression2(); if (leftGeometry == null || rightGeometry == null) { postStack.push(filter); return; } leftGeometry.accept(this, null); if (i < postStack.size()) { postStack.pop(); postStack.push(filter); return; } rightGeometry.accept(this, null); if (i < postStack.size()) { preStack.pop(); // left postStack.pop(); postStack.push(filter); return; } preStack.pop(); // left side preStack.pop(); // right side preStack.push(filter); }
/** * @see FilterVisitor#visit(PropertyIsBetween, Object) * <p>NOTE: This method is extra documented as an example of how all the other methods are * implemented. If you want to know how this class works read this method first! * @param filter the {@link Filter} to visit */ public Object visit(PropertyIsBetween filter, Object extradata) { if (original == null) original = filter; // Do we support this filter type at all? if (fcs.supports(PropertyIsBetween.class)) { // Yes, we do. Now, can we support the sub-filters? // first, remember how big the current list of "I can't support these" // filters is. int i = postStack.size(); Expression lowerBound = filter.getLowerBoundary(); Expression expr = filter.getExpression(); Expression upperBound = filter.getUpperBoundary(); if (lowerBound == null || upperBound == null || expr == null) { // Well, one of the boundaries is null, so I guess // we're saying that *no* datastore could support this. postStack.push(filter); return null; } // Ok, here's the magic. We know how big our list of "can't support" // filters is. Now we send off the lowerBound Expression to see if // it can be supported. lowerBound.accept(this, null); // Now we're back, and we check. Did the postStack get bigger? if (i < postStack.size()) { // Yes, it did. Well, that means we can't support // this particular filter. Let's back out anything that was // added by the lowerBound.accept() and add ourselves. postStack.pop(); // lowerBound.accept()'s bum filter postStack.push(filter); return null; } // Aha! The postStack didn't get any bigger, so we're still // all good. Now try again with the middle expression itself... expr.accept(this, null); // Did postStack get bigger? if (i < postStack.size()) { // Yes, it did. So that means we can't support // this particular filter. We need to back out what we've // done, which is BOTH the lowerbounds filter *and* the // thing that was added by expr.accept() when it failed. preStack.pop(); // lowerBound.accept()'s success postStack.pop(); // expr.accept()'s bum filter postStack.push(filter); return null; } // Same deal again... upperBound.accept(this, null); if (i < postStack.size()) { // post process it postStack.pop(); // upperBound.accept()'s bum filter preStack.pop(); // expr.accept()'s success preStack.pop(); // lowerBound.accept()'s success postStack.push(filter); return null; } // Well, by getting here it means that postStack didn't get // taller, even after accepting all three middle filters. This // means that this whole filter is totally pre-filterable. // Let's clean up the pre-stack (which got one added to it // for the success at each of the three above .accept() calls) // and add us to the stack. preStack.pop(); // upperBounds.accept()'s success preStack.pop(); // expr.accept()'s success preStack.pop(); // lowerBounds.accept()'s success // finally we add ourselves to the "can be pre-proccessed" filter // stack. Now when we return we've added exactly one thing to // the preStack...namely, the given filter. preStack.push(filter); } else { // No, we don't support this filter. // So we push it onto the postStack, saying // "Hey, here's one more filter that we don't support. // Someone who called us may look at this and say, // "Hmm, I called accept() on this filter and now // the postStack is taller than it was...I guess this // filter wasn't accepted. postStack.push(filter); } return null; }
/** * Sets the capabilities of this filter. * * @return FilterCapabilities for this Filter */ protected FilterCapabilities createFilterCapabilities() { capabilities = new FilterCapabilities(); capabilities.addAll(FilterCapabilities.LOGICAL_OPENGIS); capabilities.addAll(FilterCapabilities.SIMPLE_COMPARISONS_OPENGIS); capabilities.addType(FilterCapabilities.FID); capabilities.addType(FilterCapabilities.BETWEEN); capabilities.addType(FilterCapabilities.LIKE); capabilities.addType(FilterCapabilities.NULL_CHECK); capabilities.addType(FilterCapabilities.SPATIAL_BBOX); capabilities.addType(FilterCapabilities.SPATIAL_DISJOINT); capabilities.addType(FilterCapabilities.SPATIAL_WITHIN); capabilities.addType(FilterCapabilities.SPATIAL_INTERSECT); capabilities.addType(FilterCapabilities.SPATIAL_CONTAINS); // temporal filters capabilities.addType(After.class); capabilities.addType(Before.class); capabilities.addType(Begins.class); capabilities.addType(BegunBy.class); capabilities.addType(During.class); capabilities.addType(Ends.class); capabilities.addType(EndedBy.class); capabilities.addType(TContains.class); capabilities.addType(TEquals.class); return capabilities; }
/** * Sets the DB2 filter capabilities. * * @return FilterCapabilities for DB2 */ protected FilterCapabilities createFilterCapabilities() { FilterCapabilities caps = new FilterCapabilities(); caps.addAll(SQLDialect.BASE_DBMS_CAPABILITIES); // adding the spatial filters support caps.addType(BBOX.class); caps.addType(Contains.class); caps.addType(Crosses.class); caps.addType(Disjoint.class); caps.addType(Equals.class); caps.addType(Intersects.class); caps.addType(Overlaps.class); caps.addType(Touches.class); caps.addType(Within.class); caps.addType(DWithin.class); caps.addType(Beyond.class); // temporal filters caps.addType(After.class); caps.addType(Before.class); caps.addType(Begins.class); caps.addType(BegunBy.class); caps.addType(During.class); caps.addType(TOverlaps.class); caps.addType(Ends.class); caps.addType(EndedBy.class); caps.addType(TEquals.class); if (isFunctionEncodingEnabled()) { // add support for string functions caps.addType(FilterFunction_strConcat.class); caps.addType(FilterFunction_strEndsWith.class); caps.addType(FilterFunction_strStartsWith.class); caps.addType(FilterFunction_strEqualsIgnoreCase.class); caps.addType(FilterFunction_strIndexOf.class); caps.addType(FilterFunction_strLength.class); caps.addType(FilterFunction_strToLowerCase.class); caps.addType(FilterFunction_strToUpperCase.class); caps.addType(FilterFunction_strReplace.class); caps.addType(FilterFunction_strSubstring.class); caps.addType(FilterFunction_strSubstringStart.class); caps.addType(FilterFunction_strTrim.class); caps.addType(FilterFunction_strTrim2.class); // add support for math functions caps.addType(FilterFunction_abs.class); caps.addType(FilterFunction_abs_2.class); caps.addType(FilterFunction_abs_3.class); caps.addType(FilterFunction_abs_4.class); caps.addType(FilterFunction_ceil.class); caps.addType(FilterFunction_floor.class); } return caps; }