一、前言
关于geotools的源码包gt-cql-2.6.5.jar中的org.geotools.filter.text.commons.CompilerUtil、org.geotools.filter.text.commons.ICompiler编译器接口及实现类等相关,进行获取解析过滤器parseFilter、parseExpression匹配表达式等,详情参见源码说明。
二、源码说明
1.ICompiler接口及实现类ECQLCompiler、Language枚举类
package org.geotools.filter.text.commons;@b@@b@import java.util.List;@b@import org.geotools.filter.text.cql2.CQLException;@b@import org.opengis.filter.Filter;@b@import org.opengis.filter.expression.Expression;@b@@b@public abstract interface ICompiler@b@{@b@ public abstract String getSource();@b@@b@ public abstract void compileFilter()@b@ throws CQLException;@b@@b@ public abstract Filter getFilter()@b@ throws CQLException;@b@@b@ public abstract void compileExpression()@b@ throws CQLException;@b@@b@ public abstract Expression getExpression()@b@ throws CQLException;@b@@b@ public abstract void compileFilterList()@b@ throws CQLException;@b@@b@ public abstract List<Filter> getFilterList()@b@ throws CQLException;@b@@b@ public abstract IToken getTokenInPosition(int paramInt);@b@}package org.geotools.filter.text.ecql;@b@@b@import java.io.StringReader;@b@import java.util.List;@b@import org.geotools.filter.IllegalFilterException;@b@import org.geotools.filter.text.commons.ICompiler;@b@import org.geotools.filter.text.commons.IToken;@b@import org.geotools.filter.text.commons.Result;@b@import org.geotools.filter.text.commons.TokenAdapter;@b@import org.geotools.filter.text.cql2.CQLException;@b@import org.geotools.filter.text.generated.parsers.ECQLParser;@b@import org.geotools.filter.text.generated.parsers.Node;@b@import org.geotools.filter.text.generated.parsers.ParseException;@b@import org.geotools.filter.text.generated.parsers.TokenMgrError;@b@import org.opengis.filter.BinaryComparisonOperator;@b@import org.opengis.filter.Filter;@b@import org.opengis.filter.FilterFactory;@b@import org.opengis.filter.Id;@b@import org.opengis.filter.Not;@b@import org.opengis.filter.Or;@b@import org.opengis.filter.expression.BinaryExpression;@b@import org.opengis.filter.expression.Expression;@b@import org.opengis.filter.spatial.BBOX;@b@import org.opengis.filter.spatial.BinarySpatialOperator;@b@import org.opengis.filter.spatial.DistanceBufferOperator;@b@@b@public class ECQLCompiler extends ECQLParser@b@ implements ICompiler@b@{@b@ private static final String ATTRIBUTE_PATH_SEPARATOR = "/";@b@ private final String source;@b@ private final ECQLFilterBuilder builder;@b@@b@ public ECQLCompiler(String txtSource, FilterFactory filterFactory)@b@ {@b@ super(new StringReader(txtSource));@b@@b@ if ((!($assertionsDisabled)) && (txtSource == null)) throw new AssertionError("txtSource cannot be null");@b@ if ((!($assertionsDisabled)) && (filterFactory == null)) throw new AssertionError("filterFactory cannot be null");@b@@b@ this.source = txtSource;@b@ this.builder = new ECQLFilterBuilder(txtSource, filterFactory);@b@ }@b@@b@ public void compileFilter()@b@ throws CQLException@b@ {@b@ try@b@ {@b@ super.FilterCompilationUnit();@b@ } catch (TokenMgrError tokenError) {@b@ throw new CQLException(tokenError.getMessage(), getTokenInPosition(0), this.source);@b@ } catch (CQLException e) {@b@ throw e;@b@ }@b@ catch (ParseException e) {@b@ throw new CQLException(e.getMessage(), getTokenInPosition(0), e.getCause(), this.source);@b@ }@b@ }@b@@b@ public void compileExpression()@b@ throws CQLException@b@ {@b@ try@b@ {@b@ super.ExpressionCompilationUnit();@b@ } catch (TokenMgrError tokenError) {@b@ throw new CQLException(tokenError.getMessage(), getTokenInPosition(0), this.source);@b@ } catch (CQLException e) {@b@ throw e;@b@ } catch (ParseException e) {@b@ throw new CQLException(e.getMessage(), getTokenInPosition(0), e.getCause(), this.source);@b@ }@b@ }@b@@b@ public void compileFilterList()@b@ throws CQLException@b@ {@b@ try@b@ {@b@ super.FilterListCompilationUnit();@b@ } catch (TokenMgrError tokenError) {@b@ throw new CQLException(tokenError.getMessage(), getTokenInPosition(0), this.source);@b@ } catch (CQLException e) {@b@ throw e;@b@ } catch (ParseException e) {@b@ throw new CQLException(e.getMessage(), getTokenInPosition(0), e.getCause(), this.source);@b@ }@b@ }@b@@b@ public final String getSource()@b@ {@b@ return this.source;@b@ }@b@@b@ public final Filter getFilter()@b@ throws CQLException@b@ {@b@ return this.builder.getFilter();@b@ }@b@@b@ public final Expression getExpression()@b@ throws CQLException@b@ {@b@ return this.builder.getExpression();@b@ }@b@@b@ public IToken getTokenInPosition(int index) {@b@ return TokenAdapter.newAdapterFor(super.getToken(index));@b@ }@b@@b@ public List<Filter> getFilterList()@b@ throws CQLException@b@ {@b@ return this.builder.getFilterList();@b@ }@b@@b@ public final void jjtreeOpenNodeScope(Node n)@b@ {@b@ }@b@@b@ public final void jjtreeCloseNodeScope(Node n)@b@ throws ParseException@b@ {@b@ Object built;@b@ try@b@ {@b@ built = build(n);@b@@b@ IToken tokenAdapter = TokenAdapter.newAdapterFor(this.token);@b@ Result r = new Result(built, tokenAdapter, n.getType());@b@ this.builder.pushResult(r);@b@ }@b@ catch (CQLException e)@b@ {@b@ }@b@ finally {@b@ n.dispose();@b@ }@b@ }@b@@b@ private Object build(Node n)@b@ throws CQLException@b@ {@b@ switch (n.getType())@b@ {@b@ case 61:@b@ return this.builder.buildLiteralInteger(getTokenInPosition(0).toString());@b@ case 62:@b@ return this.builder.buildLiteralDouble(getTokenInPosition(0).toString());@b@ case 60:@b@ return this.builder.bulidNegativeNumber();@b@ case 65:@b@ return this.builder.buildLiteralString(getTokenInPosition(0).toString());@b@ case 56:@b@ return this.builder.buildIdentifier(57);@b@ case 57:@b@ return this.builder.buildIdentifierPart(getTokenInPosition(0));@b@ case 58:@b@ return this.builder.buildSimpleAttribute();@b@ case 59:@b@ return this.builder.buildCompoundAttribute(58, "/");@b@ case 66:@b@ return this.builder.buildFunction(67);@b@ case 67:@b@ return n;@b@ case 68:@b@ return n;@b@ case 52:@b@ case 53:@b@ case 54:@b@ case 55:@b@ return buildBinaryExpression(n.getType());@b@ case 2:@b@ return buildLogicFilter(2);@b@ case 1:@b@ return buildLogicFilter(1);@b@ case 3:@b@ return buildLogicFilter(3);@b@ case 51:@b@ return this.builder.buildBetween();@b@ case 50:@b@ return this.builder.buildNotBetween();@b@ case 28:@b@ case 29:@b@ case 30:@b@ case 31:@b@ case 32:@b@ return buildBinaryComparasionOperator(n.getType());@b@ case 33:@b@ Filter eq = buildBinaryComparasionOperator(28);@b@ Not notFilter = this.builder.buildNotFilter(eq);@b@@b@ return notFilter;@b@ case 49:@b@ return this.builder.buildLikeFilter();@b@ case 48:@b@ return this.builder.buildNotLikeFilter();@b@ case 34:@b@ return this.builder.buildPropertyIsNull();@b@ case 35:@b@ return this.builder.buildPorpertyNotIsNull();@b@ case 44:@b@ return this.builder.buildDateTimeExpression(getTokenInPosition(0));@b@ case 45:@b@ return this.builder.buildDurationExpression(getTokenInPosition(0));@b@ case 43:@b@ return this.builder.buildPeriodBetweenDates();@b@ case 42:@b@ return this.builder.buildPeriodDateAndDuration();@b@ case 41:@b@ return this.builder.buildPeriodDurationAndDate();@b@ case 36:@b@ return buildTemporalPredicateBefore();@b@ case 38:@b@ return buildTemporalPredicateAfter();@b@ case 39:@b@ return buildTemporalPredicateDuring();@b@ case 37:@b@ return buildTemporalPredicateBeforeOrDuring();@b@ case 40:@b@ return buildTemporalPredicateDuringOrAfter();@b@ case 46:@b@ return this.builder.buildPropertyExists();@b@ case 47:@b@ Filter filter = this.builder.buildPropertyExists();@b@ Filter filterPropNotExist = this.builder.buildNotFilter(filter);@b@@b@ return filterPropNotExist;@b@ case 10:@b@ case 11:@b@ case 12:@b@ case 13:@b@ case 14:@b@ case 15:@b@ case 16:@b@ case 17:@b@ return buildBinarySpatialOperator(n.getType());@b@ case 19:@b@ case 20:@b@ return buildBBox(n.getType());@b@ case 18:@b@ return this.builder.buildRelate();@b@ case 23:@b@ return this.builder.buildTolerance();@b@ case 24:@b@ return this.builder.buildDistanceUnit(getTokenInPosition(0));@b@ case 21:@b@ case 22:@b@ return buildDistanceBufferOperator(n.getType());@b@ case 69:@b@ return this.builder.buildCoordinate();@b@ case 72:@b@ return this.builder.buildPointText();@b@ case 70:@b@ return this.builder.buildLineString(69);@b@ case 73:@b@ return this.builder.buildPolygon(70);@b@ case 74:@b@ return this.builder.buildMultiPoint(72);@b@ case 75:@b@ return this.builder.buildMultiLineString(70);@b@ case 76:@b@ return this.builder.buildMultiPolygon(73);@b@ case 25:@b@ return this.builder.buildGeometryLiteral();@b@ case 77:@b@ return this.builder.buildGeometryCollection(25);@b@ case 71:@b@ return this.builder.buildGeometry();@b@ case 78:@b@ return this.builder.buildEnvelop(TokenAdapter.newAdapterFor(n.getToken()));@b@ case 26:@b@ return Filter.INCLUDE;@b@ case 27:@b@ return Filter.EXCLUDE;@b@ case 63:@b@ return this.builder.buildTrueLiteral();@b@ case 64:@b@ return this.builder.buildFalseLiteral();@b@ case 6:@b@ return this.builder.buildFeatureID(getTokenInPosition(0));@b@ case 5:@b@ return this.builder.buildFilterId(6);@b@ case 4:@b@ Id idFilter = this.builder.buildFilterId(6);@b@ Not notIdFilter = this.builder.buildNotFilter(idFilter);@b@@b@ return notIdFilter;@b@ case 8:@b@ return this.builder.buildInPredicate(9);@b@ case 7:@b@ Or orFilter = this.builder.buildInPredicate(9);@b@ Not notOrFilter = this.builder.buildNotFilter(orFilter);@b@@b@ return notOrFilter;@b@ case 9:@b@ }@b@@b@ return null;@b@ }@b@@b@ private BinaryExpression buildBinaryExpression(int nodeType)@b@ throws CQLException@b@ {@b@ BinaryExpression expr = null;@b@@b@ switch (nodeType)@b@ {@b@ case 52:@b@ expr = this.builder.buildAddExpression();@b@@b@ break;@b@ case 53:@b@ expr = this.builder.buildSubtractExression();@b@@b@ break;@b@ case 54:@b@ expr = this.builder.buildMultiplyExpression();@b@ break;@b@ case 55:@b@ expr = this.builder.buildDivideExpression();@b@ }@b@@b@ return expr;@b@ }@b@@b@ private Filter buildLogicFilter(int nodeType)@b@ throws CQLException@b@ {@b@ try@b@ {@b@ Filter logicFilter;@b@ switch (nodeType)@b@ {@b@ case 2:@b@ logicFilter = this.builder.buildAndFilter();@b@ break;@b@ case 1:@b@ logicFilter = this.builder.buildOrFilter();@b@ break;@b@ case 3:@b@ logicFilter = this.builder.buildNotFilter();@b@ break;@b@ default:@b@ throw new CQLException("Expression not supported. And, Or, Not is required", getTokenInPosition(0), this.source);@b@ }@b@@b@ return logicFilter;@b@ } catch (IllegalFilterException ife) {@b@ throw new CQLException("Exception building LogicFilter", getTokenInPosition(0), ife, this.source);@b@ }@b@ }@b@@b@ private BinarySpatialOperator buildBinarySpatialOperator(int nodeType)@b@ throws CQLException@b@ {@b@ BinarySpatialOperator filter = null;@b@@b@ switch (nodeType)@b@ {@b@ case 10:@b@ filter = this.builder.buildSpatialEqualFilter();@b@ break;@b@ case 11:@b@ filter = this.builder.buildSpatialDisjointFilter();@b@ break;@b@ case 12:@b@ filter = this.builder.buildSpatialIntersectsFilter();@b@ break;@b@ case 13:@b@ filter = this.builder.buildSpatialTouchesFilter();@b@ break;@b@ case 14:@b@ filter = this.builder.buildSpatialCrossesFilter();@b@ break;@b@ case 15:@b@ filter = this.builder.buildSpatialWithinFilter();@b@ break;@b@ case 16:@b@ filter = this.builder.buildSpatialContainsFilter();@b@ break;@b@ case 17:@b@ filter = this.builder.buildSpatialOverlapsFilter();@b@ break;@b@ default:@b@ throw new CQLException("Binary spatial operator unexpected");@b@ }@b@@b@ return filter;@b@ }@b@@b@ private BBOX buildBBox(int nodeType)@b@ throws CQLException@b@ {@b@ if (nodeType == 20)@b@ return this.builder.buildBBoxWithCRS();@b@@b@ return this.builder.buildBBox();@b@ }@b@@b@ private DistanceBufferOperator buildDistanceBufferOperator(int nodeType)@b@ throws CQLException@b@ {@b@ DistanceBufferOperator filter = null;@b@@b@ switch (nodeType)@b@ {@b@ case 21:@b@ filter = this.builder.buildSpatialDWithinFilter();@b@ break;@b@ case 22:@b@ filter = this.builder.buildSpatialBeyondFilter();@b@ break;@b@ default:@b@ throw new CQLException("Binary spatial operator unexpected");@b@ }@b@@b@ return filter;@b@ }@b@@b@ private Filter buildTemporalPredicateBeforeOrDuring()@b@ throws CQLException@b@ {@b@ Filter filter = null;@b@@b@ Result node = this.builder.peekResult();@b@@b@ switch (node.getNodeType())@b@ {@b@ case 41:@b@ case 42:@b@ case 43:@b@ filter = this.builder.buildPropertyIsLTELastDate();@b@ break;@b@ default:@b@ throw new CQLException("unexpeted date time expression in temporal predicate.", node.getToken(), this.source);@b@ }@b@@b@ return filter;@b@ }@b@@b@ private Filter buildTemporalPredicateDuringOrAfter() throws CQLException@b@ {@b@ Filter filter = null;@b@@b@ Result node = this.builder.peekResult();@b@@b@ switch (node.getNodeType())@b@ {@b@ case 41:@b@ case 42:@b@ case 43:@b@ filter = this.builder.buildPropertyIsGTEFirstDate();@b@@b@ break;@b@ default:@b@ throw new CQLException("unexpeted date time expression in temporal predicate.", node.getToken(), this.source);@b@ }@b@@b@ return filter;@b@ }@b@@b@ private Filter buildTemporalPredicateBefore()@b@ throws CQLException@b@ {@b@ Filter filter = null;@b@@b@ Result node = this.builder.peekResult();@b@@b@ switch (node.getNodeType())@b@ {@b@ case 44:@b@ filter = buildBinaryComparasionOperator(30);@b@@b@ break;@b@ case 41:@b@ case 42:@b@ case 43:@b@ filter = this.builder.buildPropertyIsLTFirsDate();@b@@b@ break;@b@ default:@b@ throw new CQLException("unexpeted date time expression in temporal predicate.", node.getToken(), this.source);@b@ }@b@@b@ return filter;@b@ }@b@@b@ private Object buildTemporalPredicateDuring()@b@ throws CQLException@b@ {@b@ Filter filter = null;@b@@b@ Result node = this.builder.peekResult();@b@@b@ switch (node.getNodeType())@b@ {@b@ case 41:@b@ case 42:@b@ case 43:@b@ filter = this.builder.buildPropertyBetweenDates();@b@@b@ break;@b@ default:@b@ throw new CQLException("unexpeted period expression in temporal predicate.", node.getToken(), this.source);@b@ }@b@@b@ return filter;@b@ }@b@@b@ private Filter buildTemporalPredicateAfter()@b@ throws CQLException@b@ {@b@ Filter filter = null;@b@@b@ Result node = this.builder.peekResult();@b@@b@ switch (node.getNodeType())@b@ {@b@ case 44:@b@ filter = buildBinaryComparasionOperator(29);@b@@b@ break;@b@ case 41:@b@ case 42:@b@ case 43:@b@ filter = this.builder.buildPropertyIsGTLastDate();@b@@b@ break;@b@ default:@b@ throw new CQLException("unexpeted date time expression in temporal predicate.", node.getToken(), this.source);@b@ }@b@@b@ return filter;@b@ }@b@@b@ private BinaryComparisonOperator buildBinaryComparasionOperator(int filterType)@b@ throws CQLException@b@ {@b@ switch (filterType)@b@ {@b@ case 28:@b@ return this.builder.buildEquals();@b@ case 29:@b@ return this.builder.buildGreater();@b@ case 30:@b@ return this.builder.buildLess();@b@ case 31:@b@ return this.builder.buildGreaterOrEqual();@b@ case 32:@b@ return this.builder.buildLessOrEqual();@b@ }@b@@b@ throw new CQLException("unexpeted filter type.");@b@ }@b@}package org.geotools.filter.text.commons;@b@@b@public enum Language@b@{@b@ ECQL, CQL;@b@@b@ public static final Language[] values()@b@ {@b@ return ((Language[])$VALUES.clone());@b@ }@b@}2.CompilerFactory工厂类
package org.geotools.filter.text.commons;@b@@b@import org.geotools.factory.CommonFactoryFinder;@b@import org.geotools.factory.Hints;@b@import org.geotools.filter.text.cql2.CQLCompiler;@b@import org.geotools.filter.text.cql2.CQLException;@b@import org.geotools.filter.text.ecql.ECQLCompiler;@b@import org.opengis.filter.FilterFactory;@b@@b@final class CompilerFactory@b@{@b@ public static ICompiler makeCompiler(Language language, String predicate, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ ICompiler compiler;@b@ FilterFactory ff = filterFactory;@b@@b@ if (filterFactory == null) {@b@ ff = CommonFactoryFinder.getFilterFactory((Hints)null);@b@ }@b@@b@ if (language == Language.ECQL)@b@ compiler = new ECQLCompiler(predicate, ff);@b@ else@b@ compiler = new CQLCompiler(predicate, ff);@b@@b@ return compiler;@b@ }@b@}3.CompilerUtil类
package org.geotools.filter.text.commons;@b@@b@import java.util.List;@b@import org.geotools.filter.text.cql2.CQLException;@b@import org.opengis.filter.Filter;@b@import org.opengis.filter.FilterFactory;@b@import org.opengis.filter.expression.Expression;@b@@b@public final class CompilerUtil@b@{@b@ public static final Filter parseFilter(Language language, String predicate, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ if ((!($assertionsDisabled)) && (language == null)) throw new AssertionError("language cannot be null");@b@ if ((!($assertionsDisabled)) && (predicate == null)) throw new AssertionError("predicate cannot be null");@b@@b@ ICompiler compiler = CompilerFactory.makeCompiler(language, predicate, filterFactory);@b@ compiler.compileFilter();@b@ Filter result = compiler.getFilter();@b@@b@ return result;@b@ }@b@@b@ public static final Filter parseFilter(Language language, String predicate)@b@ throws CQLException@b@ {@b@ if ((!($assertionsDisabled)) && (language == null)) throw new AssertionError("language cannot be null");@b@ if ((!($assertionsDisabled)) && (predicate == null)) throw new AssertionError("predicate cannot be null");@b@@b@ Filter result = parseFilter(language, predicate, null);@b@@b@ return result;@b@ }@b@@b@ public static final Expression parseExpression(Language language, String predicate, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ if ((!($assertionsDisabled)) && (language == null)) throw new AssertionError("language cannot be null");@b@ if ((!($assertionsDisabled)) && (predicate == null)) throw new AssertionError("predicate cannot be null");@b@@b@ ICompiler compiler = CompilerFactory.makeCompiler(language, predicate, filterFactory);@b@ compiler.compileExpression();@b@ Expression result = compiler.getExpression();@b@@b@ return result;@b@ }@b@@b@ public static final Expression parseExpression(Language language, String predicate)@b@ throws CQLException@b@ {@b@ Expression result = parseExpression(language, predicate, null);@b@@b@ return result;@b@ }@b@@b@ public static List<Filter> parseFilterList(Language language, String predicate, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ if ((!($assertionsDisabled)) && (language == null)) throw new AssertionError("language cannot be null");@b@ if ((!($assertionsDisabled)) && (predicate == null)) throw new AssertionError("predicate cannot be null");@b@@b@ ICompiler compiler = CompilerFactory.makeCompiler(language, predicate, filterFactory);@b@ compiler.compileFilterList();@b@ List results = compiler.getFilterList();@b@@b@ return results;@b@ }@b@@b@ public static List<Filter> parseFilterList(Language language, String predicate)@b@ throws CQLException@b@ {@b@ List results = parseFilterList(language, predicate, null);@b@@b@ return results;@b@ }@b@@b@ public static Expression parseExpression(String source, AbstractCompilerFactory compilerFactory, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ ICompiler compiler = compilerFactory.makeCompiler(source, filterFactory);@b@ compiler.compileExpression();@b@ Expression expression = compiler.getExpression();@b@@b@ return expression;@b@ }@b@@b@ public static Filter parseFilter(String source, AbstractCompilerFactory compilerFactory, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ ICompiler compiler = compilerFactory.makeCompiler(source, filterFactory);@b@ compiler.compileFilter();@b@ Filter result = compiler.getFilter();@b@@b@ return result;@b@ }@b@@b@ public static List<Filter> parseFilterList(String predicateSequence, AbstractCompilerFactory compilerFactory, FilterFactory filterFactory)@b@ throws CQLException@b@ {@b@ ICompiler compiler = compilerFactory.makeCompiler(predicateSequence, filterFactory);@b@ compiler.compileFilterList();@b@ List filters = compiler.getFilterList();@b@@b@ return filters;@b@ }@b@}