use of org.geotoolkit.cql.CQLParser.ExpressionTermContext in project geotoolkit by Geomatys.
the class CQL method convertExpression.
/**
* Convert the given tree in an Expression.
*/
private static Expression convertExpression(ParseTree tree, FilterFactory2 ff) throws CQLException {
if (tree instanceof ExpressionContext) {
// | expressionTerm
if (tree.getChildCount() == 3) {
final String operand = tree.getChild(1).getText();
final Expression left = convertExpression((ParseTree) tree.getChild(0), ff);
final Expression right = convertExpression((ParseTree) tree.getChild(2), ff);
if ("*".equals(operand)) {
return ff.multiply(left, right);
} else if ("/".equals(operand)) {
return ff.divide(left, right);
} else if ("+".equals(operand)) {
return ff.add(left, right);
} else if ("-".equals(operand)) {
return ff.subtract(left, right);
}
} else {
return convertExpression(tree.getChild(0), ff);
}
} else // }
if (tree instanceof ExpressionTermContext) {
// : expressionString
// | expressionUnary
// | PROPERTY_NAME
// | DATE
// | DURATION_P
// | DURATION_T
// | NAME (LPAREN expressionFctParam? RPAREN)?
// | expressionGeometry
// | LPAREN expression RPAREN
// : TEXT
// | expressionUnary
// | PROPERTY_NAME
// | DATE
// | DURATION_P
// | DURATION_T
// | expressionGeometry
final ExpressionTermContext exp = (ExpressionTermContext) tree;
if (exp.getChildCount() == 1) {
return convertExpression(tree.getChild(0), ff);
}
// LPAREN expression RPAREN
if (exp.expression() != null) {
return convertExpression(exp.expression(), ff);
}
// NAME (LPAREN expressionFctParam? RPAREN)?
if (exp.NAME() != null) {
final String name = exp.NAME().getText();
final ExpressionFctParamContext prm = exp.expressionFctParam();
if (prm == null) {
// try to find a function with this name
try {
Expression fct = ff.function(name, new Expression[0]);
if (fct != null)
return fct;
} catch (IllegalArgumentException ex) {
// we have try
}
// handle as property name
return ff.property(name);
}
// handle as a function
final List<ExpressionContext> params = prm.expression();
final List<Expression> exps = new ArrayList<Expression>();
for (int i = 0, n = params.size(); i < n; i++) {
exps.add(convertExpression(params.get(i), ff));
}
return ff.function(name, exps.toArray(new Expression[exps.size()]));
}
} else if (tree instanceof ExpressionUnaryContext) {
// : UNARY? expressionNum ;
final ExpressionUnaryContext exp = (ExpressionUnaryContext) tree;
return ff.literal(unaryAsNumber(exp));
} else if (tree instanceof ExpressionNumContext) {
// : INT | FLOAT ;
return convertExpression(tree.getChild(0), ff);
} else if (tree instanceof TerminalNode) {
final TerminalNode exp = (TerminalNode) tree;
final int type = exp.getSymbol().getType();
if (PROPERTY_NAME == type) {
// strip start and end "
final String text = tree.getText();
return ff.property(text.substring(1, text.length() - 1));
} else if (NAME == type) {
return ff.property(tree.getText());
} else if (INT == type) {
return ff.literal(Integer.valueOf(tree.getText()));
} else if (FLOAT == type) {
return ff.literal(Double.valueOf(tree.getText()));
} else if (DATE == type) {
final ISODateParser parser = new ISODateParser();
return ff.literal(parser.parseToDate(tree.getText()));
} else if (DURATION_P == type || DURATION_T == type) {
return ff.literal(TemporalUtilities.getTimeInMillis(tree.getText()));
} else if (TEXT == type) {
// strip start and end '
String text = tree.getText();
text = text.replaceAll("\\\\'", "'");
return ff.literal(text.substring(1, text.length() - 1));
}
} else if (tree instanceof ExpressionGeometryContext) {
// : POINT ( EMPTY | coordinateSerie )
// | LINESTRING ( EMPTY | coordinateSerie )
// | POLYGON ( EMPTY | coordinateSeries )
// | MPOINT ( EMPTY | coordinateSerie )
// | MLINESTRING ( EMPTY | coordinateSeries )
// | MPOLYGON ( EMPTY | LPAREN coordinateSeries (COMMA coordinateSeries)* RPAREN )
// | GEOMETRYCOLLECTION ( EMPTY | (LPAREN expressionGeometry (COMMA expressionGeometry)* RPAREN) )
// | ENVELOPE ( EMPTY | (LPAREN expressionUnary COMMA expressionUnary COMMA expressionUnary COMMA expressionUnary RPAREN) )
final ExpressionGeometryContext exp = (ExpressionGeometryContext) tree;
final int type = ((TerminalNode) exp.getChild(0)).getSymbol().getType();
if (POINT == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final CoordinateSequence cs;
if (isEmptyToken(st)) {
cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
} else {
cs = parseSequence(st);
}
final Geometry geom = GF.createPoint(cs);
return ff.literal(geom);
} else if (LINESTRING == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final CoordinateSequence cs;
if (isEmptyToken(st)) {
cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
} else {
cs = parseSequence(st);
}
final Geometry geom = GF.createLineString(cs);
return ff.literal(geom);
} else if (POLYGON == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final Geometry geom;
if (isEmptyToken(st)) {
geom = GF.createPolygon(GF.createLinearRing(new Coordinate[0]), new LinearRing[0]);
} else {
final CoordinateSeriesContext series = (CoordinateSeriesContext) st;
final List<CoordinateSerieContext> subs = series.coordinateSerie();
final LinearRing contour = GF.createLinearRing(parseSequence(subs.get(0)));
final int n = subs.size();
final LinearRing[] holes = new LinearRing[n - 1];
for (int i = 1; i < n; i++) {
holes[i - 1] = GF.createLinearRing(parseSequence(subs.get(i)));
}
geom = GF.createPolygon(contour, holes);
}
return ff.literal(geom);
} else if (MPOINT == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final CoordinateSequence cs;
if (isEmptyToken(st)) {
cs = GF.getCoordinateSequenceFactory().create(new Coordinate[0]);
} else {
cs = parseSequence(st);
}
final Geometry geom = GF.createMultiPoint(cs);
return ff.literal(geom);
} else if (MLINESTRING == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final Geometry geom;
if (isEmptyToken(st)) {
geom = GF.createMultiLineString(new LineString[0]);
} else {
final CoordinateSeriesContext series = (CoordinateSeriesContext) st;
final List<CoordinateSerieContext> subs = series.coordinateSerie();
final int n = subs.size();
final LineString[] strings = new LineString[n];
for (int i = 0; i < n; i++) {
strings[i] = GF.createLineString(parseSequence(subs.get(i)));
}
geom = GF.createMultiLineString(strings);
}
return ff.literal(geom);
} else if (MPOLYGON == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final Geometry geom;
if (isEmptyToken(st)) {
geom = GF.createMultiPolygon(new Polygon[0]);
} else {
final List<CoordinateSeriesContext> eles = exp.coordinateSeries();
final int n = eles.size();
final Polygon[] polygons = new Polygon[n];
for (int i = 0; i < n; i++) {
final CoordinateSeriesContext polyTree = eles.get(i);
final List<CoordinateSerieContext> subs = polyTree.coordinateSerie();
final LinearRing contour = GF.createLinearRing(parseSequence(subs.get(0)));
final int hn = subs.size();
final LinearRing[] holes = new LinearRing[hn - 1];
for (int j = 1; j < hn; j++) {
holes[j - 1] = GF.createLinearRing(parseSequence(subs.get(j)));
}
final Polygon poly = GF.createPolygon(contour, holes);
polygons[i] = poly;
}
geom = GF.createMultiPolygon(polygons);
}
return ff.literal(geom);
} else if (GEOMETRYCOLLECTION == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final Geometry geom;
if (isEmptyToken(st)) {
geom = GF.createGeometryCollection(new Geometry[0]);
} else {
final List<ExpressionGeometryContext> eles = exp.expressionGeometry();
final int n = eles.size();
final Geometry[] subs = new Geometry[n];
for (int i = 0; i < n; i++) {
final ParseTree subTree = eles.get(i);
final Geometry sub = (Geometry) convertExpression(subTree, ff).apply(null);
subs[i] = sub;
}
geom = GF.createGeometryCollection(subs);
}
return ff.literal(geom);
} else if (ENVELOPE == type) {
final ParseTree st = (ParseTree) tree.getChild(1);
final Geometry geom;
if (isEmptyToken(st)) {
geom = GF.createPolygon(GF.createLinearRing(new Coordinate[0]), new LinearRing[0]);
} else {
final List<ExpressionUnaryContext> unaries = exp.expressionUnary();
final double west = unaryAsNumber(unaries.get(0)).doubleValue();
final double east = unaryAsNumber(unaries.get(1)).doubleValue();
final double north = unaryAsNumber(unaries.get(2)).doubleValue();
final double south = unaryAsNumber(unaries.get(3)).doubleValue();
final LinearRing contour = GF.createLinearRing(new Coordinate[] { new Coordinate(west, north), new Coordinate(east, north), new Coordinate(east, south), new Coordinate(west, south), new Coordinate(west, north) });
geom = GF.createPolygon(contour, new LinearRing[0]);
}
return ff.literal(geom);
}
return convertExpression(tree.getChild(0), ff);
}
throw new CQLException("Unreconized expression : type=" + tree.getText());
}
Aggregations