From eb3c401bda015643a17d4474ce4a9f63929ed8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 15:34:16 +0100 Subject: [PATCH 01/13] Adjust pom.xml --- pom.xml | 225 +++++--------------------------------------------------- 1 file changed, 17 insertions(+), 208 deletions(-) diff --git a/pom.xml b/pom.xml index 8939380..b1a5f26 100644 --- a/pom.xml +++ b/pom.xml @@ -3,11 +3,10 @@ org.opengis.cite ets-common - 9 + 14-SNAPSHOT 4.0.0 - org.opengis.cite ets-eo-geojson10 1.1-SNAPSHOT jar @@ -59,14 +58,9 @@ org.opengis.cite schema-utils - - com.sun.jersey - jersey-client - io.rest-assured rest-assured - 4.5.1 com.sun.xml.bind @@ -77,12 +71,10 @@ com.reprezen.kaizen openapi-parser - 4.0.4 com.google.inject guice - 4.0 junit @@ -95,79 +87,36 @@ net.jadler jadler-core - 1.3.0 test net.jadler jadler-jetty - 1.3.0 test - - javax.xml.bind - jaxb-api - 2.3.1 - - - - org.opengis - geoapi-pending - 3.1-M04 - - - - com.github.erosb - everit-json-schema - 1.14.1 - - - - org.geotoolkit - geotk-utility - 3.21 - + - org.geotoolkit - geotk-referencing - 3.21 - - - org.geotoolkit.pending - geotk-geometry - 3.21 - - - org.geotoolkit.pending - geotk-temporal - 3.21 + org.opengis + geoapi-pending + + com.github.erosb + everit-json-schema + + + org.opengis.cite + geomatics-geotk + + + org.glassfish.jersey.connectors + jersey-apache-connector + + - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - 8 - true - package - - http://testng.org/javadocs/ - - - - - attach-javadocs - - jar - - - - org.apache.maven.plugins maven-assembly-plugin @@ -192,63 +141,6 @@ - - maven-surefire-plugin - - - org.apache.maven.plugins - maven-compiler-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - true - @{project.version} - release - - - - org.apache.maven.plugins - maven-site-plugin - 3.7.1 - - - site-package - prepare-package - - jar - - - - - - org.asciidoctor - asciidoctor-maven-plugin - 1.5.7.1 - - - - 8 - false - - - - org.codehaus.mojo - buildnumber-maven-plugin - - - maven-scm-publish-plugin - 1.1 - - gh-pages - - @@ -296,58 +188,11 @@ - - maven-dependency-plugin - 3.0.0 - - - - org.opengis.cite.teamengine - teamengine-web - ${docker.teamengine.version} - war - - - org.opengis.cite.teamengine - teamengine-web - ${docker.teamengine.version} - common-libs - zip - - - org.opengis.cite.teamengine - teamengine-console - ${docker.teamengine.version} - base - zip - - - - - - integration-tests - - - - maven-failsafe-plugin - 2.22.0 - - - - integration-test - verify - - - - - - - docker @@ -383,44 +228,8 @@ - - release - - - - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - --pinentry-mode - loopback - - - - - - - - - - - geotoolkit - Geotk Modules - http://maven.geotoolkit.org - default - - - - sonatype-nexus-staging From 9bd1d915fa08096bfcafa7080693bc8dbd087f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 15:34:31 +0100 Subject: [PATCH 02/13] Fix build errors --- .../cite/eogeojson10/CommonFixture.java | 22 +- .../opengis/cite/eogeojson10/ETSAssert.java | 7 +- .../eogeojson10/ReusableEntityFilter.java | 25 +-- .../cite/eogeojson10/SuiteAttribute.java | 4 +- .../eogeojson10/SuiteFixtureListener.java | 4 +- .../cite/eogeojson10/TestFailureListener.java | 16 +- .../cite/eogeojson10/util/ClientUtils.java | 197 ++++++++---------- .../cite/eogeojson10/util/URIUtils.java | 55 ++--- .../VerifySuiteFixtureListener.java | 1 - 9 files changed, 154 insertions(+), 177 deletions(-) diff --git a/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java b/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java index eecbf2a..40f3380 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java +++ b/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java @@ -1,11 +1,9 @@ package org.opengis.cite.eogeojson10; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientResponse; import java.net.URI; import java.util.Map; -import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.client.ClientRequest; import org.opengis.cite.eogeojson10.util.ClientUtils; import org.testng.ITestContext; import org.testng.SkipException; @@ -13,6 +11,10 @@ import org.testng.annotations.BeforeMethod; import org.w3c.dom.Document; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + /** * A supporting base class that sets up a common test fixture. These * configuration methods are invoked before those defined in a subclass. @@ -34,7 +36,7 @@ public class CommonFixture { /** * An HTTP response message. */ - protected ClientResponse response; + protected Response response; /** * Initializes the common test fixture with a client component for @@ -73,8 +75,7 @@ public void clearMessages() { * * @see ClientUtils#getResponseEntityAsDocument */ - public Document getResponseEntityAsDocument(ClientResponse response, - String targetURI) { + public Document getResponseEntityAsDocument(Response response, String targetURI) { return ClientUtils.getResponseEntityAsDocument(response, targetURI); } @@ -87,13 +88,12 @@ public Document getResponseEntityAsDocument(ClientResponse response, * @param qryParams A Map containing query parameters (may be null); * @param mediaTypes A list of acceptable media types; if not specified, * generic XML ("application/xml") is preferred. - * @return A ClientRequest object. + * @return A Response object. * * @see ClientUtils#buildGetRequest */ - public ClientRequest buildGetRequest(URI endpoint, - Map qryParams, MediaType... mediaTypes) { + public Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { return ClientUtils.buildGetRequest(endpoint, qryParams, mediaTypes); - } +} } diff --git a/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java b/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java index 0fd57e5..d7f01ac 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java @@ -15,6 +15,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.glassfish.jersey.client.ClientResponse; import org.opengis.cite.eogeojson10.util.NamespaceBindings; import org.opengis.cite.eogeojson10.util.XMLUtils; import org.opengis.cite.validation.SchematronValidator; @@ -25,7 +26,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import com.sun.jersey.api.client.ClientResponse; +import jakarta.ws.rs.core.Response.Status; /** * Provides a set of custom assertion methods. @@ -189,9 +190,9 @@ public static void assertDescendantElementCount(Document xmlEntity, QName elemen * will be ignored if the argument is null or empty. */ public static void assertExceptionReport(ClientResponse rsp, String exceptionCode, String locator) { - Assert.assertEquals(rsp.getStatus(), ClientResponse.Status.BAD_REQUEST.getStatusCode(), + Assert.assertEquals(rsp.getStatus(), Status.BAD_REQUEST.getStatusCode(), ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS)); - Document doc = rsp.getEntity(Document.class); + Document doc = rsp.readEntity(Document.class); String expr = String.format("//ows:Exception[@exceptionCode = '%s']", exceptionCode); NodeList nodeList = null; try { diff --git a/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java b/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java index f1e2fee..2fa1c51 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java @@ -1,9 +1,12 @@ package org.opengis.cite.eogeojson10; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.filter.ClientFilter; +import java.io.IOException; + +import org.glassfish.jersey.client.ClientResponse; + +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientResponseContext; +import jakarta.ws.rs.client.ClientResponseFilter; /** * Buffers the (response) entity so it can be read multiple times. @@ -11,16 +14,14 @@ *

WARNING: The entity InputStream must be reset after each * read attempt.

*/ -public class ReusableEntityFilter extends ClientFilter { +public class ReusableEntityFilter implements ClientResponseFilter { + /** {@inheritDoc} */ @Override - public ClientResponse handle(ClientRequest req) throws ClientHandlerException { - // leave request entity--it can usually be read multiple times - ClientResponse rsp = getNext().handle(req); - if (rsp.hasEntity()) { - rsp.bufferEntity(); - } - return rsp; + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { + if (responseContext instanceof ClientResponse) { + ((ClientResponse) responseContext).bufferEntity(); + } } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java b/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java index 7b85fdf..07a207f 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java @@ -1,11 +1,11 @@ package org.opengis.cite.eogeojson10; -import com.sun.jersey.api.client.Client; - import java.io.File; import org.w3c.dom.Document; +import jakarta.ws.rs.client.Client; + /** * An enumerated type defining ISuite attributes that may be set to constitute a * shared test fixture. diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java b/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java index 9f156b7..bd3fc79 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java @@ -9,12 +9,10 @@ import org.opengis.cite.eogeojson10.util.ClientUtils; import org.opengis.cite.eogeojson10.util.TestSuiteLogger; import org.opengis.cite.eogeojson10.util.URIUtils; -import org.opengis.cite.eogeojson10.util.XMLUtils; import org.testng.ISuite; import org.testng.ISuiteListener; -import org.w3c.dom.Document; -import com.sun.jersey.api.client.Client; +import jakarta.ws.rs.client.Client; /** * A listener that performs various tasks before and after a test suite is run, diff --git a/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java b/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java index 2ef33fe..473887a 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java +++ b/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java @@ -1,15 +1,17 @@ package org.opengis.cite.eogeojson10; -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientResponse; import java.nio.charset.StandardCharsets; -import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.client.ClientRequest; import org.opengis.cite.eogeojson10.util.ClientUtils; import org.opengis.cite.eogeojson10.util.XMLUtils; import org.testng.ITestResult; import org.testng.TestListenerAdapter; import org.w3c.dom.Document; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + /** * A listener that augments a test result with diagnostic information in the * event that a test method failed. This information will appear in the XML @@ -51,7 +53,7 @@ String getRequestMessageInfo(ClientRequest req) { } StringBuilder msgInfo = new StringBuilder(); msgInfo.append("Method: ").append(req.getMethod()).append('\n'); - msgInfo.append("Target URI: ").append(req.getURI()).append('\n'); + msgInfo.append("Target URI: ").append(req.getUri()).append('\n'); msgInfo.append("Headers: ").append(req.getHeaders()).append('\n'); if (null != req.getEntity()) { Object entity = req.getEntity(); @@ -74,7 +76,7 @@ String getRequestMessageInfo(ClientRequest req) { * @return A string containing information gleaned from the response * message. */ - String getResponseMessageInfo(ClientResponse rsp) { + String getResponseMessageInfo(Response rsp) { if (null == rsp) { return "No response message."; } @@ -82,11 +84,11 @@ String getResponseMessageInfo(ClientResponse rsp) { msgInfo.append("Status: ").append(rsp.getStatus()).append('\n'); msgInfo.append("Headers: ").append(rsp.getHeaders()).append('\n'); if (rsp.hasEntity()) { - if (rsp.getType().isCompatible(MediaType.APPLICATION_XML_TYPE)) { + if (rsp.getMediaType().isCompatible(MediaType.APPLICATION_XML_TYPE)) { Document doc = ClientUtils.getResponseEntityAsDocument(rsp, null); msgInfo.append(XMLUtils.writeNodeToString(doc)); } else { - byte[] body = rsp.getEntity(byte[].class); + byte[] body = rsp.readEntity(byte[].class); msgInfo.append(new String(body, StandardCharsets.UTF_8)); } msgInfo.append('\n'); diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java index f193228..5cef508 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java @@ -1,173 +1,144 @@ package org.opengis.cite.eogeojson10.util; -import java.io.IOException; -import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.SocketAddress; -import java.net.URL; - -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.LoggingFilter; -import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; -import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; import java.net.URI; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.ws.rs.HttpMethod; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.UriBuilder; + import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; + +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.logging.LoggingFeature; import org.opengis.cite.eogeojson10.ReusableEntityFilter; import org.w3c.dom.Document; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; + /** * Provides various utility methods for creating and configuring HTTP client * components. */ public class ClientUtils { + private static final Logger LOGGER = Logger.getLogger(ClientUtils.class.getName()); + /** - * Builds a client component for interacting with HTTP endpoints. The client - * will automatically redirect to the URI declared in 3xx responses. The - * connection timeout is 10 s. Request and response messages may be logged - * to a JDK logger (in the namespace "com.sun.jersey.api.client"). - * + * Builds a client component for interacting with HTTP endpoints. The client will + * automatically redirect to the URI declared in 3xx responses. The connection timeout + * is 10 s. Request and response messages may be logged to a JDK logger (in the + * namespace "com.sun.jersey.api.client"). * @return A Client component. */ public static Client buildClient() { - ClientConfig config = new DefaultClientConfig(); - config.getProperties().put( - ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true); - config.getProperties().put( - ClientConfig.PROPERTY_CONNECT_TIMEOUT, 10000); - Client client = Client.create(config); - client.addFilter(new ReusableEntityFilter()); - client.addFilter(new LoggingFilter()); - return client; + ClientConfig config = new ClientConfig(); + config.property(ClientProperties.FOLLOW_REDIRECTS, true); + config.property(ClientProperties.CONNECT_TIMEOUT, 10000); + config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); + Client client = ClientBuilder.newClient(config); + client.register(new ReusableEntityFilter()); + return client; } /** - * Constructs a client component that uses a specified web proxy. Proxy - * authentication is not supported. Configuring the client to use an - * intercepting proxy can be useful when debugging a test. - * + * Constructs a client component that uses a specified web proxy. Proxy authentication + * is not supported. Configuring the client to use an intercepting proxy can be useful + * when debugging a test. * @param proxyHost The host name or IP address of the proxy server. * @param proxyPort The port number of the proxy listener. - * * @return A Client component that submits requests through a web proxy. */ - public static Client buildClientWithProxy(final String proxyHost, - final int proxyPort) { - ClientConfig config = new DefaultClientConfig(); - config.getProperties().put( - ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true); - Client client = new Client(new URLConnectionClientHandler( - new HttpURLConnectionFactory() { - SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort); - Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); - - @Override - public HttpURLConnection getHttpURLConnection(URL url) throws IOException { - return (HttpURLConnection) url.openConnection(proxy); - } - }), config); - client.addFilter(new LoggingFilter()); - return client; + public static Client buildClientWithProxy(final String proxyHost, final int proxyPort) { + ClientConfig config = new ClientConfig(); + config.connectorProvider(new ApacheConnectorProvider()); + config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); + SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort); + Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); + config.property(ClientProperties.PROXY_URI, proxy); + config.property(ClientProperties.FOLLOW_REDIRECTS, true); + config.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT, LoggingFeature.Verbosity.PAYLOAD_ANY); + config.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT, Level.ALL); + Client client = ClientBuilder.newClient(config); + client.register(new ReusableEntityFilter()); + return client; } /** * Builds an HTTP request message that uses the GET method. - * * @param endpoint A URI indicating the target resource. * @param qryParams A Map containing query parameters (may be null); - * @param mediaTypes A list of acceptable media types; if not specified, - * generic XML ("application/xml") is preferred. - * + * @param mediaTypes A list of acceptable media types; if not specified, the Accept + * header is omitted. * @return A ClientRequest object. */ - public static ClientRequest buildGetRequest(URI endpoint, - Map qryParams, MediaType... mediaTypes) { - UriBuilder uriBuilder = UriBuilder.fromUri(endpoint); - if (null != qryParams) { - for (Map.Entry param : qryParams.entrySet()) { - uriBuilder.queryParam(param.getKey(), param.getValue()); + public static Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { + UriBuilder uriBuilder = UriBuilder.fromUri(endpoint); + if (null != qryParams) { + for (Map.Entry param : qryParams.entrySet()) { + uriBuilder.queryParam(param.getKey(), param.getValue()); + } + } + URI uri = uriBuilder.build(); + WebTarget target = buildClient().target(uri); + Builder reqBuilder = target.request(); + if (null != mediaTypes && mediaTypes.length > 0) { + reqBuilder = reqBuilder.accept(mediaTypes); } - } - URI uri = uriBuilder.build(); - ClientRequest.Builder reqBuilder = ClientRequest.create(); - if (null == mediaTypes || mediaTypes.length == 0) { - reqBuilder = reqBuilder.accept(MediaType.APPLICATION_XML_TYPE); - } else { - reqBuilder = reqBuilder.accept(mediaTypes); - } - ClientRequest req = reqBuilder.build(uri, HttpMethod.GET); - return req; + Invocation req = reqBuilder.buildGet(); + return req.invoke(); } /** * Creates a copy of the given MediaType object but without any parameters. - * * @param mediaType A MediaType descriptor. - * @return A new (immutable) MediaType object having the same type and - * subtype. + * @return A new (immutable) MediaType object having the same type and subtype. */ public static MediaType removeParameters(MediaType mediaType) { - return new MediaType(mediaType.getType(), mediaType.getSubtype()); + return new MediaType(mediaType.getType(), mediaType.getSubtype()); } /** - * Obtains the (XML) response entity as a JAXP Source object and resets the - * entity input stream for subsequent reads. - * + * Obtains the (XML) response entity as a JAXP Source object and resets the entity + * input stream for subsequent reads. * @param response A representation of an HTTP response message. - * @param targetURI The target URI from which the entity was retrieved (may - * be null). - * @return A Source to read the entity from; its system identifier is set - * using the given targetURI value (this may be used to resolve any relative - * URIs found in the source). + * @param targetURI The target URI from which the entity was retrieved (may be null). + * @return A Source to read the entity from; its system identifier is set using the + * given targetURI value (this may be used to resolve any relative URIs found in the + * source). */ - public static Source getResponseEntityAsSource(ClientResponse response, - String targetURI) { - Source source = response.getEntity(DOMSource.class); - if (null != targetURI && !targetURI.isEmpty()) { - source.setSystemId(targetURI); - } - if (response.getEntityInputStream().markSupported()) { - try { - // NOTE: entity was buffered by client filter - response.getEntityInputStream().reset(); - } catch (IOException ex) { - Logger.getLogger(ClientUtils.class.getName()).log(Level.WARNING, - "Failed to reset response entity.", ex); + public static Source getResponseEntityAsSource(Response response, String targetURI) { + Source source = response.readEntity(DOMSource.class); + if (null != targetURI && !targetURI.isEmpty()) { + source.setSystemId(targetURI); } - } - return source; + return source; } /** - * Obtains the (XML) response entity as a DOM Document and resets the entity - * input stream for subsequent reads. - * + * Obtains the (XML) response entity as a DOM Document and resets the entity input + * stream for subsequent reads. * @param response A representation of an HTTP response message. - * @param targetURI The target URI from which the entity was retrieved (may - * be null). - * @return A Document representing the entity; its base URI is set using the - * given targetURI value (this may be used to resolve any relative URIs - * found in the document). + * @param targetURI The target URI from which the entity was retrieved (may be null). + * @return A Document representing the entity; its base URI is set using the given + * targetURI value (this may be used to resolve any relative URIs found in the + * document). */ - public static Document getResponseEntityAsDocument(ClientResponse response, - String targetURI) { - DOMSource domSource = (DOMSource) getResponseEntityAsSource(response, - targetURI); - Document entityDoc = (Document) domSource.getNode(); - entityDoc.setDocumentURI(domSource.getSystemId()); - return entityDoc; + public static Document getResponseEntityAsDocument(Response response, String targetURI) { + DOMSource domSource = (DOMSource) getResponseEntityAsSource(response, targetURI); + Document entityDoc = (Document) domSource.getNode(); + entityDoc.setDocumentURI(domSource.getSystemId()); + return entityDoc; } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java index ae0ec98..d95a0b6 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java @@ -8,7 +8,6 @@ import java.net.URI; import java.util.logging.Level; -import javax.ws.rs.core.HttpHeaders; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -16,9 +15,11 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; /** * Provides a collection of utility methods for manipulating or resolving URI @@ -82,36 +83,40 @@ public static Document parseURI(URI uriRef) throws SAXException, */ public static File dereferenceURI(URI uriRef) throws IOException { if ((null == uriRef) || !uriRef.isAbsolute()) { - throw new IllegalArgumentException( - "Absolute URI is required, but received " + uriRef); + throw new IllegalArgumentException("Absolute URI is required, but received " + uriRef); } if (uriRef.getScheme().equalsIgnoreCase("file")) { - return new File(uriRef); + return new File(uriRef); } - Client client = Client.create(); - WebResource webRes = client.resource(uriRef); - ClientResponse rsp = webRes.get(ClientResponse.class); + Client client = ClientUtils.buildClient(); + WebTarget target = client.target(uriRef); + Builder builder = target.request(); + Response rsp = builder.buildGet().invoke(); String suffix = null; - if (rsp.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE).endsWith("xml")) { - suffix = ".xml"; + if (rsp.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE).toString().endsWith("xml")) { + suffix = ".xml"; } File destFile = File.createTempFile("entity-", suffix); if (rsp.hasEntity()) { - InputStream is = rsp.getEntityInputStream(); - OutputStream os = new FileOutputStream(destFile); - byte[] buffer = new byte[8 * 1024]; - int bytesRead; - while ((bytesRead = is.read(buffer)) != -1) { - os.write(buffer, 0, bytesRead); - } - is.close(); - os.flush(); - os.close(); + Object entity = rsp.getEntity(); + if (!(entity instanceof InputStream)) { + return null; + } + InputStream is = (InputStream) entity; + OutputStream os = new FileOutputStream(destFile); + byte[] buffer = new byte[8 * 1024]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + is.close(); + os.flush(); + os.close(); } - TestSuiteLogger.log(Level.FINE, "Wrote " + destFile.length() - + " bytes to file at " + destFile.getAbsolutePath()); + TestSuiteLogger.log(Level.FINE, + "Wrote " + destFile.length() + " bytes to file at " + destFile.getAbsolutePath()); return destFile; - } +} /** * Constructs an absolute URI from the given URI reference and a base URI. diff --git a/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java b/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java index 5fb688f..82a4d23 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java +++ b/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java @@ -15,7 +15,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.mockito.Matchers; import org.testng.ISuite; import org.testng.xml.XmlSuite; From bb4628cd55dd1e395004e52a0fa4ae5971d2084a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 15:43:53 +0100 Subject: [PATCH 03/13] Formatting, javadoc, organize imports --- .../eogeojson10/CommandLineArguments.java | 96 ++- .../cite/eogeojson10/CommonFixture.java | 144 ++-- .../opengis/cite/eogeojson10/DataFixture.java | 145 ++-- .../opengis/cite/eogeojson10/ETSAssert.java | 317 ++++----- .../cite/eogeojson10/ErrorMessage.java | 67 +- .../cite/eogeojson10/ErrorMessageKeys.java | 52 +- .../opengis/cite/eogeojson10/Namespaces.java | 40 +- .../eogeojson10/ReusableEntityFilter.java | 19 +- .../cite/eogeojson10/SuiteAttribute.java | 95 +-- .../eogeojson10/SuiteFixtureListener.java | 188 +++-- .../cite/eogeojson10/SuitePreconditions.java | 49 +- .../cite/eogeojson10/TestFailureListener.java | 152 ++-- .../cite/eogeojson10/TestNGController.java | 282 ++++---- .../opengis/cite/eogeojson10/TestRunArg.java | 30 +- .../cite/eogeojson10/TestRunListener.java | 30 +- .../AquisitionInformationConfClassTests.java | 70 +- .../AquisitionParametersConfClassTests.java | 98 +-- .../cite/eogeojson10/core/CoreTests.java | 199 +++--- .../cite/eogeojson10/core/package-info.java | 9 +- .../DataIdentificationConfClassTests.java | 64 +- .../EarthObservationConfClassTests.java | 55 +- .../EOCollectionConfClassTests.java | 107 +-- .../geometry/GeometryConfClassTests.java | 55 +- .../links/LinksConfClassTests.java | 72 +- .../MetadataInformationConfClassTests.java | 70 +- .../offering/OfferingConfClassTests.java | 72 +- .../cite/eogeojson10/package-info.java | 11 +- .../ProductInformationConfClassTests.java | 70 +- .../properties/PropertiesConfClassTests.java | 70 +- .../cite/eogeojson10/util/ClientUtils.java | 208 +++--- .../eogeojson10/util/NamespaceBindings.java | 159 +++-- .../eogeojson10/util/TestSuiteLogger.java | 107 ++- .../cite/eogeojson10/util/URIUtils.java | 205 +++--- .../eogeojson10/util/ValidationUtils.java | 236 +++---- .../cite/eogeojson10/util/XMLUtils.java | 657 +++++++++--------- .../cite/eogeojson10/VerifyETSAssert.java | 90 +-- .../VerifySuiteFixtureListener.java | 56 +- .../eogeojson10/VerifyTestNGController.java | 75 +- .../cite/eogeojson10/util/VerifyURIUtils.java | 105 ++- .../util/VerifyValidationUtils.java | 44 +- .../cite/eogeojson10/util/VerifyXMLUtils.java | 232 +++---- 41 files changed, 2437 insertions(+), 2465 deletions(-) diff --git a/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java b/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java index d99060f..8272cd4 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java +++ b/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java @@ -1,15 +1,15 @@ package org.opengis.cite.eogeojson10; -import com.beust.jcommander.Parameter; import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.List; +import com.beust.jcommander.Parameter; + /** - * Declares supported command line arguments that are parsed using the - * JCommander library. All arguments are optional. The default values are as - * follows: + * Declares supported command line arguments that are parsed using the JCommander library. + * All arguments are optional. The default values are as follows: *
    *
  • XML properties file: ${user.home}/test-run-props.xml
  • *
  • outputDir: ${user.home}
  • @@ -26,35 +26,61 @@ */ public class CommandLineArguments { - @Parameter(description = "Properties file") - private final List xmlProps; - - @Parameter(names = {"-o", "--outputDir"}, description = "Output directory") - private String outputDir; - - @Parameter(names = {"-d", "--deleteSubjectOnFinish"}, description = "Delete file containing representation of test subject when finished") - private boolean deleteSubjectOnFinish = false; - - public CommandLineArguments() { - this.xmlProps = new ArrayList<>(); - } - - public File getPropertiesFile() { - File fileRef; - if (xmlProps.isEmpty()) { - fileRef = new File(System.getProperty("user.home"), "test-run-props.xml"); - } else { - String propsFile = xmlProps.get(0); - fileRef = (propsFile.startsWith("file:")) ? new File(URI.create(propsFile)) : new File(propsFile); - } - return fileRef; - } - - public String getOutputDir() { - return (null != outputDir) ? outputDir : System.getProperty("user.home"); - } - - public boolean doDeleteSubjectOnFinish() { - return deleteSubjectOnFinish; - } + @Parameter(description = "Properties file") + private final List xmlProps; + + @Parameter(names = { "-o", "--outputDir" }, description = "Output directory") + private String outputDir; + + @Parameter(names = { "-d", "--deleteSubjectOnFinish" }, + description = "Delete file containing representation of test subject when finished") + private boolean deleteSubjectOnFinish = false; + + /** + *

    + * Constructor for CommandLineArguments. + *

    + */ + public CommandLineArguments() { + this.xmlProps = new ArrayList<>(); + } + + /** + *

    + * getPropertiesFile. + *

    + * @return a {@link java.io.File} object + */ + public File getPropertiesFile() { + File fileRef; + if (xmlProps.isEmpty()) { + fileRef = new File(System.getProperty("user.home"), "test-run-props.xml"); + } + else { + String propsFile = xmlProps.get(0); + fileRef = (propsFile.startsWith("file:")) ? new File(URI.create(propsFile)) : new File(propsFile); + } + return fileRef; + } + + /** + *

    + * Getter for the field outputDir. + *

    + * @return a {@link java.lang.String} object + */ + public String getOutputDir() { + return (null != outputDir) ? outputDir : System.getProperty("user.home"); + } + + /** + *

    + * doDeleteSubjectOnFinish. + *

    + * @return a boolean + */ + public boolean doDeleteSubjectOnFinish() { + return deleteSubjectOnFinish; + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java b/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java index 40f3380..01b6ca8 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java +++ b/src/main/java/org/opengis/cite/eogeojson10/CommonFixture.java @@ -16,84 +16,84 @@ import jakarta.ws.rs.core.Response; /** - * A supporting base class that sets up a common test fixture. These - * configuration methods are invoked before those defined in a subclass. + * A supporting base class that sets up a common test fixture. These configuration methods + * are invoked before those defined in a subclass. */ public class CommonFixture { - /** - * Root test suite package (absolute path). - */ - public static final String ROOT_PKG_PATH = "/org/opengis/cite/eogeojson10/"; - /** - * HTTP client component (JAX-RS Client API). - */ - protected Client client; - /** - * An HTTP request message. - */ - protected ClientRequest request; - /** - * An HTTP response message. - */ - protected Response response; + /** + * Root test suite package (absolute path). + */ + public static final String ROOT_PKG_PATH = "/org/opengis/cite/eogeojson10/"; - /** - * Initializes the common test fixture with a client component for - * interacting with HTTP endpoints. - * - * @param testContext The test context that contains all the information for - * a test run, including suite attributes. - */ - @BeforeClass - public void initCommonFixture(ITestContext testContext) { - Object obj = testContext.getSuite().getAttribute(SuiteAttribute.CLIENT.getName()); - if (null != obj) { - this.client = Client.class.cast(obj); - } - obj = testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJECT.getName()); - if (null == obj) { - throw new SkipException("Test subject not found in ITestContext."); - } - } + /** + * HTTP client component (JAX-RS Client API). + */ + protected Client client; - @BeforeMethod - public void clearMessages() { - this.request = null; - this.response = null; - } + /** + * An HTTP request message. + */ + protected ClientRequest request; - /** - * Obtains the (XML) response entity as a DOM Document. This convenience - * method wraps a static method call to facilitate unit testing (Mockito - * workaround). - * - * @param response A representation of an HTTP response message. - * @param targetURI The target URI from which the entity was retrieved (may - * be null). - * @return A Document representing the entity. - * - * @see ClientUtils#getResponseEntityAsDocument - */ - public Document getResponseEntityAsDocument(Response response, String targetURI) { - return ClientUtils.getResponseEntityAsDocument(response, targetURI); - } + /** + * An HTTP response message. + */ + protected Response response; - /** - * Builds an HTTP request message that uses the GET method. This convenience - * method wraps a static method call to facilitate unit testing (Mockito - * workaround). - * - * @param endpoint A URI indicating the target resource. - * @param qryParams A Map containing query parameters (may be null); - * @param mediaTypes A list of acceptable media types; if not specified, - * generic XML ("application/xml") is preferred. - * @return A Response object. - * - * @see ClientUtils#buildGetRequest - */ - public Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { - return ClientUtils.buildGetRequest(endpoint, qryParams, mediaTypes); -} + /** + * Initializes the common test fixture with a client component for interacting with + * HTTP endpoints. + * @param testContext The test context that contains all the information for a test + * run, including suite attributes. + */ + @BeforeClass + public void initCommonFixture(ITestContext testContext) { + Object obj = testContext.getSuite().getAttribute(SuiteAttribute.CLIENT.getName()); + if (null != obj) { + this.client = Client.class.cast(obj); + } + obj = testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJECT.getName()); + if (null == obj) { + throw new SkipException("Test subject not found in ITestContext."); + } + } + + /** + *

    + * clearMessages. + *

    + */ + @BeforeMethod + public void clearMessages() { + this.request = null; + this.response = null; + } + + /** + * Obtains the (XML) response entity as a DOM Document. This convenience method wraps + * a static method call to facilitate unit testing (Mockito workaround). + * @param response A representation of an HTTP response message. + * @param targetURI The target URI from which the entity was retrieved (may be null). + * @return A Document representing the entity. + * @see ClientUtils#getResponseEntityAsDocument + */ + public Document getResponseEntityAsDocument(Response response, String targetURI) { + return ClientUtils.getResponseEntityAsDocument(response, targetURI); + } + + /** + * Builds an HTTP request message that uses the GET method. This convenience method + * wraps a static method call to facilitate unit testing (Mockito workaround). + * @param endpoint A URI indicating the target resource. + * @param qryParams A Map containing query parameters (may be null); + * @param mediaTypes A list of acceptable media types; if not specified, generic XML + * ("application/xml") is preferred. + * @return A Response object. + * @see ClientUtils#buildGetRequest + */ + public Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { + return ClientUtils.buildGetRequest(endpoint, qryParams, mediaTypes); + } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java b/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java index c0b73bf..f5ca74b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java +++ b/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java @@ -11,77 +11,86 @@ import org.json.JSONObject; import org.testng.ITestContext; import org.testng.annotations.BeforeClass; -import org.w3c.dom.Document; /** * Includes various tests of capability 1. */ public class DataFixture { - protected String testSubject; - protected String collectionTestSubject; - protected final int DEFAULT_BUFFER_SIZE = 8192; - - /** - * Obtains the test subject from the ISuite context. - * - * @param testContext - * The test (group) context. - */ - @BeforeClass - public void obtainTestSubject(ITestContext testContext) { - Object obj = testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName()); - - if (null != obj) { - this.testSubject = obj.toString(); - } - - //----- - Object collectionObj = testContext.getSuite().getAttribute(SuiteAttribute.COL_TEST_SUBJ_FILE.getName()); - - if (null != collectionObj) { - this.collectionTestSubject = collectionObj.toString(); - } - } - - /** - * Sets the test subject. This method is intended to facilitate unit - * testing. - * - * @param testSubject - * A Document node representing the test subject or metadata - * about it. - */ - public void setTestSubject(String testSubject) { - this.testSubject = testSubject; - } - - public JSONObject readJSONObjectFromFile(File filePath) throws IOException { - - FileInputStream is = new FileInputStream(filePath); - try ( Scanner scanner = new Scanner(is, - StandardCharsets.UTF_8.toString())) { - scanner.useDelimiter("\\A"); - - return new JSONObject(scanner.hasNext() ? scanner.next() : ""); - } - - } - - // from https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/ - public String convertInputStreamToString(InputStream is) throws IOException { - - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - int length; - while ((length = is.read(buffer)) != -1) { - result.write(buffer, 0, length); - } - - - - return result.toString("UTF-8"); - - - } -} \ No newline at end of file + protected String testSubject; + + protected String collectionTestSubject; + + protected final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Obtains the test subject from the ISuite context. + * @param testContext The test (group) context. + */ + @BeforeClass + public void obtainTestSubject(ITestContext testContext) { + Object obj = testContext.getSuite().getAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName()); + + if (null != obj) { + this.testSubject = obj.toString(); + } + + // ----- + Object collectionObj = testContext.getSuite().getAttribute(SuiteAttribute.COL_TEST_SUBJ_FILE.getName()); + + if (null != collectionObj) { + this.collectionTestSubject = collectionObj.toString(); + } + } + + /** + * Sets the test subject. This method is intended to facilitate unit testing. + * @param testSubject A Document node representing the test subject or metadata about + * it. + */ + public void setTestSubject(String testSubject) { + this.testSubject = testSubject; + } + + /** + *

    + * readJSONObjectFromFile. + *

    + * @param filePath a {@link java.io.File} object + * @return a {@link org.json.JSONObject} object + * @throws java.io.IOException if any. + */ + public JSONObject readJSONObjectFromFile(File filePath) throws IOException { + + FileInputStream is = new FileInputStream(filePath); + try (Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.toString())) { + scanner.useDelimiter("\\A"); + + return new JSONObject(scanner.hasNext() ? scanner.next() : ""); + } + + } + + // from https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/ + /** + *

    + * convertInputStreamToString. + *

    + * @param is a {@link java.io.InputStream} object + * @return a {@link java.lang.String} object + * @throws java.io.IOException if any. + */ + public String convertInputStreamToString(InputStream is) throws IOException { + + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + int length; + while ((length = is.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + + return result.toString("UTF-8"); + + } + +} diff --git a/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java b/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java index d7f01ac..df168f2 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ETSAssert.java @@ -33,179 +33,160 @@ */ public class ETSAssert { - private static final Logger LOGR = Logger.getLogger(ETSAssert.class.getPackage().getName()); + private static final Logger LOGR = Logger.getLogger(ETSAssert.class.getPackage().getName()); - private ETSAssert() { - } + private ETSAssert() { + } - /** - * Asserts that the qualified name of a DOM Node matches the expected value. - * - * @param node - * The Node to check. - * @param qName - * A QName object containing a namespace name (URI) and a local - * part. - */ - public static void assertQualifiedName(Node node, QName qName) { - Assert.assertEquals(node.getLocalName(), qName.getLocalPart(), ErrorMessage.get(ErrorMessageKeys.LOCAL_NAME)); - Assert.assertEquals(node.getNamespaceURI(), qName.getNamespaceURI(), - ErrorMessage.get(ErrorMessageKeys.NAMESPACE_NAME)); - } + /** + * Asserts that the qualified name of a DOM Node matches the expected value. + * @param node The Node to check. + * @param qName A QName object containing a namespace name (URI) and a local part. + */ + public static void assertQualifiedName(Node node, QName qName) { + Assert.assertEquals(node.getLocalName(), qName.getLocalPart(), ErrorMessage.get(ErrorMessageKeys.LOCAL_NAME)); + Assert.assertEquals(node.getNamespaceURI(), qName.getNamespaceURI(), + ErrorMessage.get(ErrorMessageKeys.NAMESPACE_NAME)); + } - /** - * Asserts that an XPath 1.0 expression holds true for the given evaluation - * context. The following standard namespace bindings do not need to be - * explicitly declared: - * - *
      - *
    • ows: {@value org.opengis.cite.eogeojson10.Namespaces#OWS}
    • - *
    • xlink: {@value org.opengis.cite.eogeojson10.Namespaces#XLINK}
    • - *
    • gml: {@value org.opengis.cite.eogeojson10.Namespaces#GML}
    • - *
    - * - * @param expr - * A valid XPath 1.0 expression. - * @param context - * The context node. - * @param namespaceBindings - * A collection of namespace bindings for the XPath expression, - * where each entry maps a namespace URI (key) to a prefix - * (value). It may be {@code null}. - */ - public static void assertXPath(String expr, Node context, Map namespaceBindings) { - if (null == context) { - throw new NullPointerException("Context node is null."); - } - NamespaceBindings bindings = NamespaceBindings.withStandardBindings(); - bindings.addAllBindings(namespaceBindings); - XPath xpath = XPathFactory.newInstance().newXPath(); - xpath.setNamespaceContext(bindings); - Boolean result; - try { - result = (Boolean) xpath.evaluate(expr, context, XPathConstants.BOOLEAN); - } catch (XPathExpressionException xpe) { - String msg = ErrorMessage.format(ErrorMessageKeys.XPATH_ERROR, expr); - LOGR.log(Level.WARNING, msg, xpe); - throw new AssertionError(msg); - } - Element elemNode; - if (Document.class.isInstance(context)) { - elemNode = Document.class.cast(context).getDocumentElement(); - } else { - elemNode = (Element) context; - } - Assert.assertTrue(result, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT, elemNode.getNodeName(), expr)); - } + /** + * Asserts that an XPath 1.0 expression holds true for the given evaluation context. + * The following standard namespace bindings do not need to be explicitly declared: + * + *
      + *
    • ows: {@value org.opengis.cite.eogeojson10.Namespaces#OWS}
    • + *
    • xlink: {@value org.opengis.cite.eogeojson10.Namespaces#XLINK}
    • + *
    • gml: {@value org.opengis.cite.eogeojson10.Namespaces#GML}
    • + *
    + * @param expr A valid XPath 1.0 expression. + * @param context The context node. + * @param namespaceBindings A collection of namespace bindings for the XPath + * expression, where each entry maps a namespace URI (key) to a prefix (value). It may + * be {@code null}. + */ + public static void assertXPath(String expr, Node context, Map namespaceBindings) { + if (null == context) { + throw new NullPointerException("Context node is null."); + } + NamespaceBindings bindings = NamespaceBindings.withStandardBindings(); + bindings.addAllBindings(namespaceBindings); + XPath xpath = XPathFactory.newInstance().newXPath(); + xpath.setNamespaceContext(bindings); + Boolean result; + try { + result = (Boolean) xpath.evaluate(expr, context, XPathConstants.BOOLEAN); + } + catch (XPathExpressionException xpe) { + String msg = ErrorMessage.format(ErrorMessageKeys.XPATH_ERROR, expr); + LOGR.log(Level.WARNING, msg, xpe); + throw new AssertionError(msg); + } + Element elemNode; + if (Document.class.isInstance(context)) { + elemNode = Document.class.cast(context).getDocumentElement(); + } + else { + elemNode = (Element) context; + } + Assert.assertTrue(result, ErrorMessage.format(ErrorMessageKeys.XPATH_RESULT, elemNode.getNodeName(), expr)); + } - /** - * Asserts that an XML resource is schema-valid. - * - * @param validator - * The Validator to use. - * @param source - * The XML Source to be validated. - */ - public static void assertSchemaValid(Validator validator, Source source) { - ValidationErrorHandler errHandler = new ValidationErrorHandler(); - validator.setErrorHandler(errHandler); - try { - validator.validate(source); - } catch (Exception e) { - throw new AssertionError(ErrorMessage.format(ErrorMessageKeys.XML_ERROR, e.getMessage())); - } - Assert.assertFalse(errHandler.errorsDetected(), ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID, - errHandler.getErrorCount(), errHandler.toString())); - } + /** + * Asserts that an XML resource is schema-valid. + * @param validator The Validator to use. + * @param source The XML Source to be validated. + */ + public static void assertSchemaValid(Validator validator, Source source) { + ValidationErrorHandler errHandler = new ValidationErrorHandler(); + validator.setErrorHandler(errHandler); + try { + validator.validate(source); + } + catch (Exception e) { + throw new AssertionError(ErrorMessage.format(ErrorMessageKeys.XML_ERROR, e.getMessage())); + } + Assert.assertFalse(errHandler.errorsDetected(), ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID, + errHandler.getErrorCount(), errHandler.toString())); + } - /** - * Asserts that an XML resource satisfies all applicable constraints defined - * for the specified phase in a Schematron (ISO 19757-3) schema. The "xslt2" - * query language binding is supported. Two phase names have special - * meanings: - *
      - *
    • "#ALL": All patterns are active
    • - *
    • "#DEFAULT": The phase identified by the defaultPhase attribute on the - * schema element should be used.
    • - *
    - * - * @param schemaRef - * A URL that denotes the location of a Schematron schema. - * @param xmlSource - * The XML Source to be validated. - * @param activePhase - * The active phase (pattern set) whose patterns are used for - * validation; this is set to "#ALL" if not specified. - */ - public static void assertSchematronValid(URL schemaRef, Source xmlSource, String activePhase) { - String phase = (null == activePhase || activePhase.isEmpty()) ? "#ALL" : activePhase; - SchematronValidator validator; - try { - validator = new SchematronValidator(new StreamSource(schemaRef.toString()), phase); - } catch (Exception e) { - StringBuilder msg = new StringBuilder("Failed to process Schematron schema at "); - msg.append(schemaRef).append('\n'); - msg.append(e.getMessage()); - throw new AssertionError(msg); - } - DOMResult result = (DOMResult) validator.validate(xmlSource); - Assert.assertFalse(validator.ruleViolationsDetected(), ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID, - validator.getRuleViolationCount(), XMLUtils.writeNodeToString(result.getNode()))); - } + /** + * Asserts that an XML resource satisfies all applicable constraints defined for the + * specified phase in a Schematron (ISO 19757-3) schema. The "xslt2" query language + * binding is supported. Two phase names have special meanings: + *
      + *
    • "#ALL": All patterns are active
    • + *
    • "#DEFAULT": The phase identified by the defaultPhase attribute on the schema + * element should be used.
    • + *
    + * @param schemaRef A URL that denotes the location of a Schematron schema. + * @param xmlSource The XML Source to be validated. + * @param activePhase The active phase (pattern set) whose patterns are used for + * validation; this is set to "#ALL" if not specified. + */ + public static void assertSchematronValid(URL schemaRef, Source xmlSource, String activePhase) { + String phase = (null == activePhase || activePhase.isEmpty()) ? "#ALL" : activePhase; + SchematronValidator validator; + try { + validator = new SchematronValidator(new StreamSource(schemaRef.toString()), phase); + } + catch (Exception e) { + StringBuilder msg = new StringBuilder("Failed to process Schematron schema at "); + msg.append(schemaRef).append('\n'); + msg.append(e.getMessage()); + throw new AssertionError(msg); + } + DOMResult result = (DOMResult) validator.validate(xmlSource); + Assert.assertFalse(validator.ruleViolationsDetected(), ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID, + validator.getRuleViolationCount(), XMLUtils.writeNodeToString(result.getNode()))); + } - /** - * Asserts that the given XML entity contains the expected number of - * descendant elements having the specified name. - * - * @param xmlEntity - * A Document representing an XML entity. - * @param elementName - * The qualified name of the element. - * @param expectedCount - * The expected number of occurrences. - */ - public static void assertDescendantElementCount(Document xmlEntity, QName elementName, int expectedCount) { - NodeList features = xmlEntity.getElementsByTagNameNS(elementName.getNamespaceURI(), elementName.getLocalPart()); - Assert.assertEquals(features.getLength(), expectedCount, - String.format("Unexpected number of %s descendant elements.", elementName)); - } + /** + * Asserts that the given XML entity contains the expected number of descendant + * elements having the specified name. + * @param xmlEntity A Document representing an XML entity. + * @param elementName The qualified name of the element. + * @param expectedCount The expected number of occurrences. + */ + public static void assertDescendantElementCount(Document xmlEntity, QName elementName, int expectedCount) { + NodeList features = xmlEntity.getElementsByTagNameNS(elementName.getNamespaceURI(), elementName.getLocalPart()); + Assert.assertEquals(features.getLength(), expectedCount, + String.format("Unexpected number of %s descendant elements.", elementName)); + } + + /** + * Asserts that the given response message contains an OGC exception report. The + * message body must contain an XML document that has a document element with the + * following properties: + * + *
      + *
    • [local name] = "ExceptionReport"
    • + *
    • [namespace name] = "http://www.opengis.net/ows/2.0"
    • + *
    + * @param rsp A ClientResponse object representing an HTTP response message. + * @param exceptionCode The expected OGC exception code. + * @param locator A case-insensitive string value expected to occur in the locator + * attribute (e.g. a parameter name); the attribute value will be ignored if the + * argument is null or empty. + */ + public static void assertExceptionReport(ClientResponse rsp, String exceptionCode, String locator) { + Assert.assertEquals(rsp.getStatus(), Status.BAD_REQUEST.getStatusCode(), + ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS)); + Document doc = rsp.readEntity(Document.class); + String expr = String.format("//ows:Exception[@exceptionCode = '%s']", exceptionCode); + NodeList nodeList = null; + try { + nodeList = XMLUtils.evaluateXPath(doc, expr, null); + } + catch (XPathExpressionException xpe) { + // won't happen + } + Assert.assertTrue(nodeList.getLength() > 0, "Exception not found in response: " + expr); + if (null != locator && !locator.isEmpty()) { + Element exception = (Element) nodeList.item(0); + String locatorValue = exception.getAttribute("locator").toLowerCase(); + Assert.assertTrue(locatorValue.contains(locator.toLowerCase()), + String.format("Expected locator attribute to contain '%s']", locator)); + } + } - /** - * Asserts that the given response message contains an OGC exception report. - * The message body must contain an XML document that has a document element - * with the following properties: - * - *
      - *
    • [local name] = "ExceptionReport"
    • - *
    • [namespace name] = "http://www.opengis.net/ows/2.0"
    • - *
    - * - * @param rsp - * A ClientResponse object representing an HTTP response message. - * @param exceptionCode - * The expected OGC exception code. - * @param locator - * A case-insensitive string value expected to occur in the - * locator attribute (e.g. a parameter name); the attribute value - * will be ignored if the argument is null or empty. - */ - public static void assertExceptionReport(ClientResponse rsp, String exceptionCode, String locator) { - Assert.assertEquals(rsp.getStatus(), Status.BAD_REQUEST.getStatusCode(), - ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS)); - Document doc = rsp.readEntity(Document.class); - String expr = String.format("//ows:Exception[@exceptionCode = '%s']", exceptionCode); - NodeList nodeList = null; - try { - nodeList = XMLUtils.evaluateXPath(doc, expr, null); - } catch (XPathExpressionException xpe) { - // won't happen - } - Assert.assertTrue(nodeList.getLength() > 0, "Exception not found in response: " + expr); - if (null != locator && !locator.isEmpty()) { - Element exception = (Element) nodeList.item(0); - String locatorValue = exception.getAttribute("locator").toLowerCase(); - Assert.assertTrue(locatorValue.contains(locator.toLowerCase()), - String.format("Expected locator attribute to contain '%s']", locator)); - } - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/ErrorMessage.java b/src/main/java/org/opengis/cite/eogeojson10/ErrorMessage.java index ca9e213..b47182f 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ErrorMessage.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ErrorMessage.java @@ -4,46 +4,39 @@ import java.util.ResourceBundle; /** - * Utility class for retrieving and formatting localized error messages that - * describe failed assertions. + * Utility class for retrieving and formatting localized error messages that describe + * failed assertions. */ public class ErrorMessage { - private static final String BASE_NAME = - "org.opengis.cite.eogeojson10.MessageBundle"; - private static ResourceBundle msgResources = - ResourceBundle.getBundle(BASE_NAME); + private static final String BASE_NAME = "org.opengis.cite.eogeojson10.MessageBundle"; - /** - * Produces a formatted error message using the supplied substitution - * arguments and the current locale. The arguments should reflect the order - * of the placeholders in the message template. - * - * @param msgKey - * The key identifying the message template; it should be a - * member of {@code ErrorMessageKeys}. - * @param args - * An array of arguments to be formatted and substituted in the - * content of the message. - * @return A String containing the message content. If no message is found - * for the given key, a {@link java.util.MissingResourceException} - * is thrown. - */ - public static String format(String msgKey, Object... args) { - return MessageFormat.format(msgResources.getString(msgKey), args); - } + private static ResourceBundle msgResources = ResourceBundle.getBundle(BASE_NAME); + + /** + * Produces a formatted error message using the supplied substitution arguments and + * the current locale. The arguments should reflect the order of the placeholders in + * the message template. + * @param msgKey The key identifying the message template; it should be a member of + * {@code ErrorMessageKeys}. + * @param args An array of arguments to be formatted and substituted in the content of + * the message. + * @return A String containing the message content. If no message is found for the + * given key, a {@link java.util.MissingResourceException} is thrown. + */ + public static String format(String msgKey, Object... args) { + return MessageFormat.format(msgResources.getString(msgKey), args); + } + + /** + * Retrieves a simple message according to the current locale. + * @param msgKey The key identifying the message; it should be a member of + * {@code ErrorMessageKeys}. + * @return A String containing the message content. If no message is found for the + * given key, a {@link java.util.MissingResourceException} is thrown. + */ + public static String get(String msgKey) { + return msgResources.getString(msgKey); + } - /** - * Retrieves a simple message according to the current locale. - * - * @param msgKey - * The key identifying the message; it should be a member of - * {@code ErrorMessageKeys}. - * @return A String containing the message content. If no message is found - * for the given key, a {@link java.util.MissingResourceException} - * is thrown. - */ - public static String get(String msgKey) { - return msgResources.getString(msgKey); - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/ErrorMessageKeys.java b/src/main/java/org/opengis/cite/eogeojson10/ErrorMessageKeys.java index 9af02a6..a453c3d 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ErrorMessageKeys.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ErrorMessageKeys.java @@ -1,22 +1,44 @@ package org.opengis.cite.eogeojson10; /** - * Defines keys used to access localized messages for assertion errors. The - * messages are stored in Properties files that are encoded in ISO-8859-1 - * (Latin-1). For some languages the {@code native2ascii} tool must be used to - * process the files and produce escaped Unicode characters. + * Defines keys used to access localized messages for assertion errors. The messages are + * stored in Properties files that are encoded in ISO-8859-1 (Latin-1). For some languages + * the {@code native2ascii} tool must be used to process the files and produce escaped + * Unicode characters. */ public class ErrorMessageKeys { - public static final String NOT_SCHEMA_VALID = "NotSchemaValid"; - public static final String EMPTY_STRING = "EmptyString"; - public static final String XPATH_RESULT = "XPathResult"; - public static final String NAMESPACE_NAME = "NamespaceName"; - public static final String LOCAL_NAME = "LocalName"; - public static final String XML_ERROR = "XMLError"; - public static final String XPATH_ERROR = "XPathError"; - public static final String MISSING_INFOSET_ITEM = "MissingInfosetItem"; - public static final String UNEXPECTED_STATUS = "UnexpectedStatus"; - public static final String UNEXPECTED_MEDIA_TYPE = "UnexpectedMediaType"; - public static final String MISSING_ENTITY = "MissingEntity"; + /** Constant NOT_SCHEMA_VALID="NotSchemaValid" */ + public static final String NOT_SCHEMA_VALID = "NotSchemaValid"; + + /** Constant EMPTY_STRING="EmptyString" */ + public static final String EMPTY_STRING = "EmptyString"; + + /** Constant XPATH_RESULT="XPathResult" */ + public static final String XPATH_RESULT = "XPathResult"; + + /** Constant NAMESPACE_NAME="NamespaceName" */ + public static final String NAMESPACE_NAME = "NamespaceName"; + + /** Constant LOCAL_NAME="LocalName" */ + public static final String LOCAL_NAME = "LocalName"; + + /** Constant XML_ERROR="XMLError" */ + public static final String XML_ERROR = "XMLError"; + + /** Constant XPATH_ERROR="XPathError" */ + public static final String XPATH_ERROR = "XPathError"; + + /** Constant MISSING_INFOSET_ITEM="MissingInfosetItem" */ + public static final String MISSING_INFOSET_ITEM = "MissingInfosetItem"; + + /** Constant UNEXPECTED_STATUS="UnexpectedStatus" */ + public static final String UNEXPECTED_STATUS = "UnexpectedStatus"; + + /** Constant UNEXPECTED_MEDIA_TYPE="UnexpectedMediaType" */ + public static final String UNEXPECTED_MEDIA_TYPE = "UnexpectedMediaType"; + + /** Constant MISSING_ENTITY="MissingEntity" */ + public static final String MISSING_ENTITY = "MissingEntity"; + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/Namespaces.java b/src/main/java/org/opengis/cite/eogeojson10/Namespaces.java index 86ebafc..2586a0b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/Namespaces.java +++ b/src/main/java/org/opengis/cite/eogeojson10/Namespaces.java @@ -4,28 +4,30 @@ /** * XML namespace names. - * - * @see Namespaces in XML 1.0 * + * @see Namespaces in XML 1.0 */ public class Namespaces { - private Namespaces() { - } - - /** SOAP 1.2 message envelopes. */ - public static final String SOAP_ENV = "http://www.w3.org/2003/05/soap-envelope"; - /** W3C XLink */ - public static final String XLINK = "http://www.w3.org/1999/xlink"; - /** OGC 06-121r3 (OWS 1.1) */ - public static final String OWS = "http://www.opengis.net/ows/1.1"; - /** ISO 19136 (GML 3.2) */ - public static final String GML = "http://www.opengis.net/gml/3.2"; - /** W3C XML Schema namespace */ - public static final URI XSD = URI - .create("http://www.w3.org/2001/XMLSchema"); - /** Schematron (ISO 19757-3) namespace */ - public static final URI SCH = URI - .create("http://purl.oclc.org/dsdl/schematron"); + private Namespaces() { + } + + /** SOAP 1.2 message envelopes. */ + public static final String SOAP_ENV = "http://www.w3.org/2003/05/soap-envelope"; + + /** W3C XLink */ + public static final String XLINK = "http://www.w3.org/1999/xlink"; + + /** OGC 06-121r3 (OWS 1.1) */ + public static final String OWS = "http://www.opengis.net/ows/1.1"; + + /** ISO 19136 (GML 3.2) */ + public static final String GML = "http://www.opengis.net/gml/3.2"; + + /** W3C XML Schema namespace */ + public static final URI XSD = URI.create("http://www.w3.org/2001/XMLSchema"); + + /** Schematron (ISO 19757-3) namespace */ + public static final URI SCH = URI.create("http://purl.oclc.org/dsdl/schematron"); } diff --git a/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java b/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java index 2fa1c51..bfb5880 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java +++ b/src/main/java/org/opengis/cite/eogeojson10/ReusableEntityFilter.java @@ -11,17 +11,18 @@ /** * Buffers the (response) entity so it can be read multiple times. * - *

    WARNING: The entity InputStream must be reset after each - * read attempt.

    + *

    + * WARNING: The entity InputStream must be reset after each read attempt. + *

    */ public class ReusableEntityFilter implements ClientResponseFilter { - /** {@inheritDoc} */ - @Override - public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { - if (responseContext instanceof ClientResponse) { - ((ClientResponse) responseContext).bufferEntity(); - } - } + /** {@inheritDoc} */ + @Override + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { + if (responseContext instanceof ClientResponse) { + ((ClientResponse) responseContext).bufferEntity(); + } + } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java b/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java index 07a207f..3ce2ca7 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuiteAttribute.java @@ -7,47 +7,64 @@ import jakarta.ws.rs.client.Client; /** - * An enumerated type defining ISuite attributes that may be set to constitute a - * shared test fixture. + * An enumerated type defining ISuite attributes that may be set to constitute a shared + * test fixture. */ @SuppressWarnings("rawtypes") public enum SuiteAttribute { - /** - * A client component for interacting with HTTP endpoints. - */ - CLIENT("httpClient", Client.class), - /** - * A DOM Document that represents the test subject or metadata about it. - */ - TEST_SUBJECT("testSubject", Document.class), - /** - * A File containing the feature collection test subject or a description of it. - */ - COL_TEST_SUBJ_FILE("collectionTestSubjectFile", File.class), /** - * A File containing the feature test subject or a description of it. - */ - TEST_SUBJ_FILE("testSubjectFile", File.class); - private final Class attrType; - private final String attrName; - - private SuiteAttribute(String attrName, Class attrType) { - this.attrName = attrName; - this.attrType = attrType; - } - - public Class getType() { - return attrType; - } - - public String getName() { - return attrName; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(attrName); - sb.append('(').append(attrType.getName()).append(')'); - return sb.toString(); - } + /** + * A client component for interacting with HTTP endpoints. + */ + CLIENT("httpClient", Client.class), + /** + * A DOM Document that represents the test subject or metadata about it. + */ + TEST_SUBJECT("testSubject", Document.class), + /** + * A File containing the feature collection test subject or a description of it. + */ + COL_TEST_SUBJ_FILE("collectionTestSubjectFile", File.class), + /** + * A File containing the feature test subject or a description of it. + */ + TEST_SUBJ_FILE("testSubjectFile", File.class); + + private final Class attrType; + + private final String attrName; + + private SuiteAttribute(String attrName, Class attrType) { + this.attrName = attrName; + this.attrType = attrType; + } + + /** + *

    + * getType. + *

    + * @return a {@link java.lang.Class} object + */ + public Class getType() { + return attrType; + } + + /** + *

    + * getName. + *

    + * @return a {@link java.lang.String} object + */ + public String getName() { + return attrName; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(attrName); + sb.append('(').append(attrType.getName()).append(')'); + return sb.toString(); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java b/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java index bd3fc79..80c283f 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuiteFixtureListener.java @@ -15,109 +15,107 @@ import jakarta.ws.rs.client.Client; /** - * A listener that performs various tasks before and after a test suite is run, - * usually concerned with maintaining a shared test suite fixture. Since this - * listener is loaded using the ServiceLoader mechanism, its methods will be - * called before those of other suite listeners listed in the test suite - * definition and before any annotated configuration methods. + * A listener that performs various tasks before and after a test suite is run, usually + * concerned with maintaining a shared test suite fixture. Since this listener is loaded + * using the ServiceLoader mechanism, its methods will be called before those of other + * suite listeners listed in the test suite definition and before any annotated + * configuration methods. * - * Attributes set on an ISuite instance are not inherited by constituent test - * group contexts (ITestContext). However, suite attributes are still accessible - * from lower contexts. + * Attributes set on an ISuite instance are not inherited by constituent test group + * contexts (ITestContext). However, suite attributes are still accessible from lower + * contexts. * * @see org.testng.ISuite ISuite interface */ public class SuiteFixtureListener implements ISuiteListener { - @Override - public void onStart(ISuite suite) { - processSuiteParameters(suite); - registerClientComponent(suite); - } + /** {@inheritDoc} */ + @Override + public void onStart(ISuite suite) { + processSuiteParameters(suite); + registerClientComponent(suite); + } - @Override - public void onFinish(ISuite suite) { - if (null != System.getProperty("deleteSubjectOnFinish")) { - deleteTempFiles(suite); - System.getProperties().remove("deleteSubjectOnFinish"); - } - } + /** {@inheritDoc} */ + @Override + public void onFinish(ISuite suite) { + if (null != System.getProperty("deleteSubjectOnFinish")) { + deleteTempFiles(suite); + System.getProperties().remove("deleteSubjectOnFinish"); + } + } - /** - * Processes test suite arguments and sets suite attributes accordingly. The - * entity referenced by the {@link TestRunArg#IUT iut} argument is retrieved - * and written to a File that is set as the value of the suite attribute - * {@link SuiteAttribute#TEST_SUBJ_FILE testSubjectFile}. - * - * @param suite - * An ISuite object representing a TestNG test suite. - */ - void processSuiteParameters(ISuite suite) { - Map params = suite.getXmlSuite().getParameters(); - TestSuiteLogger.log(Level.CONFIG, "Suite parameters\n" + params.toString()); - String iutParam = params.get(TestRunArg.IUT.toString()); - if ((null == iutParam) || iutParam.isEmpty()) { - throw new IllegalArgumentException("Required test run parameter not found: " + TestRunArg.IUT.toString()); - } - URI iutRef = URI.create(iutParam.trim()); - File entityFile = null; - try { - entityFile = URIUtils.dereferenceURI( iutRef ); - } catch ( IOException iox ) { - throw new RuntimeException( "Failed to dereference resource located at " + iutRef, iox ); - } - TestSuiteLogger.log( Level.FINE, String.format( "Wrote test subject to file: %s (%d bytes)", - entityFile.getAbsolutePath(), entityFile.length() ) ); - suite.setAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName(), entityFile); - - //------ - - String colIutParam = params.get(TestRunArg.COL.toString()); - if ((null == colIutParam) || colIutParam.isEmpty()) { - throw new IllegalArgumentException("Required test run parameter not found: " + TestRunArg.COL.toString()); - } - URI colIutRef = URI.create(colIutParam.trim()); - File colEntityFile = null; - try { - colEntityFile = URIUtils.dereferenceURI( colIutRef ); - } catch ( IOException ioxc ) { - throw new RuntimeException( "Failed to dereference resource located at " + colIutRef, ioxc ); - } - TestSuiteLogger.log( Level.FINE, String.format( "Wrote test subject to file: %s (%d bytes)", - colEntityFile.getAbsolutePath(), colEntityFile.length() ) ); - suite.setAttribute(SuiteAttribute.COL_TEST_SUBJ_FILE.getName(), colEntityFile); - } + /** + * Processes test suite arguments and sets suite attributes accordingly. The entity + * referenced by the {@link TestRunArg#IUT iut} argument is retrieved and written to a + * File that is set as the value of the suite attribute + * {@link SuiteAttribute#TEST_SUBJ_FILE testSubjectFile}. + * @param suite An ISuite object representing a TestNG test suite. + */ + void processSuiteParameters(ISuite suite) { + Map params = suite.getXmlSuite().getParameters(); + TestSuiteLogger.log(Level.CONFIG, "Suite parameters\n" + params.toString()); + String iutParam = params.get(TestRunArg.IUT.toString()); + if ((null == iutParam) || iutParam.isEmpty()) { + throw new IllegalArgumentException("Required test run parameter not found: " + TestRunArg.IUT.toString()); + } + URI iutRef = URI.create(iutParam.trim()); + File entityFile = null; + try { + entityFile = URIUtils.dereferenceURI(iutRef); + } + catch (IOException iox) { + throw new RuntimeException("Failed to dereference resource located at " + iutRef, iox); + } + TestSuiteLogger.log(Level.FINE, String.format("Wrote test subject to file: %s (%d bytes)", + entityFile.getAbsolutePath(), entityFile.length())); + suite.setAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName(), entityFile); - /** - * A client component is added to the suite fixture as the value of the - * {@link SuiteAttribute#CLIENT} attribute; it may be subsequently accessed - * via the {@link org.testng.ITestContext#getSuite()} method. - * - * @param suite - * The test suite instance. - */ - void registerClientComponent(ISuite suite) { - Client client = ClientUtils.buildClient(); - if (null != client) { - suite.setAttribute(SuiteAttribute.CLIENT.getName(), client); - } - } + // ------ + + String colIutParam = params.get(TestRunArg.COL.toString()); + if ((null == colIutParam) || colIutParam.isEmpty()) { + throw new IllegalArgumentException("Required test run parameter not found: " + TestRunArg.COL.toString()); + } + URI colIutRef = URI.create(colIutParam.trim()); + File colEntityFile = null; + try { + colEntityFile = URIUtils.dereferenceURI(colIutRef); + } + catch (IOException ioxc) { + throw new RuntimeException("Failed to dereference resource located at " + colIutRef, ioxc); + } + TestSuiteLogger.log(Level.FINE, String.format("Wrote test subject to file: %s (%d bytes)", + colEntityFile.getAbsolutePath(), colEntityFile.length())); + suite.setAttribute(SuiteAttribute.COL_TEST_SUBJ_FILE.getName(), colEntityFile); + } + + /** + * A client component is added to the suite fixture as the value of the + * {@link SuiteAttribute#CLIENT} attribute; it may be subsequently accessed via the + * {@link org.testng.ITestContext#getSuite()} method. + * @param suite The test suite instance. + */ + void registerClientComponent(ISuite suite) { + Client client = ClientUtils.buildClient(); + if (null != client) { + suite.setAttribute(SuiteAttribute.CLIENT.getName(), client); + } + } + + /** + * Deletes temporary files created during the test run if TestSuiteLogger is enabled + * at the INFO level or higher (they are left intact at the CONFIG level or lower). + * @param suite The test suite. + */ + void deleteTempFiles(ISuite suite) { + if (TestSuiteLogger.isLoggable(Level.CONFIG)) { + return; + } + File testSubjFile = (File) suite.getAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName()); + if (testSubjFile.exists()) { + testSubjFile.delete(); + } + } - /** - * Deletes temporary files created during the test run if TestSuiteLogger is - * enabled at the INFO level or higher (they are left intact at the CONFIG - * level or lower). - * - * @param suite - * The test suite. - */ - void deleteTempFiles(ISuite suite) { - if (TestSuiteLogger.isLoggable(Level.CONFIG)) { - return; - } - File testSubjFile = (File) suite.getAttribute(SuiteAttribute.TEST_SUBJ_FILE.getName()); - if (testSubjFile.exists()) { - testSubjFile.delete(); - } - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java b/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java index 0f36062..8713ace 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java @@ -7,33 +7,32 @@ import org.testng.annotations.BeforeSuite; /** - * Checks that various preconditions are satisfied before the test suite is run. - * If any of these (BeforeSuite) methods fail, all tests will be skipped. + * Checks that various preconditions are satisfied before the test suite is run. If any of + * these (BeforeSuite) methods fail, all tests will be skipped. */ public class SuitePreconditions { - private static final Logger LOGR = Logger.getLogger(SuitePreconditions.class.getName()); + private static final Logger LOGR = Logger.getLogger(SuitePreconditions.class.getName()); + + /** + * Verifies that the referenced test subject exists and has the expected type. + * @param testContext Information about the (pending) test run. + */ + @BeforeSuite + @SuppressWarnings("rawtypes") + public void verifyTestSubject(ITestContext testContext) { + SuiteAttribute testFileAttr = SuiteAttribute.TEST_SUBJ_FILE; + Object sutObj = testContext.getSuite().getAttribute(testFileAttr.getName()); + Class expectedType = testFileAttr.getType(); + if (null != sutObj && expectedType.isInstance(sutObj)) { + // TODO: Verify test subject + } + else { + String msg = String.format("Value of test suite attribute '%s' is missing or is not an instance of %s", + testFileAttr.getName(), expectedType.getName()); + LOGR.log(Level.SEVERE, msg); + throw new AssertionError(msg); + } + } - /** - * Verifies that the referenced test subject exists and has the expected - * type. - * - * @param testContext - * Information about the (pending) test run. - */ - @BeforeSuite - @SuppressWarnings("rawtypes") - public void verifyTestSubject(ITestContext testContext) { - SuiteAttribute testFileAttr = SuiteAttribute.TEST_SUBJ_FILE; - Object sutObj = testContext.getSuite().getAttribute(testFileAttr.getName()); - Class expectedType = testFileAttr.getType(); - if (null != sutObj && expectedType.isInstance(sutObj)) { - // TODO: Verify test subject - } else { - String msg = String.format("Value of test suite attribute '%s' is missing or is not an instance of %s", - testFileAttr.getName(), expectedType.getName()); - LOGR.log(Level.SEVERE, msg); - throw new AssertionError(msg); - } - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java b/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java index 473887a..dff74b9 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java +++ b/src/main/java/org/opengis/cite/eogeojson10/TestFailureListener.java @@ -13,87 +13,85 @@ import jakarta.ws.rs.core.Response; /** - * A listener that augments a test result with diagnostic information in the - * event that a test method failed. This information will appear in the XML - * report when the test run is completed. + * A listener that augments a test result with diagnostic information in the event that a + * test method failed. This information will appear in the XML report when the test run is + * completed. */ public class TestFailureListener extends TestListenerAdapter { - /** - * Sets the "request" and "response" attributes of a test result. The value - * of these attributes is a string that contains information about the - * content of an outgoing or incoming message: target resource, status code, - * headers, entity (if present). The entity is represented as a String with - * UTF-8 character encoding. - * - * @param result A description of a test result (with a fail verdict). - */ - @Override - public void onTestFailure(ITestResult result) { - super.onTestFailure(result); - Object instance = result.getInstance(); - if (CommonFixture.class.isInstance(instance)) { - CommonFixture fixture = CommonFixture.class.cast(instance); - result.setAttribute("request", getRequestMessageInfo(fixture.request)); - result.setAttribute("response", getResponseMessageInfo(fixture.response)); - } - } + /** + * {@inheritDoc} + * + * Sets the "request" and "response" attributes of a test result. The value of these + * attributes is a string that contains information about the content of an outgoing + * or incoming message: target resource, status code, headers, entity (if present). + * The entity is represented as a String with UTF-8 character encoding. + */ + @Override + public void onTestFailure(ITestResult result) { + super.onTestFailure(result); + Object instance = result.getInstance(); + if (CommonFixture.class.isInstance(instance)) { + CommonFixture fixture = CommonFixture.class.cast(instance); + result.setAttribute("request", getRequestMessageInfo(fixture.request)); + result.setAttribute("response", getResponseMessageInfo(fixture.response)); + } + } - /** - * Gets diagnostic information about a request message. If the request - * contains a message body, it should be represented as a DOM Document node - * or as an object having a meaningful toString() implementation. - * - * @param req An object representing an HTTP request message. - * @return A string containing information gleaned from the request message. - */ - String getRequestMessageInfo(ClientRequest req) { - if (null == req) { - return "No request message."; - } - StringBuilder msgInfo = new StringBuilder(); - msgInfo.append("Method: ").append(req.getMethod()).append('\n'); - msgInfo.append("Target URI: ").append(req.getUri()).append('\n'); - msgInfo.append("Headers: ").append(req.getHeaders()).append('\n'); - if (null != req.getEntity()) { - Object entity = req.getEntity(); - String body; - if (Document.class.isInstance(entity)) { - Document doc = Document.class.cast(entity); - body = XMLUtils.writeNodeToString(doc); - } else { - body = entity.toString(); - } - msgInfo.append(body).append('\n'); - } - return msgInfo.toString(); - } + /** + * Gets diagnostic information about a request message. If the request contains a + * message body, it should be represented as a DOM Document node or as an object + * having a meaningful toString() implementation. + * @param req An object representing an HTTP request message. + * @return A string containing information gleaned from the request message. + */ + String getRequestMessageInfo(ClientRequest req) { + if (null == req) { + return "No request message."; + } + StringBuilder msgInfo = new StringBuilder(); + msgInfo.append("Method: ").append(req.getMethod()).append('\n'); + msgInfo.append("Target URI: ").append(req.getUri()).append('\n'); + msgInfo.append("Headers: ").append(req.getHeaders()).append('\n'); + if (null != req.getEntity()) { + Object entity = req.getEntity(); + String body; + if (Document.class.isInstance(entity)) { + Document doc = Document.class.cast(entity); + body = XMLUtils.writeNodeToString(doc); + } + else { + body = entity.toString(); + } + msgInfo.append(body).append('\n'); + } + return msgInfo.toString(); + } - /** - * Gets diagnostic information about a response message. - * - * @param rsp An object representing an HTTP response message. - * @return A string containing information gleaned from the response - * message. - */ - String getResponseMessageInfo(Response rsp) { - if (null == rsp) { - return "No response message."; - } - StringBuilder msgInfo = new StringBuilder(); - msgInfo.append("Status: ").append(rsp.getStatus()).append('\n'); - msgInfo.append("Headers: ").append(rsp.getHeaders()).append('\n'); - if (rsp.hasEntity()) { - if (rsp.getMediaType().isCompatible(MediaType.APPLICATION_XML_TYPE)) { - Document doc = ClientUtils.getResponseEntityAsDocument(rsp, null); - msgInfo.append(XMLUtils.writeNodeToString(doc)); - } else { - byte[] body = rsp.readEntity(byte[].class); - msgInfo.append(new String(body, StandardCharsets.UTF_8)); - } - msgInfo.append('\n'); - } - return msgInfo.toString(); - } + /** + * Gets diagnostic information about a response message. + * @param rsp An object representing an HTTP response message. + * @return A string containing information gleaned from the response message. + */ + String getResponseMessageInfo(Response rsp) { + if (null == rsp) { + return "No response message."; + } + StringBuilder msgInfo = new StringBuilder(); + msgInfo.append("Status: ").append(rsp.getStatus()).append('\n'); + msgInfo.append("Headers: ").append(rsp.getHeaders()).append('\n'); + if (rsp.hasEntity()) { + if (rsp.getMediaType().isCompatible(MediaType.APPLICATION_XML_TYPE)) { + Document doc = ClientUtils.getResponseEntityAsDocument(rsp, null); + msgInfo.append(XMLUtils.writeNodeToString(doc)); + } + else { + byte[] body = rsp.readEntity(byte[].class); + msgInfo.append(new String(body, StandardCharsets.UTF_8)); + } + msgInfo.append('\n'); + } + return msgInfo.toString(); + } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/TestNGController.java b/src/main/java/org/opengis/cite/eogeojson10/TestNGController.java index e65d569..fb4e39b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/TestNGController.java +++ b/src/main/java/org/opengis/cite/eogeojson10/TestNGController.java @@ -30,144 +30,146 @@ */ public class TestNGController implements TestSuiteController { - private TestRunExecutor executor; - private Properties etsProperties = new Properties(); - - /** - * A convenience method for running the test suite using a command-line - * interface. The default values of the test run arguments are as follows: - *
      - *
    • XML properties file: ${user.home}/test-run-props.xml
    • - *
    • outputDir: ${user.home}
    • - *
    • deleteSubjectOnFinish: false
    • - *
    - *

    - * Synopsis - *

    - * - *
    -     * ets-*-aio.jar [-o|--outputDir $TMPDIR] [-d|--deleteSubjectOnFinish] [test-run-props.xml]
    -     * 
    - * - * @param args - * Test run arguments (optional). The first argument must refer - * to an XML properties file containing the expected set of test - * run arguments. If no argument is supplied, the file located at - * ${user.home}/test-run-props.xml will be used. - * @throws Exception - * If the test run cannot be executed (usually due to - * unsatisfied pre-conditions). - */ - public static void main(String[] args) throws Exception { - CommandLineArguments testRunArgs = new CommandLineArguments(); - JCommander cmd = new JCommander(testRunArgs); - try { - cmd.parse(args); - } catch (ParameterException px) { - System.out.println(px.getMessage()); - cmd.usage(); - } - if (testRunArgs.doDeleteSubjectOnFinish()) { - System.setProperty("deleteSubjectOnFinish", "true"); - } - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - File xmlArgs = testRunArgs.getPropertiesFile(); - Document testRunProps = db.parse(xmlArgs); - TestNGController controller = new TestNGController(testRunArgs.getOutputDir()); - Source testResults = controller.doTestRun(testRunProps); - System.out.println("Test results: " + testResults.getSystemId()); - } - - /** - * Default constructor uses the location given by the "java.io.tmpdir" - * system property as the root output directory. - */ - public TestNGController() { - this(System.getProperty("java.io.tmpdir")); - } - - /** - * Construct a controller that writes results to the given output directory. - * - * @param outputDir - * The location of the directory in which test results will be - * written (a file system path or a 'file' URI). It will be - * created if it does not exist. - */ - public TestNGController(String outputDir) { - InputStream is = getClass().getResourceAsStream("ets.properties"); - try { - this.etsProperties.load(is); - } catch (IOException ex) { - TestSuiteLogger.log(Level.WARNING, "Unable to load ets.properties. " + ex.getMessage()); - } - URL tngSuite = TestNGController.class.getResource("testng.xml"); - File resultsDir; - if (null == outputDir || outputDir.isEmpty()) { - resultsDir = new File(System.getProperty("user.home")); - } else if (outputDir.startsWith("file:")) { - resultsDir = new File(URI.create(outputDir)); - } else { - resultsDir = new File(outputDir); - } - TestSuiteLogger.log(Level.CONFIG, "Using TestNG config: " + tngSuite); - TestSuiteLogger.log(Level.CONFIG, "Using outputDirPath: " + resultsDir.getAbsolutePath()); - // NOTE: setting third argument to 'true' enables the default listeners - this.executor = new TestNGExecutor(tngSuite.toString(), resultsDir.getAbsolutePath(), false); - } - - @Override - public String getCode() { - return etsProperties.getProperty("ets-code"); - } - - @Override - public String getVersion() { - return etsProperties.getProperty("ets-version"); - } - - @Override - public String getTitle() { - return etsProperties.getProperty("ets-title"); - } - - @Override - public Source doTestRun(Document testRunArgs) throws Exception { - validateTestRunArgs(testRunArgs); - return executor.execute(testRunArgs); - } - - /** - * Validates the test run arguments. The test run is aborted if any of these - * checks fail. - * - * @param testRunArgs - * A DOM Document containing a set of XML properties (key-value - * pairs). - * @throws IllegalArgumentException - * If any arguments are missing or invalid for some reason. - */ - void validateTestRunArgs(Document testRunArgs) { - if (null == testRunArgs || !testRunArgs.getDocumentElement().getNodeName().equals("properties")) { - throw new IllegalArgumentException("Input is not an XML properties document."); - } - NodeList entries = testRunArgs.getDocumentElement().getElementsByTagName("entry"); - if (entries.getLength() == 0) { - throw new IllegalArgumentException("No test run arguments found."); - } - Map args = new HashMap(); - for (int i = 0; i < entries.getLength(); i++) { - Element entry = (Element) entries.item(i); - args.put(entry.getAttribute("key"), entry.getTextContent()); - } - if (!args.containsKey(TestRunArg.IUT.toString())) { - throw new IllegalArgumentException( - String.format("Missing argument: '%s' must be present.", TestRunArg.IUT)); - } - if (!args.containsKey(TestRunArg.COL.toString())) { - throw new IllegalArgumentException( - String.format("Missing argument: '%s' must be present.", TestRunArg.COL)); - } - } + private TestRunExecutor executor; + + private Properties etsProperties = new Properties(); + + /** + * A convenience method for running the test suite using a command-line interface. The + * default values of the test run arguments are as follows: + *
      + *
    • XML properties file: ${user.home}/test-run-props.xml
    • + *
    • outputDir: ${user.home}
    • + *
    • deleteSubjectOnFinish: false
    • + *
    + *

    + * Synopsis + *

    + * + *
    +	 * ets-*-aio.jar [-o|--outputDir $TMPDIR] [-d|--deleteSubjectOnFinish] [test-run-props.xml]
    +	 * 
    + * @param args Test run arguments (optional). The first argument must refer to an XML + * properties file containing the expected set of test run arguments. If no argument + * is supplied, the file located at ${user.home}/test-run-props.xml will be used. + * @throws java.lang.Exception If the test run cannot be executed (usually due to + * unsatisfied pre-conditions). + */ + public static void main(String[] args) throws Exception { + CommandLineArguments testRunArgs = new CommandLineArguments(); + JCommander cmd = new JCommander(testRunArgs); + try { + cmd.parse(args); + } + catch (ParameterException px) { + System.out.println(px.getMessage()); + cmd.usage(); + } + if (testRunArgs.doDeleteSubjectOnFinish()) { + System.setProperty("deleteSubjectOnFinish", "true"); + } + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + File xmlArgs = testRunArgs.getPropertiesFile(); + Document testRunProps = db.parse(xmlArgs); + TestNGController controller = new TestNGController(testRunArgs.getOutputDir()); + Source testResults = controller.doTestRun(testRunProps); + System.out.println("Test results: " + testResults.getSystemId()); + } + + /** + * Default constructor uses the location given by the "java.io.tmpdir" system property + * as the root output directory. + */ + public TestNGController() { + this(System.getProperty("java.io.tmpdir")); + } + + /** + * Construct a controller that writes results to the given output directory. + * @param outputDir The location of the directory in which test results will be + * written (a file system path or a 'file' URI). It will be created if it does not + * exist. + */ + public TestNGController(String outputDir) { + InputStream is = getClass().getResourceAsStream("ets.properties"); + try { + this.etsProperties.load(is); + } + catch (IOException ex) { + TestSuiteLogger.log(Level.WARNING, "Unable to load ets.properties. " + ex.getMessage()); + } + URL tngSuite = TestNGController.class.getResource("testng.xml"); + File resultsDir; + if (null == outputDir || outputDir.isEmpty()) { + resultsDir = new File(System.getProperty("user.home")); + } + else if (outputDir.startsWith("file:")) { + resultsDir = new File(URI.create(outputDir)); + } + else { + resultsDir = new File(outputDir); + } + TestSuiteLogger.log(Level.CONFIG, "Using TestNG config: " + tngSuite); + TestSuiteLogger.log(Level.CONFIG, "Using outputDirPath: " + resultsDir.getAbsolutePath()); + // NOTE: setting third argument to 'true' enables the default listeners + this.executor = new TestNGExecutor(tngSuite.toString(), resultsDir.getAbsolutePath(), false); + } + + /** {@inheritDoc} */ + @Override + public String getCode() { + return etsProperties.getProperty("ets-code"); + } + + /** {@inheritDoc} */ + @Override + public String getVersion() { + return etsProperties.getProperty("ets-version"); + } + + /** {@inheritDoc} */ + @Override + public String getTitle() { + return etsProperties.getProperty("ets-title"); + } + + /** {@inheritDoc} */ + @Override + public Source doTestRun(Document testRunArgs) throws Exception { + validateTestRunArgs(testRunArgs); + return executor.execute(testRunArgs); + } + + /** + * Validates the test run arguments. The test run is aborted if any of these checks + * fail. + * @param testRunArgs A DOM Document containing a set of XML properties (key-value + * pairs). + * @throws IllegalArgumentException If any arguments are missing or invalid for some + * reason. + */ + void validateTestRunArgs(Document testRunArgs) { + if (null == testRunArgs || !testRunArgs.getDocumentElement().getNodeName().equals("properties")) { + throw new IllegalArgumentException("Input is not an XML properties document."); + } + NodeList entries = testRunArgs.getDocumentElement().getElementsByTagName("entry"); + if (entries.getLength() == 0) { + throw new IllegalArgumentException("No test run arguments found."); + } + Map args = new HashMap(); + for (int i = 0; i < entries.getLength(); i++) { + Element entry = (Element) entries.item(i); + args.put(entry.getAttribute("key"), entry.getTextContent()); + } + if (!args.containsKey(TestRunArg.IUT.toString())) { + throw new IllegalArgumentException( + String.format("Missing argument: '%s' must be present.", TestRunArg.IUT)); + } + if (!args.containsKey(TestRunArg.COL.toString())) { + throw new IllegalArgumentException( + String.format("Missing argument: '%s' must be present.", TestRunArg.COL)); + } + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/TestRunArg.java b/src/main/java/org/opengis/cite/eogeojson10/TestRunArg.java index 6991989..8a850b1 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/TestRunArg.java +++ b/src/main/java/org/opengis/cite/eogeojson10/TestRunArg.java @@ -5,19 +5,21 @@ */ public enum TestRunArg { - /** - * An absolute URI that refers to a representation of the test subject or - * metadata about it. - */ - COL, - /** - * An absolute URI that refers to a representation of the test subject or - * metadata about it. - */ - IUT; + /** + * An absolute URI that refers to a representation of the test subject or metadata + * about it. + */ + COL, + /** + * An absolute URI that refers to a representation of the test subject or metadata + * about it. + */ + IUT; + + /** {@inheritDoc} */ + @Override + public String toString() { + return name().toLowerCase(); + } - @Override - public String toString() { - return name().toLowerCase(); - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/TestRunListener.java b/src/main/java/org/opengis/cite/eogeojson10/TestRunListener.java index 17b1a32..8497ad1 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/TestRunListener.java +++ b/src/main/java/org/opengis/cite/eogeojson10/TestRunListener.java @@ -3,24 +3,28 @@ import org.testng.IExecutionListener; /** - * A listener that is invoked before and after a test run. It is often used to - * configure a shared fixture that endures for the duration of the entire test - * run. A FixtureManager may be used to manage such a fixture. + * A listener that is invoked before and after a test run. It is often used to configure a + * shared fixture that endures for the duration of the entire test run. A FixtureManager + * may be used to manage such a fixture. * - *

    A shared fixture should be used with caution in order to avoid undesirable - * test interactions. In general, it should be populated with "read-only" - * objects that are not modified during the test run.

    + *

    + * A shared fixture should be used with caution in order to avoid undesirable test + * interactions. In general, it should be populated with "read-only" objects that are not + * modified during the test run. + *

    * * @see com.occamlab.te.spi.executors.FixtureManager FixtureManager - * */ public class TestRunListener implements IExecutionListener { - @Override - public void onExecutionStart() { - } + /** {@inheritDoc} */ + @Override + public void onExecutionStart() { + } + + /** {@inheritDoc} */ + @Override + public void onExecutionFinish() { + } - @Override - public void onExecutionFinish() { - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/acquisitioninformation/AquisitionInformationConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/acquisitioninformation/AquisitionInformationConfClassTests.java index c9c05f1..7c8ac69 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/acquisitioninformation/AquisitionInformationConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/acquisitioninformation/AquisitionInformationConfClassTests.java @@ -6,38 +6,44 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class AquisitionInformationConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/acquisition-information, Section 7.6 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/acquisition-information, Section 7.6") - public void validateAquisitionInformation() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("acquisitionInformation")) { - //do nothing - } - else { - sb.append("acquisitionInformation field is missing. \n"); - valid = false; - } - } - else { - sb.append("acquisitionInformation field is missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * AquisitionInformationConfClassTests class. + *

    + * + */ +public class AquisitionInformationConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/acquisition-information, Section 7.6 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/acquisition-information, Section 7.6") + public void validateAquisitionInformation() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("acquisitionInformation")) { + // do nothing + } + else { + sb.append("acquisitionInformation field is missing. \n"); + valid = false; + } + } + else { + sb.append("acquisitionInformation field is missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/acquisitionparameters/AquisitionParametersConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/acquisitionparameters/AquisitionParametersConfClassTests.java index 9f62fb3..cefeeb2 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/acquisitionparameters/AquisitionParametersConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/acquisitionparameters/AquisitionParametersConfClassTests.java @@ -7,52 +7,58 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class AquisitionParametersConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/acquisition-parameters, Section 7.6 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/acquisition-parameters, Section 7.6") - public void validateAquisitionParameters() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("acquisitionInformation")) { - - //------------------- - JSONArray acquisitionInformationJO = propertiesJO.getJSONArray("acquisitionInformation"); - for(int i=0; i < acquisitionInformationJO.length(); i++) { - JSONObject acquisitionInformationJOItem = (JSONObject) acquisitionInformationJO.get(i); - if(acquisitionInformationJOItem.has("acquisitionParameters")) { - //do nothing - } - else { - sb.append("acquisitionParameters field is missing. \n"); - valid = false; - } - //------------------- - } - - } - else { - sb.append("acquisitionInformation and acquisitionParameters fields are missing. \n"); - valid = false; - } - } - else { - sb.append("acquisitionInformation and acquisitionParameters fields are missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * AquisitionParametersConfClassTests class. + *

    + * + */ +public class AquisitionParametersConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/acquisition-parameters, Section 7.6 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/acquisition-parameters, Section 7.6") + public void validateAquisitionParameters() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("acquisitionInformation")) { + + // ------------------- + JSONArray acquisitionInformationJO = propertiesJO.getJSONArray("acquisitionInformation"); + for (int i = 0; i < acquisitionInformationJO.length(); i++) { + JSONObject acquisitionInformationJOItem = (JSONObject) acquisitionInformationJO.get(i); + if (acquisitionInformationJOItem.has("acquisitionParameters")) { + // do nothing + } + else { + sb.append("acquisitionParameters field is missing. \n"); + valid = false; + } + // ------------------- + } + + } + else { + sb.append("acquisitionInformation and acquisitionParameters fields are missing. \n"); + valid = false; + } + } + else { + sb.append("acquisitionInformation and acquisitionParameters fields are missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/core/CoreTests.java b/src/main/java/org/opengis/cite/eogeojson10/core/CoreTests.java index 479def3..f98cc2b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/core/CoreTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/core/CoreTests.java @@ -1,136 +1,95 @@ package org.opengis.cite.eogeojson10.core; -import org.everit.json.schema.Schema; -import org.everit.json.schema.loader.SchemaLoader; -import org.json.JSONObject; - -import org.opengis.cite.eogeojson10.DataFixture; -import org.opengis.cite.eogeojson10.ErrorMessage; -import org.opengis.cite.eogeojson10.ErrorMessageKeys; +import java.io.File; +import java.io.InputStream; -import io.restassured.http.ContentType; -import io.restassured.http.Method; -import io.restassured.path.json.JsonPath; -import io.restassured.response.Response; import org.everit.json.schema.Schema; import org.everit.json.schema.loader.SchemaLoader; import org.json.JSONObject; +import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.ITestContext; -import org.testng.SkipException; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.w3c.dom.Document; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.*; - -import static io.restassured.http.ContentType.JSON; -import static io.restassured.http.Method.GET; - -import static org.testng.Assert.assertTrue; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Scanner; /** * Includes various tests of capability 1. */ public class CoreTests extends DataFixture { + /** + * Verifies conformance to /conf/core, Sections 7.1 and Section 7.8 + */ + @Test(description = "Implements /conf/core, Sections 7.1 and Section 7.8") + public void validateEOMetadataGeoJSONValidPerSchema() { + + StringBuffer errorMessage = new StringBuffer(); + + String schemaToApply = "/org/opengis/cite/eogeojson10/jsonschema/eo-geojson-schema-standalone.json"; + + boolean valid = false; + InputStream inputStream = getClass().getResourceAsStream(schemaToApply); + + Schema schema = null; + // ------Test the Feature + + try { + JSONObject rawSchema = new JSONObject(convertInputStreamToString(inputStream)); + schema = SchemaLoader.load(rawSchema); + + schema.validate(readJSONObjectFromFile(new File(testSubject))); // throws a + // ValidationException + // if this + // object is + // invalid + + valid = true; + } + catch (Exception ex) { + errorMessage.append("Validation of single feature document failed because " + ex.getMessage() + "\n"); + + valid = false; + } + + if (valid == false) { + Assert.assertTrue(valid, "Validation failed. " + errorMessage.toString() + " . "); + } + + // ------Test the Feature Collection + + JSONObject jo = null; + boolean validCol = false; + try { + + jo = readJSONObjectFromFile(new File(collectionTestSubject)); + + if (jo.has("type")) { + + if (jo.get("type").equals("FeatureCollection")) { + schema.validate(jo); // throws a ValidationException if this object is + // invalid + validCol = true; + } + else { + validCol = false; + errorMessage.append( + "Validation of feature collection did not have type property value that equals 'FeatureCollection'\n"); + } + } + else { + validCol = false; + errorMessage.append("Validation of feature collection did not have type property\n"); + } + + } + catch (Exception ex) { + errorMessage.append("Validation of Feature Collection failed because " + ex.getMessage() + "\n"); + + validCol = false; + } + + if (validCol == false) { + Assert.assertTrue(validCol, "Validation failed. " + errorMessage.toString()); + } + + } - /** - * Verifies conformance to /conf/core, Sections 7.1 and Section 7.8 - */ - @Test(description = "Implements /conf/core, Sections 7.1 and Section 7.8") - public void validateEOMetadataGeoJSONValidPerSchema(){ - - StringBuffer errorMessage = new StringBuffer(); - - String schemaToApply = "/org/opengis/cite/eogeojson10/jsonschema/eo-geojson-schema-standalone.json"; - - - boolean valid = false; - InputStream inputStream = getClass() - .getResourceAsStream(schemaToApply); - - - Schema schema = null; - //------Test the Feature - - try { - JSONObject rawSchema = new JSONObject(convertInputStreamToString(inputStream)); - schema = SchemaLoader.load(rawSchema); - - schema.validate(readJSONObjectFromFile(new File(testSubject))); // throws a ValidationException if this object is invalid - - valid = true; - } - catch(Exception ex) { - errorMessage.append("Validation of single feature document failed because "+ex.getMessage()+"\n"); - - valid = false; - } - - if(valid==false) { - Assert.assertTrue(valid, - "Validation failed. "+errorMessage.toString()+ " . "); - } - - //------Test the Feature Collection - - JSONObject jo = null; - boolean validCol = false; - try { - - jo = readJSONObjectFromFile(new File(collectionTestSubject)); - - - if(jo.has("type")) { - - if(jo.get("type").equals("FeatureCollection")) { - schema.validate(jo); // throws a ValidationException if this object is invalid - validCol = true; - } - else { - validCol = false; - errorMessage.append("Validation of feature collection did not have type property value that equals 'FeatureCollection'\n"); - } - } - else { - validCol = false; - errorMessage.append("Validation of feature collection did not have type property\n"); - } - - } - catch(Exception ex) - { - errorMessage.append("Validation of Feature Collection failed because "+ex.getMessage()+"\n"); - - validCol = false; - } - - if(validCol==false) { - Assert.assertTrue(validCol, - "Validation failed. "+errorMessage.toString()); - } - - } - - - - } diff --git a/src/main/java/org/opengis/cite/eogeojson10/core/package-info.java b/src/main/java/org/opengis/cite/eogeojson10/core/package-info.java index 6793070..8d9eebc 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/core/package-info.java +++ b/src/main/java/org/opengis/cite/eogeojson10/core/package-info.java @@ -1,14 +1,13 @@ /** - * Conformance Level 1 includes basic facilities. The following capabilities - * must be supported: + * Conformance Level 1 includes basic facilities. The following capabilities must be + * supported: *
      *
    • Capability 1.1
    • *
    • Capability 1.2
    • - *
    • Capability 1.3
    • + *
    • Capability 1.3
    • *
    * - * @see HTML5 + * @see HTML5 * - Conformance classes */ package org.opengis.cite.eogeojson10.core; diff --git a/src/main/java/org/opengis/cite/eogeojson10/dataidentification/DataIdentificationConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/dataidentification/DataIdentificationConfClassTests.java index fbfbccb..4ba4719 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/dataidentification/DataIdentificationConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/dataidentification/DataIdentificationConfClassTests.java @@ -6,36 +6,40 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class DataIdentificationConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/data-identification, Section 7.3 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/data-identification, Section 7.3") - public void validateDataIdentification() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - String[] mandatoryFields = {"title","identifier","date"}; - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - for(String prop:mandatoryFields) - { - if(propertiesJO.has(prop)!=true) { - sb.append(prop+" field is missing. \n"); - valid = false; - } - } - } - - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * DataIdentificationConfClassTests class. + *

    + * + */ +public class DataIdentificationConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/data-identification, Section 7.3 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/data-identification, Section 7.3") + public void validateDataIdentification() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + String[] mandatoryFields = { "title", "identifier", "date" }; + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + for (String prop : mandatoryFields) { + if (propertiesJO.has(prop) != true) { + sb.append(prop + " field is missing. \n"); + valid = false; + } + } + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/earthobservation/EarthObservationConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/earthobservation/EarthObservationConfClassTests.java index 2fdec00..b1f9913 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/earthobservation/EarthObservationConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/earthobservation/EarthObservationConfClassTests.java @@ -6,31 +6,36 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class EarthObservationConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/earthobservation, Section 7.1 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/earthobservation, Section 7.1") - public void validateEarthObservationMetadata() throws IOException{ - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - String[] mandatoryFields = {"type","id","geometry","properties"}; - - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - for(String prop:mandatoryFields) - { - if(jo.has(prop)!=true) { - sb.append(prop+" field is missing. \n"); - valid = false; - } - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * EarthObservationConfClassTests class. + *

    + * + */ +public class EarthObservationConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/earthobservation, Section 7.1 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/earthobservation, Section 7.1") + public void validateEarthObservationMetadata() throws IOException { + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + String[] mandatoryFields = { "type", "id", "geometry", "properties" }; + + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + for (String prop : mandatoryFields) { + if (jo.has(prop) != true) { + sb.append(prop + " field is missing. \n"); + valid = false; + } + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/earthobservationcollection/EOCollectionConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/earthobservationcollection/EOCollectionConfClassTests.java index 5c526a5..c92d458 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/earthobservationcollection/EOCollectionConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/earthobservationcollection/EOCollectionConfClassTests.java @@ -9,58 +9,63 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class EOCollectionConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/earthobservation-collection, Section 7.8 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/earthobservation-collection, Section 7.8") - public void validateEarthObservationMetadataCollection() throws IOException{ - - String schemaToApply = "/org/opengis/cite/eogeojson10/jsonschema/eo-geojson-schema-standalone.json"; - InputStream inputStream = getClass() - .getResourceAsStream(schemaToApply); - JSONObject rawSchema = new JSONObject(convertInputStreamToString(inputStream)); - StringBuffer errorMessage = new StringBuffer(); - Schema schema = SchemaLoader.load(rawSchema); - JSONObject jo = null; - boolean validCol = false; - try { - - jo = readJSONObjectFromFile(new File(collectionTestSubject)); - - - if(jo.has("type")) { - - if(jo.get("type").equals("FeatureCollection")) { - schema.validate(jo); // throws a ValidationException if this object is invalid - validCol = true; - } - else { - validCol = false; - errorMessage.append("Validation of feature collection did not have type property value that equals 'FeatureCollection'\n"); - } - } - else { - validCol = false; - errorMessage.append("Validation of feature collection did not have type property\n"); - } - - } - catch(Exception ex) - { - errorMessage.append("Validation of Feature Collection failed because "+ex.getMessage()+"\n"); - - validCol = false; - } - - if(validCol==false) { - Assert.assertTrue(validCol, - "Validation failed. "+errorMessage.toString()); - } +/** + *

    + * EOCollectionConfClassTests class. + *

    + * + */ +public class EOCollectionConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/earthobservation-collection, Section 7.8 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/earthobservation-collection, Section 7.8") + public void validateEarthObservationMetadataCollection() throws IOException { + + String schemaToApply = "/org/opengis/cite/eogeojson10/jsonschema/eo-geojson-schema-standalone.json"; + InputStream inputStream = getClass().getResourceAsStream(schemaToApply); + JSONObject rawSchema = new JSONObject(convertInputStreamToString(inputStream)); + StringBuffer errorMessage = new StringBuffer(); + Schema schema = SchemaLoader.load(rawSchema); + JSONObject jo = null; + boolean validCol = false; + try { + + jo = readJSONObjectFromFile(new File(collectionTestSubject)); + + if (jo.has("type")) { + + if (jo.get("type").equals("FeatureCollection")) { + schema.validate(jo); // throws a ValidationException if this object is + // invalid + validCol = true; + } + else { + validCol = false; + errorMessage.append( + "Validation of feature collection did not have type property value that equals 'FeatureCollection'\n"); + } + } + else { + validCol = false; + errorMessage.append("Validation of feature collection did not have type property\n"); + } + + } + catch (Exception ex) { + errorMessage.append("Validation of Feature Collection failed because " + ex.getMessage() + "\n"); + + validCol = false; + } + + if (validCol == false) { + Assert.assertTrue(validCol, "Validation failed. " + errorMessage.toString()); + } + + } - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/geometry/GeometryConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/geometry/GeometryConfClassTests.java index 426787d..40eb012 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/geometry/GeometryConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/geometry/GeometryConfClassTests.java @@ -6,31 +6,36 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class GeometryConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/geometry, Section 7.4 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/geometry, Section 7.4") - public void validateGeometry() throws IOException{ - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - String[] mandatoryFields = {"geometry"}; - - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - for(String prop:mandatoryFields) - { - if(jo.has(prop)!=true) { - sb.append(prop+" field is missing. \n"); - valid = false; - } - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * GeometryConfClassTests class. + *

    + * + */ +public class GeometryConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/geometry, Section 7.4 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/geometry, Section 7.4") + public void validateGeometry() throws IOException { + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + String[] mandatoryFields = { "geometry" }; + + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + for (String prop : mandatoryFields) { + if (jo.has(prop) != true) { + sb.append(prop + " field is missing. \n"); + valid = false; + } + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/links/LinksConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/links/LinksConfClassTests.java index ba3ace0..d9490e1 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/links/LinksConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/links/LinksConfClassTests.java @@ -6,39 +6,45 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class LinksConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/links, Section 7.1.2 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/links, Section 7.1.2") - public void validateLinks() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("links")) { - //do nothing - } - else { - sb.append("links field is missing. \n"); - valid = false; - } - } - else { - sb.append("links field is missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - - } +/** + *

    + * LinksConfClassTests class. + *

    + * + */ +public class LinksConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/links, Section 7.1.2 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/links, Section 7.1.2") + public void validateLinks() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("links")) { + // do nothing + } + else { + sb.append("links field is missing. \n"); + valid = false; + } + } + else { + sb.append("links field is missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/metadatainformation/MetadataInformationConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/metadatainformation/MetadataInformationConfClassTests.java index 264d204..aad0027 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/metadatainformation/MetadataInformationConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/metadatainformation/MetadataInformationConfClassTests.java @@ -6,38 +6,44 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class MetadataInformationConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/metadata-information, Section 7.2 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/metadata-information, Section 7.2") - public void validateMetadataInformation() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("updated")) { - //do nothing - } - else { - sb.append("updated field is missing. \n"); - valid = false; - } - } - else { - sb.append("updated field is missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * MetadataInformationConfClassTests class. + *

    + * + */ +public class MetadataInformationConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/metadata-information, Section 7.2 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/metadata-information, Section 7.2") + public void validateMetadataInformation() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("updated")) { + // do nothing + } + else { + sb.append("updated field is missing. \n"); + valid = false; + } + } + else { + sb.append("updated field is missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/offering/OfferingConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/offering/OfferingConfClassTests.java index 32be4f1..0ca38f3 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/offering/OfferingConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/offering/OfferingConfClassTests.java @@ -6,39 +6,45 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class OfferingConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/offering, Section 7.1.4 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/offering, Section 7.1.4") - public void validateOffering() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("offerings")) { - //do nothing - } - else { - sb.append("offerings field is missing. \n"); - valid = false; - } - } - else { - sb.append("offerings field is missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - - } +/** + *

    + * OfferingConfClassTests class. + *

    + * + */ +public class OfferingConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/offering, Section 7.1.4 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/offering, Section 7.1.4") + public void validateOffering() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("offerings")) { + // do nothing + } + else { + sb.append("offerings field is missing. \n"); + valid = false; + } + } + else { + sb.append("offerings field is missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/package-info.java b/src/main/java/org/opengis/cite/eogeojson10/package-info.java index 13232b1..204f0c8 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/package-info.java +++ b/src/main/java/org/opengis/cite/eogeojson10/package-info.java @@ -1,8 +1,9 @@ /** - * The root package includes supporting classes of general utility such as the - * main controller, listeners, and reporters. + * The root package includes supporting classes of general utility such as the main + * controller, listeners, and reporters. * - *

    Subsidiary packages correspond to distinct test groups such as conformance - * classes.

    + *

    + * Subsidiary packages correspond to distinct test groups such as conformance classes. + *

    */ -package org.opengis.cite.eogeojson10; \ No newline at end of file +package org.opengis.cite.eogeojson10; \ No newline at end of file diff --git a/src/main/java/org/opengis/cite/eogeojson10/productinformation/ProductInformationConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/productinformation/ProductInformationConfClassTests.java index 09c007b..9257b70 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/productinformation/ProductInformationConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/productinformation/ProductInformationConfClassTests.java @@ -6,38 +6,44 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class ProductInformationConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/product-information, Section 7.7 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/product-information, Section 7.7") - public void validateProductInformation() throws IOException{ - boolean valid = true; - StringBuffer sb = new StringBuffer(); - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - if(propertiesJO.has("productInformation")) { - //do nothing - } - else { - sb.append("productInformation field is missing. \n"); - valid = false; - } - } - else { - sb.append("productInformation field is missing. \n"); - valid = false; - } - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - } +/** + *

    + * ProductInformationConfClassTests class. + *

    + * + */ +public class ProductInformationConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/product-information, Section 7.7 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/product-information, Section 7.7") + public void validateProductInformation() throws IOException { + boolean valid = true; + StringBuffer sb = new StringBuffer(); + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + if (propertiesJO.has("productInformation")) { + // do nothing + } + else { + sb.append("productInformation field is missing. \n"); + valid = false; + } + } + else { + sb.append("productInformation field is missing. \n"); + valid = false; + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/properties/PropertiesConfClassTests.java b/src/main/java/org/opengis/cite/eogeojson10/properties/PropertiesConfClassTests.java index 3a03231..24ec30d 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/properties/PropertiesConfClassTests.java +++ b/src/main/java/org/opengis/cite/eogeojson10/properties/PropertiesConfClassTests.java @@ -6,40 +6,42 @@ import org.json.JSONObject; import org.opengis.cite.eogeojson10.DataFixture; import org.testng.Assert; -import org.testng.SkipException; import org.testng.annotations.Test; -public class PropertiesConfClassTests extends DataFixture{ - /** - * Verifies conformance to /conf/properties, Section 7.1.1 - * @throws IOException Thrown if the file cannot be read - */ - @Test(description = "Implements /conf/properties, Section 7.1.1") - public void validateProperties() throws IOException{ - - boolean valid = true; - StringBuffer sb = new StringBuffer(); - String[] mandatoryFields = {"links","status","acquisitionInformation"}; - - JSONObject jo = readJSONObjectFromFile(new File(testSubject)); - - - - if(jo.has("properties")) { - - JSONObject propertiesJO = jo.getJSONObject("properties"); - for(String prop:mandatoryFields) - { - if(propertiesJO.has(prop)!=true) { - sb.append(prop+" field is missing. \n"); - valid = false; - } - } - } - - - Assert.assertTrue(valid, - "Validation failed because "+sb.toString()+ " . "); - - } +/** + *

    + * PropertiesConfClassTests class. + *

    + * + */ +public class PropertiesConfClassTests extends DataFixture { + + /** + * Verifies conformance to /conf/properties, Section 7.1.1 + * @throws java.io.IOException Thrown if the file cannot be read + */ + @Test(description = "Implements /conf/properties, Section 7.1.1") + public void validateProperties() throws IOException { + + boolean valid = true; + StringBuffer sb = new StringBuffer(); + String[] mandatoryFields = { "links", "status", "acquisitionInformation" }; + + JSONObject jo = readJSONObjectFromFile(new File(testSubject)); + + if (jo.has("properties")) { + + JSONObject propertiesJO = jo.getJSONObject("properties"); + for (String prop : mandatoryFields) { + if (propertiesJO.has(prop) != true) { + sb.append(prop + " field is missing. \n"); + valid = false; + } + } + } + + Assert.assertTrue(valid, "Validation failed because " + sb.toString() + " . "); + + } + } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java index 5cef508..c045dac 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/ClientUtils.java @@ -28,117 +28,117 @@ import jakarta.ws.rs.core.UriBuilder; /** - * Provides various utility methods for creating and configuring HTTP client - * components. + * Provides various utility methods for creating and configuring HTTP client components. */ public class ClientUtils { - private static final Logger LOGGER = Logger.getLogger(ClientUtils.class.getName()); + private static final Logger LOGGER = Logger.getLogger(ClientUtils.class.getName()); - /** - * Builds a client component for interacting with HTTP endpoints. The client will - * automatically redirect to the URI declared in 3xx responses. The connection timeout - * is 10 s. Request and response messages may be logged to a JDK logger (in the - * namespace "com.sun.jersey.api.client"). - * @return A Client component. - */ - public static Client buildClient() { - ClientConfig config = new ClientConfig(); - config.property(ClientProperties.FOLLOW_REDIRECTS, true); - config.property(ClientProperties.CONNECT_TIMEOUT, 10000); - config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); - Client client = ClientBuilder.newClient(config); - client.register(new ReusableEntityFilter()); - return client; - } + /** + * Builds a client component for interacting with HTTP endpoints. The client will + * automatically redirect to the URI declared in 3xx responses. The connection timeout + * is 10 s. Request and response messages may be logged to a JDK logger (in the + * namespace "com.sun.jersey.api.client"). + * @return A Client component. + */ + public static Client buildClient() { + ClientConfig config = new ClientConfig(); + config.property(ClientProperties.FOLLOW_REDIRECTS, true); + config.property(ClientProperties.CONNECT_TIMEOUT, 10000); + config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); + Client client = ClientBuilder.newClient(config); + client.register(new ReusableEntityFilter()); + return client; + } - /** - * Constructs a client component that uses a specified web proxy. Proxy authentication - * is not supported. Configuring the client to use an intercepting proxy can be useful - * when debugging a test. - * @param proxyHost The host name or IP address of the proxy server. - * @param proxyPort The port number of the proxy listener. - * @return A Client component that submits requests through a web proxy. - */ - public static Client buildClientWithProxy(final String proxyHost, final int proxyPort) { - ClientConfig config = new ClientConfig(); - config.connectorProvider(new ApacheConnectorProvider()); - config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); - SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort); - Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); - config.property(ClientProperties.PROXY_URI, proxy); - config.property(ClientProperties.FOLLOW_REDIRECTS, true); - config.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT, LoggingFeature.Verbosity.PAYLOAD_ANY); - config.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT, Level.ALL); - Client client = ClientBuilder.newClient(config); - client.register(new ReusableEntityFilter()); - return client; - } + /** + * Constructs a client component that uses a specified web proxy. Proxy authentication + * is not supported. Configuring the client to use an intercepting proxy can be useful + * when debugging a test. + * @param proxyHost The host name or IP address of the proxy server. + * @param proxyPort The port number of the proxy listener. + * @return A Client component that submits requests through a web proxy. + */ + public static Client buildClientWithProxy(final String proxyHost, final int proxyPort) { + ClientConfig config = new ClientConfig(); + config.connectorProvider(new ApacheConnectorProvider()); + config.register(new LoggingFeature(LOGGER, Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, 5000)); + SocketAddress addr = new InetSocketAddress(proxyHost, proxyPort); + Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); + config.property(ClientProperties.PROXY_URI, proxy); + config.property(ClientProperties.FOLLOW_REDIRECTS, true); + config.property(LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT, LoggingFeature.Verbosity.PAYLOAD_ANY); + config.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT, Level.ALL); + Client client = ClientBuilder.newClient(config); + client.register(new ReusableEntityFilter()); + return client; + } - /** - * Builds an HTTP request message that uses the GET method. - * @param endpoint A URI indicating the target resource. - * @param qryParams A Map containing query parameters (may be null); - * @param mediaTypes A list of acceptable media types; if not specified, the Accept - * header is omitted. - * @return A ClientRequest object. - */ - public static Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { - UriBuilder uriBuilder = UriBuilder.fromUri(endpoint); - if (null != qryParams) { - for (Map.Entry param : qryParams.entrySet()) { - uriBuilder.queryParam(param.getKey(), param.getValue()); - } - } - URI uri = uriBuilder.build(); - WebTarget target = buildClient().target(uri); - Builder reqBuilder = target.request(); - if (null != mediaTypes && mediaTypes.length > 0) { - reqBuilder = reqBuilder.accept(mediaTypes); - } - Invocation req = reqBuilder.buildGet(); - return req.invoke(); - } + /** + * Builds an HTTP request message that uses the GET method. + * @param endpoint A URI indicating the target resource. + * @param qryParams A Map containing query parameters (may be null); + * @param mediaTypes A list of acceptable media types; if not specified, the Accept + * header is omitted. + * @return A ClientRequest object. + */ + public static Response buildGetRequest(URI endpoint, Map qryParams, MediaType... mediaTypes) { + UriBuilder uriBuilder = UriBuilder.fromUri(endpoint); + if (null != qryParams) { + for (Map.Entry param : qryParams.entrySet()) { + uriBuilder.queryParam(param.getKey(), param.getValue()); + } + } + URI uri = uriBuilder.build(); + WebTarget target = buildClient().target(uri); + Builder reqBuilder = target.request(); + if (null != mediaTypes && mediaTypes.length > 0) { + reqBuilder = reqBuilder.accept(mediaTypes); + } + Invocation req = reqBuilder.buildGet(); + return req.invoke(); + } - /** - * Creates a copy of the given MediaType object but without any parameters. - * @param mediaType A MediaType descriptor. - * @return A new (immutable) MediaType object having the same type and subtype. - */ - public static MediaType removeParameters(MediaType mediaType) { - return new MediaType(mediaType.getType(), mediaType.getSubtype()); - } + /** + * Creates a copy of the given MediaType object but without any parameters. + * @param mediaType A MediaType descriptor. + * @return A new (immutable) MediaType object having the same type and subtype. + */ + public static MediaType removeParameters(MediaType mediaType) { + return new MediaType(mediaType.getType(), mediaType.getSubtype()); + } - /** - * Obtains the (XML) response entity as a JAXP Source object and resets the entity - * input stream for subsequent reads. - * @param response A representation of an HTTP response message. - * @param targetURI The target URI from which the entity was retrieved (may be null). - * @return A Source to read the entity from; its system identifier is set using the - * given targetURI value (this may be used to resolve any relative URIs found in the - * source). - */ - public static Source getResponseEntityAsSource(Response response, String targetURI) { - Source source = response.readEntity(DOMSource.class); - if (null != targetURI && !targetURI.isEmpty()) { - source.setSystemId(targetURI); - } - return source; - } + /** + * Obtains the (XML) response entity as a JAXP Source object and resets the entity + * input stream for subsequent reads. + * @param response A representation of an HTTP response message. + * @param targetURI The target URI from which the entity was retrieved (may be null). + * @return A Source to read the entity from; its system identifier is set using the + * given targetURI value (this may be used to resolve any relative URIs found in the + * source). + */ + public static Source getResponseEntityAsSource(Response response, String targetURI) { + Source source = response.readEntity(DOMSource.class); + if (null != targetURI && !targetURI.isEmpty()) { + source.setSystemId(targetURI); + } + return source; + } + + /** + * Obtains the (XML) response entity as a DOM Document and resets the entity input + * stream for subsequent reads. + * @param response A representation of an HTTP response message. + * @param targetURI The target URI from which the entity was retrieved (may be null). + * @return A Document representing the entity; its base URI is set using the given + * targetURI value (this may be used to resolve any relative URIs found in the + * document). + */ + public static Document getResponseEntityAsDocument(Response response, String targetURI) { + DOMSource domSource = (DOMSource) getResponseEntityAsSource(response, targetURI); + Document entityDoc = (Document) domSource.getNode(); + entityDoc.setDocumentURI(domSource.getSystemId()); + return entityDoc; + } - /** - * Obtains the (XML) response entity as a DOM Document and resets the entity input - * stream for subsequent reads. - * @param response A representation of an HTTP response message. - * @param targetURI The target URI from which the entity was retrieved (may be null). - * @return A Document representing the entity; its base URI is set using the given - * targetURI value (this may be used to resolve any relative URIs found in the - * document). - */ - public static Document getResponseEntityAsDocument(Response response, String targetURI) { - DOMSource domSource = (DOMSource) getResponseEntityAsSource(response, targetURI); - Document entityDoc = (Document) domSource.getNode(); - entityDoc.setDocumentURI(domSource.getSystemId()); - return entityDoc; - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/NamespaceBindings.java b/src/main/java/org/opengis/cite/eogeojson10/util/NamespaceBindings.java index 463cad0..8ad2362 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/NamespaceBindings.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/NamespaceBindings.java @@ -5,100 +5,97 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; + import javax.xml.namespace.NamespaceContext; + import org.opengis.cite.eogeojson10.Namespaces; /** - * Provides namespace bindings for evaluating XPath 1.0 expressions using the - * JAXP XPath API. A namespace name (URI) may be bound to only one prefix. + * Provides namespace bindings for evaluating XPath 1.0 expressions using the JAXP XPath + * API. A namespace name (URI) may be bound to only one prefix. */ public class NamespaceBindings implements NamespaceContext { - private Map bindings = new HashMap(); + private Map bindings = new HashMap(); + + /** {@inheritDoc} */ + @Override + public String getNamespaceURI(String prefix) { + String nsName = null; + for (Map.Entry binding : bindings.entrySet()) { + if (binding.getValue().equals(prefix)) { + nsName = binding.getKey(); + break; + } + } + return nsName; + } - @Override - public String getNamespaceURI(String prefix) { - String nsName = null; - for (Map.Entry binding : bindings.entrySet()) { - if (binding.getValue().equals(prefix)) { - nsName = binding.getKey(); - break; - } - } - return nsName; - } + /** {@inheritDoc} */ + @Override + public String getPrefix(String namespaceURI) { + return bindings.get(namespaceURI); + } - @Override - public String getPrefix(String namespaceURI) { - return bindings.get(namespaceURI); - } + /** {@inheritDoc} */ + @Override + public Iterator getPrefixes(String namespaceURI) { + return Arrays.asList(getPrefix(namespaceURI)).iterator(); + } - @Override - public Iterator getPrefixes(String namespaceURI) { - return Arrays.asList(getPrefix(namespaceURI)).iterator(); - } + /** + * Adds a namespace binding that associates a namespace name with a prefix. If a + * binding for a given namespace name already exists it will be replaced. + * @param namespaceURI A String denoting a namespace name (an absolute URI value). + * @param prefix A prefix associated with the namespace name. + */ + public void addNamespaceBinding(String namespaceURI, String prefix) { + bindings.put(namespaceURI, prefix); + } - /** - * Adds a namespace binding that associates a namespace name with a prefix. - * If a binding for a given namespace name already exists it will be - * replaced. - * - * @param namespaceURI - * A String denoting a namespace name (an absolute URI value). - * @param prefix - * A prefix associated with the namespace name. - */ - public void addNamespaceBinding(String namespaceURI, String prefix) { - bindings.put(namespaceURI, prefix); - } + /** + * Adds all of the supplied namespace bindings to the existing set of entries. + * @param nsBindings A Map containing a collection of namespace bindings where the key + * is an absolute URI specifying the namespace name and the value denotes the + * associated prefix. + */ + public void addAllBindings(Map nsBindings) { + if (null != nsBindings) + bindings.putAll(nsBindings); + } - /** - * Adds all of the supplied namespace bindings to the existing set of - * entries. - * - * @param nsBindings - * A Map containing a collection of namespace bindings where the - * key is an absolute URI specifying the namespace name and the - * value denotes the associated prefix. - */ - public void addAllBindings(Map nsBindings) { - if (null != nsBindings) - bindings.putAll(nsBindings); - } + /** + * Returns an unmodifiable view of the declared namespace bindings. + * @return An immutable Map containing zero or more namespace bindings where the key + * is an absolute URI specifying the namespace name and the value is the associated + * prefix. + */ + public Map getAllBindings() { + return Collections.unmodifiableMap(this.bindings); + } - /** - * Returns an unmodifiable view of the declared namespace bindings. - * - * @return An immutable Map containing zero or more namespace bindings where - * the key is an absolute URI specifying the namespace name and the - * value is the associated prefix. - */ - public Map getAllBindings() { - return Collections.unmodifiableMap(this.bindings); - } + /** + * Creates a NamespaceBindings object that declares the following namespace bindings: + * + *
      + *
    • ows: {@value org.opengis.cite.eogeojson10.Namespaces#OWS}
    • + *
    • xlink: {@value org.opengis.cite.eogeojson10.Namespaces#XLINK}
    • + *
    • gml: {@value org.opengis.cite.eogeojson10.Namespaces#GML}
    • + *
    + * @return A NamespaceBindings object. + */ + public static NamespaceBindings withStandardBindings() { + NamespaceBindings nsBindings = new NamespaceBindings(); + nsBindings.addNamespaceBinding(Namespaces.OWS, "ows"); + nsBindings.addNamespaceBinding(Namespaces.XLINK, "xlink"); + nsBindings.addNamespaceBinding(Namespaces.GML, "gml"); + return nsBindings; + } - /** - * Creates a NamespaceBindings object that declares the following namespace - * bindings: - * - *
      - *
    • ows: {@value org.opengis.cite.eogeojson10.Namespaces#OWS}
    • - *
    • xlink: {@value org.opengis.cite.eogeojson10.Namespaces#XLINK}
    • - *
    • gml: {@value org.opengis.cite.eogeojson10.Namespaces#GML}
    • - *
    - * - * @return A NamespaceBindings object. - */ - public static NamespaceBindings withStandardBindings() { - NamespaceBindings nsBindings = new NamespaceBindings(); - nsBindings.addNamespaceBinding(Namespaces.OWS, "ows"); - nsBindings.addNamespaceBinding(Namespaces.XLINK, "xlink"); - nsBindings.addNamespaceBinding(Namespaces.GML, "gml"); - return nsBindings; - } + /** {@inheritDoc} */ + @Override + public String toString() { + return "NamespaceBindings:\n" + bindings; + } - @Override - public String toString() { - return "NamespaceBindings:\n" + bindings; - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/TestSuiteLogger.java b/src/main/java/org/opengis/cite/eogeojson10/util/TestSuiteLogger.java index 68a413e..7fb427a 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/TestSuiteLogger.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/TestSuiteLogger.java @@ -4,70 +4,65 @@ import java.util.logging.Logger; /** - * Logging utility class that provides simple access to the JDK Logging API. Set - * the "java.util.logging.config.file" system property to specify the location - * of the desired logging configuration file. A sample configuration file is - * available at {@code src/main/config/logging.properties}. + * Logging utility class that provides simple access to the JDK Logging API. Set the + * "java.util.logging.config.file" system property to specify the location of the desired + * logging configuration file. A sample configuration file is available at + * {@code src/main/config/logging.properties}. * * @see java.util.logging.LogManager LogManager */ public class TestSuiteLogger { - private static final Logger LOGR = - Logger.getLogger(TestSuiteLogger.class.getPackage().getName()); + private static final Logger LOGR = Logger.getLogger(TestSuiteLogger.class.getPackage().getName()); - /** - * Logs a message at the specified logging level with the given message - * parameters. - * - * @param level The logging {@link Level level}. - * @param message A String representing the content of the log message. - * @param params An array of message parameters. - */ - public static void log(Level level, String message, Object[] params) { - if (LOGR.isLoggable(level)) { - LOGR.log(level, message, params); - } - } + /** + * Logs a message at the specified logging level with the given message parameters. + * @param level The logging {@link Level level}. + * @param message A String representing the content of the log message. + * @param params An array of message parameters. + */ + public static void log(Level level, String message, Object[] params) { + if (LOGR.isLoggable(level)) { + LOGR.log(level, message, params); + } + } - /** - * Logs a message at the specified logging level with the given Exception - * object that represents a noteworthy error condition. - * - * @param level The logging {@link Level level}. - * @param message A String representing the content of the log message. - * @param except An object that indicates an exceptional situation. - */ - public static void log(Level level, String message, Exception except) { - if (LOGR.isLoggable(level)) { - LOGR.log(level, message, except); - } - } + /** + * Logs a message at the specified logging level with the given Exception object that + * represents a noteworthy error condition. + * @param level The logging {@link Level level}. + * @param message A String representing the content of the log message. + * @param except An object that indicates an exceptional situation. + */ + public static void log(Level level, String message, Exception except) { + if (LOGR.isLoggable(level)) { + LOGR.log(level, message, except); + } + } - /** - * Logs a simple message at the specified logging level. - * - * @param level The logging {@link Level level}. - * @param message A String representing the content of the log message. - */ - public static void log(Level level, String message) { - if (LOGR.isLoggable(level)) { - LOGR.log(level, message); - } - } + /** + * Logs a simple message at the specified logging level. + * @param level The logging {@link Level level}. + * @param message A String representing the content of the log message. + */ + public static void log(Level level, String message) { + if (LOGR.isLoggable(level)) { + LOGR.log(level, message); + } + } - /** - * Indicates if the logger is enabled at a given logging level. Message - * levels lower than this value will be discarded. - * - * @param level The logging {@link Level level}. - * @return true if the logger is currently enabled for this logging level; - * false otherwise. - */ - public static boolean isLoggable(Level level) { - return LOGR.isLoggable(level); - } + /** + * Indicates if the logger is enabled at a given logging level. Message levels lower + * than this value will be discarded. + * @param level The logging {@link Level level}. + * @return true if the logger is currently enabled for this logging level; false + * otherwise. + */ + public static boolean isLoggable(Level level) { + return LOGR.isLoggable(level); + } + + private TestSuiteLogger() { + } - private TestSuiteLogger() { - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java index d95a0b6..cf821de 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/URIUtils.java @@ -22,121 +22,104 @@ import jakarta.ws.rs.core.Response; /** - * Provides a collection of utility methods for manipulating or resolving URI - * references. + * Provides a collection of utility methods for manipulating or resolving URI references. */ public class URIUtils { - private static final String FIXUP_BASE_URI = "http://apache.org/xml/features/xinclude/fixup-base-uris"; + private static final String FIXUP_BASE_URI = "http://apache.org/xml/features/xinclude/fixup-base-uris"; - /** - * Parses the content of the given URI as an XML document and returns a new - * DOM Document object. Entity reference nodes will not be expanded. XML - * inclusions (xi:include elements) will be processed if present. - * - * @param uriRef - * An absolute URI specifying the location of an XML resource. - * @return A DOM Document node representing an XML resource. - * @throws SAXException - * If the resource cannot be parsed. - * @throws IOException - * If the resource is not accessible. - */ - public static Document parseURI(URI uriRef) throws SAXException, - IOException { - if ((null == uriRef) || !uriRef.isAbsolute()) { - throw new IllegalArgumentException( - "Absolute URI is required, but received " + uriRef); - } - DocumentBuilderFactory docFactory = DocumentBuilderFactory - .newInstance(); - docFactory.setNamespaceAware(true); - docFactory.setExpandEntityReferences(false); - docFactory.setXIncludeAware(true); - Document doc = null; - try { - // XInclude processor will not add xml:base attributes - docFactory.setFeature(FIXUP_BASE_URI, false); - DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); - doc = docBuilder.parse(uriRef.toString()); - } catch (ParserConfigurationException x) { - TestSuiteLogger.log(Level.WARNING, - "Failed to create DocumentBuilder." + x); - } - if (null != doc) { - doc.setDocumentURI(uriRef.toString()); - } - return doc; - } + /** + * Parses the content of the given URI as an XML document and returns a new DOM + * Document object. Entity reference nodes will not be expanded. XML inclusions + * (xi:include elements) will be processed if present. + * @param uriRef An absolute URI specifying the location of an XML resource. + * @return A DOM Document node representing an XML resource. + * @throws org.xml.sax.SAXException If the resource cannot be parsed. + * @throws java.io.IOException If the resource is not accessible. + */ + public static Document parseURI(URI uriRef) throws SAXException, IOException { + if ((null == uriRef) || !uriRef.isAbsolute()) { + throw new IllegalArgumentException("Absolute URI is required, but received " + uriRef); + } + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + docFactory.setExpandEntityReferences(false); + docFactory.setXIncludeAware(true); + Document doc = null; + try { + // XInclude processor will not add xml:base attributes + docFactory.setFeature(FIXUP_BASE_URI, false); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + doc = docBuilder.parse(uriRef.toString()); + } + catch (ParserConfigurationException x) { + TestSuiteLogger.log(Level.WARNING, "Failed to create DocumentBuilder." + x); + } + if (null != doc) { + doc.setDocumentURI(uriRef.toString()); + } + return doc; + } - /** - * Dereferences the given URI and stores the resulting resource - * representation in a local file. The file will be located in the default - * temporary file directory. - * - * @param uriRef - * An absolute URI specifying the location of some resource. - * @return A File containing the content of the resource; it may be empty if - * resolution failed for any reason. - * @throws IOException - * If an IO error occurred. - */ - public static File dereferenceURI(URI uriRef) throws IOException { - if ((null == uriRef) || !uriRef.isAbsolute()) { - throw new IllegalArgumentException("Absolute URI is required, but received " + uriRef); - } - if (uriRef.getScheme().equalsIgnoreCase("file")) { - return new File(uriRef); - } - Client client = ClientUtils.buildClient(); - WebTarget target = client.target(uriRef); - Builder builder = target.request(); - Response rsp = builder.buildGet().invoke(); - String suffix = null; - if (rsp.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE).toString().endsWith("xml")) { - suffix = ".xml"; - } - File destFile = File.createTempFile("entity-", suffix); - if (rsp.hasEntity()) { - Object entity = rsp.getEntity(); - if (!(entity instanceof InputStream)) { - return null; - } - InputStream is = (InputStream) entity; - OutputStream os = new FileOutputStream(destFile); - byte[] buffer = new byte[8 * 1024]; - int bytesRead; - while ((bytesRead = is.read(buffer)) != -1) { - os.write(buffer, 0, bytesRead); - } - is.close(); - os.flush(); - os.close(); - } - TestSuiteLogger.log(Level.FINE, - "Wrote " + destFile.length() + " bytes to file at " + destFile.getAbsolutePath()); - return destFile; -} + /** + * Dereferences the given URI and stores the resulting resource representation in a + * local file. The file will be located in the default temporary file directory. + * @param uriRef An absolute URI specifying the location of some resource. + * @return A File containing the content of the resource; it may be empty if + * resolution failed for any reason. + * @throws java.io.IOException If an IO error occurred. + */ + public static File dereferenceURI(URI uriRef) throws IOException { + if ((null == uriRef) || !uriRef.isAbsolute()) { + throw new IllegalArgumentException("Absolute URI is required, but received " + uriRef); + } + if (uriRef.getScheme().equalsIgnoreCase("file")) { + return new File(uriRef); + } + Client client = ClientUtils.buildClient(); + WebTarget target = client.target(uriRef); + Builder builder = target.request(); + Response rsp = builder.buildGet().invoke(); + String suffix = null; + if (rsp.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE).toString().endsWith("xml")) { + suffix = ".xml"; + } + File destFile = File.createTempFile("entity-", suffix); + if (rsp.hasEntity()) { + Object entity = rsp.getEntity(); + if (!(entity instanceof InputStream)) { + return null; + } + InputStream is = (InputStream) entity; + OutputStream os = new FileOutputStream(destFile); + byte[] buffer = new byte[8 * 1024]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + is.close(); + os.flush(); + os.close(); + } + TestSuiteLogger.log(Level.FINE, + "Wrote " + destFile.length() + " bytes to file at " + destFile.getAbsolutePath()); + return destFile; + } + + /** + * Constructs an absolute URI from the given URI reference and a base URI. + * + * @see RFC 3986, 5.2 + * @param baseURI The base URI; if present, it must be an absolute URI. + * @param uriRef A URI reference that may be relative to the given base URI. + * @return The resulting URI. + */ + public static URI resolveRelativeURI(String baseURI, String uriRef) { + URI uri = (null != baseURI) ? URI.create(baseURI) : URI.create(""); + if (null != baseURI && null == uri.getScheme()) { + throw new IllegalArgumentException("Base URI has no scheme component: " + baseURI); + } + return uri.resolve(uriRef); + } - /** - * Constructs an absolute URI from the given URI reference and a base URI. - * - * @see RFC 3986, - * 5.2 - * - * @param baseURI - * The base URI; if present, it must be an absolute URI. - * @param uriRef - * A URI reference that may be relative to the given base URI. - * @return The resulting URI. - * - */ - public static URI resolveRelativeURI(String baseURI, String uriRef) { - URI uri = (null != baseURI) ? URI.create(baseURI) : URI.create(""); - if (null != baseURI && null == uri.getScheme()) { - throw new IllegalArgumentException( - "Base URI has no scheme component: " + baseURI); - } - return uri.resolve(uriRef); - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java index 8e88d83..379f9dc 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java @@ -25,138 +25,120 @@ import org.w3c.dom.ls.LSResourceResolver; /** - * A utility class that provides convenience methods to support schema - * validation. + * A utility class that provides convenience methods to support schema validation. */ public class ValidationUtils { - static final String ROOT_PKG = "/org/opengis/cite/eogeojson10/"; - private static final XMLCatalogResolver SCH_RESOLVER = initCatalogResolver(); + static final String ROOT_PKG = "/org/opengis/cite/eogeojson10/"; - private static XMLCatalogResolver initCatalogResolver() { - return (XMLCatalogResolver) createSchemaResolver(Namespaces.SCH); - } + private static final XMLCatalogResolver SCH_RESOLVER = initCatalogResolver(); - /** - * Creates a resource resolver suitable for locating schemas using an entity - * catalog. In effect, local copies of standard schemas are returned instead - * of retrieving them from external repositories. - * - * @param schemaLanguage - * A URI that identifies a schema language by namespace name. - * @return A {@code LSResourceResolver} object that is configured to use an - * OASIS entity catalog. - */ - public static LSResourceResolver createSchemaResolver(URI schemaLanguage) { - String catalogFileName; - if (schemaLanguage.equals(Namespaces.XSD)) { - catalogFileName = "schema-catalog.xml"; - } else { - catalogFileName = "schematron-catalog.xml"; - } - URL catalogURL = ValidationUtils.class.getResource(ROOT_PKG - + catalogFileName); - XMLCatalogResolver resolver = new XMLCatalogResolver(); - resolver.setCatalogList(new String[] { catalogURL.toString() }); - return resolver; - } + private static XMLCatalogResolver initCatalogResolver() { + return (XMLCatalogResolver) createSchemaResolver(Namespaces.SCH); + } - /** - * Constructs a SchematronValidator that will check an XML resource against - * the rules defined in a Schematron schema. An attempt is made to resolve - * the schema reference using an entity catalog; if this fails the reference - * is used as given. - * - * @param schemaRef - * A reference to a Schematron schema; this is expected to be a - * relative or absolute URI value, possibly matching the system - * identifier for some entry in an entity catalog. - * @param phase - * The name of the phase to invoke. - * @return A SchematronValidator instance, or {@code null} if the validator - * cannot be constructed (e.g. invalid schema reference or phase - * name). - */ - public static SchematronValidator buildSchematronValidator( - String schemaRef, String phase) { - Source source = null; - try { - String catalogRef = SCH_RESOLVER - .resolveSystem(schemaRef.toString()); - if (null != catalogRef) { - source = new StreamSource(URI.create(catalogRef).toString()); - } else { - source = new StreamSource(schemaRef); - } - } catch (IOException x) { - TestSuiteLogger.log(Level.WARNING, - "Error reading Schematron schema catalog.", x); - } - SchematronValidator validator = null; - try { - validator = new SchematronValidator(source, phase); - } catch (Exception e) { - TestSuiteLogger.log(Level.WARNING, - "Error creating Schematron validator.", e); - } - return validator; - } + /** + * Creates a resource resolver suitable for locating schemas using an entity catalog. + * In effect, local copies of standard schemas are returned instead of retrieving them + * from external repositories. + * @param schemaLanguage A URI that identifies a schema language by namespace name. + * @return A {@code LSResourceResolver} object that is configured to use an OASIS + * entity catalog. + */ + public static LSResourceResolver createSchemaResolver(URI schemaLanguage) { + String catalogFileName; + if (schemaLanguage.equals(Namespaces.XSD)) { + catalogFileName = "schema-catalog.xml"; + } + else { + catalogFileName = "schematron-catalog.xml"; + } + URL catalogURL = ValidationUtils.class.getResource(ROOT_PKG + catalogFileName); + XMLCatalogResolver resolver = new XMLCatalogResolver(); + resolver.setCatalogList(new String[] { catalogURL.toString() }); + return resolver; + } + + /** + * Constructs a SchematronValidator that will check an XML resource against the rules + * defined in a Schematron schema. An attempt is made to resolve the schema reference + * using an entity catalog; if this fails the reference is used as given. + * @param schemaRef A reference to a Schematron schema; this is expected to be a + * relative or absolute URI value, possibly matching the system identifier for some + * entry in an entity catalog. + * @param phase The name of the phase to invoke. + * @return A SchematronValidator instance, or {@code null} if the validator cannot be + * constructed (e.g. invalid schema reference or phase name). + */ + public static SchematronValidator buildSchematronValidator(String schemaRef, String phase) { + Source source = null; + try { + String catalogRef = SCH_RESOLVER.resolveSystem(schemaRef.toString()); + if (null != catalogRef) { + source = new StreamSource(URI.create(catalogRef).toString()); + } + else { + source = new StreamSource(schemaRef); + } + } + catch (IOException x) { + TestSuiteLogger.log(Level.WARNING, "Error reading Schematron schema catalog.", x); + } + SchematronValidator validator = null; + try { + validator = new SchematronValidator(source, phase); + } + catch (Exception e) { + TestSuiteLogger.log(Level.WARNING, "Error creating Schematron validator.", e); + } + return validator; + } + + /** + * Extracts a set of XML Schema references from a source XML document. The document + * element is expected to include the standard xsi:schemaLocation attribute. + * @param source The source instance to read from; its base URI (systemId) should be + * set. + * @param baseURI An alternative base URI to use if the source does not have a system + * identifier set or if its system id is a {@code file} URI. This will usually be the + * URI used to retrieve the resource; it may be null. + * @return A Set containing absolute URI references that specify the locations of XML + * Schema resources. + * @throws javax.xml.stream.XMLStreamException If an error occurs while reading the + * source instance. + */ + public static Set extractSchemaReferences(Source source, String baseURI) throws XMLStreamException { + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLEventReader reader = factory.createXMLEventReader(source); + // advance to document element + StartElement docElem = reader.nextTag().asStartElement(); + Attribute schemaLoc = docElem + .getAttributeByName(new QName(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation")); + if (null == schemaLoc) { + throw new RuntimeException("No xsi:schemaLocation attribute found. See ISO 19136, A.3.1."); + } + String[] uriValues = schemaLoc.getValue().split("\\s+"); + if (uriValues.length % 2 != 0) { + throw new RuntimeException("xsi:schemaLocation attribute contains an odd number of URI values:\n" + + Arrays.toString(uriValues)); + } + Set schemaURIs = new HashSet(); + // one or more pairs of [namespace name] [schema location] + for (int i = 0; i < uriValues.length; i += 2) { + URI schemaURI = null; + if (!URI.create(uriValues[i + 1]).isAbsolute() && (null != source.getSystemId())) { + String schemaRef = URIUtils.resolveRelativeURI(source.getSystemId(), uriValues[i + 1]).toString(); + if (schemaRef.startsWith("file") && !new File(schemaRef).exists() && (null != baseURI)) { + schemaRef = URIUtils.resolveRelativeURI(baseURI, uriValues[i + 1]).toString(); + } + schemaURI = URI.create(schemaRef); + } + else { + schemaURI = URI.create(uriValues[i + 1]); + } + schemaURIs.add(schemaURI); + } + return schemaURIs; + } - /** - * Extracts a set of XML Schema references from a source XML document. The - * document element is expected to include the standard xsi:schemaLocation - * attribute. - * - * @param source - * The source instance to read from; its base URI (systemId) - * should be set. - * @param baseURI - * An alternative base URI to use if the source does not have a - * system identifier set or if its system id is a {@code file} - * URI. This will usually be the URI used to retrieve the - * resource; it may be null. - * @return A Set containing absolute URI references that specify the - * locations of XML Schema resources. - * @throws XMLStreamException - * If an error occurs while reading the source instance. - */ - public static Set extractSchemaReferences(Source source, String baseURI) - throws XMLStreamException { - XMLInputFactory factory = XMLInputFactory.newInstance(); - XMLEventReader reader = factory.createXMLEventReader(source); - // advance to document element - StartElement docElem = reader.nextTag().asStartElement(); - Attribute schemaLoc = docElem.getAttributeByName(new QName( - XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation")); - if (null == schemaLoc) { - throw new RuntimeException( - "No xsi:schemaLocation attribute found. See ISO 19136, A.3.1."); - } - String[] uriValues = schemaLoc.getValue().split("\\s+"); - if (uriValues.length % 2 != 0) { - throw new RuntimeException( - "xsi:schemaLocation attribute contains an odd number of URI values:\n" - + Arrays.toString(uriValues)); - } - Set schemaURIs = new HashSet(); - // one or more pairs of [namespace name] [schema location] - for (int i = 0; i < uriValues.length; i += 2) { - URI schemaURI = null; - if (!URI.create(uriValues[i + 1]).isAbsolute() - && (null != source.getSystemId())) { - String schemaRef = URIUtils.resolveRelativeURI( - source.getSystemId(), uriValues[i + 1]).toString(); - if (schemaRef.startsWith("file") - && !new File(schemaRef).exists() && (null != baseURI)) { - schemaRef = URIUtils.resolveRelativeURI(baseURI, - uriValues[i + 1]).toString(); - } - schemaURI = URI.create(schemaRef); - } else { - schemaURI = URI.create(uriValues[i + 1]); - } - schemaURIs.add(schemaURI); - } - return schemaURIs; - } } diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/XMLUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/XMLUtils.java index 4be4e42..cc58bc4 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/XMLUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/XMLUtils.java @@ -30,6 +30,11 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import net.sf.saxon.s9api.DOMDestination; import net.sf.saxon.s9api.DocumentBuilder; import net.sf.saxon.s9api.Processor; @@ -45,366 +50,330 @@ import net.sf.saxon.s9api.XsltExecutable; import net.sf.saxon.s9api.XsltTransformer; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - /** - * Provides various utility methods for accessing or manipulating XML - * representations. + * Provides various utility methods for accessing or manipulating XML representations. */ public class XMLUtils { - private static final Logger LOGR = Logger.getLogger(XMLUtils.class.getPackage().getName()); - private static final XMLInputFactory STAX_FACTORY = initXMLInputFactory(); - private static final XPathFactory XPATH_FACTORY = initXPathFactory(); + private static final Logger LOGR = Logger.getLogger(XMLUtils.class.getPackage().getName()); + + private static final XMLInputFactory STAX_FACTORY = initXMLInputFactory(); + + private static final XPathFactory XPATH_FACTORY = initXPathFactory(); + + private static XPathFactory initXPathFactory() { + XPathFactory factory = XPathFactory.newInstance(); + return factory; + } - private static XPathFactory initXPathFactory() { - XPathFactory factory = XPathFactory.newInstance(); - return factory; - } + private static XMLInputFactory initXMLInputFactory() { + XMLInputFactory factory = XMLInputFactory.newInstance(); + factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); + return factory; + } - private static XMLInputFactory initXMLInputFactory() { - XMLInputFactory factory = XMLInputFactory.newInstance(); - factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); - return factory; - } + /** + * Writes the content of a DOM Node to a string. The XML declaration is omitted and + * the character encoding is set to "US-ASCII" (any character outside of this set is + * serialized as a numeric character reference). + * @param node The DOM Node to be serialized. + * @return A String representing the content of the given node. + */ + public static String writeNodeToString(Node node) { + if (null == node) { + return ""; + } + Writer writer = null; + try { + Transformer idTransformer = TransformerFactory.newInstance().newTransformer(); + Properties outProps = new Properties(); + outProps.setProperty(OutputKeys.ENCODING, "US-ASCII"); + outProps.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + outProps.setProperty(OutputKeys.INDENT, "yes"); + idTransformer.setOutputProperties(outProps); + writer = new StringWriter(); + idTransformer.transform(new DOMSource(node), new StreamResult(writer)); + } + catch (TransformerException ex) { + TestSuiteLogger.log(Level.WARNING, "Failed to serialize node " + node.getNodeName(), ex); + } + return writer.toString(); + } - /** - * Writes the content of a DOM Node to a string. The XML declaration is - * omitted and the character encoding is set to "US-ASCII" (any character - * outside of this set is serialized as a numeric character reference). - * - * @param node - * The DOM Node to be serialized. - * @return A String representing the content of the given node. - */ - public static String writeNodeToString(Node node) { - if (null == node) { - return ""; - } - Writer writer = null; - try { - Transformer idTransformer = TransformerFactory.newInstance().newTransformer(); - Properties outProps = new Properties(); - outProps.setProperty(OutputKeys.ENCODING, "US-ASCII"); - outProps.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - outProps.setProperty(OutputKeys.INDENT, "yes"); - idTransformer.setOutputProperties(outProps); - writer = new StringWriter(); - idTransformer.transform(new DOMSource(node), new StreamResult(writer)); - } catch (TransformerException ex) { - TestSuiteLogger.log(Level.WARNING, "Failed to serialize node " + node.getNodeName(), ex); - } - return writer.toString(); - } + /** + * Writes the content of a DOM Node to a byte stream. An XML declaration is always + * omitted. + * @param node The DOM Node to be serialized. + * @param outputStream The destination OutputStream reference. + */ + public static void writeNode(Node node, OutputStream outputStream) { + try { + Transformer idTransformer = TransformerFactory.newInstance().newTransformer(); + Properties outProps = new Properties(); + outProps.setProperty(OutputKeys.METHOD, "xml"); + outProps.setProperty(OutputKeys.ENCODING, "UTF-8"); + outProps.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + outProps.setProperty(OutputKeys.INDENT, "yes"); + idTransformer.setOutputProperties(outProps); + idTransformer.transform(new DOMSource(node), new StreamResult(outputStream)); + } + catch (TransformerException ex) { + String nodeName = (node.getNodeType() == Node.DOCUMENT_NODE) + ? Document.class.cast(node).getDocumentElement().getNodeName() : node.getNodeName(); + TestSuiteLogger.log(Level.WARNING, "Failed to serialize DOM node: " + nodeName, ex); + } + } - /** - * Writes the content of a DOM Node to a byte stream. An XML declaration is - * always omitted. - * - * @param node - * The DOM Node to be serialized. - * @param outputStream - * The destination OutputStream reference. - */ - public static void writeNode(Node node, OutputStream outputStream) { - try { - Transformer idTransformer = TransformerFactory.newInstance().newTransformer(); - Properties outProps = new Properties(); - outProps.setProperty(OutputKeys.METHOD, "xml"); - outProps.setProperty(OutputKeys.ENCODING, "UTF-8"); - outProps.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - outProps.setProperty(OutputKeys.INDENT, "yes"); - idTransformer.setOutputProperties(outProps); - idTransformer.transform(new DOMSource(node), new StreamResult(outputStream)); - } catch (TransformerException ex) { - String nodeName = (node.getNodeType() == Node.DOCUMENT_NODE) - ? Document.class.cast(node).getDocumentElement().getNodeName() : node.getNodeName(); - TestSuiteLogger.log(Level.WARNING, "Failed to serialize DOM node: " + nodeName, ex); - } - } + /** + * Evaluates an XPath 1.0 expression using the given context and returns the result as + * a node set. + * @param context The context node. + * @param expr An XPath expression. + * @param namespaceBindings A collection of namespace bindings for the XPath + * expression, where each entry maps a namespace URI (key) to a prefix (value). + * Standard bindings do not need to be declared (see + * {@link org.opengis.cite.eogeojson10.util.NamespaceBindings#withStandardBindings()}. + * @return A NodeList containing nodes that satisfy the expression (it may be empty). + * @throws javax.xml.xpath.XPathExpressionException If the expression cannot be + * evaluated for any reason. + */ + public static NodeList evaluateXPath(Node context, String expr, Map namespaceBindings) + throws XPathExpressionException { + Object result = evaluateXPath(context, expr, namespaceBindings, XPathConstants.NODESET); + if (!NodeList.class.isInstance(result)) { + throw new XPathExpressionException("Expression does not evaluate to a NodeList: " + expr); + } + return (NodeList) result; + } - /** - * Evaluates an XPath 1.0 expression using the given context and returns the - * result as a node set. - * - * @param context - * The context node. - * @param expr - * An XPath expression. - * @param namespaceBindings - * A collection of namespace bindings for the XPath expression, - * where each entry maps a namespace URI (key) to a prefix - * (value). Standard bindings do not need to be declared (see - * {@link NamespaceBindings#withStandardBindings()}. - * @return A NodeList containing nodes that satisfy the expression (it may - * be empty). - * @throws XPathExpressionException - * If the expression cannot be evaluated for any reason. - */ - public static NodeList evaluateXPath(Node context, String expr, Map namespaceBindings) - throws XPathExpressionException { - Object result = evaluateXPath(context, expr, namespaceBindings, XPathConstants.NODESET); - if (!NodeList.class.isInstance(result)) { - throw new XPathExpressionException("Expression does not evaluate to a NodeList: " + expr); - } - return (NodeList) result; - } + /** + * Evaluates an XPath expression using the given context and returns the result as the + * specified type. + * + *

    + * Note: The Saxon implementation supports XPath 2.0 expressions when + * using the JAXP XPath APIs (the default implementation will throw an exception). + *

    + * @param context The context node. + * @param expr An XPath expression. + * @param namespaceBindings A collection of namespace bindings for the XPath + * expression, where each entry maps a namespace URI (key) to a prefix (value). + * Standard bindings do not need to be declared (see + * {@link org.opengis.cite.eogeojson10.util.NamespaceBindings#withStandardBindings()}. + * @param returnType The desired return type (as declared in + * {@link javax.xml.xpath.XPathConstants} ). + * @return The result converted to the desired returnType. + * @throws javax.xml.xpath.XPathExpressionException If the expression cannot be + * evaluated for any reason. + */ + public static Object evaluateXPath(Node context, String expr, Map namespaceBindings, + QName returnType) throws XPathExpressionException { + NamespaceBindings bindings = NamespaceBindings.withStandardBindings(); + bindings.addAllBindings(namespaceBindings); + XPathFactory factory = XPATH_FACTORY; + // WARNING: If context node is Saxon NodeOverNodeInfo, the factory must + // use the same Configuration object to avoid IllegalArgumentException + XPath xpath = factory.newXPath(); + xpath.setNamespaceContext(bindings); + Object result = xpath.evaluate(expr, context, returnType); + return result; + } - /** - * Evaluates an XPath expression using the given context and returns the - * result as the specified type. - * - *

    - * Note: The Saxon implementation supports XPath 2.0 - * expressions when using the JAXP XPath APIs (the default implementation - * will throw an exception). - *

    - * - * @param context - * The context node. - * @param expr - * An XPath expression. - * @param namespaceBindings - * A collection of namespace bindings for the XPath expression, - * where each entry maps a namespace URI (key) to a prefix - * (value). Standard bindings do not need to be declared (see - * {@link NamespaceBindings#withStandardBindings()}. - * @param returnType - * The desired return type (as declared in {@link XPathConstants} - * ). - * @return The result converted to the desired returnType. - * @throws XPathExpressionException - * If the expression cannot be evaluated for any reason. - */ - public static Object evaluateXPath(Node context, String expr, Map namespaceBindings, - QName returnType) throws XPathExpressionException { - NamespaceBindings bindings = NamespaceBindings.withStandardBindings(); - bindings.addAllBindings(namespaceBindings); - XPathFactory factory = XPATH_FACTORY; - // WARNING: If context node is Saxon NodeOverNodeInfo, the factory must - // use the same Configuration object to avoid IllegalArgumentException - XPath xpath = factory.newXPath(); - xpath.setNamespaceContext(bindings); - Object result = xpath.evaluate(expr, context, returnType); - return result; - } + /** + * Evaluates an XPath 2.0 expression using the Saxon s9api interfaces. + * @param xmlSource The XML Source. + * @param expr The XPath expression to be evaluated. + * @param nsBindings A collection of namespace bindings required to evaluate the XPath + * expression, where each entry maps a namespace URI (key) to a prefix (value); this + * may be {@code null} if not needed. + * @return An XdmValue object representing a value in the XDM data model; this is a + * sequence of zero or more items, where each item is either an atomic value or a + * node. + * @throws net.sf.saxon.s9api.SaxonApiException If an error occurs while evaluating + * the expression; this always wraps some other underlying exception. + */ + public static XdmValue evaluateXPath2(Source xmlSource, String expr, Map nsBindings) + throws SaxonApiException { + Processor proc = new Processor(false); + XPathCompiler compiler = proc.newXPathCompiler(); + if (null != nsBindings) { + for (String nsURI : nsBindings.keySet()) { + compiler.declareNamespace(nsBindings.get(nsURI), nsURI); + } + } + XPathSelector xpath = compiler.compile(expr).load(); + DocumentBuilder builder = proc.newDocumentBuilder(); + XdmNode node = null; + if (DOMSource.class.isInstance(xmlSource)) { + DOMSource domSource = (DOMSource) xmlSource; + node = builder.wrap(domSource.getNode()); + } + else { + node = builder.build(xmlSource); + } + xpath.setContextItem(node); + return xpath.evaluate(); + } - /** - * Evaluates an XPath 2.0 expression using the Saxon s9api interfaces. - * - * @param xmlSource - * The XML Source. - * @param expr - * The XPath expression to be evaluated. - * @param nsBindings - * A collection of namespace bindings required to evaluate the - * XPath expression, where each entry maps a namespace URI (key) - * to a prefix (value); this may be {@code null} if not needed. - * @return An XdmValue object representing a value in the XDM data model; - * this is a sequence of zero or more items, where each item is - * either an atomic value or a node. - * @throws SaxonApiException - * If an error occurs while evaluating the expression; this - * always wraps some other underlying exception. - */ - public static XdmValue evaluateXPath2(Source xmlSource, String expr, Map nsBindings) - throws SaxonApiException { - Processor proc = new Processor(false); - XPathCompiler compiler = proc.newXPathCompiler(); - if (null != nsBindings) { - for (String nsURI : nsBindings.keySet()) { - compiler.declareNamespace(nsBindings.get(nsURI), nsURI); - } - } - XPathSelector xpath = compiler.compile(expr).load(); - DocumentBuilder builder = proc.newDocumentBuilder(); - XdmNode node = null; - if (DOMSource.class.isInstance(xmlSource)) { - DOMSource domSource = (DOMSource) xmlSource; - node = builder.wrap(domSource.getNode()); - } else { - node = builder.build(xmlSource); - } - xpath.setContextItem(node); - return xpath.evaluate(); - } + /** + * Evaluates an XQuery 1.0 expression using the Saxon s9api interfaces. + * @param source The XML Source. + * @param query The query expression. + * @param nsBindings A collection of namespace bindings required to evaluate the + * query, where each entry maps a namespace URI (key) to a prefix (value). + * @return An XdmValue object representing a value in the XDM data model. + * @throws net.sf.saxon.s9api.SaxonApiException If an error occurs while evaluating + * the query (this always wraps some other underlying exception). + */ + public static XdmValue evaluateXQuery(Source source, String query, Map nsBindings) + throws SaxonApiException { + Processor proc = new Processor(false); + XQueryCompiler xqCompiler = proc.newXQueryCompiler(); + if (null != nsBindings) { + for (String nsURI : nsBindings.keySet()) { + xqCompiler.declareNamespace(nsBindings.get(nsURI), nsURI); + } + } + XQueryExecutable xqExec = xqCompiler.compile(query); + XQueryEvaluator xqEval = xqExec.load(); + xqEval.setSource(source); + return xqEval.evaluate(); + } - /** - * Evaluates an XQuery 1.0 expression using the Saxon s9api interfaces. - * - * @param source - * The XML Source. - * @param query - * The query expression. - * @param nsBindings - * A collection of namespace bindings required to evaluate the - * query, where each entry maps a namespace URI (key) to a prefix - * (value). - * @return An XdmValue object representing a value in the XDM data model. - * @throws SaxonApiException - * If an error occurs while evaluating the query (this always - * wraps some other underlying exception). - */ - public static XdmValue evaluateXQuery(Source source, String query, Map nsBindings) - throws SaxonApiException { - Processor proc = new Processor(false); - XQueryCompiler xqCompiler = proc.newXQueryCompiler(); - if (null != nsBindings) { - for (String nsURI : nsBindings.keySet()) { - xqCompiler.declareNamespace(nsBindings.get(nsURI), nsURI); - } - } - XQueryExecutable xqExec = xqCompiler.compile(query); - XQueryEvaluator xqEval = xqExec.load(); - xqEval.setSource(source); - return xqEval.evaluate(); - } + /** + * Creates a new Element having the specified qualified name. The element must be + * {@link org.w3c.dom.Document#adoptNode(Node) adopted} when inserted into another + * Document. + * @param qName A QName object. + * @return An Element node (with a Document owner but no parent). + */ + public static Element createElement(QName qName) { + Document doc = null; + try { + doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } + catch (ParserConfigurationException e) { + throw new RuntimeException(e); + } + Element elem = doc.createElementNS(qName.getNamespaceURI(), qName.getLocalPart()); + return elem; + } - /** - * Creates a new Element having the specified qualified name. The element - * must be {@link Document#adoptNode(Node) adopted} when inserted into - * another Document. - * - * @param qName - * A QName object. - * @return An Element node (with a Document owner but no parent). - */ - public static Element createElement(QName qName) { - Document doc = null; - try { - doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - } catch (ParserConfigurationException e) { - throw new RuntimeException(e); - } - Element elem = doc.createElementNS(qName.getNamespaceURI(), qName.getLocalPart()); - return elem; - } + /** + * Returns a List of all descendant Element nodes having the specified [namespace + * name] property. The elements are listed in document order. + * @param node The node to search from. + * @param namespaceURI An absolute URI denoting a namespace name. + * @return A List containing elements in the specified namespace; the list is empty if + * there are no elements in the namespace. + */ + public static List getElementsByNamespaceURI(Node node, String namespaceURI) { + List list = new ArrayList(); + NodeList children = node.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() != Node.ELEMENT_NODE) + continue; + if (child.getNamespaceURI().equals(namespaceURI)) + list.add((Element) child); + } + return list; + } - /** - * Returns a List of all descendant Element nodes having the specified - * [namespace name] property. The elements are listed in document order. - * - * @param node - * The node to search from. - * @param namespaceURI - * An absolute URI denoting a namespace name. - * @return A List containing elements in the specified namespace; the list - * is empty if there are no elements in the namespace. - */ - public static List getElementsByNamespaceURI(Node node, String namespaceURI) { - List list = new ArrayList(); - NodeList children = node.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child.getNodeType() != Node.ELEMENT_NODE) - continue; - if (child.getNamespaceURI().equals(namespaceURI)) - list.add((Element) child); - } - return list; - } + /** + * Transforms the content of a DOM Node using a specified XSLT stylesheet. + * @param xslt A Source object representing a stylesheet (XSLT 1.0 or 2.0). + * @param source A Node representing the XML source. If it is an Element node it will + * be imported into a new DOM Document. + * @return A DOM Document containing the result of the transformation. + */ + public static Document transform(Source xslt, Node source) { + Document sourceDoc = null; + Document resultDoc = null; + try { + resultDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + if (source.getNodeType() == Node.DOCUMENT_NODE) { + sourceDoc = (Document) source; + } + else { + sourceDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + sourceDoc.appendChild(sourceDoc.importNode(source, true)); + } + } + catch (ParserConfigurationException pce) { + throw new RuntimeException(pce); + } + Processor processor = new Processor(false); + XsltCompiler compiler = processor.newXsltCompiler(); + try { + XsltExecutable exec = compiler.compile(xslt); + XsltTransformer transformer = exec.load(); + transformer.setSource(new DOMSource(sourceDoc)); + transformer.setDestination(new DOMDestination(resultDoc)); + transformer.transform(); + } + catch (SaxonApiException e) { + throw new RuntimeException(e); + } + return resultDoc; + } - /** - * Transforms the content of a DOM Node using a specified XSLT stylesheet. - * - * @param xslt - * A Source object representing a stylesheet (XSLT 1.0 or 2.0). - * @param source - * A Node representing the XML source. If it is an Element node - * it will be imported into a new DOM Document. - * @return A DOM Document containing the result of the transformation. - */ - public static Document transform(Source xslt, Node source) { - Document sourceDoc = null; - Document resultDoc = null; - try { - resultDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - if (source.getNodeType() == Node.DOCUMENT_NODE) { - sourceDoc = (Document) source; - } else { - sourceDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - sourceDoc.appendChild(sourceDoc.importNode(source, true)); - } - } catch (ParserConfigurationException pce) { - throw new RuntimeException(pce); - } - Processor processor = new Processor(false); - XsltCompiler compiler = processor.newXsltCompiler(); - try { - XsltExecutable exec = compiler.compile(xslt); - XsltTransformer transformer = exec.load(); - transformer.setSource(new DOMSource(sourceDoc)); - transformer.setDestination(new DOMDestination(resultDoc)); - transformer.transform(); - } catch (SaxonApiException e) { - throw new RuntimeException(e); - } - return resultDoc; - } + /** + * Expands character entity ({@literal &name;}) and numeric references ( + * {@literal &#xhhhh;} or {@literal &dddd;}) that occur within a given string value. + * It may be necessary to do this before processing an XPath expression. + * @param value A string representing text content. + * @return A string with all included references expanded. + */ + public static String expandReferencesInText(String value) { + StringBuilder wrapper = new StringBuilder(""); + wrapper.append(value).append(""); + Reader reader = new StringReader(wrapper.toString()); + String str = null; + try { + XMLStreamReader xsr = STAX_FACTORY.createXMLStreamReader(reader); + xsr.nextTag(); // document element + str = xsr.getElementText(); + } + catch (XMLStreamException xse) { + LOGR.log(Level.WARNING, xse.getMessage(), xse); + } + return str; + } - /** - * Expands character entity ({@literal &name;}) and numeric references ( - * {@literal &#xhhhh;} or {@literal &dddd;}) that occur within a given - * string value. It may be necessary to do this before processing an XPath - * expression. - * - * @param value - * A string representing text content. - * @return A string with all included references expanded. - */ - public static String expandReferencesInText(String value) { - StringBuilder wrapper = new StringBuilder(""); - wrapper.append(value).append(""); - Reader reader = new StringReader(wrapper.toString()); - String str = null; - try { - XMLStreamReader xsr = STAX_FACTORY.createXMLStreamReader(reader); - xsr.nextTag(); // document element - str = xsr.getElementText(); - } catch (XMLStreamException xse) { - LOGR.log(Level.WARNING, xse.getMessage(), xse); - } - return str; - } + /** + * Creates a DOM Document with the given Element as the document element. A deep copy + * of the element is imported; the source element is not altered. + * @param elem An Element node. + * @return A Document node. + */ + public static Document importElement(Element elem) { + javax.xml.parsers.DocumentBuilder docBuilder = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + docBuilder = factory.newDocumentBuilder(); + } + catch (ParserConfigurationException ex) { + LOGR.log(Level.WARNING, null, ex); + } + Document newDoc = docBuilder.newDocument(); + Node newNode = newDoc.importNode(elem, true); + newDoc.appendChild(newNode); + return newDoc; + } - /** - * Creates a DOM Document with the given Element as the document element. A - * deep copy of the element is imported; the source element is not altered. - * - * @param elem - * An Element node. - * @return A Document node. - */ - public static Document importElement(Element elem) { - javax.xml.parsers.DocumentBuilder docBuilder = null; - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - docBuilder = factory.newDocumentBuilder(); - } catch (ParserConfigurationException ex) { - LOGR.log(Level.WARNING, null, ex); - } - Document newDoc = docBuilder.newDocument(); - Node newNode = newDoc.importNode(elem, true); - newDoc.appendChild(newNode); - return newDoc; - } + /** + * Returns a List view of the nodes in the given NodeList collection. + * @param nodeList An ordered collection of DOM nodes. + * @return A List containing the original sequence of Node objects. + */ + public static List asList(NodeList nodeList) { + List nodes = new ArrayList<>(); + for (int i = 0; i < nodeList.getLength(); i++) { + nodes.add(nodeList.item(i)); + } + return nodes; + } - /** - * Returns a List view of the nodes in the given NodeList collection. - * - * @param nodeList - * An ordered collection of DOM nodes. - * @return A List containing the original sequence of Node objects. - */ - public static List asList(NodeList nodeList) { - List nodes = new ArrayList<>(); - for (int i = 0; i < nodeList.getLength(); i++) { - nodes.add(nodeList.item(i)); - } - return nodes; - } } diff --git a/src/test/java/org/opengis/cite/eogeojson10/VerifyETSAssert.java b/src/test/java/org/opengis/cite/eogeojson10/VerifyETSAssert.java index d136e9a..39117a9 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/VerifyETSAssert.java +++ b/src/test/java/org/opengis/cite/eogeojson10/VerifyETSAssert.java @@ -4,6 +4,7 @@ import java.net.URL; import java.util.HashMap; import java.util.Map; + import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -12,6 +13,7 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; + import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -21,53 +23,53 @@ public class VerifyETSAssert { - private static final String WADL_NS = "http://wadl.dev.java.net/2009/02"; - private static DocumentBuilder docBuilder; - private static SchemaFactory factory; - @Rule - public ExpectedException thrown = ExpectedException.none(); + private static final String WADL_NS = "http://wadl.dev.java.net/2009/02"; + + private static DocumentBuilder docBuilder; + + private static SchemaFactory factory; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + public VerifyETSAssert() { + } - public VerifyETSAssert() { - } + @BeforeClass + public static void setUpClass() throws ParserConfigurationException { + factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + docBuilder = dbf.newDocumentBuilder(); + } - @BeforeClass - public static void setUpClass() throws ParserConfigurationException { - factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - docBuilder = dbf.newDocumentBuilder(); - } + @Test + public void validateUsingSchemaHints_expect2Errors() throws SAXException { + thrown.expect(AssertionError.class); + thrown.expectMessage("2 schema validation error(s) detected"); + URL url = this.getClass().getResource("/Gamma.xml"); + Schema schema = factory.newSchema(); + Validator validator = schema.newValidator(); + ETSAssert.assertSchemaValid(validator, new StreamSource(url.toString())); + } - @Test - public void validateUsingSchemaHints_expect2Errors() throws SAXException { - thrown.expect(AssertionError.class); - thrown.expectMessage("2 schema validation error(s) detected"); - URL url = this.getClass().getResource("/Gamma.xml"); - Schema schema = factory.newSchema(); - Validator validator = schema.newValidator(); - ETSAssert - .assertSchemaValid(validator, new StreamSource(url.toString())); - } + @Test + public void assertXPathWithNamespaceBindings() throws SAXException, IOException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/capabilities-simple.xml")); + Map nsBindings = new HashMap(); + nsBindings.put(WADL_NS, "ns1"); + String xpath = "//ns1:resources"; + ETSAssert.assertXPath(xpath, doc, nsBindings); + } - @Test - public void assertXPathWithNamespaceBindings() throws SAXException, - IOException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/capabilities-simple.xml")); - Map nsBindings = new HashMap(); - nsBindings.put(WADL_NS, "ns1"); - String xpath = "//ns1:resources"; - ETSAssert.assertXPath(xpath, doc, nsBindings); - } + @Test + public void assertXPath_expectFalse() throws SAXException, IOException { + thrown.expect(AssertionError.class); + thrown.expectMessage("Unexpected result evaluating XPath expression"); + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/capabilities-simple.xml")); + // using built-in namespace binding + String xpath = "//ows:OperationsMetadata/ows:Constraint[@name='XMLEncoding']/ows:DefaultValue = 'TRUE'"; + ETSAssert.assertXPath(xpath, doc, null); + } - @Test - public void assertXPath_expectFalse() throws SAXException, IOException { - thrown.expect(AssertionError.class); - thrown.expectMessage("Unexpected result evaluating XPath expression"); - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/capabilities-simple.xml")); - // using built-in namespace binding - String xpath = "//ows:OperationsMetadata/ows:Constraint[@name='XMLEncoding']/ows:DefaultValue = 'TRUE'"; - ETSAssert.assertXPath(xpath, doc, null); - } } diff --git a/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java b/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java index 82a4d23..c26cf0d 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java +++ b/src/test/java/org/opengis/cite/eogeojson10/VerifySuiteFixtureListener.java @@ -1,12 +1,8 @@ package org.opengis.cite.eogeojson10; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.io.File; -import java.net.URISyntaxException; -import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -20,38 +16,38 @@ public class VerifySuiteFixtureListener { - private static XmlSuite xmlSuite; - private static ISuite suite; + private static XmlSuite xmlSuite; - public VerifySuiteFixtureListener() { - } + private static ISuite suite; - @BeforeClass - public static void setUpClass() { - xmlSuite = mock(XmlSuite.class); - suite = mock(ISuite.class); - when(suite.getXmlSuite()).thenReturn(xmlSuite); - } + public VerifySuiteFixtureListener() { + } - @AfterClass - public static void tearDownClass() { - } + @BeforeClass + public static void setUpClass() { + xmlSuite = mock(XmlSuite.class); + suite = mock(ISuite.class); + when(suite.getXmlSuite()).thenReturn(xmlSuite); + } - @Before - public void setUp() { - } + @AfterClass + public static void tearDownClass() { + } - @After - public void tearDown() { - } + @Before + public void setUp() { + } - @Test(expected = IllegalArgumentException.class) - public void noSuiteParameters() { - Map params = new HashMap(); - when(xmlSuite.getParameters()).thenReturn(params); - SuiteFixtureListener iut = new SuiteFixtureListener(); - iut.onStart(suite); - } + @After + public void tearDown() { + } + @Test(expected = IllegalArgumentException.class) + public void noSuiteParameters() { + Map params = new HashMap(); + when(xmlSuite.getParameters()).thenReturn(params); + SuiteFixtureListener iut = new SuiteFixtureListener(); + iut.onStart(suite); + } } diff --git a/src/test/java/org/opengis/cite/eogeojson10/VerifyTestNGController.java b/src/test/java/org/opengis/cite/eogeojson10/VerifyTestNGController.java index 176d60f..3af6d74 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/VerifyTestNGController.java +++ b/src/test/java/org/opengis/cite/eogeojson10/VerifyTestNGController.java @@ -1,6 +1,6 @@ package org.opengis.cite.eogeojson10; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -14,58 +14,53 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; -import net.sf.saxon.s9api.XdmValue; - import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.opengis.cite.eogeojson10.util.XMLUtils; import org.w3c.dom.Document; +import net.sf.saxon.s9api.XdmValue; + /** * Verifies the results of executing a test run using the main controller * (TestNGController). - * + * */ public class VerifyTestNGController { - private static DocumentBuilder docBuilder; - private Properties testRunProps; + private static DocumentBuilder docBuilder; + + private Properties testRunProps; + + @BeforeClass + public static void initParser() throws ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + docBuilder = dbf.newDocumentBuilder(); + } - @BeforeClass - public static void initParser() throws ParserConfigurationException { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(false); - dbf.setFeature( - "http://apache.org/xml/features/nonvalidating/load-external-dtd", - false); - docBuilder = dbf.newDocumentBuilder(); - } + @Before + public void loadDefaultTestRunProperties() throws InvalidPropertiesFormatException, IOException { + this.testRunProps = new Properties(); + this.testRunProps.loadFromXML(getClass().getResourceAsStream("/test-run-props.xml")); + } - @Before - public void loadDefaultTestRunProperties() - throws InvalidPropertiesFormatException, IOException { - this.testRunProps = new Properties(); - this.testRunProps.loadFromXML(getClass().getResourceAsStream( - "/test-run-props.xml")); - } + @Test + public void doTestRun() throws Exception { + URL testSubject = getClass().getResource("/example-1-seasat.json"); + this.testRunProps.setProperty(TestRunArg.IUT.toString(), testSubject.toURI().toString()); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024); + this.testRunProps.storeToXML(outStream, "Integration test"); + Document testRunArgs = docBuilder.parse(new ByteArrayInputStream(outStream.toByteArray())); + TestNGController controller = new TestNGController(); + Source results = controller.doTestRun(testRunArgs); + String xpath = "/testng-results/@failed"; + XdmValue failed = XMLUtils.evaluateXPath2(results, xpath, null); + int numFailed = Integer.parseInt(failed.getUnderlyingValue().getStringValue()); + assertEquals("Unexpected number of fail verdicts.", 0, numFailed); + } - @Test - public void doTestRun() throws Exception { - URL testSubject = getClass().getResource("/example-1-seasat.json"); - this.testRunProps.setProperty(TestRunArg.IUT.toString(), testSubject - .toURI().toString()); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024); - this.testRunProps.storeToXML(outStream, "Integration test"); - Document testRunArgs = docBuilder.parse(new ByteArrayInputStream( - outStream.toByteArray())); - TestNGController controller = new TestNGController(); - Source results = controller.doTestRun(testRunArgs); - String xpath = "/testng-results/@failed"; - XdmValue failed = XMLUtils.evaluateXPath2(results, xpath, null); - int numFailed = Integer.parseInt(failed.getUnderlyingValue() - .getStringValue()); - assertEquals("Unexpected number of fail verdicts.", 0, numFailed); - } } diff --git a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyURIUtils.java b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyURIUtils.java index e4c0fc2..830528d 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyURIUtils.java +++ b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyURIUtils.java @@ -19,65 +19,60 @@ */ public class VerifyURIUtils { - public VerifyURIUtils() { - } + public VerifyURIUtils() { + } - @BeforeClass - public static void setUpClass() { - } + @BeforeClass + public static void setUpClass() { + } - @Ignore - @Test - // comment out @Ignore to run test (requires network connection) - public void resolveHttpUriAsDocument() throws SAXException, IOException { - URI uriRef = URI.create("http://www.w3schools.com/xml/note.xml"); - Document doc = URIUtils.parseURI(uriRef); - Assert.assertNotNull(doc); - Assert.assertEquals("Document element has unexpected [local name].", - "note", doc.getDocumentElement().getLocalName()); - } + @Ignore + @Test + // comment out @Ignore to run test (requires network connection) + public void resolveHttpUriAsDocument() throws SAXException, IOException { + URI uriRef = URI.create("http://www.w3schools.com/xml/note.xml"); + Document doc = URIUtils.parseURI(uriRef); + Assert.assertNotNull(doc); + Assert.assertEquals("Document element has unexpected [local name].", "note", + doc.getDocumentElement().getLocalName()); + } - @Ignore - @Test - // comment out @Ignore to run test (requires network connection) - public void resolveHttpUriAsFile() throws SAXException, IOException { - URI uriRef = URI.create("http://www.w3schools.com/xml/note.xml"); - File file = URIUtils.dereferenceURI(uriRef); - Assert.assertNotNull(file); - Assert.assertTrue("File should not be empty", file.length() > 0); - } + @Ignore + @Test + // comment out @Ignore to run test (requires network connection) + public void resolveHttpUriAsFile() throws SAXException, IOException { + URI uriRef = URI.create("http://www.w3schools.com/xml/note.xml"); + File file = URIUtils.dereferenceURI(uriRef); + Assert.assertNotNull(file); + Assert.assertTrue("File should not be empty", file.length() > 0); + } - @Test - public void resolveClasspathResource() throws SAXException, IOException, - URISyntaxException { - URL url = this.getClass().getResource("/atom-feed.xml"); - Document doc = URIUtils.parseURI(url.toURI()); - Assert.assertNotNull(doc); - Assert.assertEquals("Document element has unexpected [local name].", - "feed", doc.getDocumentElement().getLocalName()); - } + @Test + public void resolveClasspathResource() throws SAXException, IOException, URISyntaxException { + URL url = this.getClass().getResource("/atom-feed.xml"); + Document doc = URIUtils.parseURI(url.toURI()); + Assert.assertNotNull(doc); + Assert.assertEquals("Document element has unexpected [local name].", "feed", + doc.getDocumentElement().getLocalName()); + } - @Test - public void resolveFileRefWithXInclude() throws SAXException, IOException, - URISyntaxException { - File file = new File("src/test/resources/Alpha-xinclude.xml"); - Document doc = URIUtils.parseURI(file.toURI()); - Assert.assertNotNull(doc); - Assert.assertEquals("Document element has unexpected [local name].", - "Alpha", doc.getDocumentElement().getLocalName()); - NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS( - "http://www.example.net/gamma", "Gamma"); - Assert.assertEquals( - "Expected element {http://www.example.net/gamma}Gamma", 1, - nodes.getLength()); - } + @Test + public void resolveFileRefWithXInclude() throws SAXException, IOException, URISyntaxException { + File file = new File("src/test/resources/Alpha-xinclude.xml"); + Document doc = URIUtils.parseURI(file.toURI()); + Assert.assertNotNull(doc); + Assert.assertEquals("Document element has unexpected [local name].", "Alpha", + doc.getDocumentElement().getLocalName()); + NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS("http://www.example.net/gamma", "Gamma"); + Assert.assertEquals("Expected element {http://www.example.net/gamma}Gamma", 1, nodes.getLength()); + } + + @Test(expected = IllegalArgumentException.class) + public void resolveMissingClasspathResource() throws SAXException, URISyntaxException, IOException { + URL url = this.getClass().getResource("/alpha.xml"); + URI uri = (null != url) ? url.toURI() : null; + Document doc = URIUtils.parseURI(uri); + Assert.assertNull(doc); + } - @Test(expected = IllegalArgumentException.class) - public void resolveMissingClasspathResource() throws SAXException, - URISyntaxException, IOException { - URL url = this.getClass().getResource("/alpha.xml"); - URI uri = (null != url) ? url.toURI() : null; - Document doc = URIUtils.parseURI(uri); - Assert.assertNull(doc); - } } diff --git a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyValidationUtils.java b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyValidationUtils.java index 949df81..0bc4c03 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyValidationUtils.java +++ b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyValidationUtils.java @@ -1,6 +1,7 @@ package org.opengis.cite.eogeojson10.util; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; @@ -18,26 +19,23 @@ */ public class VerifyValidationUtils { - public VerifyValidationUtils() { - } - - @Test - public void testBuildSchematronValidator() { - String schemaRef = "http://schemas.opengis.net/gml/3.2.1/SchematronConstraints.xml"; - String phase = ""; - SchematronValidator result = ValidationUtils.buildSchematronValidator( - schemaRef, phase); - assertNotNull(result); - } - - @Test - public void extractRelativeSchemaReference() throws FileNotFoundException, - XMLStreamException { - File xmlFile = new File("src/test/resources/Alpha-1.xml"); - Set xsdSet = ValidationUtils.extractSchemaReferences( - new StreamSource(xmlFile), null); - URI schemaURI = xsdSet.iterator().next(); - assertTrue("Expected schema reference */xsd/alpha.xsd", schemaURI - .toString().endsWith("/xsd/alpha.xsd")); - } + public VerifyValidationUtils() { + } + + @Test + public void testBuildSchematronValidator() { + String schemaRef = "http://schemas.opengis.net/gml/3.2.1/SchematronConstraints.xml"; + String phase = ""; + SchematronValidator result = ValidationUtils.buildSchematronValidator(schemaRef, phase); + assertNotNull(result); + } + + @Test + public void extractRelativeSchemaReference() throws FileNotFoundException, XMLStreamException { + File xmlFile = new File("src/test/resources/Alpha-1.xml"); + Set xsdSet = ValidationUtils.extractSchemaReferences(new StreamSource(xmlFile), null); + URI schemaURI = xsdSet.iterator().next(); + assertTrue("Expected schema reference */xsd/alpha.xsd", schemaURI.toString().endsWith("/xsd/alpha.xsd")); + } + } diff --git a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyXMLUtils.java b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyXMLUtils.java index cd78ce4..4d90e7a 100644 --- a/src/test/java/org/opengis/cite/eogeojson10/util/VerifyXMLUtils.java +++ b/src/test/java/org/opengis/cite/eogeojson10/util/VerifyXMLUtils.java @@ -3,14 +3,12 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; + import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.xpath.XPathExpressionException; -import net.sf.saxon.s9api.SaxonApiException; -import net.sf.saxon.s9api.XdmValue; -import net.sf.saxon.trans.XPathException; import org.junit.Assert; import org.junit.BeforeClass; @@ -21,127 +19,119 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import net.sf.saxon.s9api.SaxonApiException; +import net.sf.saxon.s9api.XdmValue; +import net.sf.saxon.trans.XPathException; + /** * Verifies the behavior of the XMLUtils class. */ public class VerifyXMLUtils { - private static final String ATOM_NS = "http://www.w3.org/2005/Atom"; - private static final String EX_NS = "http://example.org/ns1"; - private static DocumentBuilder docBuilder; - - public VerifyXMLUtils() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - docBuilder = dbf.newDocumentBuilder(); - } - - @Test - public void writeDocToString() throws SAXException, IOException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/atom-feed.xml")); - String content = XMLUtils.writeNodeToString(doc); - Assert.assertTrue("String should start with ' nsBindings = new HashMap(); - nsBindings.put(ATOM_NS, "tns"); - nsBindings.put(EX_NS, "ns1"); - NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); - Assert.assertTrue("Expected 1 node in results.", - results.getLength() == 1); - Assert.assertEquals("author", results.item(0).getLocalName()); - } - - @Test - public void evaluateXPathExpression_noMatch() - throws XPathExpressionException, SAXException, IOException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/atom-feed.xml")); - String expr = "/tns:feed/tns:author[ns1:blog]"; - Map nsBindings = new HashMap(); - nsBindings.put(ATOM_NS, "tns"); - nsBindings.put(EX_NS, "ns1"); - NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); - Assert.assertTrue("Expected empty results.", results.getLength() == 0); - } - - @Test(expected = XPathExpressionException.class) - public void evaluateXPathExpression_booleanResult() - throws XPathExpressionException, SAXException, IOException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/atom-feed.xml")); - String expr = "count(//tns:entry) > 0"; - Map nsBindings = new HashMap(); - nsBindings.put(ATOM_NS, "tns"); - NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); - Assert.assertNull(results); - } - - @Test - public void createElement_Alpha() { - QName qName = new QName("http://example.org", "Alpha"); - Element elem = XMLUtils.createElement(qName); - Assert.assertEquals("Alpha", elem.getLocalName()); - Assert.assertNull(elem.getParentNode()); - Assert.assertNotNull(elem.getOwnerDocument()); - } - - @Test - public void evaluateXPath2ExpressionAgainstDocument() throws SAXException, - IOException, SaxonApiException, XPathException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/atom-feed.xml")); - String expr = "matches(//tns:entry/tns:title, '.*Robots')"; - Map nsBindings = new HashMap(); - nsBindings.put(ATOM_NS, "tns"); - XdmValue result = XMLUtils.evaluateXPath2(new DOMSource(doc), expr, - nsBindings); - Assert.assertTrue("Expected non-empty result.", result.size() > 0); - Assert.assertEquals("Result has unexpected string value.", "true", - result.getUnderlyingValue().getStringValue()); - } - - @Test - public void evaluateXPath2ExpressionAgainstElement() throws SAXException, - IOException, SaxonApiException, XPathException { - Document doc = docBuilder.parse(this.getClass().getResourceAsStream( - "/atom-feed.xml")); - Node entry = doc.getElementsByTagNameNS(ATOM_NS, "entry").item(0); - String expr = "matches(tns:title, '.*Robots')"; - Map nsBindings = new HashMap(); - nsBindings.put(ATOM_NS, "tns"); - XdmValue result = XMLUtils.evaluateXPath2(new DOMSource(entry), expr, - nsBindings); - Assert.assertTrue("Expected non-empty result.", result.size() > 0); - Assert.assertEquals("Result has unexpected string value.", "true", - result.getUnderlyingValue().getStringValue()); - } - - @Test - public void expandCharacterEntity() { - String text = "Ce n'est pas"; - String result = XMLUtils.expandReferencesInText(text); - Assert.assertTrue("Expected result to contain an apostrophe (')", - result.contains("'")); - } - - @Test - public void expandNumericCharacterReference() { - String text = "Montréal"; - String result = XMLUtils.expandReferencesInText(text); - Assert.assertEquals("Expected result to contain character é (U+00E9)", - "Montréal", result); - } + private static final String ATOM_NS = "http://www.w3.org/2005/Atom"; + + private static final String EX_NS = "http://example.org/ns1"; + + private static DocumentBuilder docBuilder; + + public VerifyXMLUtils() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + docBuilder = dbf.newDocumentBuilder(); + } + + @Test + public void writeDocToString() throws SAXException, IOException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/atom-feed.xml")); + String content = XMLUtils.writeNodeToString(doc); + Assert.assertTrue("String should start with ' nsBindings = new HashMap(); + nsBindings.put(ATOM_NS, "tns"); + nsBindings.put(EX_NS, "ns1"); + NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); + Assert.assertTrue("Expected 1 node in results.", results.getLength() == 1); + Assert.assertEquals("author", results.item(0).getLocalName()); + } + + @Test + public void evaluateXPathExpression_noMatch() throws XPathExpressionException, SAXException, IOException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/atom-feed.xml")); + String expr = "/tns:feed/tns:author[ns1:blog]"; + Map nsBindings = new HashMap(); + nsBindings.put(ATOM_NS, "tns"); + nsBindings.put(EX_NS, "ns1"); + NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); + Assert.assertTrue("Expected empty results.", results.getLength() == 0); + } + + @Test(expected = XPathExpressionException.class) + public void evaluateXPathExpression_booleanResult() throws XPathExpressionException, SAXException, IOException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/atom-feed.xml")); + String expr = "count(//tns:entry) > 0"; + Map nsBindings = new HashMap(); + nsBindings.put(ATOM_NS, "tns"); + NodeList results = XMLUtils.evaluateXPath(doc, expr, nsBindings); + Assert.assertNull(results); + } + + @Test + public void createElement_Alpha() { + QName qName = new QName("http://example.org", "Alpha"); + Element elem = XMLUtils.createElement(qName); + Assert.assertEquals("Alpha", elem.getLocalName()); + Assert.assertNull(elem.getParentNode()); + Assert.assertNotNull(elem.getOwnerDocument()); + } + + @Test + public void evaluateXPath2ExpressionAgainstDocument() + throws SAXException, IOException, SaxonApiException, XPathException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/atom-feed.xml")); + String expr = "matches(//tns:entry/tns:title, '.*Robots')"; + Map nsBindings = new HashMap(); + nsBindings.put(ATOM_NS, "tns"); + XdmValue result = XMLUtils.evaluateXPath2(new DOMSource(doc), expr, nsBindings); + Assert.assertTrue("Expected non-empty result.", result.size() > 0); + Assert.assertEquals("Result has unexpected string value.", "true", + result.getUnderlyingValue().getStringValue()); + } + + @Test + public void evaluateXPath2ExpressionAgainstElement() + throws SAXException, IOException, SaxonApiException, XPathException { + Document doc = docBuilder.parse(this.getClass().getResourceAsStream("/atom-feed.xml")); + Node entry = doc.getElementsByTagNameNS(ATOM_NS, "entry").item(0); + String expr = "matches(tns:title, '.*Robots')"; + Map nsBindings = new HashMap(); + nsBindings.put(ATOM_NS, "tns"); + XdmValue result = XMLUtils.evaluateXPath2(new DOMSource(entry), expr, nsBindings); + Assert.assertTrue("Expected non-empty result.", result.size() > 0); + Assert.assertEquals("Result has unexpected string value.", "true", + result.getUnderlyingValue().getStringValue()); + } + + @Test + public void expandCharacterEntity() { + String text = "Ce n'est pas"; + String result = XMLUtils.expandReferencesInText(text); + Assert.assertTrue("Expected result to contain an apostrophe (')", result.contains("'")); + } + + @Test + public void expandNumericCharacterReference() { + String text = "Montréal"; + String result = XMLUtils.expandReferencesInText(text); + Assert.assertEquals("Expected result to contain character é (U+00E9)", "Montréal", result); + } + } From d8ea69c73e7bd10c04811043ee188b12bba176a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:50:18 +0100 Subject: [PATCH 04/13] Fix wrong package name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1a5f26..3720e99 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,7 @@ - org.opengis.cite.ogcapiedr10.TestNGController + org.opengis.cite.eogeojson10.TestNGController From a9080eecf7d3adc0967514f7198e39a2b9a6bf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:50:36 +0100 Subject: [PATCH 05/13] Adjust assembly files --- src/assembly/aio.xml | 3 --- src/assembly/deps.xml | 16 ++++------------ 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/assembly/aio.xml b/src/assembly/aio.xml index 637399b..34c320c 100644 --- a/src/assembly/aio.xml +++ b/src/assembly/aio.xml @@ -12,9 +12,6 @@ true true runtime - - com.sun.jersey:jersey-server - diff --git a/src/assembly/deps.xml b/src/assembly/deps.xml index e878346..080a72e 100644 --- a/src/assembly/deps.xml +++ b/src/assembly/deps.xml @@ -10,21 +10,13 @@ false - - - com.sun.jersey:jersey-client - org.opengis.cite:schema-utils - - / - false - runtime - false - org.opengis.cite.teamengine:teamengine-spi - com.sun.jersey:jersey-client - org.opengis.cite:schema-utils + *:jersey-client + *:jersey-server + *:jersey-common + jakarta.ws.rs:jakarta.ws.rs-api / false From 0cd91d83bc8adff703604252f7bb6b37002892bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:50:57 +0100 Subject: [PATCH 06/13] Remove final modifier --- .../java/org/opengis/cite/eogeojson10/CommandLineArguments.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java b/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java index 8272cd4..09a630b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java +++ b/src/main/java/org/opengis/cite/eogeojson10/CommandLineArguments.java @@ -27,7 +27,7 @@ public class CommandLineArguments { @Parameter(description = "Properties file") - private final List xmlProps; + private List xmlProps; @Parameter(names = { "-o", "--outputDir" }, description = "Output directory") private String outputDir; From 897fed69ce0061c3776b621a03ee8fde041e9cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:51:22 +0100 Subject: [PATCH 07/13] Adjust to testng 7 --- .../opengis/cite/eogeojson10/SuitePreconditions.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java b/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java index 8713ace..8ee614b 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java +++ b/src/main/java/org/opengis/cite/eogeojson10/SuitePreconditions.java @@ -3,7 +3,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.testng.ITestContext; +import org.testng.Reporter; import org.testng.annotations.BeforeSuite; /** @@ -16,13 +16,15 @@ public class SuitePreconditions { /** * Verifies that the referenced test subject exists and has the expected type. - * @param testContext Information about the (pending) test run. */ @BeforeSuite @SuppressWarnings("rawtypes") - public void verifyTestSubject(ITestContext testContext) { + public void verifyTestSubject() { SuiteAttribute testFileAttr = SuiteAttribute.TEST_SUBJ_FILE; - Object sutObj = testContext.getSuite().getAttribute(testFileAttr.getName()); + Object sutObj = Reporter.getCurrentTestResult() + .getTestContext() + .getSuite() + .getAttribute(testFileAttr.getName()); Class expectedType = testFileAttr.getType(); if (null != sutObj && expectedType.isInstance(sutObj)) { // TODO: Verify test subject From 1d3c9046a9c635505669ca70f0eef21f55b61d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:51:33 +0100 Subject: [PATCH 08/13] Manually fix javadoc --- .../java/org/opengis/cite/eogeojson10/DataFixture.java | 9 +++++++++ .../opengis/cite/eogeojson10/util/ValidationUtils.java | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java b/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java index f5ca74b..880ce0c 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java +++ b/src/main/java/org/opengis/cite/eogeojson10/DataFixture.java @@ -17,10 +17,19 @@ */ public class DataFixture { + /** + * testSubject + */ protected String testSubject; + /** + * collectionTestSubject + */ protected String collectionTestSubject; + /** + * DEFAULT_BUFFER_SIZE = 8192 + */ protected final int DEFAULT_BUFFER_SIZE = 8192; /** diff --git a/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java b/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java index 379f9dc..5e5669c 100644 --- a/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java +++ b/src/main/java/org/opengis/cite/eogeojson10/util/ValidationUtils.java @@ -29,6 +29,9 @@ */ public class ValidationUtils { + /** + * ROOT_PKG = "/org/opengis/cite/eogeojson10/" + */ static final String ROOT_PKG = "/org/opengis/cite/eogeojson10/"; private static final XMLCatalogResolver SCH_RESOLVER = initCatalogResolver(); From eeb94b8c0c82e7c259e8ada9f2e3ff60fe5a6655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:58:39 +0100 Subject: [PATCH 09/13] Adjust Dockerfile --- src/docker/Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/docker/Dockerfile b/src/docker/Dockerfile index b1980d1..d2d8d5b 100644 --- a/src/docker/Dockerfile +++ b/src/docker/Dockerfile @@ -1,4 +1,6 @@ -FROM tomcat:7.0-jre8 +FROM tomcat:10.1-jre17 + +RUN apt update && apt install -y unzip # add TEAM engine webapp ADD maven/dependency/teamengine-web-*.war /root/ @@ -21,5 +23,7 @@ RUN cd /root/ && unzip -q ets-eo-geojson10-*-ctl.zip -d /root/te_base/scripts ADD maven/ets-eo-geojson10-*-deps.zip /root/ RUN cd /root/ && unzip -q -o ets-eo-geojson10-*-deps.zip -d /usr/local/tomcat/webapps/teamengine/WEB-INF/lib +RUN rm -R /root/te_base/scripts/note + # run tomcat CMD ["catalina.sh", "jpda", "run"] \ No newline at end of file From 410fab0e64abbbaa94d222aa1142dbeaae61e7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Mon, 16 Dec 2024 16:59:07 +0100 Subject: [PATCH 10/13] Remove version of docker-maven-plugin --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3720e99..44a05ba 100644 --- a/pom.xml +++ b/pom.xml @@ -147,7 +147,6 @@ io.fabric8 docker-maven-plugin - 0.28.0 From de9ea0570f78b2c2b20e66dcb5819e075bdff2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Tue, 17 Dec 2024 13:12:16 +0100 Subject: [PATCH 11/13] Remove inherited dependency --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 44a05ba..03c8bf9 100644 --- a/pom.xml +++ b/pom.xml @@ -72,10 +72,6 @@ com.reprezen.kaizen openapi-parser - - com.google.inject - guice - junit junit From 3e64873a9999965a378026b537846ce711b2a0dd Mon Sep 17 00:00:00 2001 From: Dirk Stenger Date: Fri, 3 Jan 2025 12:21:00 +0100 Subject: [PATCH 12/13] #14 - Add plugin and repository and adjust outdated and delete obsolete content in pom.xml and update jenkinsfiles --- jenkinsfiles/build/Jenkinsfile | 6 +-- jenkinsfiles/release/Jenkinsfile | 19 ++++---- pom.xml | 83 +++++++++++++------------------- 3 files changed, 47 insertions(+), 61 deletions(-) diff --git a/jenkinsfiles/build/Jenkinsfile b/jenkinsfiles/build/Jenkinsfile index d29654f..c9562bc 100644 --- a/jenkinsfiles/build/Jenkinsfile +++ b/jenkinsfiles/build/Jenkinsfile @@ -1,8 +1,8 @@ pipeline { agent any tools { - maven 'mvn' - jdk 'JDK 8' + maven 'mvn396' + jdk 'temurin-jdk17' } stages { stage('Preparation') { @@ -14,7 +14,7 @@ pipeline { stage('Build') { steps{ sh 'mvn --version' - sh 'mvn clean install site -Pintegration-tests,docker' + sh 'mvn clean install site -Pintegration-tests,docker -Dsoapui.test.fail.ignore=true' } } stage('Results') { diff --git a/jenkinsfiles/release/Jenkinsfile b/jenkinsfiles/release/Jenkinsfile index a86fea6..4571ac0 100644 --- a/jenkinsfiles/release/Jenkinsfile +++ b/jenkinsfiles/release/Jenkinsfile @@ -1,34 +1,35 @@ pipeline { agent any tools { - maven 'mvn' - jdk 'JDK 8' + maven 'mvn396' + jdk 'temurin-jdk17' } stages { - stage('Preparation') { + stage('Initialize') { steps{ - deleteDir() - sh 'git clone git@github.com:opengeospatial/ets-eo-geojson10.git .' + sh ''' + echo "PATH = ${PATH}" + echo "M2_HOME = ${M2_HOME}" + ''' + sh 'mvn --version' } } stage('Release') { steps{ - sh 'mvn --version' sh 'mvn -Dresume=false -DdryRun=true release:prepare -Psign-artifacts-with-ogc,integration-tests,docker -DreleaseVersion=${releaseVersion} -DdevelopmentVersion=${developmentVersion}' sh 'mvn -Dresume=false release:prepare release:perform -Psign-artifacts-with-ogc,integration-tests,docker -DreleaseVersion=${releaseVersion} -DdevelopmentVersion=${developmentVersion}' } } stage('Publication of site') { steps{ - sh 'mvn --version' sh 'git checkout ${releaseVersion}' sh 'mvn clean install site site:stage scm-publish:publish-scm' } } stage('Results') { steps{ - junit '**/target/surefire-reports/TEST-*.xml' - archive 'target/*' + archiveArtifacts artifacts: 'target/*', allowEmptyArchive: true + deleteDir() } } } diff --git a/pom.xml b/pom.xml index 03c8bf9..99a85b4 100644 --- a/pom.xml +++ b/pom.xml @@ -13,17 +13,17 @@ EO GeoJSON 1.0 Conformance Test Suite Describe purpose of test suite. - http://opengeospatial.github.io/ets-eo-geojson10/ + https://opengeospatial.github.io/ets-eo-geojson10/ Apache License, Version 2.0 - http://opensource.org/licenses/Apache-2.0 + https://opensource.org/licenses/Apache-2.0 Open Geospatial Consortium - http://www.opengeospatial.org/ + https://www.ogc.org/ scm:git:https://github.com/opengeospatial/ets-eo-geojson10.git @@ -37,16 +37,14 @@ - Alpha Beta - https://github.com/ - UTC + Dirk Stenger + https://github.com/dstenger eo-geojson10 1.0 - 5.4 @@ -66,6 +64,10 @@ com.sun.xml.bind jaxb-osgi + + commons-logging + commons-logging + @@ -90,15 +92,19 @@ jadler-jetty test - org.opengis geoapi-pending - com.github.erosb everit-json-schema + + + joda-time + joda-time + + org.opengis.cite @@ -107,14 +113,18 @@ org.glassfish.jersey.connectors jersey-apache-connector + + + commons-logging + commons-logging + + - - org.apache.maven.plugins maven-assembly-plugin @@ -122,22 +132,13 @@ org.opengis.cite.eogeojson10.TestNGController - - ${basedir}/src/assembly/deps.xml - ${basedir}/src/assembly/ctl-scripts.xml - ${basedir}/src/assembly/aio.xml - - - - package - - single - - - + + + maven-scm-publish-plugin + @@ -146,28 +147,6 @@ - ogccite/${project.artifactId} - - ${project.basedir}/src/docker - - ${project.version}-teamengine-${docker.teamengine.version} - - - - - - ${project.build.directory} - . - - dependency/*teamengine-*.war - dependency/*teamengine-*.zip - *ets-*.zip - - - - - - 8081:8080 @@ -225,11 +204,17 @@ - + + - sonatype-nexus-staging - https://oss.sonatype.org/service/local/staging/deploy/maven2/ + geotoolkit + Geotk Modules + https://nexus.geomatys.com/repository/maven-public + default + + + site scm:git:git@github.com:opengeospatial/ets-eo-geojson10.git From 30e3d057bc706825e11f1f33b2dba4f944e645fa Mon Sep 17 00:00:00 2001 From: Dirk Stenger Date: Fri, 3 Jan 2025 12:22:37 +0100 Subject: [PATCH 13/13] #14 - Formatting --- pom.xml | 239 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 120 insertions(+), 119 deletions(-) diff --git a/pom.xml b/pom.xml index 99a85b4..c7745c9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - + org.opengis.cite @@ -47,55 +48,55 @@ 1.0 - - - org.opengis.cite.teamengine - teamengine-spi - - - org.opengis.cite - schema-utils - - - io.rest-assured - rest-assured - - - com.sun.xml.bind - jaxb-osgi - - - commons-logging - commons-logging - - - - - com.reprezen.kaizen - openapi-parser - - - junit - junit - - - org.mockito - mockito-core - - - net.jadler - jadler-core - test - - - net.jadler - jadler-jetty - test - - - org.opengis - geoapi-pending - + + + org.opengis.cite.teamengine + teamengine-spi + + + org.opengis.cite + schema-utils + + + io.rest-assured + rest-assured + + + com.sun.xml.bind + jaxb-osgi + + + commons-logging + commons-logging + + + + + com.reprezen.kaizen + openapi-parser + + + junit + junit + + + org.mockito + mockito-core + + + net.jadler + jadler-core + test + + + net.jadler + jadler-jetty + test + + + org.opengis + geoapi-pending + com.github.erosb everit-json-schema @@ -120,89 +121,89 @@ - + - - - - maven-assembly-plugin - - - - org.opengis.cite.eogeojson10.TestNGController - - - - - - maven-scm-publish-plugin - - - - + - io.fabric8 - docker-maven-plugin + maven-assembly-plugin - - - - - 8081:8080 - - - - http://localhost:8081/teamengine - - - - - - + + + org.opengis.cite.eogeojson10.TestNGController + + + + maven-scm-publish-plugin + - - - - - docker - + io.fabric8 docker-maven-plugin - - - build - - build - - - - push - - push - - - - - - maven-dependency-plugin - - - - copy - - - + + + + + + 8081:8080 + + + + http://localhost:8081/teamengine + + + + + + + - - - + + + + + + docker + + + + io.fabric8 + docker-maven-plugin + + + build + + build + + + + push + + push + + + + + + maven-dependency-plugin + + + + copy + + + + + + + +