diff --git a/cadc-adql/src/test/java/ca/nrc/cadc/tap/permissions/TapSchemaReadAccessConverterTest.java b/cadc-adql/src/test/java/ca/nrc/cadc/tap/permissions/TapSchemaReadAccessConverterTest.java index c8812c1a..68f8da3e 100644 --- a/cadc-adql/src/test/java/ca/nrc/cadc/tap/permissions/TapSchemaReadAccessConverterTest.java +++ b/cadc-adql/src/test/java/ca/nrc/cadc/tap/permissions/TapSchemaReadAccessConverterTest.java @@ -81,6 +81,7 @@ import javax.security.auth.Subject; +import ca.nrc.cadc.auth.NotAuthenticatedException; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.junit.Assert; diff --git a/cadc-tap-server-oracle/build.gradle b/cadc-tap-server-oracle/build.gradle index 1c4d98bb..68aeb11a 100644 --- a/cadc-tap-server-oracle/build.gradle +++ b/cadc-tap-server-oracle/build.gradle @@ -13,7 +13,7 @@ repositories { apply from: '../opencadc.gradle' sourceCompatibility = 1.8 group = 'org.opencadc' -version = '1.2.11' +version = '1.2.12' description = 'OpenCADC TAP-1.1 tap server plugin (Oracle)' def git_url = 'https://github.com/opencadc/tap' diff --git a/cadc-tap-server-oracle/src/main/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygon.java b/cadc-tap-server-oracle/src/main/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygon.java index 17a1b05c..b8af70fe 100644 --- a/cadc-tap-server-oracle/src/main/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygon.java +++ b/cadc-tap-server-oracle/src/main/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygon.java @@ -71,23 +71,24 @@ import ca.nrc.cadc.dali.Point; import ca.nrc.cadc.dali.Polygon; -import ca.nrc.cadc.tap.parser.RegionFinder; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; import net.sf.jsqlparser.expression.DoubleValue; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +/** + * Represents an Oracle Polygon object. + */ public class OraclePolygon extends OracleGeometricFunction { - private static final int[] ORACLE_ELEMENT_INFO_VALUES = new int[] { 1, 2003, 1 }; @@ -101,55 +102,95 @@ public class OraclePolygon extends OracleGeometricFunction { } } - private final List vertices = new ArrayList<>(); + private final List vertexExpressions = new ArrayList<>(); private OraclePolygon() { super(ORACLE_ELEMENT_INFO); } - public OraclePolygon(final List verticeExpressions) { + public OraclePolygon(final List vertexExpressions) { this(); - if (verticeExpressions != null) { - this.vertices.addAll(verticeExpressions); + if (vertexExpressions != null) { + // Skip the first value as it's the coord sys (e.g. ICRS). + this.vertexExpressions.addAll(vertexExpressions.subList(1, vertexExpressions.size())); } + ensureCounterClockwise(); processOrdinateParameters(); } public OraclePolygon(final Polygon polygon) { this(); - vertices.add(new StringValue(RegionFinder.ICRS)); for (final Point p : polygon.getVertices()) { - vertices.add(new DoubleValue(Double.toString(p.getLongitude()))); - vertices.add(new DoubleValue(Double.toString(p.getLatitude()))); + vertexExpressions.add(new DoubleValue(Double.toString(p.getLongitude()))); + vertexExpressions.add(new DoubleValue(Double.toString(p.getLatitude()))); } + ensureCounterClockwise(); processOrdinateParameters(); } + private void ensureCounterClockwise() { + double edgeSum = 0.0D; + final int length = this.vertexExpressions.size(); + for (int i = 0; i < length; i = i + 2) { + final Expression ra1 = this.vertexExpressions.get(i); + final Expression dec1 = this.vertexExpressions.get(i + 1); + + final Expression ra2; + final Expression dec2; + if (i == length - 2) { + // Back to the beginning if we're on the last vertex. + ra2 = this.vertexExpressions.get(0); + dec2 = this.vertexExpressions.get(1); + } else { + // Back to the beginning if we're on the last vertex. + ra2 = this.vertexExpressions.get(i + 2); + dec2 = this.vertexExpressions.get(i + 3); + } + edgeSum += (Double.parseDouble(ra2.toString()) - Double.parseDouble(ra1.toString())) * + (Double.parseDouble(dec2.toString()) + Double.parseDouble(dec1.toString())); + } + + if (edgeSum > 0.0D) { + final List reversedVertices = new ArrayList<>(); + // Clockwise, so reverse the vertices, but maintain the pairs of points. + for (int i = length - 2; i >= 0; i -= 2) { + reversedVertices.add(this.vertexExpressions.get(i)); + reversedVertices.add(this.vertexExpressions.get(i + 1)); + } + + this.vertexExpressions.clear(); + this.vertexExpressions.addAll(reversedVertices); + } + } + /** * Map this shape's values to ORACLE ORDINATE function parameters. * * @param parameterList The ExpressionList to add parameters to. */ @Override + @SuppressWarnings("unchecked") void mapValues(final ExpressionList parameterList) { - // Start at 1 since the first item will be the coordinate system. - for (int i = 1; i < this.vertices.size(); i = i + 2) { - final Expression ra = this.vertices.get(i); - final Expression dec = this.vertices.get(i + 1); - addNumericExpression(ra, parameterList); - addNumericExpression(dec, parameterList); + final int vertexCount = this.vertexExpressions.size(); + for (int i = 0; i < vertexCount; i = i + 2) { + final Expression ra = this.vertexExpressions.get(i); + final Expression dec = this.vertexExpressions.get(i + 1); + parameterList.getExpressions().add(ra); + parameterList.getExpressions().add(dec); } - } - @SuppressWarnings("unchecked") - void addNumericExpression(final Expression expression, final ExpressionList parameterList) { - if (!(expression instanceof DoubleValue) && !(expression instanceof LongValue)) { - throw new UnsupportedOperationException( - String.format("Cannot use non-constant coordinates in Polygon. Expected Double or Long but found" - + " '%s'", expression.toString())); - } else { - parameterList.getExpressions().add(expression); + final Expression firstVertexXExpression = this.vertexExpressions.get(0); + final Expression firstVertexYExpression = this.vertexExpressions.get(1); + final double firstVertexX = Double.parseDouble(firstVertexXExpression.toString()); + final double firstVertexY = Double.parseDouble(firstVertexYExpression.toString()); + final double lastVertexX = Double.parseDouble(this.vertexExpressions.get(vertexCount - 2).toString()); + final double lastVertexY = Double.parseDouble(this.vertexExpressions.get(vertexCount - 1).toString()); + + // Close the Polygon, if necessary, as per Oracle's requirements. + if (firstVertexX != lastVertexX || firstVertexY != lastVertexY) { + parameterList.getExpressions().add(firstVertexXExpression); + parameterList.getExpressions().add(firstVertexYExpression); } } @@ -164,6 +205,6 @@ public static boolean structMatches(final BigDecimal[] structTypeArray) { final List currValues = Arrays.stream(ORACLE_ELEMENT_INFO_VALUES).boxed().collect(Collectors.toList()); final List structValues = Arrays.stream(structTypeArray).map(BigDecimal::intValue).collect( Collectors.toList()); - return structValues.containsAll(currValues); + return new HashSet<>(structValues).containsAll(currValues); } } diff --git a/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygonTest.java b/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygonTest.java index de108dbb..6794445c 100644 --- a/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygonTest.java +++ b/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/parser/region/function/OraclePolygonTest.java @@ -106,7 +106,18 @@ public void convertParameters() { final Function ordinateArrayFunction = new Function(); final ExpressionList ordinateArrayFunctionParams = new ExpressionList(new ArrayList<>()); ordinateArrayFunction.setName(OraclePolygon.ORDINATE_ARRAY_FUNCTION_NAME); - ordinateArrayFunctionParams.getExpressions().addAll(expressionList.subList(1, expressionList.size())); + + final List expectedExpressionList = new ArrayList<>(); + expectedExpressionList.add(new DoubleValue("288.0")); + expectedExpressionList.add(new DoubleValue("28.0")); + expectedExpressionList.add(new DoubleValue("288.0")); + expectedExpressionList.add(new DoubleValue("388.0")); + expectedExpressionList.add(new DoubleValue("88.0")); + expectedExpressionList.add(new DoubleValue("188.0")); + expectedExpressionList.add(new DoubleValue("288.0")); + expectedExpressionList.add(new DoubleValue("28.0")); + + ordinateArrayFunctionParams.getExpressions().addAll(expectedExpressionList); ordinateArrayFunction.setParameters(ordinateArrayFunctionParams); expectedExpressions.add(new LongValue("2003")); @@ -140,6 +151,8 @@ public void convertParametersFromPolygon() { expectedVertices.add(new DoubleValue("77.9")); expectedVertices.add(new DoubleValue("20.0")); expectedVertices.add(new DoubleValue("-0.8")); + expectedVertices.add(new DoubleValue("44.0")); + expectedVertices.add(new DoubleValue("89.8")); ordinateArrayFunction.setName(OraclePolygon.ORDINATE_ARRAY_FUNCTION_NAME); ordinageArrayFunctionParams.getExpressions().addAll(expectedVertices); diff --git a/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/writer/format/OraclePolygonFormatTest.java b/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/writer/format/OraclePolygonFormatTest.java index 7a0b699e..f3c440b2 100644 --- a/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/writer/format/OraclePolygonFormatTest.java +++ b/cadc-tap-server-oracle/src/test/java/ca/nrc/cadc/tap/writer/format/OraclePolygonFormatTest.java @@ -107,7 +107,7 @@ public void getPolygon() { final Polygon polygon = testSubject.getPolygon(OraclePolygonFormat.POLYGON_FUNCTION + "(0.9, 4.6, 9.0, 10.2, 3.3, 8.7, 12.9, 45.6)"); final List vertices = polygon.getVertices(); - assertEquals("Wrong vertice count.", 4, vertices.size()); + assertEquals("Wrong vertex count.", 4, vertices.size()); } @Test @@ -119,7 +119,7 @@ public void format() { polygon.getVertices().add(new Point(88.4D, -19.2D)); polygon.getVertices().add(new Point(8.6D, 45.3D)); - assertEquals("Wrong output.", "Polygon 88.0 90.0 88.4 -19.2 8.6 45.3", testSubject.format(polygon)); + assertEquals("Wrong output.", "Polygon 8.6 45.3 88.4 -19.2 88.0 90.0", testSubject.format(polygon)); assertEquals("Wrong output from null input.", "", testSubject.format(null)); } diff --git a/cadc-tap/build.gradle b/cadc-tap/build.gradle index c837fef9..9e663f23 100644 --- a/cadc-tap/build.gradle +++ b/cadc-tap/build.gradle @@ -2,7 +2,6 @@ plugins { id "java" id "maven" id 'maven-publish' - id 'com.jfrog.bintray' version '1.8.4' id 'checkstyle' }