* - ISO 19142:2010, cl. A.1.2: Basic WFS
* - ISO 19142:2010, Table 1: Conformance classes (FES Conformance Tests)
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/BBOXTests.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/BBOXTests.java
index 09ae996f..f88ff476 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/BBOXTests.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/BBOXTests.java
@@ -40,9 +40,8 @@
import jakarta.ws.rs.core.Response.Status;
/**
- * Tests the response to a GetFeature request that includes a BBOX predicate.
- * All conforming "Basic WFS" implementations must support this spatial
- * operator.
+ * Tests the response to a GetFeature request that includes a BBOX predicate. All
+ * conforming "Basic WFS" implementations must support this spatial operator.
*
*
* Sources
@@ -54,255 +53,249 @@
*/
public class BBOXTests extends QueryFilterFixture {
- private static final String XSLT_ENV2POLYGON = "/org/opengis/cite/iso19142/util/bbox2polygon.xsl";
- // avoids rounding issues in the GML encoding
- public static final double ENVELOPE_EXPANSION = 0.01;
- private XSTypeDefinition gmlGeomBaseType;
+ private static final String XSLT_ENV2POLYGON = "/org/opengis/cite/iso19142/util/bbox2polygon.xsl";
- /**
- * Creates an XSTypeDefinition object representing the
- * gml:AbstractGeometryType definition.
- */
- @BeforeClass
- public void createGeometryBaseType() {
- this.gmlGeomBaseType = getModel().getTypeDefinition("AbstractGeometryType", Namespaces.GML);
- }
+ // avoids rounding issues in the GML encoding
+ public static final double ENVELOPE_EXPANSION = 0.01;
- /**
- * [{@code Test}] Submits a GetFeature request with a non-specific BBOX
- * predicate. If no value reference is specified the predicate is applied to
- * all spatial properties. The response entity (wfs:FeatureCollection) must
- * be schema-valid and contain only instances of the requested type that
- * satisfy the spatial predicate.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- *
- * @see "ISO 19143:2010, 7.8.3.2: BBOX operator"
- */
- @Test(description = "See ISO 19143: 7.8.3.2", dataProvider = "protocol-featureType")
- public void nonSpecificBBOX(ProtocolBinding binding, QName featureType) {
- List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
- gmlGeomBaseType);
- if (geomProps.isEmpty()) {
- throw new SkipException("Feature type has no geometry properties: " + featureType);
- }
- Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
- Document gmlEnv = null;
- try {
- gmlEnv = envelopeAsGML(extent);
- } catch (Exception e) {
- throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ private XSTypeDefinition gmlGeomBaseType;
+
+ /**
+ * Creates an XSTypeDefinition object representing the gml:AbstractGeometryType
+ * definition.
+ */
+ @BeforeClass
+ public void createGeometryBaseType() {
+ this.gmlGeomBaseType = getModel().getTypeDefinition("AbstractGeometryType", Namespaces.GML);
+ }
+
+ /**
+ * [{@code Test}] Submits a GetFeature request with a non-specific BBOX predicate. If
+ * no value reference is specified the predicate is applied to all spatial properties.
+ * The response entity (wfs:FeatureCollection) must be schema-valid and contain only
+ * instances of the requested type that satisfy the spatial predicate.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ *
+ * @see "ISO 19143:2010, 7.8.3.2: BBOX operator"
+ */
+ @Test(description = "See ISO 19143: 7.8.3.2", dataProvider = "protocol-featureType")
+ public void nonSpecificBBOX(ProtocolBinding binding, QName featureType) {
+ List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
+ gmlGeomBaseType);
+ if (geomProps.isEmpty()) {
+ throw new SkipException("Feature type has no geometry properties: " + featureType);
+ }
+ Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
+ Document gmlEnv = null;
+ try {
+ gmlEnv = envelopeAsGML(extent);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ }
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), null);
+ URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
+ Response rsp = wfsClient.submitRequest(new DOMSource(reqEntity), binding, endpoint);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ Map nsBindings = new HashMap();
+ nsBindings.put(Namespaces.WFS, "wfs");
+ NodeList members;
+ String xpath = "//wfs:member/*";
+ try {
+ members = XMLUtils.evaluateXPath(this.rspEntity, xpath, nsBindings);
+ }
+ catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
}
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), null);
- URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
- Response rsp = wfsClient.submitRequest(new DOMSource(reqEntity), binding, endpoint);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- Map nsBindings = new HashMap();
- nsBindings.put(Namespaces.WFS, "wfs");
- NodeList members;
- String xpath = "//wfs:member/*";
- try {
- members = XMLUtils.evaluateXPath(this.rspEntity, xpath, nsBindings);
- } catch (XPathExpressionException e) {
- throw new RuntimeException(e);
- }
- Assert.assertTrue(members.getLength() > 0, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT,
- this.rspEntity.getDocumentElement().getNodeName(), xpath));
- for (int i = 0; i < members.getLength(); i++) {
- ETSAssert.assertQualifiedName(members.item(i), featureType);
- }
- }
+ Assert.assertTrue(members.getLength() > 0, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT,
+ this.rspEntity.getDocumentElement().getNodeName(), xpath));
+ for (int i = 0; i < members.getLength(); i++) {
+ ETSAssert.assertQualifiedName(members.item(i), featureType);
+ }
+ }
- /**
- * [{@code Test}] Submits a GetFeature request with a BBOX predicate
- * referring to a valid geometry property. The response shall contain only
- * features possessing a geometry value that spatially interacts (i.e. is
- * not disjoint) with the given envelope.
- *
- *
- * Sources
- *
- *
- * - ISO 19143:2010, cl. A.7: Test cases for minimum spatial filter
- * - ISO 19143:2010, 7.8.3.2: BBOX operator
- *
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- *
- */
- @Test(description = "See ISO 19143: 7.8.3.2, A.7", dataProvider = "protocol-featureType")
- public void bboxWithDefaultExtent(ProtocolBinding binding, QName featureType) {
- List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
- gmlGeomBaseType);
- if (geomProps.isEmpty()) {
- throw new SkipException("Feature type has no geometry properties: " + featureType);
- }
- XSElementDeclaration geomProp = geomProps.get(0);
- Element valueRef = WFSMessage.createValueReference(geomProp);
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
- Document gmlEnv = null;
- try {
- gmlEnv = envelopeAsGML(extent);
- } catch (Exception e) {
- throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ /**
+ * [{@code Test}] Submits a GetFeature request with a BBOX predicate referring to a
+ * valid geometry property. The response shall contain only features possessing a
+ * geometry value that spatially interacts (i.e. is not disjoint) with the given
+ * envelope.
+ *
+ *
+ * Sources
+ *
+ *
+ * - ISO 19143:2010, cl. A.7: Test cases for minimum spatial filter
+ * - ISO 19143:2010, 7.8.3.2: BBOX operator
+ *
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ *
+ */
+ @Test(description = "See ISO 19143: 7.8.3.2, A.7", dataProvider = "protocol-featureType")
+ public void bboxWithDefaultExtent(ProtocolBinding binding, QName featureType) {
+ List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
+ gmlGeomBaseType);
+ if (geomProps.isEmpty()) {
+ throw new SkipException("Feature type has no geometry properties: " + featureType);
+ }
+ XSElementDeclaration geomProp = geomProps.get(0);
+ Element valueRef = WFSMessage.createValueReference(geomProp);
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
+ Document gmlEnv = null;
+ try {
+ gmlEnv = envelopeAsGML(extent);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ }
+ addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), valueRef);
+ Response rsp = wfsClient.submitRequest(reqEntity, binding);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ Map nsBindings = new HashMap();
+ nsBindings.put(featureType.getNamespaceURI(), "ns1");
+ String xpath;
+ if (!geomProp.getNamespace().equals(featureType.getNamespaceURI())) {
+ nsBindings.put(geomProp.getNamespace(), "ns2");
+ xpath = String.format("//ns1:%s/ns2:%s/*[1]", featureType.getLocalPart(), geomProp.getName());
+ }
+ else {
+ xpath = String.format("//ns1:%s/ns1:%s/*[1]", featureType.getLocalPart(), geomProp.getName());
}
- addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), valueRef);
- Response rsp = wfsClient.submitRequest(reqEntity, binding);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- Map nsBindings = new HashMap();
- nsBindings.put(featureType.getNamespaceURI(), "ns1");
- String xpath;
- if (!geomProp.getNamespace().equals(featureType.getNamespaceURI())) {
- nsBindings.put(geomProp.getNamespace(), "ns2");
- xpath = String.format("//ns1:%s/ns2:%s/*[1]", featureType.getLocalPart(), geomProp.getName());
- } else {
- xpath = String.format("//ns1:%s/ns1:%s/*[1]", featureType.getLocalPart(), geomProp.getName());
- }
- NodeList geometryNodes;
- try {
- geometryNodes = XMLUtils.evaluateXPath(this.rspEntity, xpath, nsBindings);
- } catch (XPathExpressionException e) {
- throw new RuntimeException(e);
- }
- Assert.assertTrue(geometryNodes.getLength() > 0, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT,
- this.rspEntity.getDocumentElement().getNodeName(), xpath));
- Document gmlPolygon = XMLUtils.transform(new StreamSource(getClass().getResourceAsStream(XSLT_ENV2POLYGON)),
- gmlEnv, null);
- for (int i = 0; i < geometryNodes.getLength(); i++) {
- Element geometry = (Element) geometryNodes.item(i);
- if (geometry.getElementsByTagNameNS(Namespaces.GML, "PolygonPatch").getLength() > 0) {
- // gml:Surface comprised of one or more PolygonPatch elements
- geometry = surfaceToPolygon(geometry);
- }
- boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS,
- gmlPolygon.getDocumentElement(), geometry);
- Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, "BBOX",
- XMLUtils.writeNodeToString(gmlPolygon), XMLUtils.writeNodeToString(geometry)));
- }
- }
+ NodeList geometryNodes;
+ try {
+ geometryNodes = XMLUtils.evaluateXPath(this.rspEntity, xpath, nsBindings);
+ }
+ catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ }
+ Assert.assertTrue(geometryNodes.getLength() > 0, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT,
+ this.rspEntity.getDocumentElement().getNodeName(), xpath));
+ Document gmlPolygon = XMLUtils.transform(new StreamSource(getClass().getResourceAsStream(XSLT_ENV2POLYGON)),
+ gmlEnv, null);
+ for (int i = 0; i < geometryNodes.getLength(); i++) {
+ Element geometry = (Element) geometryNodes.item(i);
+ if (geometry.getElementsByTagNameNS(Namespaces.GML, "PolygonPatch").getLength() > 0) {
+ // gml:Surface comprised of one or more PolygonPatch elements
+ geometry = surfaceToPolygon(geometry);
+ }
+ boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS,
+ gmlPolygon.getDocumentElement(), geometry);
+ Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, "BBOX",
+ XMLUtils.writeNodeToString(gmlPolygon), XMLUtils.writeNodeToString(geometry)));
+ }
+ }
- /**
- * Work around for Extents{@link #envelopeAsGML(Envelope)} only using 2 decimals
- *
- * @param extent the envelope
- * @return the envelope as GML
- */
- public Document envelopeAsGML(Envelope extent) {
- double[] low = new double[extent.getDimension()];
- double[] high = new double[extent.getDimension()];
- for (int i = 0; i < extent.getDimension(); i++) {
- low[i] = extent.getMinimum(i) - ENVELOPE_EXPANSION;
- high[i] = extent.getMaximum(i) + ENVELOPE_EXPANSION;
- }
- GeneralEnvelope expanded = new GeneralEnvelope(low, high);
- expanded.setCoordinateReferenceSystem(extent.getCoordinateReferenceSystem());
- return Extents.envelopeAsGML(expanded);
- }
+ /**
+ * Work around for Extents{@link #envelopeAsGML(Envelope)} only using 2 decimals
+ * @param extent the envelope
+ * @return the envelope as GML
+ */
+ public Document envelopeAsGML(Envelope extent) {
+ double[] low = new double[extent.getDimension()];
+ double[] high = new double[extent.getDimension()];
+ for (int i = 0; i < extent.getDimension(); i++) {
+ low[i] = extent.getMinimum(i) - ENVELOPE_EXPANSION;
+ high[i] = extent.getMaximum(i) + ENVELOPE_EXPANSION;
+ }
+ GeneralEnvelope expanded = new GeneralEnvelope(low, high);
+ expanded.setCoordinateReferenceSystem(extent.getCoordinateReferenceSystem());
+ return Extents.envelopeAsGML(expanded);
+ }
- /**
- * [{@code Test}] Submits a GetFeature request where the BBOX predicate
- * refers to a feature property (gml:description) that is not
- * geometry-valued. An exception is expected in response with status code
- * 400 and exception code {@code InvalidParameterValue}.
- *
- * @param featureType
- * A QName representing the qualified name of a feature type for
- * which instances exist.
- *
- * @see "ISO 19142:2010, 11.4: GetFeature - Exceptions"
- * @see "ISO 19143:2010, 8.3: Exceptions"
- */
- @Test(description = "See ISO 19142: 11.4; ISO 19143: 8.3", dataProvider = "instantiated-feature-types")
- public void invalidGeometryOperand(QName featureType) {
- XSElementDeclaration gmlDesc = getModel().getElementDeclaration("description", Namespaces.GML);
- Element valueRef = WFSMessage.createValueReference(gmlDesc);
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Envelope extent = featureInfo.get(featureType).getSpatialExtent();
- Document gmlEnv = null;
- try {
- gmlEnv = envelopeAsGML(extent);
- } catch (Exception e) {
- throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ /**
+ * [{@code Test}] Submits a GetFeature request where the BBOX predicate refers to a
+ * feature property (gml:description) that is not geometry-valued. An exception is
+ * expected in response with status code 400 and exception code
+ * {@code InvalidParameterValue}.
+ * @param featureType A QName representing the qualified name of a feature type for
+ * which instances exist.
+ *
+ * @see "ISO 19142:2010, 11.4: GetFeature - Exceptions"
+ * @see "ISO 19143:2010, 8.3: Exceptions"
+ */
+ @Test(description = "See ISO 19142: 11.4; ISO 19143: 8.3", dataProvider = "instantiated-feature-types")
+ public void invalidGeometryOperand(QName featureType) {
+ XSElementDeclaration gmlDesc = getModel().getElementDeclaration("description", Namespaces.GML);
+ Element valueRef = WFSMessage.createValueReference(gmlDesc);
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Envelope extent = featureInfo.get(featureType).getSpatialExtent();
+ Document gmlEnv = null;
+ try {
+ gmlEnv = envelopeAsGML(extent);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ }
+ addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), valueRef);
+ Response rsp = wfsClient.submitRequest(reqEntity, ProtocolBinding.ANY);
+ this.rspEntity = rsp.readEntity(Document.class);
+ // https://github.com/opengeospatial/ets-wfs20/issues/147
+ // Agreed solution to this issue is to also allow OperationProcessingFailed
+ // (Status Code 403) as valid exception type.
+ int statusCode = rsp.getStatus();
+ if (statusCode == Status.BAD_REQUEST.getStatusCode()) {
+ String xpath = "//ows:Exception[@exceptionCode='InvalidParameterValue']";
+ ETSAssert.assertXPath(xpath, this.rspEntity, null);
}
- addBBOXPredicate(this.reqEntity, gmlEnv.getDocumentElement(), valueRef);
- Response rsp = wfsClient.submitRequest(reqEntity, ProtocolBinding.ANY);
- this.rspEntity = rsp.readEntity(Document.class);
- //https://github.com/opengeospatial/ets-wfs20/issues/147
- //Agreed solution to this issue is to also allow OperationProcessingFailed (Status Code 403) as valid exception type.
- int statusCode = rsp.getStatus();
- if(statusCode == Status.BAD_REQUEST.getStatusCode()) {
- String xpath = "//ows:Exception[@exceptionCode='InvalidParameterValue']";
- ETSAssert.assertXPath(xpath, this.rspEntity, null);
- } else if(statusCode == Status.FORBIDDEN.getStatusCode()) {
- String xpath = "//ows:Exception[@exceptionCode='OperationProcessingFailed']";
- ETSAssert.assertXPath(xpath, this.rspEntity, null);
- } else {
- Assert.fail(ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- }
- }
+ else if (statusCode == Status.FORBIDDEN.getStatusCode()) {
+ String xpath = "//ows:Exception[@exceptionCode='OperationProcessingFailed']";
+ ETSAssert.assertXPath(xpath, this.rspEntity, null);
+ }
+ else {
+ Assert.fail(ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ }
+ }
+
+ // bboxWithOtherCRS
+ // bboxWithUnsupportedCRS
- // bboxWithOtherCRS
- // bboxWithUnsupportedCRS
+ /**
+ * Replaces gml:Surface elements having a single gml:PolygonPatch with a gml:Polygon
+ * element. Such a simplification facilitates a binding to JTS geometry objects.
+ * @param geometry A GML geometry collection.
+ * @return A new DOM Element containing a simplified representation of the original
+ * geometry collection.
+ *
+ * @see "ISO 19125-1: Geographic information -- Simple feature access -- Part 1:
+ * Common architecture"
+ */
+ Element surfaceToPolygon(Element geometry) {
+ Document result = XMLUtils.transform(new StreamSource(getClass().getResourceAsStream("surface2polygon.xsl")),
+ geometry, null);
+ return result.getDocumentElement();
+ }
- /**
- * Replaces gml:Surface elements having a single gml:PolygonPatch with a
- * gml:Polygon element. Such a simplification facilitates a binding to JTS
- * geometry objects.
- *
- * @param geometry
- * A GML geometry collection.
- * @return A new DOM Element containing a simplified representation of the
- * original geometry collection.
- *
- * @see "ISO 19125-1: Geographic information -- Simple feature access --
- * Part 1: Common architecture"
- */
- Element surfaceToPolygon(Element geometry) {
- Document result = XMLUtils.transform(new StreamSource(getClass().getResourceAsStream("surface2polygon.xsl")),
- geometry, null);
- return result.getDocumentElement();
- }
+ /**
+ * Adds a BBOX spatial predicate to a GetFeature request entity. If the envelope has
+ * no spatial reference (srsName) it is assumed to be the default CRS specified in the
+ * capabilities document.
+ * @param request The request entity (/wfs:GetFeature).
+ * @param envelope A DOM Element representing a gml:Envelope.
+ * @param valueRef An Element (fes:ValueReference) that specifies the spatial property
+ * to check. If it is {@code null}, the predicate applies to all spatial properties.
+ */
+ void addBBOXPredicate(Document request, Element envelope, Element valueRef) {
+ if (!request.getDocumentElement().getLocalName().equals(WFS2.GET_FEATURE)) {
+ throw new IllegalArgumentException(
+ "Not a GetFeature request: " + request.getDocumentElement().getNodeName());
+ }
+ Element queryElem = (Element) request.getElementsByTagNameNS(Namespaces.WFS, WFS2.QUERY_ELEM).item(0);
+ Element filter = request.createElementNS(Namespaces.FES, "fes:Filter");
+ queryElem.appendChild(filter);
+ Element bbox = request.createElementNS(Namespaces.FES, "fes:BBOX");
+ filter.appendChild(bbox);
+ if (null != valueRef) {
+ bbox.appendChild(request.importNode(valueRef, true));
+ }
+ // import envelope node to avoid WRONG_DOCUMENT_ERR
+ bbox.appendChild(request.importNode(envelope, true));
+ }
- /**
- * Adds a BBOX spatial predicate to a GetFeature request entity. If the
- * envelope has no spatial reference (srsName) it is assumed to be the
- * default CRS specified in the capabilities document.
- *
- * @param request
- * The request entity (/wfs:GetFeature).
- * @param envelope
- * A DOM Element representing a gml:Envelope.
- * @param valueRef
- * An Element (fes:ValueReference) that specifies the spatial
- * property to check. If it is {@code null}, the predicate
- * applies to all spatial properties.
- */
- void addBBOXPredicate(Document request, Element envelope, Element valueRef) {
- if (!request.getDocumentElement().getLocalName().equals(WFS2.GET_FEATURE)) {
- throw new IllegalArgumentException(
- "Not a GetFeature request: " + request.getDocumentElement().getNodeName());
- }
- Element queryElem = (Element) request.getElementsByTagNameNS(Namespaces.WFS, WFS2.QUERY_ELEM).item(0);
- Element filter = request.createElementNS(Namespaces.FES, "fes:Filter");
- queryElem.appendChild(filter);
- Element bbox = request.createElementNS(Namespaces.FES, "fes:BBOX");
- filter.appendChild(bbox);
- if (null != valueRef) {
- bbox.appendChild(request.importNode(valueRef, true));
- }
- // import envelope node to avoid WRONG_DOCUMENT_ERR
- bbox.appendChild(request.importNode(envelope, true));
- }
}
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/IntersectsTests.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/IntersectsTests.java
index e73805e0..fcafdbb4 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/IntersectsTests.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/IntersectsTests.java
@@ -49,311 +49,298 @@
import jakarta.ws.rs.core.Response.Status;
/**
- * Tests the response to a GetFeature request that includes the spatial
- * predicate Intersects. This predicate is the logical complement of
- * the Disjoint predicate; that is:
- *
+ * Tests the response to a GetFeature request that includes the spatial predicate
+ * Intersects. This predicate is the logical complement of the Disjoint
+ * predicate; that is:
+ *
*
* a.Intersects(b) ⇔ ! a.Disjoint(b)
*
- *
+ *
* @see "OGC 09-026r2, A.8: Test cases for spatial filter"
* @see "ISO 19125-1, 6.1.15.3"
*/
public class IntersectsTests extends QueryFilterFixture {
- public final static String IMPL_SPATIAL_FILTER = "ImplementsSpatialFilter";
- private static final String INTERSECTS_OP = "Intersects";
- private Map> allGeomProperties;
- private Set geomOperands;
- private static final String XSLT_ENV2POLYGON = "/org/opengis/cite/iso19142/util/bbox2polygon.xsl";
+ public final static String IMPL_SPATIAL_FILTER = "ImplementsSpatialFilter";
- /**
- * Checks the value of the filter constraint {@value #IMPL_SPATIAL_FILTER}
- * in the capabilities document. All tests are skipped if this is not
- * "TRUE".
- *
- * @param testContext
- * Information about the test run environment.
- */
- @BeforeTest
- public void implementsSpatialFilter(ITestContext testContext) {
- this.wfsMetadata = (Document) testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJECT.getName());
- String xpath = String.format("//fes:Constraint[@name='%s' and (ows:DefaultValue = 'TRUE')]",
- IMPL_SPATIAL_FILTER);
- NodeList result;
- try {
- result = XMLUtils.evaluateXPath(this.wfsMetadata, xpath, null);
- } catch (XPathExpressionException e) {
- throw new AssertionError(e.getMessage());
- }
- if (result.getLength() == 0) {
- throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, IMPL_SPATIAL_FILTER));
- }
- }
+ private static final String INTERSECTS_OP = "Intersects";
- /**
- * Finds the geometry properties for all feature types recognized by the
- * SUT.
- */
- @BeforeClass
- public void findAllGeometryProperties() {
- XSTypeDefinition geomBaseType = getModel().getTypeDefinition("AbstractGeometryType", Namespaces.GML);
- this.allGeomProperties = new HashMap<>();
- for (QName featureType : this.featureTypes) {
- List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
- geomBaseType);
- if (!geomProps.isEmpty()) {
- this.allGeomProperties.put(featureType, geomProps);
- }
- }
- }
+ private Map> allGeomProperties;
- /**
- * Checks if the spatial operator "Intersects" is implemented and which
- * geometry operands are supported. If it's not implemented, all tests for
- * this operator are skipped.
- */
- @BeforeClass
- public void implementsIntersectsOp() {
- Map> capabilities = ServiceMetadataUtils.getSpatialCapabilities(this.wfsMetadata);
- if (!capabilities.containsKey(SpatialOperator.INTERSECTS)) {
- throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, SpatialOperator.INTERSECTS));
- }
- this.geomOperands = capabilities.get(SpatialOperator.INTERSECTS);
- }
+ private Set geomOperands;
- /**
- * [{@code Test}] Submits a GetFeature request containing an Intersects
- * predicate with a gml:Polygon operand. The response entity must be
- * schema-valid and contain only matching instances.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See OGC 09-026r2, A.8", dataProvider = "protocol-featureType")
- public void intersectsPolygon(ProtocolBinding binding, QName featureType) throws XPathExpressionException {
- if (!this.allGeomProperties.keySet().contains(featureType)) {
- throw new SkipException("Feature type has no geometry properties: " + featureType);
- }
- QName gmlPolygon = new QName(Namespaces.GML, GML32.POLYGON);
- if (!this.geomOperands.contains(gmlPolygon)) {
- throw new SkipException("Unsupported geometry operand: " + gmlPolygon);
- }
- Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
- Document gmlEnv = null;
- try {
- gmlEnv = Extents.envelopeAsGML(extent);
- } catch (Exception e) {
- throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ private static final String XSLT_ENV2POLYGON = "/org/opengis/cite/iso19142/util/bbox2polygon.xsl";
+
+ /**
+ * Checks the value of the filter constraint {@value #IMPL_SPATIAL_FILTER} in the
+ * capabilities document. All tests are skipped if this is not "TRUE".
+ * @param testContext Information about the test run environment.
+ */
+ @BeforeTest
+ public void implementsSpatialFilter(ITestContext testContext) {
+ this.wfsMetadata = (Document) testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJECT.getName());
+ String xpath = String.format("//fes:Constraint[@name='%s' and (ows:DefaultValue = 'TRUE')]",
+ IMPL_SPATIAL_FILTER);
+ NodeList result;
+ try {
+ result = XMLUtils.evaluateXPath(this.wfsMetadata, xpath, null);
+ }
+ catch (XPathExpressionException e) {
+ throw new AssertionError(e.getMessage());
+ }
+ if (result.getLength() == 0) {
+ throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, IMPL_SPATIAL_FILTER));
+ }
+ }
+
+ /**
+ * Finds the geometry properties for all feature types recognized by the SUT.
+ */
+ @BeforeClass
+ public void findAllGeometryProperties() {
+ XSTypeDefinition geomBaseType = getModel().getTypeDefinition("AbstractGeometryType", Namespaces.GML);
+ this.allGeomProperties = new HashMap<>();
+ for (QName featureType : this.featureTypes) {
+ List geomProps = AppSchemaUtils.getFeaturePropertiesByType(getModel(), featureType,
+ geomBaseType);
+ if (!geomProps.isEmpty()) {
+ this.allGeomProperties.put(featureType, geomProps);
+ }
+ }
+ }
+
+ /**
+ * Checks if the spatial operator "Intersects" is implemented and which geometry
+ * operands are supported. If it's not implemented, all tests for this operator are
+ * skipped.
+ */
+ @BeforeClass
+ public void implementsIntersectsOp() {
+ Map> capabilities = ServiceMetadataUtils.getSpatialCapabilities(this.wfsMetadata);
+ if (!capabilities.containsKey(SpatialOperator.INTERSECTS)) {
+ throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, SpatialOperator.INTERSECTS));
+ }
+ this.geomOperands = capabilities.get(SpatialOperator.INTERSECTS);
+ }
+
+ /**
+ * [{@code Test}] Submits a GetFeature request containing an Intersects predicate with
+ * a gml:Polygon operand. The response entity must be schema-valid and contain only
+ * matching instances.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See OGC 09-026r2, A.8", dataProvider = "protocol-featureType")
+ public void intersectsPolygon(ProtocolBinding binding, QName featureType) throws XPathExpressionException {
+ if (!this.allGeomProperties.keySet().contains(featureType)) {
+ throw new SkipException("Feature type has no geometry properties: " + featureType);
+ }
+ QName gmlPolygon = new QName(Namespaces.GML, GML32.POLYGON);
+ if (!this.geomOperands.contains(gmlPolygon)) {
+ throw new SkipException("Unsupported geometry operand: " + gmlPolygon);
+ }
+ Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
+ Document gmlEnv = null;
+ try {
+ gmlEnv = Extents.envelopeAsGML(extent);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ }
+ Element gmlPolygonElem = XMLUtils
+ .transform(new StreamSource(getClass().getResourceAsStream(XSLT_ENV2POLYGON)), gmlEnv, null)
+ .getDocumentElement();
+ List geomProps = this.allGeomProperties.get(featureType);
+ Iterator itr = geomProps.iterator();
+ XSElementDeclaration geomProperty = null;
+ XSElementDeclaration value = null;
+ while (itr.hasNext()) {
+ geomProperty = itr.next();
+ value = AppSchemaUtils.getComplexPropertyValue(geomProperty);
+ // this also filters out MultiPoint geometry types, see
+ // https://github.com/opengeospatial/ets-wfs20/issues/236
+ if (!value.getName().contains(GML32.POINT))
+ break;
}
- Element gmlPolygonElem = XMLUtils
- .transform(new StreamSource(getClass().getResourceAsStream(XSLT_ENV2POLYGON)), gmlEnv, null)
- .getDocumentElement();
- List geomProps = this.allGeomProperties.get(featureType);
- Iterator itr = geomProps.iterator();
- XSElementDeclaration geomProperty = null;
- XSElementDeclaration value = null;
- while (itr.hasNext()) {
- geomProperty = itr.next();
- value = AppSchemaUtils.getComplexPropertyValue(geomProperty);
- // this also filters out MultiPoint geometry types, see https://github.com/opengeospatial/ets-wfs20/issues/236
- if (!value.getName().contains(GML32.POINT))
- break;
- }
- if(value.getName().contains(GML32.POINT)){
- // ignore point property--unlikely to intersect line
- throw new SkipException("Intersects tests are not supported for point geometry types.");
- }
- this.reqEntity = buildGetFeatureRequest(featureType, INTERSECTS_OP, geomProperty, gmlPolygonElem);
- URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
- Response rsp = wfsClient.submitRequest(new DOMSource(reqEntity), binding, endpoint);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- NodeList geomNodes = findGeometryPropertyValues(featureType, geomProperty);
- if (geomNodes.getLength() == 0) {
- TestSuiteLogger.log(Level.INFO, String.format(
- "intersectsPolygon: No values found for geometry property %s (in %s)", geomProperty, featureType));
- }
- for (int i = 0; i < geomNodes.getLength(); i++) {
- Node geom = geomNodes.item(i);
- if (GmlUtils.checkForAbstractSurfacePatchTypes(geom)) {
- geom = GmlUtils.handleAbstractSurfacePatch(geom);
- }
- boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS, gmlPolygonElem,
- geom);
- Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, INTERSECTS_OP,
- XMLUtils.writeNodeToString(gmlPolygonElem), XMLUtils.writeNodeToString(geom)));
- }
- }
+ if (value.getName().contains(GML32.POINT)) {
+ // ignore point property--unlikely to intersect line
+ throw new SkipException("Intersects tests are not supported for point geometry types.");
+ }
+ this.reqEntity = buildGetFeatureRequest(featureType, INTERSECTS_OP, geomProperty, gmlPolygonElem);
+ URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
+ Response rsp = wfsClient.submitRequest(new DOMSource(reqEntity), binding, endpoint);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ NodeList geomNodes = findGeometryPropertyValues(featureType, geomProperty);
+ if (geomNodes.getLength() == 0) {
+ TestSuiteLogger.log(Level.INFO, String.format(
+ "intersectsPolygon: No values found for geometry property %s (in %s)", geomProperty, featureType));
+ }
+ for (int i = 0; i < geomNodes.getLength(); i++) {
+ Node geom = geomNodes.item(i);
+ if (GmlUtils.checkForAbstractSurfacePatchTypes(geom)) {
+ geom = GmlUtils.handleAbstractSurfacePatch(geom);
+ }
+ boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS, gmlPolygonElem,
+ geom);
+ Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, INTERSECTS_OP,
+ XMLUtils.writeNodeToString(gmlPolygonElem), XMLUtils.writeNodeToString(geom)));
+ }
+ }
- /**
- * [{@code Test}] Submits a GetFeature request containing an
- * Intersects predicate with a gml:LineString or gml:Curve
- * (LineStringSegment) operand. The response entity must be schema-valid and
- * contain only matching instances.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See OGC 09-026r2, A.8", dataProvider = "protocol-featureType")
- public void intersectsCurve(ProtocolBinding binding, QName featureType) throws XPathExpressionException {
- if (!this.allGeomProperties.keySet().contains(featureType)) {
- throw new SkipException("Feature type has no geometry properties: " + featureType);
- }
- QName gmlCurve = new QName(Namespaces.GML, GML32.LINE_STRING);
- if (!this.geomOperands.contains(gmlCurve)) {
- gmlCurve = new QName(Namespaces.GML, GML32.CURVE);
- if (!this.geomOperands.contains(gmlCurve)) {
- throw new SkipException("Unsupported geometry operands: gml:LineString, gml:Curve");
- }
- }
- Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
- Document gmlEnv = null;
- try {
- gmlEnv = Extents.envelopeAsGML(extent);
- } catch (Exception e) {
- throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ /**
+ * [{@code Test}] Submits a GetFeature request containing an
+ * Intersects predicate with a gml:LineString or gml:Curve
+ * (LineStringSegment) operand. The response entity must be schema-valid and contain
+ * only matching instances.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See OGC 09-026r2, A.8", dataProvider = "protocol-featureType")
+ public void intersectsCurve(ProtocolBinding binding, QName featureType) throws XPathExpressionException {
+ if (!this.allGeomProperties.keySet().contains(featureType)) {
+ throw new SkipException("Feature type has no geometry properties: " + featureType);
+ }
+ QName gmlCurve = new QName(Namespaces.GML, GML32.LINE_STRING);
+ if (!this.geomOperands.contains(gmlCurve)) {
+ gmlCurve = new QName(Namespaces.GML, GML32.CURVE);
+ if (!this.geomOperands.contains(gmlCurve)) {
+ throw new SkipException("Unsupported geometry operands: gml:LineString, gml:Curve");
+ }
+ }
+ Envelope extent = this.dataSampler.getSpatialExtent(getModel(), featureType);
+ Document gmlEnv = null;
+ try {
+ gmlEnv = Extents.envelopeAsGML(extent);
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Could not create envelope for feature type: " + featureType);
+ }
+ Element gmlCurveElem = XMLUtils
+ .transform(new StreamSource(getClass().getResourceAsStream("envelopeTocurve.xsl")), gmlEnv,
+ Collections.singletonMap("curveType", gmlCurve.getLocalPart()))
+ .getDocumentElement();
+ List geomProps = this.allGeomProperties.get(featureType);
+ Iterator itr = geomProps.iterator();
+ XSElementDeclaration geomProperty = null;
+ XSElementDeclaration value = null;
+ while (itr.hasNext()) {
+ geomProperty = itr.next();
+ value = AppSchemaUtils.getComplexPropertyValue(geomProperty);
+ // this also filters out MultiPoint geometry types, see
+ // https://github.com/opengeospatial/ets-wfs20/issues/236
+ if (!value.getName().contains(GML32.POINT))
+ break;
}
- Element gmlCurveElem = XMLUtils
- .transform(new StreamSource(getClass().getResourceAsStream("envelopeTocurve.xsl")), gmlEnv,
- Collections.singletonMap("curveType", gmlCurve.getLocalPart()))
- .getDocumentElement();
- List geomProps = this.allGeomProperties.get(featureType);
- Iterator itr = geomProps.iterator();
- XSElementDeclaration geomProperty = null;
- XSElementDeclaration value = null;
- while (itr.hasNext()) {
- geomProperty = itr.next();
- value = AppSchemaUtils.getComplexPropertyValue(geomProperty);
- // this also filters out MultiPoint geometry types, see https://github.com/opengeospatial/ets-wfs20/issues/236
- if (!value.getName().contains(GML32.POINT))
- break;
- }
- if(value.getName().contains(GML32.POINT)){
- // ignore point property--unlikely to intersect line
- throw new SkipException("Intersects tests are not supported for point geometry types.");
- }
+ if (value.getName().contains(GML32.POINT)) {
+ // ignore point property--unlikely to intersect line
+ throw new SkipException("Intersects tests are not supported for point geometry types.");
+ }
- this.reqEntity = buildGetFeatureRequest(featureType, INTERSECTS_OP, geomProperty, gmlCurveElem);
- URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
- Response rsp = wfsClient.submitRequest(new DOMSource(this.reqEntity), binding, endpoint);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- NodeList geomNodes = findGeometryPropertyValues(featureType, geomProperty);
- if (geomNodes.getLength() == 0) {
- TestSuiteLogger.log(Level.INFO, String.format(
- "intersectsCurve: No values found for geometry property %s (in %s)", geomProperty, featureType));
- }
- for (int i = 0; i < geomNodes.getLength(); i++) {
- Node geom = geomNodes.item(i);
- if (GmlUtils.checkForAbstractSurfacePatchTypes(geom)) {
- geom = GmlUtils.handleAbstractSurfacePatch(geom);
- }
- boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS, gmlCurveElem,
- geom);
- Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, INTERSECTS_OP,
- XMLUtils.writeNodeToString(gmlCurveElem), XMLUtils.writeNodeToString(geom)));
- }
- }
+ this.reqEntity = buildGetFeatureRequest(featureType, INTERSECTS_OP, geomProperty, gmlCurveElem);
+ URI endpoint = ServiceMetadataUtils.getOperationEndpoint(this.wfsMetadata, WFS2.GET_FEATURE, binding);
+ Response rsp = wfsClient.submitRequest(new DOMSource(this.reqEntity), binding, endpoint);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ NodeList geomNodes = findGeometryPropertyValues(featureType, geomProperty);
+ if (geomNodes.getLength() == 0) {
+ TestSuiteLogger.log(Level.INFO, String.format(
+ "intersectsCurve: No values found for geometry property %s (in %s)", geomProperty, featureType));
+ }
+ for (int i = 0; i < geomNodes.getLength(); i++) {
+ Node geom = geomNodes.item(i);
+ if (GmlUtils.checkForAbstractSurfacePatchTypes(geom)) {
+ geom = GmlUtils.handleAbstractSurfacePatch(geom);
+ }
+ boolean intersects = TopologicalRelationships.isSpatiallyRelated(SpatialOperator.INTERSECTS, gmlCurveElem,
+ geom);
+ Assert.assertTrue(intersects, ErrorMessage.format(ErrorMessageKeys.PREDICATE_NOT_SATISFIED, INTERSECTS_OP,
+ XMLUtils.writeNodeToString(gmlCurveElem), XMLUtils.writeNodeToString(geom)));
+ }
+ }
- // intersectsCurve (corner points of bbox) - other CRS
- // intersectsCircle (corner points of bbox) - default CRS
+ // intersectsCurve (corner points of bbox) - other CRS
+ // intersectsCircle (corner points of bbox) - default CRS
- /**
- * Builds a simple GetFeature request entity that contains a basic filter
- * expression.
- *
- * @param featureType
- * The name of the feature type.
- * @param operator
- * The name of the filter predicate (operator).
- * @param propertyDecl
- * The declaration of the feature property to be queried.
- * @param literal
- * An element representing the literal value to match.
- * @return A Document containing a request entity with wfs:GetFeature as the
- * document element.
- */
- Document buildGetFeatureRequest(QName featureType, String operator, XSElementDeclaration propertyDecl,
- Element literal) {
- Document entity = WFSMessage.createRequestEntity(GET_FEATURE_MINIMAL, this.wfsVersion);
- WFSMessage.appendSimpleQuery(entity, featureType);
- Element valueRef = WFSMessage.createValueReference(propertyDecl);
- addSpatialPredicate(entity, operator, literal, valueRef);
- return entity;
- }
+ /**
+ * Builds a simple GetFeature request entity that contains a basic filter expression.
+ * @param featureType The name of the feature type.
+ * @param operator The name of the filter predicate (operator).
+ * @param propertyDecl The declaration of the feature property to be queried.
+ * @param literal An element representing the literal value to match.
+ * @return A Document containing a request entity with wfs:GetFeature as the document
+ * element.
+ */
+ Document buildGetFeatureRequest(QName featureType, String operator, XSElementDeclaration propertyDecl,
+ Element literal) {
+ Document entity = WFSMessage.createRequestEntity(GET_FEATURE_MINIMAL, this.wfsVersion);
+ WFSMessage.appendSimpleQuery(entity, featureType);
+ Element valueRef = WFSMessage.createValueReference(propertyDecl);
+ addSpatialPredicate(entity, operator, literal, valueRef);
+ return entity;
+ }
- /**
- * Adds a spatial predicate to a GetFeature request entity. If the given
- * geometry element has no spatial reference (srsName) it is assumed to use
- * the default CRS specified in the capabilities document.
- *
- * @param request
- * The request entity (wfs:GetFeature).
- * @param spatialOp
- * The name of a spatial operator.
- * @param gmlGeom
- * A DOM Element representing a GML geometry.
- * @param valueRef
- * An Element (fes:ValueReference) that specifies the spatial
- * property to check. If it is {@code null}, the predicate
- * applies to all spatial properties.
- */
- void addSpatialPredicate(Document request, String spatialOp, Element gmlGeom, Element valueRef) {
- if (!request.getDocumentElement().getLocalName().equals(WFS2.GET_FEATURE)) {
- throw new IllegalArgumentException(
- "Not a GetFeature request: " + request.getDocumentElement().getNodeName());
- }
- Element queryElem = (Element) request.getElementsByTagNameNS(Namespaces.WFS, WFS2.QUERY_ELEM).item(0);
- if (null == queryElem) {
- throw new IllegalArgumentException("No Query element found in GetFeature request entity.");
- }
- Element filter = request.createElementNS(Namespaces.FES, "fes:Filter");
- queryElem.appendChild(filter);
- Element predicate = request.createElementNS(Namespaces.FES, "fes:" + spatialOp);
- filter.appendChild(predicate);
- if (null != valueRef) {
- predicate.appendChild(request.importNode(valueRef, true));
- }
- // import geometry element to avoid WRONG_DOCUMENT_ERR
- predicate.appendChild(request.importNode(gmlGeom, true));
- }
+ /**
+ * Adds a spatial predicate to a GetFeature request entity. If the given geometry
+ * element has no spatial reference (srsName) it is assumed to use the default CRS
+ * specified in the capabilities document.
+ * @param request The request entity (wfs:GetFeature).
+ * @param spatialOp The name of a spatial operator.
+ * @param gmlGeom A DOM Element representing a GML geometry.
+ * @param valueRef An Element (fes:ValueReference) that specifies the spatial property
+ * to check. If it is {@code null}, the predicate applies to all spatial properties.
+ */
+ void addSpatialPredicate(Document request, String spatialOp, Element gmlGeom, Element valueRef) {
+ if (!request.getDocumentElement().getLocalName().equals(WFS2.GET_FEATURE)) {
+ throw new IllegalArgumentException(
+ "Not a GetFeature request: " + request.getDocumentElement().getNodeName());
+ }
+ Element queryElem = (Element) request.getElementsByTagNameNS(Namespaces.WFS, WFS2.QUERY_ELEM).item(0);
+ if (null == queryElem) {
+ throw new IllegalArgumentException("No Query element found in GetFeature request entity.");
+ }
+ Element filter = request.createElementNS(Namespaces.FES, "fes:Filter");
+ queryElem.appendChild(filter);
+ Element predicate = request.createElementNS(Namespaces.FES, "fes:" + spatialOp);
+ filter.appendChild(predicate);
+ if (null != valueRef) {
+ predicate.appendChild(request.importNode(valueRef, true));
+ }
+ // import geometry element to avoid WRONG_DOCUMENT_ERR
+ predicate.appendChild(request.importNode(gmlGeom, true));
+ }
- private NodeList findGeometryPropertyValues( QName featureType, XSElementDeclaration geomProperty )
- throws XPathExpressionException {
- String featureTypeNs = featureType.getNamespaceURI();
- String featureTypePrefix = getFeatureTypePrefix( featureType );
- String geomPropNs = geomProperty.getNamespace();
- String geomPropPrefix = getGeomPropPrefix( featureTypeNs, featureTypePrefix, geomPropNs );
- String xpath = String.format( "//%s:%s/%s:%s/*", featureTypePrefix, featureType.getLocalPart(), geomPropPrefix,
- geomProperty.getName() );
- Map nsBindings = new HashMap<>();
- nsBindings.put( featureTypeNs, featureTypePrefix );
- if ( !geomPropPrefix.equals( featureTypePrefix ) )
- nsBindings.put( geomPropNs, geomPropPrefix );
- return XMLUtils.evaluateXPath( this.rspEntity, xpath, nsBindings );
- }
+ private NodeList findGeometryPropertyValues(QName featureType, XSElementDeclaration geomProperty)
+ throws XPathExpressionException {
+ String featureTypeNs = featureType.getNamespaceURI();
+ String featureTypePrefix = getFeatureTypePrefix(featureType);
+ String geomPropNs = geomProperty.getNamespace();
+ String geomPropPrefix = getGeomPropPrefix(featureTypeNs, featureTypePrefix, geomPropNs);
+ String xpath = String.format("//%s:%s/%s:%s/*", featureTypePrefix, featureType.getLocalPart(), geomPropPrefix,
+ geomProperty.getName());
+ Map nsBindings = new HashMap<>();
+ nsBindings.put(featureTypeNs, featureTypePrefix);
+ if (!geomPropPrefix.equals(featureTypePrefix))
+ nsBindings.put(geomPropNs, geomPropPrefix);
+ return XMLUtils.evaluateXPath(this.rspEntity, xpath, nsBindings);
+ }
- private String getFeatureTypePrefix( QName featureType ) {
- String prefix = featureType.getPrefix();
- if ( prefix != null && !prefix.isEmpty() )
- return prefix;
- return "t1";
- }
+ private String getFeatureTypePrefix(QName featureType) {
+ String prefix = featureType.getPrefix();
+ if (prefix != null && !prefix.isEmpty())
+ return prefix;
+ return "t1";
+ }
- private String getGeomPropPrefix( String featureTypeNs, String featureTypePrefix, String geomPropNs ) {
- if ( geomPropNs != null && geomPropNs.equals( featureTypeNs ) || ( geomPropNs == null && featureTypeNs == null ) )
- return featureTypePrefix;
- return "t2";
- }
+ private String getGeomPropPrefix(String featureTypeNs, String featureTypePrefix, String geomPropNs) {
+ if (geomPropNs != null && geomPropNs.equals(featureTypeNs) || (geomPropNs == null && featureTypeNs == null))
+ return featureTypePrefix;
+ return "t2";
+ }
}
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/package-info.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/package-info.java
index 5578d22b..97b301c7 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/package-info.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/spatial/package-info.java
@@ -1,9 +1,9 @@
/**
- * This package includes tests covering the use of spatial operators in query
- * expressions. The BBOX predicate must be implemented at the "Basic WFS" conformance
- * level. Support for at least one other spatial operator is required to meet the
- * requirements of the Spatial Filter conformance class.
- *
+ * This package includes tests covering the use of spatial operators in query expressions.
+ * The BBOX predicate must be implemented at the "Basic WFS" conformance level. Support
+ * for at least one other spatial operator is required to meet the requirements of the
+ * Spatial Filter conformance class.
+ *
*
* - BBOX (required for "Basic WFS" conformance)
* - Equals
@@ -18,11 +18,14 @@
* - DWithin
*
*
- * Sources
+ *
+ * Sources
+ *
*
* - OGC 09-026r2, Table 1: FE conformance classes
* - OGC 09-026r2, 7.8: Spatial operators
- * - OGC 06-103r4, 6.1.15.3: Named spatial relationship predicates based on the DE-9IM
+ * - OGC 06-103r4, 6.1.15.3: Named spatial relationship predicates based on the
+ * DE-9IM
*
*/
package org.opengis.cite.iso19142.basic.filter.spatial;
\ No newline at end of file
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AbstractTemporalTest.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AbstractTemporalTest.java
index 77ddc06f..eaffb2a4 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AbstractTemporalTest.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AbstractTemporalTest.java
@@ -15,68 +15,69 @@
*/
public abstract class AbstractTemporalTest extends QueryFilterFixture {
- private static final Logger LOGR = Logger.getLogger( AbstractTemporalTest.class.getPackage().getName() );
-
- public TemporalProperty findTemporalProperty( QName featureType ) {
- List temporalProperties = findTemporalProperties( featureType );
- if ( temporalProperties.isEmpty() ) {
- throw new SkipException( "Feature type has no temporal properties: " + featureType );
- }
-
- TemporalProperty temporalExtent = null;
-
- try {
- temporalExtent = findTemporalExtent( featureType, temporalProperties );
- } catch (Exception e) {
- if(e instanceof SkipException) {
- throw e;
- }
+ private static final Logger LOGR = Logger.getLogger(AbstractTemporalTest.class.getPackage().getName());
+
+ public TemporalProperty findTemporalProperty(QName featureType) {
+ List temporalProperties = findTemporalProperties(featureType);
+ if (temporalProperties.isEmpty()) {
+ throw new SkipException("Feature type has no temporal properties: " + featureType);
+ }
+
+ TemporalProperty temporalExtent = null;
+
+ try {
+ temporalExtent = findTemporalExtent(featureType, temporalProperties);
+ }
+ catch (Exception e) {
+ if (e instanceof SkipException) {
+ throw e;
+ }
+ }
+
+ if (temporalExtent == null)
+ throw new SkipException("Feature type + " + featureType
+ + " has at least one temporal properties but an extent could not be calculated (e.g. all properties are nill). ");
+ return temporalExtent;
+ }
+
+ private TemporalProperty findTemporalExtent(QName featureType, List temporalProperties) {
+ for (XSElementDeclaration temporalProp : temporalProperties) {
+ try {
+ Period temporalExtent = this.dataSampler.getTemporalExtentOfProperty(getModel(), featureType,
+ temporalProp);
+ if (temporalExtent != null)
+ return new TemporalProperty(temporalProp, temporalExtent);
+ }
+ catch (Exception e) {
+ LOGR.warning("Could not calculate the extent of the temporal property " + temporalProp
+ + " of the feature type " + featureType);
+ if (e instanceof SkipException) {
+ throw e;
+ }
+ }
+ }
+ return null;
+ }
+
+ class TemporalProperty {
+
+ private XSElementDeclaration property;
+
+ private Period extent;
+
+ public TemporalProperty(XSElementDeclaration property, Period extent) {
+ this.property = property;
+ this.extent = extent;
}
-
- if ( temporalExtent == null )
- throw new SkipException(
- "Feature type + "
- + featureType
- + " has at least one temporal properties but an extent could not be calculated (e.g. all properties are nill). " );
- return temporalExtent;
- }
-
- private TemporalProperty findTemporalExtent( QName featureType, List temporalProperties ) {
- for ( XSElementDeclaration temporalProp : temporalProperties ) {
- try {
- Period temporalExtent = this.dataSampler.getTemporalExtentOfProperty(getModel(), featureType,
- temporalProp);
- if ( temporalExtent != null )
- return new TemporalProperty( temporalProp, temporalExtent );
- } catch ( Exception e ) {
- LOGR.warning( "Could not calculate the extent of the temporal property " + temporalProp
- + " of the feature type " + featureType );
- if(e instanceof SkipException) {
- throw e;
- }
- }
- }
- return null;
- }
-
- class TemporalProperty {
-
- private XSElementDeclaration property;
-
- private Period extent;
-
- public TemporalProperty( XSElementDeclaration property, Period extent ) {
- this.property = property;
- this.extent = extent;
- }
-
- public XSElementDeclaration getProperty() {
- return property;
- }
-
- public Period getExtent() {
- return extent;
- }
- }
+
+ public XSElementDeclaration getProperty() {
+ return property;
+ }
+
+ public Period getExtent() {
+ return extent;
+ }
+
+ }
}
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AfterTests.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AfterTests.java
index a3338527..998c1628 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AfterTests.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/AfterTests.java
@@ -32,16 +32,14 @@
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
-
/**
- * Tests the response to a GetFeature request that includes the temporal
- * predicate After. Either operand may represent an instant or a
- * period.
- *
+ * Tests the response to a GetFeature request that includes the temporal predicate
+ * After. Either operand may represent an instant or a period.
+ *
*
- * The following figure illustrates the relationship. A solid line denotes a
- * temporal property; a dashed line denotes a literal time value that specifies
- * the temporal extent of interest.
+ * The following figure illustrates the relationship. A solid line denotes a temporal
+ * property; a dashed line denotes a literal time value that specifies the temporal extent
+ * of interest.
*
*
*
@@ -49,135 +47,126 @@
*/
public class AfterTests extends AbstractTemporalTest {
- private static final String AFTER_OP = "After";
+ private static final String AFTER_OP = "After";
+
+ /**
+ * Checks if the temporal operator "After" is supported. If not, the relevant tests
+ * are skipped.
+ */
+ @BeforeClass
+ public void implementsAfterOperator() {
+ if (!ServiceMetadataUtils.implementsTemporalOperator(this.wfsMetadata, AFTER_OP)) {
+ throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, "After operator"));
+ }
+ }
- /**
- * Checks if the temporal operator "After" is supported. If not, the
- * relevant tests are skipped.
- */
- @BeforeClass
- public void implementsAfterOperator() {
- if (!ServiceMetadataUtils.implementsTemporalOperator(this.wfsMetadata, AFTER_OP)) {
- throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, "After operator"));
- }
- }
+ /**
+ * [{@code Test}] Submits a GetFeature request containing the After
+ * temporal predicate with a literal gml:TimePeriod value. The response entity must
+ * contain only feature instances having a temporal property value that is after the
+ * specified period.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
+ public void afterPeriod(ProtocolBinding binding, QName featureType) {
+ TemporalProperty temporalProperty = findTemporalProperty(featureType);
- /**
- * [{@code Test}] Submits a GetFeature request containing the
- * After
temporal predicate with a literal gml:TimePeriod
- * value. The response entity must contain only feature instances having a
- * temporal property value that is after the specified period.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
- public void afterPeriod(ProtocolBinding binding, QName featureType) {
- TemporalProperty temporalProperty = findTemporalProperty( featureType );
+ List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
+ Period firstSubInterval = subIntervals.get(0);
+ Document gmlTimeLiteral = TimeUtils.periodAsGMLSubtractOneDay(firstSubInterval);
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
+ WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
+ Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(),
+ getModel());
+ assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
+ }
- List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
- Period firstSubInterval = subIntervals.get(0);
- Document gmlTimeLiteral = TimeUtils.periodAsGMLSubtractOneDay(firstSubInterval);
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
- WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
- Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(), getModel());
- assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
- }
+ /**
+ * [{@code Test}] Submits a GetFeature request containing the After
+ * temporal predicate with a literal gml:TimeInstant value. The response entity must
+ * contain only feature instances having a temporal property value that is after the
+ * specified (UTC) instant.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
+ public void afterInstant(ProtocolBinding binding, QName featureType) {
+ TemporalProperty temporalProperty = findTemporalProperty(featureType);
- /**
- * [{@code Test}] Submits a GetFeature request containing the
- * After
temporal predicate with a literal gml:TimeInstant
- * value. The response entity must contain only feature instances having a
- * temporal property value that is after the specified (UTC) instant.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
- public void afterInstant(ProtocolBinding binding, QName featureType) {
- TemporalProperty temporalProperty = findTemporalProperty( featureType );
+ List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
+ // end of first sub-interval
+ Instant instant = subIntervals.get(0).getEnding();
+ Document gmlTimeLiteral = TimeUtils.instantAsGMLSubtractOneDay(instant, ZoneOffset.UTC);
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
+ WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
+ Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(),
+ getModel());
+ assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
+ }
- List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
- // end of first sub-interval
- Instant instant = subIntervals.get(0).getEnding();
- Document gmlTimeLiteral = TimeUtils.instantAsGMLSubtractOneDay(instant, ZoneOffset.UTC);
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
- WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
- Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(), getModel());
- assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
- }
+ /**
+ * [{@code Test}] Submits a GetFeature request containing the After
+ * temporal predicate with a literal gml:TimeInstant value that is offset from UTC.
+ * The response entity must contain only feature instances having a temporal property
+ * value that is after the specified instant.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
+ public void afterInstantWithOffset(ProtocolBinding binding, QName featureType) {
+ TemporalProperty temporalProperty = findTemporalProperty(featureType);
- /**
- * [{@code Test}] Submits a GetFeature request containing the
- * After
temporal predicate with a literal gml:TimeInstant
- * value that is offset from UTC. The response entity must contain only
- * feature instances having a temporal property value that is after the
- * specified instant.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
- public void afterInstantWithOffset(ProtocolBinding binding, QName featureType) {
- TemporalProperty temporalProperty = findTemporalProperty( featureType );
+ List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
+ // end of first sub-interval with UTC offset +09:00 (Japan)
+ Instant instant = subIntervals.get(0).getEnding();
+ Document gmlTimeLiteral = TimeUtils.instantAsGMLSubtractOneDay(instant, ZoneOffset.ofHours(9));
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
+ WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
+ Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(),
+ getModel());
+ assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
+ }
- List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
- // end of first sub-interval with UTC offset +09:00 (Japan)
- Instant instant = subIntervals.get(0).getEnding();
- Document gmlTimeLiteral = TimeUtils.instantAsGMLSubtractOneDay(instant, ZoneOffset.ofHours(9));
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
- WFSMessage.addTemporalPredicate(this.reqEntity, AFTER_OP, gmlTimeLiteral, valueRef);
- Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(), getModel());
- assertAfter(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
- }
+ /**
+ * Asserts that all temporal values in the given list occur after the specified GML
+ * temporal value.
+ * @param temporalNodes A list of simple or complex temporal values.
+ * @param propertyDecl An element declaration for a temporal property.
+ * @param gmlTimeLiteral A document that contains a GML representation of an instant
+ * or period.
+ */
+ void assertAfter(List temporalNodes, XSElementDeclaration propertyDecl, Document gmlTimeLiteral) {
+ Assert.assertFalse(temporalNodes.isEmpty(),
+ String.format("No temporal values found in results: property is %s.", propertyDecl));
+ TemporalGeometricPrimitive t2 = GmlUtils.gmlToTemporalGeometricPrimitive(gmlTimeLiteral.getDocumentElement());
+ XSTypeDefinition typeDef = propertyDecl.getTypeDefinition();
+ for (Node timeNode : temporalNodes) {
+ TemporalGeometricPrimitive t1 = null;
+ if (typeDef.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE || ((XSComplexTypeDefinition) typeDef)
+ .getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE) {
+ t1 = TemporalQuery.parseTemporalValue(timeNode.getTextContent(), typeDef);
+ }
+ else {
+ t1 = GmlUtils.gmlToTemporalGeometricPrimitive((Element) timeNode);
+ }
+ TemporalUtils.assertTemporalRelation(RelativePosition.AFTER, t1, t2);
+ }
+ }
- /**
- * Asserts that all temporal values in the given list occur after the
- * specified GML temporal value.
- *
- * @param temporalNodes
- * A list of simple or complex temporal values.
- * @param propertyDecl
- * An element declaration for a temporal property.
- * @param gmlTimeLiteral
- * A document that contains a GML representation of an instant or
- * period.
- */
- void assertAfter(List temporalNodes, XSElementDeclaration propertyDecl, Document gmlTimeLiteral) {
- Assert.assertFalse(temporalNodes.isEmpty(),
- String.format("No temporal values found in results: property is %s.", propertyDecl));
- TemporalGeometricPrimitive t2 = GmlUtils.gmlToTemporalGeometricPrimitive(gmlTimeLiteral.getDocumentElement());
- XSTypeDefinition typeDef = propertyDecl.getTypeDefinition();
- for (Node timeNode : temporalNodes) {
- TemporalGeometricPrimitive t1 = null;
- if ( typeDef.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE
- || ( (XSComplexTypeDefinition) typeDef ).getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE ) {
- t1 = TemporalQuery.parseTemporalValue(timeNode.getTextContent(), typeDef);
- } else {
- t1 = GmlUtils.gmlToTemporalGeometricPrimitive((Element) timeNode);
- }
- TemporalUtils.assertTemporalRelation(RelativePosition.AFTER, t1, t2);
- }
- }
}
diff --git a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/BeforeTests.java b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/BeforeTests.java
index ac66fde8..6fee164e 100644
--- a/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/BeforeTests.java
+++ b/src/main/java/org/opengis/cite/iso19142/basic/filter/temporal/BeforeTests.java
@@ -31,88 +31,83 @@
import jakarta.ws.rs.core.Response.Status;
/**
- * Tests the response to a GetFeature request that includes the temporal
- * predicate Before. Either operand may represent an instant or a
- * period.
+ * Tests the response to a GetFeature request that includes the temporal predicate
+ * Before. Either operand may represent an instant or a period.
*
*
- * The following figure illustrates the relationship. A solid line denotes a
- * temporal property; a dashed line denotes a literal time value that specifies
- * the temporal extent of interest.
+ * The following figure illustrates the relationship. A solid line denotes a temporal
+ * property; a dashed line denotes a literal time value that specifies the temporal extent
+ * of interest.
*
*
*
*/
public class BeforeTests extends AbstractTemporalTest {
- private static final String BEFORE_OP = "Before";
+ private static final String BEFORE_OP = "Before";
- /**
- * Checks if the temporal operator "Before" is supported. If not, the
- * relevant tests are skipped.
- */
- @BeforeClass
- public void implementsBeforeOperator() {
- if (!ServiceMetadataUtils.implementsTemporalOperator(this.wfsMetadata, BEFORE_OP)) {
- throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, "Before operator"));
- }
- }
+ /**
+ * Checks if the temporal operator "Before" is supported. If not, the relevant tests
+ * are skipped.
+ */
+ @BeforeClass
+ public void implementsBeforeOperator() {
+ if (!ServiceMetadataUtils.implementsTemporalOperator(this.wfsMetadata, BEFORE_OP)) {
+ throw new SkipException(ErrorMessage.format(ErrorMessageKeys.NOT_IMPLEMENTED, "Before operator"));
+ }
+ }
- /**
- * [{@code Test}] Submits a GetFeature request containing the
- * Before
temporal predicate with a literal gml:TimePeriod
- * value. The response entity must contain only feature instances having a
- * temporal property value that is before the specified period.
- *
- * @param binding
- * The ProtocolBinding to use for this request.
- * @param featureType
- * A QName representing the qualified name of some feature type.
- */
- @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
- public void beforePeriod(ProtocolBinding binding, QName featureType) {
- TemporalProperty temporalProperty = findTemporalProperty( featureType );
+ /**
+ * [{@code Test}] Submits a GetFeature request containing the Before
+ * temporal predicate with a literal gml:TimePeriod value. The response entity must
+ * contain only feature instances having a temporal property value that is before the
+ * specified period.
+ * @param binding The ProtocolBinding to use for this request.
+ * @param featureType A QName representing the qualified name of some feature type.
+ */
+ @Test(description = "See ISO 19143: A.10", dataProvider = "protocol-featureType")
+ public void beforePeriod(ProtocolBinding binding, QName featureType) {
+ TemporalProperty temporalProperty = findTemporalProperty(featureType);
- List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
- Period lastSubInterval = subIntervals.get(2);
- Document gmlTimeLiteral = TimeUtils.periodAsGMLAddOneDay(lastSubInterval);
- WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
- Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
- WFSMessage.addTemporalPredicate(this.reqEntity, BEFORE_OP, gmlTimeLiteral, valueRef);
- Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
- this.rspEntity = extractBodyAsDocument(rsp);
- Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- List temporalNodes = TemporalQuery.extractTemporalNodes(this.rspEntity, temporalProperty.getProperty(), getModel());
- assertBefore(temporalNodes, temporalProperty.getProperty(), gmlTimeLiteral);
- }
+ List subIntervals = TemporalUtils.splitInterval(temporalProperty.getExtent(), 3);
+ Period lastSubInterval = subIntervals.get(2);
+ Document gmlTimeLiteral = TimeUtils.periodAsGMLAddOneDay(lastSubInterval);
+ WFSMessage.appendSimpleQuery(this.reqEntity, featureType);
+ Element valueRef = WFSMessage.createValueReference(temporalProperty.getProperty());
+ WFSMessage.addTemporalPredicate(this.reqEntity, BEFORE_OP, gmlTimeLiteral, valueRef);
+ Response rsp = wfsClient.getFeature(new DOMSource(this.reqEntity), binding);
+ this.rspEntity = extractBodyAsDocument(rsp);
+ Assert.assertEquals(rsp.getStatus(), Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ List