Line2DExpression.java
/*
* Copyright 2015 greg.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nz.co.gregs.dbvolution.expressions.spatial2D;
import nz.co.gregs.dbvolution.results.Line2DResult;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import java.util.HashSet;
import java.util.Set;
import nz.co.gregs.dbvolution.DBRow;
import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
import nz.co.gregs.dbvolution.datatypes.spatial2D.DBLine2D;
import nz.co.gregs.dbvolution.datatypes.spatial2D.DBMultiPoint2D;
import nz.co.gregs.dbvolution.expressions.BooleanExpression;
import nz.co.gregs.dbvolution.expressions.NumberExpression;
import nz.co.gregs.dbvolution.expressions.StringExpression;
import nz.co.gregs.dbvolution.results.AnyResult;
import nz.co.gregs.dbvolution.results.MultiPoint2DResult;
/**
* Represents SQL expressions that are a 2 dimensional path, as a series of
* connected line segments with X and Y coordinates.
*
*
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @author Gregory Graham
*/
public class Line2DExpression extends Spatial2DExpression<com.vividsolutions.jts.geom.LineString, Line2DResult, DBLine2D> implements Line2DResult {
private final static long serialVersionUID = 1l;
private final boolean moreNullProtectionRequired;
/**
* Default constructor, probably shouldn't be used.
*
*/
protected Line2DExpression() {
super();
moreNullProtectionRequired = false;
}
/**
* Create a new Line2DExpression containing the specified value or value.
*
* <p>
* {@link Line2DResult} classes include {@link DBLine2D} and
* {@link Line2DExpression}.
*
* @param value the expression to use in this expression
*/
public Line2DExpression(Line2DResult value) {
super(value);
moreNullProtectionRequired = value == null;
}
/**
* Create a new Line2DExpression containing the specified value or value.
*
* <p>
* {@link Line2DResult} classes include {@link DBLine2D} and
* {@link Line2DExpression}.
*
* @param value the expression to use in this expression
*/
protected Line2DExpression(AnyResult<?> value) {
super(value);
moreNullProtectionRequired = value == null;
}
/**
* Create a Line2DExpression representing the line supplied.
*
* @param line the value to use in this expression
*/
public Line2DExpression(LineString line) {
super(new DBLine2D(line));
moreNullProtectionRequired = line == null;
}
/**
* Create a Line2DExpression representing the set of points as a line.
*
* @param points the points to create a line from and use in this expression
*/
public Line2DExpression(Point... points) {
super(new DBLine2D(points));
boolean nulls = false;
moreNullProtectionRequired
= points == null
|| points.length == 0
|| nulls
|| new DBLine2D(points).getIncludesNull();
}
/**
* Create a Line2DExpression representing the set of coordinates as a line.
*
* @param coords the points to create a line from and use in this expression
*/
public Line2DExpression(Coordinate... coords) {
super(new DBLine2D(coords));
boolean nulls = false;
moreNullProtectionRequired
= coords == null
|| coords.length == 0
|| nulls
|| new DBLine2D(coords).getIncludesNull();
}
@Override
public boolean getIncludesNull() {
return moreNullProtectionRequired
|| super.getIncludesNull();
}
/**
* Creates an expression that will return the most common value of the column
* supplied.
*
* <p>
* MODE: The number which appears most often in a set of numbers. For example:
* in {6, 3, 9, 6, 6, 5, 9, 3} the Mode is 6.</p>
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return a number expression.
*/
public Line2DExpression modeSimple() {
@SuppressWarnings("unchecked")
Line2DExpression modeExpr = new Line2DExpression(
new ModeSimpleExpression<>(this));
return modeExpr;
}
/**
* Creates an expression that will return the most common value of the column
* supplied.
*
* <p>
* MODE: The number which appears most often in a set of numbers. For example:
* in {6, 3, 9, 6, 6, 5, 9, 3} the Mode is 6.</p>
*
* <p>
* This version of Mode implements a stricter definition that will return null
* if the mode is undefined. The mode can be undefined if there are 2 or more
* values with the highest frequency value. </p>
*
* <p>
* For example in the list {0,0,0,0,1,1,2,2,2,2,3,4} both 0 and 2 occur four
* times and no other value occurs more frequently so the mode is undefined.
* {@link #modeSimple() The modeSimple()} method would return either 0 or 2
* randomly for the same set.</p>
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the mode or null if undefined.
*/
public Line2DExpression modeStrict() {
@SuppressWarnings("unchecked")
Line2DExpression modeExpr = new Line2DExpression(
new ModeStrictExpression<>(this));
return modeExpr;
}
/**
* Create a Line2DExpression representing the set of points as a line.
*
* @param points a series of points that constitute a line.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a Line2DExpression
*/
public Line2DExpression expression(Point... points) {
return new Line2DExpression(points);
}
public static Line2DExpression value(Point... points) {
return new Line2DExpression(points);
}
/**
* Create a Line2DExpression representing the set of coordinates as a line.
*
* @param coords a series of number to be interpreted as X and Y points of a
* line.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a Line2DExpression
*/
public Line2DExpression expression(Coordinate... coords) {
return new Line2DExpression(coords);
}
public static Line2DExpression value(Coordinate... coords) {
return new Line2DExpression(coords);
}
/**
* Create a Line2DExpression representing the line.
*
* @param line create a Line2DExpression from this line.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a Line2DExpression
*/
@Override
public Line2DExpression expression(LineString line) {
return new Line2DExpression(line);
}
/**
* Create a Line2DExpression representing the line.
*
* @param line create a Line2DExpression from this line.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a Line2DExpression
*/
@Override
public Line2DExpression expression(Line2DResult line) {
return new Line2DExpression(line);
}
public static Line2DExpression value(Line2DResult line) {
return new Line2DExpression(line);
}
/**
* Create a Line2DExpression representing the {@link MultiPoint2DExpression}
* or {@link DBMultiPoint2D} as a line.
*
* @param multipoint2DExpression a series of point that constitute a line
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a Line2DExpression
*/
public Line2DExpression expression(MultiPoint2DResult multipoint2DExpression) {
return value(multipoint2DExpression);
}
public static Line2DExpression value(MultiPoint2DResult multipoint2DExpression) {
return MultiPoint2DExpression.value(multipoint2DExpression).line2DResult();
}
@Override
public Line2DExpression nullExpression() {
return new NullExpression();
}
@Override
public Line2DExpression expression(DBLine2D value) {
return new Line2DExpression(value);
}
@Override
public StringExpression toWKTFormat() {
return stringResult();
}
@Override
public DBLine2D getQueryableDatatypeForExpressionValue() {
return new DBLine2D();
}
@Override
protected boolean isNullSafetyTerminator() {
return super.isNullSafetyTerminator()
&& moreNullProtectionRequired == false;
}
@Override
public Line2DExpression copy() {
return isNullSafetyTerminator()
? new Line2DExpression()
: getInnerResult() == null
? nullLine2D()
: new Line2DExpression((AnyResult<?>) getInnerResult().copy());
}
/**
* Convert the Line2D value into a String value.
*
* <p>
* This should be the WKT (Well Known Text) version of the line.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return a StringExpression of the Line2D in WKT format.
*/
@Override
public StringExpression stringResult() {
return new StringExpression(new StringResultExpression(this));
}
/**
* Compare the value of the given LineString to this value using the
* equivalent of EQUALS.
*
* <p>
* The boolean value will be TRUE if the two expressions are functionally
* equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the value this value may equal.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE when the two expressions are
* functionally equivalent, otherwise FALSE.
*/
@Override
public BooleanExpression is(LineString rightHandSide) {
return is(new DBLine2D(rightHandSide));
}
/**
* Compare this value to the exterior ring of the given Polygon2D using the
* equivalent of EQUALS.
*
* <p>
* The boolean value will be TRUE if the exterior ring and the line are
* functionally equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the polygon whose exterior ring may equal this line
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE when the two expressions are
* functionally equivalent, otherwise FALSE.
*/
public BooleanExpression is(Polygon rightHandSide) {
return is(rightHandSide.getExteriorRing());
}
/**
* Compare the value of the given Line2D to this value using the equivalent of
* EQUALS.
*
* <p>
* The boolean value will be TRUE if the two expressions are functionally
* equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the line that this value might equal
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE when the two expressions are
* functionally equivalent, otherwise FALSE.
*/
@Override
public BooleanExpression is(Line2DResult rightHandSide) {
return new BooleanExpression(new IsExpression(this, new Line2DExpression(rightHandSide)));
}
/**
* Compare the value of the given LineString to this value using the
* equivalent of NOT EQUALS.
*
* <p>
* The boolean value will be FALSE if the two expressions are functionally
* equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the line that this value might equal
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be FALSE when the two expressions are
* functionally equivalent, otherwise TRUE.
*/
@Override
public BooleanExpression isNot(LineString rightHandSide) {
return isNot(new DBLine2D(rightHandSide));
}
/**
* Compare this value to the exterior ring of the given Polygon2D using the
* equivalent of NOT EQUALS.
*
* <p>
* The boolean value will be FALSE if the exterior ring and the line are
* functionally equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the polygon whose exterior ring might not equal this
* value's value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be FALSE when the two expressions are
* functionally equivalent, otherwise TRUE.
*/
public BooleanExpression isNot(Polygon rightHandSide) {
return isNot(rightHandSide.getExteriorRing());
}
/**
* Compare the value of the given Line2D to this value using the equivalent of
* NOT EQUALS.
*
* <p>
* The boolean value will be FALSE if the two expressions are functionally
* equivalent.
*
* <p>
* Due to to the imperfect interpretation of floating point numbers there may
* some discrepancies between databases but DBV tries to be as accurate as the
* database allows.
*
* @param rightHandSide the line to compare to this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be FALSE when the two expressions are
* functionally equivalent, otherwise TRUE.
*/
@Override
public BooleanExpression isNot(Line2DResult rightHandSide) {
return new BooleanExpression(new IsNotExpression(this, new Line2DExpression(rightHandSide)));
}
@Override
public NumberExpression measurableDimensions() {
return new NumberExpression(new MeasurableDimensionsExpression(this));
}
@Override
public NumberExpression spatialDimensions() {
return new NumberExpression(new SpatialDimensionsExpression(this));
}
@Override
public BooleanExpression hasMagnitude() {
return new BooleanExpression(new HasMagnitudeExpression(this));
}
@Override
public NumberExpression magnitude() {
return new NumberExpression(new MagnitudeExpression(this));
}
@Override
public Polygon2DExpression boundingBox() {
return new Polygon2DExpression(new BoundingBoxExpression(this));
}
/**
* Return the maximum X value in the Line2D.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the numeric value of the largest X coordinate for the Line2D.
*/
@Override
public NumberExpression maxX() {
return new NumberExpression(new MaxXExpression(this));
}
/**
* Return the minimum X value in the Line2D.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the numeric value of the smallest X coordinate for the Line2D.
*/
@Override
public NumberExpression minX() {
return new NumberExpression(new MinXExpression(this));
}
/**
* Return the maximum Y value in the Line2D.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the numeric value of the largest Y coordinate for the Line2D.
*/
@Override
public NumberExpression maxY() {
return new NumberExpression(new MaxYExpression(this));
}
/**
* Return the minimum Y value in the Line2D.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the numeric value of the smallest Y coordinate for the Line2D.
*/
@Override
public NumberExpression minY() {
return new NumberExpression(new MinYExpression(this));
}
/**
* Tests whether this line and the line represented by the points ever cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports TRUE or FALSE.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param points points that constitute a line that might intersect this
* value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public BooleanExpression intersects(Point... points) {
return this.intersects(expression(points));
}
/**
* Tests whether this line and the line represented by the coordinates ever
* cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports TRUE or FALSE.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param coords a series of X and Y values that constitute a line that might
* intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public BooleanExpression intersects(Coordinate... coords) {
return this.intersects(expression(coords));
}
/**
* Tests whether this line and the other line ever cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports TRUE or FALSE.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param lineString a line that might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public BooleanExpression intersects(LineString lineString) {
return this.intersects(value(lineString));
}
/**
* Tests whether this line and the other line ever cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports TRUE or FALSE.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine a line that might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public BooleanExpression intersects(Line2DResult crossingLine) {
return new BooleanExpression(new IntersectsExpression(this, new Line2DExpression(crossingLine)));
}
/**
* Find all the points of intersection between this value and the specified
* Line2D value.
*
* @param crossingLine a line that might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a MultiPoint2D value containing all the intersection points of the
* 2 lines.
*/
public MultiPoint2DExpression intersectionPoints(Line2DResult crossingLine) {
return new MultiPoint2DExpression(new IntersectionPointsExpression(this, new Line2DExpression(crossingLine)));
}
/**
* Find a point where this line and the other line (represented as a series of
* points) cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports the first point found.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine points that constitute a line that might intersect this
* value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public Point2DExpression intersectionWith(Point... crossingLine) {
return intersectionWith(expression(crossingLine));
}
/**
* Find a point where this line and the other line (represented as a series of
* coordinates) cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports the first point found.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine a series of X and Y values that constitute a line that
* might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public Point2DExpression intersectionWith(Coordinate... crossingLine) {
return intersectionWith(expression(crossingLine));
}
/**
* Find a point where this line and the other line cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports the first point found.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine a line that might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public Point2DExpression intersectionWith(LineString crossingLine) {
return intersectionWith(value(crossingLine));
}
/**
* Find a point where this line and the line derived from the MultiPoint
* cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports the first point found.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine points that constitute a line that might intersect this
* value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public Point2DExpression intersectionWith(MultiPoint2DExpression crossingLine) {
return intersectionWith(expression(crossingLine));
}
/**
* Find a point where this line and the other line cross.
*
* <p>
* Multiple line segments means it may cross at several points, however this
* method only reports the first point found.
*
* <p>
* Use {@link #intersectionPoints(nz.co.gregs.dbvolution.results.Line2DResult)
* } to find the intersection points of these lines
*
* @param crossingLine a line that might intersect this value.
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a BooleanExpression that will be TRUE if the lines ever cross,
* otherwise FALSE.
*/
public Point2DExpression intersectionWith(Line2DResult crossingLine) {
return new Point2DExpression(new IntersectionWithExpression(this, new Line2DExpression(crossingLine)));
}
/**
* Provides a value that represents the line2d value as a polygon2d value.
*
* <P>
* Points are added to the polygon in index order. If necessary the polygon is
* closed by adding the first point to the end.
*
* <p>
* Line2D values with less than 3 points will return NULL values.
*
* @return a polygon2d value
*/
public Polygon2DExpression polygon2DResult() {
throw new UnsupportedOperationException("Line2DExpression does not support polygon2DResult(String) yet.");
}
@Override
public DBLine2D asExpressionColumn() {
return new DBLine2D(this);
}
private static abstract class LineLineWithBooleanResult extends BooleanExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private final Line2DExpression second;
private boolean requiresNullProtection;
LineLineWithBooleanResult(Line2DExpression first, Line2DExpression second) {
this.first = first;
this.second = second;
if (this.second == null || this.second.getIncludesNull()) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
Line2DExpression getSecond() {
return second;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
if (second != null) {
hashSet.addAll(second.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator() || second.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineWithBooleanResult extends BooleanExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private boolean requiresNullProtection;
LineWithBooleanResult(Line2DExpression first) {
this.first = first;
}
Line2DExpression getFirst() {
return first;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineLineWithPoint2DResult extends Point2DExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private final Line2DExpression second;
private boolean requiresNullProtection;
LineLineWithPoint2DResult(Line2DExpression first, Line2DExpression second) {
this.first = first;
this.second = second;
if (this.second == null || this.second.getIncludesNull()) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
Line2DExpression getSecond() {
return second;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
if (second != null) {
hashSet.addAll(second.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator() || second.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineLineWithMultiPoint2DResult extends MultiPoint2DExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private final Line2DExpression second;
private boolean requiresNullProtection;
LineLineWithMultiPoint2DResult(Line2DExpression first, Line2DExpression second) {
this.first = first;
this.second = second;
if (this.second == null || this.second.getIncludesNull()) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
Line2DExpression getSecond() {
return second;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
if (second != null) {
hashSet.addAll(second.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator() || second.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineFunctionWithNumberResult extends NumberExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private boolean requiresNullProtection;
LineFunctionWithNumberResult(Line2DExpression first) {
this.first = first;
if (this.first == null) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineFunctionWithStringResult extends StringExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private boolean requiresNullProtection;
LineFunctionWithStringResult(Line2DExpression first) {
this.first = first;
if (this.first == null) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static abstract class LineFunctionWithPolygon2DResult extends Polygon2DExpression {
private static final long serialVersionUID = 1L;
private final Line2DExpression first;
private boolean requiresNullProtection;
LineFunctionWithPolygon2DResult(Line2DExpression first) {
this.first = first;
if (this.first == null) {
this.requiresNullProtection = true;
}
}
Line2DExpression getFirst() {
return first;
}
@Override
public final String toSQLString(DBDefinition db) {
if (this.getIncludesNull()) {
return BooleanExpression.isNull(first).toSQLString(db);
} else {
return doExpressionTransform(db);
}
}
protected abstract String doExpressionTransform(DBDefinition db);
@Override
public Set<DBRow> getTablesInvolved() {
HashSet<DBRow> hashSet = new HashSet<DBRow>();
if (first != null) {
hashSet.addAll(first.getTablesInvolved());
}
return hashSet;
}
@Override
public boolean isAggregator() {
return first.isAggregator();//|| second.isAggregator();
}
@Override
public boolean getIncludesNull() {
return requiresNullProtection;
}
}
private static class NullExpression extends Line2DExpression {
public NullExpression() {
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getNull();
}
@Override
public Line2DExpression copy() {
return new NullExpression();
}
}
protected static class StringResultExpression extends LineFunctionWithStringResult {
public StringResultExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
protected String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DAsTextTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return getFirst().toSQLString(db);
}
}
@Override
public Line2DExpression.StringResultExpression copy() {
return new Line2DExpression.StringResultExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class IsExpression extends LineLineWithBooleanResult {
public IsExpression(Line2DExpression first, Line2DExpression second) {
super(first, second);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DEqualsTransform(getFirst().toSQLString(db), getSecond().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return getFirst().stringResult().is(getSecond().stringResult()).toSQLString(db);
}
}
@Override
public Line2DExpression.IsExpression copy() {
return new Line2DExpression.IsExpression(
getFirst() == null ? null : getFirst().copy(),
getSecond() == null ? null : getSecond().copy()
);
}
}
protected static class IsNotExpression extends LineLineWithBooleanResult {
public IsNotExpression(Line2DExpression first, Line2DExpression second) {
super(first, second);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition defn) {
try {
return defn.doLine2DNotEqualsTransform(getFirst().toSQLString(defn), getSecond().toSQLString(defn));
} catch (UnsupportedOperationException unsupported) {
return getFirst().stringResult().is(getSecond().stringResult()).not().toSQLString(defn);
}
}
@Override
public Line2DExpression.IsNotExpression copy() {
return new Line2DExpression.IsNotExpression(
getFirst() == null ? null : getFirst().copy(),
getSecond() == null ? null : getSecond().copy()
);
}
}
protected static class MeasurableDimensionsExpression extends LineFunctionWithNumberResult {
public MeasurableDimensionsExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DMeasurableDimensionsTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return NumberExpression.value(1).toSQLString(db);
}
}
@Override
public MeasurableDimensionsExpression copy() {
return new Line2DExpression.MeasurableDimensionsExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class SpatialDimensionsExpression extends LineFunctionWithNumberResult {
public SpatialDimensionsExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DSpatialDimensionsTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return NumberExpression.value(2).toSQLString(db);
}
}
@Override
public SpatialDimensionsExpression copy() {
return new Line2DExpression.SpatialDimensionsExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class HasMagnitudeExpression extends LineWithBooleanResult {
public HasMagnitudeExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DHasMagnitudeTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return BooleanExpression.falseExpression().toSQLString(db);
}
}
@Override
public HasMagnitudeExpression copy() {
return new Line2DExpression.HasMagnitudeExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class MagnitudeExpression extends LineFunctionWithNumberResult {
public MagnitudeExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DGetMagnitudeTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
return nullExpression().toSQLString(db);
}
}
@Override
public MagnitudeExpression copy() {
return new Line2DExpression.MagnitudeExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class BoundingBoxExpression extends LineFunctionWithPolygon2DResult {
public BoundingBoxExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
try {
return db.doLine2DGetBoundingBoxTransform(getFirst().toSQLString(db));
} catch (UnsupportedOperationException unsupported) {
final Line2DExpression first = getFirst();
final NumberExpression maxX = first.maxX();
final NumberExpression maxY = first.maxY();
final NumberExpression minX = first.minX();
final NumberExpression minY = first.minY();
return Polygon2DExpression.value(Point2DExpression.value(minX, minY),
Point2DExpression.value(maxX, minY),
Point2DExpression.value(maxX, maxY),
Point2DExpression.value(minX, maxY),
Point2DExpression.value(minX, minY))
.toSQLString(db);
}
}
@Override
public Line2DExpression.BoundingBoxExpression copy() {
return new Line2DExpression.BoundingBoxExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class MaxXExpression extends LineFunctionWithNumberResult {
public MaxXExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
return db.doLine2DGetMaxXTransform(getFirst().toSQLString(db));
}
@Override
public MaxXExpression copy() {
return new Line2DExpression.MaxXExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class MinXExpression extends LineFunctionWithNumberResult {
public MinXExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
return db.doLine2DGetMinXTransform(getFirst().toSQLString(db));
}
@Override
public MinXExpression copy() {
return new Line2DExpression.MinXExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class MaxYExpression extends LineFunctionWithNumberResult {
public MaxYExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
return db.doLine2DGetMaxYTransform(getFirst().toSQLString(db));
}
@Override
public MaxYExpression copy() {
return new Line2DExpression.MaxYExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class MinYExpression extends LineFunctionWithNumberResult {
public MinYExpression(Line2DExpression first) {
super(first);
}
private final static long serialVersionUID = 1l;
@Override
public String doExpressionTransform(DBDefinition db) {
return db.doLine2DGetMinYTransform(getFirst().toSQLString(db));
}
@Override
public MinYExpression copy() {
return new Line2DExpression.MinYExpression(
getFirst() == null ? null : getFirst().copy()
);
}
}
protected static class IntersectsExpression extends LineLineWithBooleanResult {
public IntersectsExpression(Line2DExpression first, Line2DExpression second) {
super(first, second);
}
private final static long serialVersionUID = 1l;
@Override
protected String doExpressionTransform(DBDefinition db) {
return db.doLine2DIntersectsLine2DTransform(getFirst().toSQLString(db), getSecond().toSQLString(db));
}
@Override
public IntersectsExpression copy() {
return new Line2DExpression.IntersectsExpression(
getFirst() == null ? null : getFirst().copy(),
getSecond() == null ? null : getSecond().copy()
);
}
}
protected static class IntersectionPointsExpression extends LineLineWithMultiPoint2DResult {
public IntersectionPointsExpression(Line2DExpression first, Line2DExpression second) {
super(first, second);
}
private final static long serialVersionUID = 1l;
@Override
protected String doExpressionTransform(DBDefinition db) {
return db.doLine2DAllIntersectionPointsWithLine2DTransform(getFirst().toSQLString(db), getSecond().toSQLString(db));
}
@Override
public IntersectionPointsExpression copy() {
return new Line2DExpression.IntersectionPointsExpression(
getFirst() == null ? null : getFirst().copy(),
getSecond() == null ? null : getSecond().copy()
);
}
}
protected static class IntersectionWithExpression extends LineLineWithPoint2DResult {
public IntersectionWithExpression(Line2DExpression first, Line2DExpression second) {
super(first, second);
}
private final static long serialVersionUID = 1l;
@Override
protected String doExpressionTransform(DBDefinition db) {
return db.doLine2DIntersectionPointWithLine2DTransform(getFirst().toSQLString(db), getSecond().toSQLString(db));
}
@Override
public IntersectionWithExpression copy() {
return new Line2DExpression.IntersectionWithExpression(
getFirst() == null ? null : getFirst().copy(),
getSecond() == null ? null : getSecond().copy()
);
}
}
}