diff --git a/pom.xml b/pom.xml
index 12072b4..d0877c0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,5 @@
-
- * WARNING: The entity InputStream must be reset after each
- * read attempt.
- *
- *
- * @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("Capabilities document not found in ITestContext.");
- }
- this.cswCapabilities = Document.class.cast(obj);
- obj = testContext.getSuite().getAttribute(SuiteAttribute.CSW_SCHEMA.getName());
- if (null == obj) {
- throw new SkipException("CSW schema not found in ITestContext.");
- }
- this.cswSchema = Schema.class.cast(obj);
- obj = testContext.getSuite().getAttribute(SuiteAttribute.ATOM_SCHEMA.getName());
- if (null == obj) {
- throw new SkipException("Atom schema not found in ITestContext.");
- }
- this.atomSchema = Schema.class.cast(obj);
- }
-
- @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(com.sun.jersey.api.client.ClientResponse,
- * java.lang.String)
- */
- 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 ClientRequest object.
- *
- * @see ClientUtils#buildGetRequest(java.net.URI, java.util.Map,
- * javax.ws.rs.core.MediaType...)
- */
- public Response buildGetRequest(URI endpoint,
- Map
+ *
+ * @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("Capabilities document not found in ITestContext.");
+ }
+ this.cswCapabilities = Document.class.cast(obj);
+ obj = testContext.getSuite().getAttribute(SuiteAttribute.CSW_SCHEMA.getName());
+ if (null == obj) {
+ throw new SkipException("CSW schema not found in ITestContext.");
+ }
+ this.cswSchema = Schema.class.cast(obj);
+ obj = testContext.getSuite().getAttribute(SuiteAttribute.ATOM_SCHEMA.getName());
+ if (null == obj) {
+ throw new SkipException("Atom schema not found in ITestContext.");
+ }
+ this.atomSchema = Schema.class.cast(obj);
+ }
+
+ @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(com.sun.jersey.api.client.ClientResponse,
+ * java.lang.String)
+ */
+ 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 ClientRequest object.
+ *
+ * @see ClientUtils#buildGetRequest(java.net.URI, java.util.Map,
+ * javax.ws.rs.core.MediaType...)
+ */
+ public Response buildGetRequest(URI endpoint, Map
- *
- *
- * @param expr A valid XPath 1.0 expression.
- * @param context The context node (Document or Element).
- * @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
+ *
+ * @param expr A valid XPath 1.0 expression.
+ * @param context The context node (Document or Element).
+ * @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
- *
- *
- * @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(Response rsp,
- String exceptionCode, String locator) {
- Assert.assertEquals(rsp.getStatus(),
- Response.Status.BAD_REQUEST.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- Document doc = null;
- try {
- doc = rsp.readEntity(Document.class);
- } catch (RuntimeException ex) {
- StringBuilder msg = new StringBuilder();
- msg.append("Failed to parse response entity. ");
- msg.append(ex.getMessage()).append('\n');
- byte[] body = rsp.readEntity(byte[].class);
- msg.append(new String(body, StandardCharsets.US_ASCII));
- throw new AssertionError(msg);
- }
- 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,
- "Expected 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:
+ *
+ *
+ *
+ * @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(Response rsp, String exceptionCode, String locator) {
+ Assert.assertEquals(rsp.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ Document doc = null;
+ try {
+ doc = rsp.readEntity(Document.class);
+ }
+ catch (RuntimeException ex) {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Failed to parse response entity. ");
+ msg.append(ex.getMessage()).append('\n');
+ byte[] body = rsp.readEntity(byte[].class);
+ msg.append(new String(body, StandardCharsets.US_ASCII));
+ throw new AssertionError(msg);
+ }
+ 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, "Expected 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 all bounding boxes appearing in the search results intersect
- * the given envelope. The following bounding box representations are
- * recognized:
- *
- *
- *
- * @param bbox An envelope specifying a spatial extent in some CRS.
- * @param results A Source object for reading the query results (the
- * document element is typically csw:GetRecordsResponse or atom:feed).
- */
- public static void assertEnvelopeIntersectsBoundingBoxes(final Envelope bbox,
- final Source results) {
- NodeList boxNodeList = null;
- Map
+ *
+ * @param bbox An envelope specifying a spatial extent in some CRS.
+ * @param results A Source object for reading the query results (the document element
+ * is typically csw:GetRecordsResponse or atom:feed).
+ */
+ public static void assertEnvelopeIntersectsBoundingBoxes(final Envelope bbox, final Source results) {
+ NodeList boxNodeList = null;
+ Map
SuiteAttribute | - *Schema | - *
---|---|
SuiteAttribute.CSW_SCHEMA |
- * OGC 12-176r6, 7.9(a): cswAll.xsd | - *
SuiteAttribute.ATOM_SCHEMA |
- * RFC 4287, Appendix B: RELAX NG Compact Schema | - *
SuiteAttribute | + *Schema | + *
---|---|
SuiteAttribute.CSW_SCHEMA |
+ * OGC 12-176r6, 7.9(a): cswAll.xsd | + *
SuiteAttribute.ATOM_SCHEMA |
+ * RFC 4287, Appendix B: RELAX NG Compact Schema | + *
- * Synopsis - *
- *- * ets-cat30-${version}-aio.jar [-o|--outputDir $TMPDIR] [test-run-props.xml] - *- * - * @param args Test run arguments (optional). - * @throws Exception If the test run cannot be executed (usually due to - * unsatisfied pre-conditions). - */ - public static void main(String[] args) throws Exception { - TestRunArguments testRunArgs = new TestRunArguments(); - JCommander cmd = new JCommander(testRunArgs); - try { - cmd.parse(args); - } catch (ParameterException px) { - System.out.println(px.getMessage()); - cmd.usage(); - } - 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 "user.home" system - * property as the root output directory. - */ - public TestNGController() { - this(new File(System.getProperty("user.home")).toURI().toString()); - } - - /** - * 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. 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(FilenameUtils.normalize(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 test run arguments are missing or - * invalid. - */ - void validateTestRunArgs(Document testRunArgs) throws IllegalArgumentException { - 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
+ * Synopsis + *
+ *+ * ets-cat30-${version}-aio.jar [-o|--outputDir $TMPDIR] [test-run-props.xml] + *+ * @param args Test run arguments (optional). + * @throws Exception If the test run cannot be executed (usually due to unsatisfied + * pre-conditions). + */ + public static void main(String[] args) throws Exception { + TestRunArguments testRunArgs = new TestRunArguments(); + JCommander cmd = new JCommander(testRunArgs); + try { + cmd.parse(args); + } + catch (ParameterException px) { + System.out.println(px.getMessage()); + cmd.usage(); + } + 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 "user.home" system property as + * the root output directory. + */ + public TestNGController() { + this(new File(System.getProperty("user.home")).toURI().toString()); + } + + /** + * 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. 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(FilenameUtils.normalize(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 test run arguments are missing or invalid. + */ + void validateTestRunArgs(Document testRunArgs) throws IllegalArgumentException { + 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
GetRecords
request using the
- * KVP syntax.
+ * Provides tests that apply to the GetRecords
request using the KVP syntax.
*
* - * The KVP syntax must be supported; this encoding is generally used with the - * GET method but may also be used with the POST method; however a POST method - * binding is very unusual and will be advertised in the capabilities document - * as an operational constraint as indicated below. The media type of a KVP - * request entity is "application/x-www-form-urlencoded". + * The KVP syntax must be supported; this encoding is generally used with the GET method + * but may also be used with the POST method; however a POST method binding is very + * unusual and will be advertised in the capabilities document as an operational + * constraint as indicated below. The media type of a KVP request entity is + * "application/x-www-form-urlencoded". *
* * @see "OGC 12-176r6, 7.3: GetRecords operation" */ public class BasicGetRecordsTests extends CommonFixture { - /** - * Service endpoint for GetRecords using the GET method. - */ - private URI getURI; - /** - * Service endpoint for GetRecords using the POST method. - */ - private URI postURI; - /** - * Information about the sample data retrieved from the IUT. - */ - private DatasetInfo datasetInfo; + /** + * Service endpoint for GetRecords using the GET method. + */ + private URI getURI; - void setGetEndpoint(URI uri) { - this.getURI = uri; - } + /** + * Service endpoint for GetRecords using the POST method. + */ + private URI postURI; - /** - * Finds the GET and POST method endpoints for the GetRecords request in the - * capabilities document. - * - * @param testContext The test context containing various suite attributes. - */ - @BeforeClass - public void findRequestEndpoints(ITestContext testContext) { - this.getURI = ServiceMetadataUtils.getOperationEndpoint( - this.cswCapabilities, CAT3.GET_RECORDS, HttpMethod.GET); - if (null == this.getURI.getScheme()) { - throw new SkipException("GET endpoint for GetRecords request not found."); - } - this.postURI = ServiceMetadataUtils.getOperationEndpoint( - this.cswCapabilities, CAT3.GET_RECORDS, HttpMethod.POST); - } + /** + * Information about the sample data retrieved from the IUT. + */ + private DatasetInfo datasetInfo; - /** - * Gets information about the sample data obtained from the IUT, including: - * its total geographic extent; a collection of record titles; and a set of - * record identifiers. Each csw:Record element may contain at least one - * ows:BoundingBox (or ows:WGS84BoundingBox) element that describes the - * spatial coverage of a catalogued resource. - * - * @param testContext The test context containing various suite attributes. - */ - @BeforeClass - public void getDatasetInfo(ITestContext testContext) { - DatasetInfo dataset = (DatasetInfo) testContext.getSuite().getAttribute( - SuiteAttribute.DATASET.getName()); - if (null == dataset) { - throw new SkipException("Dataset info not found in test context."); - } - this.datasetInfo = dataset; - } + void setGetEndpoint(URI uri) { + this.getURI = uri; + } - /** - * [Test] Submits a GetRecords request with no search criteria. The - *namespace
parameter declares a namespace binding for the
- * common type name (tns:Record). The results must contain one or more
- * csw:BriefRecord elements.
- *
- * Sources
- *Sources
- *namespace
parameter declares a namespace binding for the common type
+ * name (tns:Record). The results must contain one or more csw:BriefRecord elements.
+ *
+ * + * Sources + *
+ *text/example
) as the value of the outputFormat
- * parameter. An exception report is expected in response with HTTP status
- * code 400 and exception code
- * "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
- */
- @Test(description = "Requirements: 035,037,042")
- public void getRecordsInUnsupportedOutputFormat() {
- MaptypeName
parameter value. Since the type does not belong to
- * any supported information model, an exception report is expected in
- * response with HTTP status code 400 and exception code
- * "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
- *
- * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding,
- * 7.3.4.7: typeNames parameter"
- */
- @Test(description = "Requirements: 088")
- public void getRecordsWithUnknownTypeName() {
- Map+ * Sources + *
+ *elementSetName
parameter value. An exception report is
- * expected in response with HTTP status code 400 and exception code
- * "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
- *
- * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding,
- * 7.3.4.8: ElementName or ElementSetName parameter"
- */
- @Test(description = "Requirements: 102")
- public void unknownElementSetName() {
- Maptext/example
) as the value of the outputFormat parameter. An
+ * exception report is expected in response with HTTP status code 400 and exception
+ * code "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
+ */
+ @Test(description = "Requirements: 035,037,042")
+ public void getRecordsInUnsupportedOutputFormat() {
+ MaptypeName
+ * parameter value. Since the type does not belong to any supported information model,
+ * an exception report is expected in response with HTTP status code 400 and exception
+ * code "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
+ *
+ * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding, 7.3.4.7:
+ * typeNames parameter"
+ */
+ @Test(description = "Requirements: 088")
+ public void getRecordsWithUnknownTypeName() {
+ MapelementSetName
parameter value. An exception report is expected in
+ * response with HTTP status code 400 and exception code
+ * "{@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL}".
+ *
+ * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding, 7.3.4.8:
+ * ElementName or ElementSetName parameter"
+ */
+ @Test(description = "Requirements: 102")
+ public void unknownElementSetName() {
+ MapElementName
and ElementSetName
parameters.
- * Since these parameters are mutually exclusive, an exception report is
- * expected in response with HTTP status code 400 and exception code
- * "{@value org.opengis.cite.cat30.CAT3#NO_CODE}".
- */
- @Test(description = "Requirements: 099")
- public void elementSetAndElementName() {
- MapstartPosition
- * and maxRecords
parameters have non-default values. The
- * csw:SearchResults element in the response entity must present the correct
- * "slice" of the result set.
- */
- @Test(description = "Requirements: 082,084")
- public void getPartialResults() {
- MapElementName
+ * and ElementSetName
parameters. Since these parameters are mutually
+ * exclusive, an exception report is expected in response with HTTP status code 400
+ * and exception code "{@value org.opengis.cite.cat30.CAT3#NO_CODE}".
+ */
+ @Test(description = "Requirements: 099")
+ public void elementSetAndElementName() {
+ MapstartPosition
and
+ * maxRecords
parameters have non-default values. The csw:SearchResults
+ * element in the response entity must present the correct "slice" of the result set.
+ */
+ @Test(description = "Requirements: 082,084")
+ public void getPartialResults() {
+ MapstartPosition
and
+ * maxRecords
parameters have non-default values. The atom:feed element
+ * in the response entity must present the correct "slice" of the result set.
+ *
+ * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding, 7.3.6: Atom
+ * response"
+ * @see "OGC OpenSearch Geo and Time Extensions, Table 6"
+ */
+ @Test(description = "Requirements: 082,084,122")
+ public void getPartialResultsAsAtomFeed() {
+ MapstartPosition
- * and maxRecords
parameters have non-default values. The
- * atom:feed element in the response entity must present the correct "slice"
- * of the result set.
- *
- * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding,
- * 7.3.6: Atom response"
- * @see "OGC OpenSearch Geo and Time Extensions, Table 6"
- */
- @Test(description = "Requirements: 082,084,122")
- public void getPartialResultsAsAtomFeed() {
- MapFilter-FES-KVP
- * conformance class. The following basic search capabilities must be
- * implemented:
+ * Includes GetRecords tests pertaining to the Filter-FES-KVP
conformance
+ * class. The following basic search capabilities must be implemented:
* * Sources @@ -160,19 +157,16 @@ public void getRecordsByBBOXWithUnsupportedCRS() { qryParams.put(CAT3.VERSION, CAT3.VERSION_3_0_0); qryParams.put(CAT3.TYPE_NAMES, "Record"); qryParams.put(CAT3.ELEMENT_SET, CAT3.ELEMENT_SET_BRIEF); - qryParams.put(CAT3.BBOX, - "472944,5363287,492722,5455253,urn:ogc:def:crs:EPSG::0000"); - response = ClientUtils.buildGetRequest(this.getURI, qryParams, - MediaType.APPLICATION_XML_TYPE); - ETSAssert.assertExceptionReport(response, CAT3.INVALID_PARAM_VAL, - CAT3.BBOX); + qryParams.put(CAT3.BBOX, "472944,5363287,492722,5455253,urn:ogc:def:crs:EPSG::0000"); + response = ClientUtils.buildGetRequest(this.getURI, qryParams, MediaType.APPLICATION_XML_TYPE); + ETSAssert.assertExceptionReport(response, CAT3.INVALID_PARAM_VAL, CAT3.BBOX); } /** - * [Test] Submits a GetRecords request with a BBOX parameter that includes a - * supported CRS reference. The brief records in the response must all - * contain an ows:BoundingBox (or ows:WGS84BoundingBox) element that - * intersects the specified bounding box. + * [Test] Submits a GetRecords request with a BBOX parameter that includes a supported + * CRS reference. The brief records in the response must all contain an + * ows:BoundingBox (or ows:WGS84BoundingBox) element that intersects the specified + * bounding box. * *
* Sources
@@ -187,8 +181,7 @@ public void getRecordsByBBOXWithUnsupportedCRS() {
@Test(description = "Requirements: 017; Tests: 017")
public void getBriefRecordsByBBOX() {
if (null == this.geoExtent) {
- throw new SkipException(
- "Could not determine extent of sample data.");
+ throw new SkipException("Could not determine extent of sample data.");
}
Map
* Sources
@@ -227,8 +218,7 @@ public void getBriefRecordsByBBOX() {
@Test(description = "Requirements: 017; Tests: 017")
public void getSummaryRecordsByWGS84BBOX() {
if (null == this.geoExtent) {
- throw new SkipException(
- "Could not determine extent of sample data.");
+ throw new SkipException("Could not determine extent of sample data.");
}
Map
- * Note: According to Table 4 in OGC OpenSearch Geo and
- * Time Extensions (OGC 10-032r8), the domain of keyword matching
- * should include the record elements indicated below.
+ * Note: According to Table 4 in OGC OpenSearch Geo and Time
+ * Extensions (OGC 10-032r8), the domain of keyword matching should include the
+ * record elements indicated below.
*
- * The KVP syntax must be supported; this encoding is generally used with the
- * GET method but may also be used with the POST method. The media type of a KVP
- * request entity is "application/x-www-form-urlencoded".
+ * The KVP syntax must be supported; this encoding is generally used with the GET method
+ * but may also be used with the POST method. The media type of a KVP request entity is
+ * "application/x-www-form-urlencoded".
* Sources
+ * Sources
+ *
+ * The
- * The
+ * The possible section names are listed below.
+ *
- * The possible section names are listed below.
- * The KVP syntax must be supported; this encoding is generally used with the
- * GET method but may also be used with the POST method; this latter capability
- * will be advertised in the capabilities document as an operational constraint
- * as indicated below. The media type of a KVP request entity is
- * "application/x-www-form-urlencoded".
+ * The KVP syntax must be supported; this encoding is generally used with the GET method
+ * but may also be used with the POST method; this latter capability will be advertised in
+ * the capabilities document as an operational constraint as indicated below. The media
+ * type of a KVP request entity is "application/x-www-form-urlencoded".
* Sources
+ * Sources
+ *
+ * The atom:entry element is expected to include a dc:identifier element in accord
+ * with the mappings given in OGC 10-032r8, Table 7.
+ *
+ * Sources
+ *
- * The atom:entry element is expected to include a dc:identifier element in
- * accord with the mappings given in OGC 10-032r8, Table 7.
- * Sources
+ * The resulting csw:Record (full) representations are inspected in order to construct
+ * successful service requests (e.g. a GetRecordById request that produces a matching
+ * record, GetRecords request with a spatial filter).
+ *
- * The resulting csw:Record (full) representations are inspected in order to
- * construct successful service requests (e.g. a GetRecordById request that
- * produces a matching record, GetRecords request with a spatial filter).
- * Includes tests covering capabilities required for Basic-Catalogue
- * conformance. The service requests listed below fall into this group; they may
- * be submitted using either the GET method or the POST method with the content
- * type "application/x-www-form-urlencoded" (key-value pair syntax).
+ * Includes tests covering capabilities required for Basic-Catalogue
+ * conformance. The service requests listed below fall into this group; they may be
+ * submitted using either the GET method or the POST method with the content type
+ * "application/x-www-form-urlencoded" (key-value pair syntax).
+ * The following presentation formats must be supported:
+ * The following presentation formats must be supported:
+ * Sources
+ * Sources
+ *
- * Note: None of the media types listed above appear in the
- * IANA media type registry. Registrations in the standards tree
- * must be approved by the IESG or originate from a recognized standards-related
- * organization (see RFC 6838); third-party registrations are allowed in the
- * vendor tree.
+ * Note: None of the media types listed above appear in the IANA
+ * media type registry. Registrations in the standards tree must be approved
+ * by the IESG or originate from a recognized standards-related organization (see
+ * RFC 6838);
+ * third-party registrations are allowed in the vendor tree.
* Sources
+ * Sources
+ *
- * All implementations must satisfy the requirements of the
- * Core conformance class (see OGC 10-032r8, Table 1). A
- * conforming service must:
- * In an Atom feed or entry, a bounding box is represented using a GeoRSS
- * element. Either the simple or GML variant is acceptable:
- * In addition to the service capabilities listed above, a Catalog v3 service
- * must also implement the Get record by id conformance class
- * that allows a client to retrieve a record by identifier
- * ( Sources
+ * Sources
+ *
+ * All matching record representations in the response entity must satisfy the
+ * bounding box constraint. If the entity is an Atom feed, it must also contain the
+ * os:Query element that describes the search request.
+ *
- * All matching record representations in the response entity must satisfy
- * the bounding box constraint. If the entity is an Atom feed, it must also
- * contain the os:Query element that describes the search request.
- *
+ * An attempt will be made to retrieve an OpenSearch description document from the
+ * IUT. A representation is expected to be obtained by dereferencing the URI
+ * corresponding to the GetCapabilities (GET) endpoint. The resulting Document object
+ * is stored as the value of the suite attribute
+ * {@link SuiteAttribute#OPENSEARCH_DESCR}.
+ *
- * An attempt will be made to retrieve an OpenSearch description document
- * from the IUT. A representation is expected to be obtained by
- * dereferencing the URI corresponding to the GetCapabilities (GET)
- * endpoint. The resulting Document object is stored as the value of the
- * suite attribute {@link SuiteAttribute#OPENSEARCH_DESCR}.
- * Includes tests covering capabilities required for OpenSearch
- * conformance. The query template parameters listed below must be supported:
+ * Includes tests covering capabilities required for OpenSearch
+ * conformance. The query template parameters listed below must be supported:
+ * Sources
+ * Sources
+ * Subsidiary packages correspond to distinct test groups such as conformance
- * classes.
+ * Subsidiary packages correspond to distinct test groups such as conformance classes.
+ *
+ * An alternative endpoint may be presented in the capabilities document using the
+ * "OpenSearchDescriptionDocument" constraint.
+ *
- * An alternative endpoint may be presented in the capabilities document
- * using the "OpenSearchDescriptionDocument" constraint.
- *
- * Note: The Saxon implementation supports XPath 2.0
- * expressions when using the JAXP XPath APIs (the default implementation
- * will throw an exception).
- *
+ * Note: The Saxon implementation supports XPath 2.0 expressions when
+ * using the JAXP XPath APIs (the default implementation will throw an exception).
+ *
@@ -367,32 +348,27 @@ public void singleTermTextSearch() {
// remove any chars that may give rise to invalid XPath expression
keyword = keyword.replaceAll("[()]", "");
qryParams.put(CAT3.Q, URIUtils.getPercentEncodedString(keyword));
- response = ClientUtils.buildGetRequest(this.getURI, qryParams,
- MediaType.APPLICATION_XML_TYPE);
- Assert.assertEquals(response.getStatus(),
- Response.Status.OK.getStatusCode(),
+ response = ClientUtils.buildGetRequest(this.getURI, qryParams, MediaType.APPLICATION_XML_TYPE);
+ Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
Document entity = getResponseEntityAsDocument(response, null);
QName recordName = new QName(Namespaces.CSW, "Record");
- NodeList recordList = entity.getElementsByTagNameNS(
- recordName.getNamespaceURI(), recordName.getLocalPart());
- Assert.assertTrue(recordList.getLength() > 0, ErrorMessage.format(
- ErrorMessageKeys.EMPTY_RESULT_SET, recordName));
+ NodeList recordList = entity.getElementsByTagNameNS(recordName.getNamespaceURI(), recordName.getLocalPart());
+ Assert.assertTrue(recordList.getLength() > 0,
+ ErrorMessage.format(ErrorMessageKeys.EMPTY_RESULT_SET, recordName));
// NOTE: Spec does not indicate how records are matched
// ETSAssert.assertAllTermsOccur(recordList, keyword);
}
/**
- * [Test] Submits a GetRecords request where the
q
parameter
- * contains a subject word and the maxRecords
parameter value
- * has the value "0" (zero). The csw:SearchResults element in the response
- * must be empty.
+ * [Test] Submits a GetRecords request where the q
parameter contains a
+ * subject word and the maxRecords
parameter value has the value "0"
+ * (zero). The csw:SearchResults element in the response must be empty.
*/
@Test(description = "Requirements: 086")
public void getRecordsBySubjectWithoutResults() {
if (this.recordTopics.isEmpty()) {
- throw new SkipException(
- "No dc:subject elements found in sample records.");
+ throw new SkipException("No dc:subject elements found in sample records.");
}
Mapbbox
and
- * q
parameters, where the latter matches one or more record
- * titles. The response must include all records that satisfy both search
- * criteria.
+ * q
parameters, where the latter matches one or more record titles. The
+ * response must include all records that satisfy both search criteria.
*
- * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding,
- * 6.5.5.3: KVP encoding"
+ * @see "OGC Catalogue Services 3.0 Specification - HTTP Protocol Binding, 6.5.5.3:
+ * KVP encoding"
*/
@Test(description = "Requirements: Table 6")
public void getRecordsByBBOXAndTitle() {
if (null == this.geoExtent) {
- throw new SkipException(
- "Could not determine extent of sample data.");
+ throw new SkipException("Could not determine extent of sample data.");
}
int maxRecords = 15;
MapGetCapabilities
request. This
- * request implements the abstract getCapabilities operation defined in
- * the OGCWebService interface (OGC 06-121r9, Figure C.2).
+ * Provides tests pertaining to the GetCapabilities
request. This request
+ * implements the abstract getCapabilities operation defined in the OGCWebService
+ * interface (OGC 06-121r9, Figure C.2).
*
*
*
Accept
request header expresses a preference for a representation
+ * of type {@value javax.ws.rs.core.MediaType#APPLICATION_XML}.
+ * Accept
request header expresses a preference for a
- * representation of type
- * {@value javax.ws.rs.core.MediaType#APPLICATION_XML}.
- * Accept: text/html; q=0.5, application/xml
+ *
+ * The response shall include a complete XML representation.
+ *
+ * @see "OGC 12-176r6, 6.4: Obtaining service metadata"
+ */
+ @Test(description = "Requirements: 007")
+ public void getCapabilitiesFromBaseURLAsXML() {
+ response = ClientUtils.buildGetRequest(this.getCapabilitiesURI, null,
+ MediaType.valueOf(MediaType.TEXT_HTML + "; q=0.5"), MediaType.APPLICATION_XML_TYPE);
+ Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ Source source = ClientUtils.getResponseEntityAsSource(response, null);
+ URL schURL = getClass().getResource(SCHEMATRON_CSW_CAPABILITIES);
+ ETSAssert.assertSchematronValid(schURL, source);
+ }
- /**
- * [Test] Attempts to retrieve the capabilities document from the base URL
- * (endpoint for GetCapabilities via GET). The Accept header indicates XML
- * as the preferred media type:
- *
- * Accept: text/html; q=0.5, application/xml
- *
- * The response shall include a complete XML representation.
- *
- * @see "OGC 12-176r6, 6.4: Obtaining service metadata"
- */
- @Test(description = "Requirements: 007")
- public void getCapabilitiesFromBaseURLAsXML() {
- response = ClientUtils.buildGetRequest(this.getCapabilitiesURI, null,
- MediaType.valueOf(MediaType.TEXT_HTML + "; q=0.5"),
- MediaType.APPLICATION_XML_TYPE);
- Assert.assertEquals(response.getStatus(),
- Response.Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- Source source = ClientUtils.getResponseEntityAsSource(response, null);
- URL schURL = getClass().getResource(SCHEMATRON_CSW_CAPABILITIES);
- ETSAssert.assertSchematronValid(schURL, source);
- }
+ /**
+ * [Test] Query parameter names must be handled in a case-insensitive manner. The
+ * parameter names are all presented in mixed case; a complete capabilities document
+ * is expected in response.
+ *
+ * @see "OGC 12-176r5, 6.5.4: KVP encoding rules"
+ */
+ @Test(description = "Requirements: 011")
+ public void getCapabilitiesWithMixedCaseParamNames() {
+ Maprequest=getCapabilities
; an exception report is
+ * expected in response with OGC exception code
+ * {@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL} and status code 400.
+ *
+ * @see "OGC 12-176r5, 6.5.4: KVP encoding rules"
+ * @see "OGC 06-121r9, Table 28: Standard exception codes and meanings"
+ */
+ @Test(description = "Requirements: 012")
+ public void getCapabilitiesWithInvalidParamValue() {
+ Maprequest=getCapabilities
; an exception
- * report is expected in response with OGC exception code
- * {@value org.opengis.cite.cat30.CAT3#INVALID_PARAM_VAL} and status code
- * 400.
- *
- * @see "OGC 12-176r5, 6.5.4: KVP encoding rules"
- * @see "OGC 06-121r9, Table 28: Standard exception codes and meanings"
- */
- @Test(description = "Requirements: 012")
- public void getCapabilitiesWithInvalidParamValue() {
- Map
+ *
+ *
+ * @see "OGC 06-121r9, 7.3.3: Sections parameter"
+ * @see "OGC 12-176, Table 12"
+ */
+ @Test(description = "Requirements: 044")
+ public void getCapabilitiesBySection() {
+ Map
- *
- *
- * @see "OGC 06-121r9, 7.3.3: Sections parameter"
- * @see "OGC 12-176, Table 12"
- */
- @Test(description = "Requirements: 044")
- public void getCapabilitiesBySection() {
- MapGetRecordById
request. This
- * request implements the abstract GetResourceByID operation defined in
- * the OGCWebService interface (OGC 06-121r9, Figure C.2).
+ * Provides tests that apply to the GetRecordById
request. This request
+ * implements the abstract GetResourceByID operation defined in the OGCWebService
+ * interface (OGC 06-121r9, Figure C.2).
*
* {@literal
@@ -64,7 +63,9 @@
*}
*
*
- *
*
Accept
request header
+ * indicates a preference for Atom content; the outputFormat parameter is omitted
+ * (thus the header value applies). The content of the entry must conform to RFC 4287.
+ *
+ * {@literal
+ *
+ *
+ *
+ *
+ */
+ @Test(description = "Requirements: 003,139,140")
+ public void getRecordByIdAsAtomEntryUsingAcceptHeader() {
+ MapAccept
request header indicates a preference for Atom
- * content; the outputFormat parameter is omitted (thus the header value
- * applies). The content of the entry must conform to RFC 4287.
- *
- * {@literal
- *
- *
- *
- *
- */
- @Test(description = "Requirements: 003,139,140")
- public void getRecordByIdAsAtomEntryUsingAcceptHeader() {
- Map
- *
- *
- * GetCapabilities
: Obtain information (service-related
- * metadata) about the capabilities of the serviceGetRecordById
: Retrieve a representation of a catalog
- * record by identifier.GetRecords
: Search catalog content and retrieve results
- * using basic filter criteria.GetCapabilities
: Obtain information (service-related metadata) about
+ * the capabilities of the serviceGetRecordById
: Retrieve a representation of a catalog record by
+ * identifier.GetRecords
: Search catalog content and retrieve results using basic
+ * filter criteria.
- *
+ *
*
- *
- *
*/
diff --git a/src/main/java/org/opengis/cite/cat30/opensearch/OpenSearchCoreTests.java b/src/main/java/org/opengis/cite/cat30/opensearch/OpenSearchCoreTests.java
index aba5477..b0b1210 100644
--- a/src/main/java/org/opengis/cite/cat30/opensearch/OpenSearchCoreTests.java
+++ b/src/main/java/org/opengis/cite/cat30/opensearch/OpenSearchCoreTests.java
@@ -39,9 +39,9 @@
import jakarta.ws.rs.core.Response;
/**
- * Verifies behavior of the SUT when processing queries that contain one or more
- * core OpenSearch parameters. The relevant query parameter bindings are shown
- * in the following table.
+ * Verifies behavior of the SUT when processing queries that contain one or more core
+ * OpenSearch parameters. The relevant query parameter bindings are shown in the following
+ * table.
*
*
*
@@ -75,25 +75,30 @@
* Sources
*
*
*
* q
* {searchTerms}
- * A comma-separated list of terms used to search across all text fields.
- * The value must be URL-encoded.
+ * A comma-separated list of terms used to search across all text fields. The value
+ * must be URL-encoded.
*
* startPosition
@@ -65,8 +65,8 @@
*
*
*
* maxRecords
* {count?}
- * Non-negative integer value specifying the number of search results (per
- * page) desired by the client.
+ * Non-negative integer value specifying the number of search results (per page)
+ * desired by the client.
*
- *
*/
public class OpenSearchCoreTests extends CommonFixture {
private String searchTerm;
- private static final QName SEARCH_TERMS_PARAM = new QName(Namespaces.OSD11,
- "searchTerms");
+
+ private static final QName SEARCH_TERMS_PARAM = new QName(Namespaces.OSD11, "searchTerms");
+
private Document openSearchDescr;
+
private Listcount
and
- * startIndex
parameters. The response entity must contain the
- * requested 'slice' of the result set in accord with its content model:
+ * startIndex
parameters. The response entity must contain the requested
+ * 'slice' of the result set in accord with its content model:
*
*
Accept
request
- * header expresses a preference for any of the following media types:
+ * Verifies the structure and content of the OpenSearch description document obtained from
+ * the SUT. The document is obtained in response to a GET request submitted to the base
+ * service endpoint where the Accept
request header expresses a preference
+ * for any of the following media types:
*
*
*
*
* application/vnd.a9.opensearchdescription+xml
*
*
*/
public class OpenSearchDescriptionTests extends CommonFixture {
- private RelaxNGValidator osdValidator;
- private URI baseUri;
- private static final String SCHEMATRON_OPENSEARCH_DESCR
- = CommonFixture.ROOT_PKG_PATH + "sch/opensearch-1.1.sch";
- public static final String OPENSEARCH_CONSTRAINT
- = "OpenSearchDescriptionDocument";
+ private RelaxNGValidator osdValidator;
+
+ private URI baseUri;
+
+ private static final String SCHEMATRON_OPENSEARCH_DESCR = CommonFixture.ROOT_PKG_PATH + "sch/opensearch-1.1.sch";
+
+ public static final String OPENSEARCH_CONSTRAINT = "OpenSearchDescriptionDocument";
+
+ /**
+ * Initializes the test fixture by:
+ *
+ *
+ * @param testContext The test context containing various suite attributes.
+ *
+ */
+ @BeforeClass
+ public void initFixture(ITestContext testContext) {
+ URL rncSchema = getClass().getResource(CommonFixture.ROOT_PKG_PATH + "rnc/osd-1.1-draft5.rnc");
+ try {
+ this.osdValidator = new RelaxNGValidator(rncSchema);
+ }
+ catch (SAXException | IOException ex) {
+ TestSuiteLogger.log(Level.WARNING, getClass().getName(), ex);
+ }
+ this.baseUri = ServiceMetadataUtils.getOperationEndpoint(this.cswCapabilities, CAT3.GET_CAPABILITIES,
+ HttpMethod.GET);
+ }
- /**
- * Initializes the test fixture by:
- * /org/opengis/cite/cat30/rnc/osd-1.1-draft5.rnc
- *
- *
- * @param testContext The test context containing various suite attributes.
- *
- */
- @BeforeClass
- public void initFixture(ITestContext testContext) {
- URL rncSchema = getClass().getResource(CommonFixture.ROOT_PKG_PATH
- + "rnc/osd-1.1-draft5.rnc");
- try {
- this.osdValidator = new RelaxNGValidator(rncSchema);
- } catch (SAXException | IOException ex) {
- TestSuiteLogger.log(Level.WARNING, getClass().getName(), ex);
- }
- this.baseUri = ServiceMetadataUtils.getOperationEndpoint(
- this.cswCapabilities, CAT3.GET_CAPABILITIES, HttpMethod.GET);
- }
+ /**
+ * [Test] Requests an OpenSearch description document as the most preferred media
+ * type. The generic XML media type is included in the Accept header with a q
+ * parameter value < 1:
+ *
+ * /org/opengis/cite/cat30/rnc/osd-1.1-draft5.rnc
Accept: application/xml; q=0.5, application/opensearchdescription+xml
+ */
+ @Test(description = "Requirements: 008; Tests: 008")
+ public void preferOpenSearchDescription() {
+ String xmlNotPreferred = MediaType.APPLICATION_XML + "; q=0.5";
+ response = ClientUtils.buildGetRequest(this.baseUri, null, MediaType.valueOf(xmlNotPreferred),
+ MediaType.valueOf(CAT3.APP_OPENSEARCH_XML));
+ Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
+ ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
+ Assert.assertTrue(XMLUtils.isXML(response.getMediaType()),
+ ErrorMessage.format(ErrorMessageKeys.NOT_XML, response.getMediaType()));
+ Document entity = ClientUtils.getResponseEntityAsDocument(response, null);
+ QName osdDocElemName = new QName(Namespaces.OSD11, "OpenSearchDescription");
+ ETSAssert.assertQualifiedName(entity.getDocumentElement(), osdDocElemName);
+ }
- /**
- * [Test] Requests an OpenSearch description document as the most preferred
- * media type. The generic XML media type is included in the Accept header
- * with a q parameter value < 1:
- *
- * Accept: application/xml; q=0.5, application/opensearchdescription+xml
- */
- @Test(description = "Requirements: 008; Tests: 008")
- public void preferOpenSearchDescription() {
- String xmlNotPreferred = MediaType.APPLICATION_XML + "; q=0.5";
- response = ClientUtils.buildGetRequest(this.baseUri, null,
- MediaType.valueOf(xmlNotPreferred),
- MediaType.valueOf(CAT3.APP_OPENSEARCH_XML));
- Assert.assertEquals(response.getStatus(),
- Response.Status.OK.getStatusCode(),
- ErrorMessage.get(ErrorMessageKeys.UNEXPECTED_STATUS));
- Assert.assertTrue(XMLUtils.isXML(response.getMediaType()),
- ErrorMessage.format(ErrorMessageKeys.NOT_XML, response.getMediaType()));
- Document entity = ClientUtils.getResponseEntityAsDocument(response, null);
- QName osdDocElemName = new QName(Namespaces.OSD11, "OpenSearchDescription");
- ETSAssert.assertQualifiedName(entity.getDocumentElement(), osdDocElemName);
- }
+ /**
+ * [Test] Validates the OpenSearch description document obtained from the IUT. The
+ * document is checked against the constraints in the OpenSearch 1.1 draft 5
+ * specification.
+ * @throws SAXException If the document cannot be read.
+ * @throws IOException If an I/O error occurs while trying to access the document.
+ *
+ * @see "[CAT-HTTP], 6.5.6.5: Requirements for an OpenSearch enabled CSW"
+ */
+ @Test(description = "Requirements: 021; Tests: 021")
+ public void validOpenSearchDescription() throws SAXException, IOException {
+ response = ClientUtils.buildGetRequest(this.baseUri, null, MediaType.valueOf(CAT3.APP_VND_OPENSEARCH_XML),
+ MediaType.valueOf(CAT3.APP_OPENSEARCH_XML));
+ Assert.assertTrue(XMLUtils.isXML(response.getMediaType()),
+ ErrorMessage.format(ErrorMessageKeys.NOT_XML, response.getMediaType()));
+ Source entity = ClientUtils.getResponseEntityAsSource(response, null);
+ this.osdValidator.validate(entity);
+ ValidationErrorHandler err = osdValidator.getErrorHandler();
+ Assert.assertFalse(err.errorsDetected(),
+ ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID, err.getErrorCount(), err.toString()));
+ URL schemaUrl = getClass().getResource(SCHEMATRON_OPENSEARCH_DESCR);
+ ETSAssert.assertSchematronValid(schemaUrl, entity);
+ }
- /**
- * [Test] Validates the OpenSearch description document obtained from the
- * IUT. The document is checked against the constraints in the OpenSearch
- * 1.1 draft 5 specification.
- *
- * @throws SAXException If the document cannot be read.
- * @throws IOException If an I/O error occurs while trying to access the
- * document.
- *
- * @see "[CAT-HTTP], 6.5.6.5: Requirements for an OpenSearch enabled CSW"
- */
- @Test(description = "Requirements: 021; Tests: 021")
- public void validOpenSearchDescription() throws SAXException, IOException {
- response = ClientUtils.buildGetRequest(this.baseUri, null,
- MediaType.valueOf(CAT3.APP_VND_OPENSEARCH_XML),
- MediaType.valueOf(CAT3.APP_OPENSEARCH_XML));
- Assert.assertTrue(XMLUtils.isXML(response.getMediaType()),
- ErrorMessage.format(ErrorMessageKeys.NOT_XML, response.getMediaType()));
- Source entity = ClientUtils.getResponseEntityAsSource(response, null);
- this.osdValidator.validate(entity);
- ValidationErrorHandler err = osdValidator.getErrorHandler();
- Assert.assertFalse(err.errorsDetected(),
- ErrorMessage.format(ErrorMessageKeys.NOT_SCHEMA_VALID,
- err.getErrorCount(), err.toString()));
- URL schemaUrl = getClass().getResource(SCHEMATRON_OPENSEARCH_DESCR);
- ETSAssert.assertSchematronValid(schemaUrl, entity);
- }
+ /**
+ * [Test] Attempts to retrieve an OpenSearch description document using the URI
+ * presented in the capabilities document as the value of the
+ * {@value #OPENSEARCH_CONSTRAINT} constraint.
+ *
+ * @see "[CAT-HTTP], 6.5.6.2, Table 16"
+ */
+ @Test(description = "[CAT-HTTP]: 6.5.6.2, Table 16")
+ public void getOpenSearchDescriptionFromCapabilities() {
+ URI getCapabilitiesEndpoint = ServiceMetadataUtils.getOperationEndpoint(this.cswCapabilities,
+ CAT3.GET_CAPABILITIES, HttpMethod.GET);
+ CSWClient cswClient = new CSWClient();
+ Document capabilitiesDoc = cswClient.getCapabilities(getCapabilitiesEndpoint);
+ Assert.assertNotNull(capabilitiesDoc,
+ "Failed to retrieve capabilities document as 'application/xml' from " + getCapabilitiesEndpoint);
+ Sethttp://a9.com/-/opensearch/extensions/geo/1.0/
.
*
*
*
*
*
*
*
* georss:box
(EPSG 4326)georss:where/{http://www.opengis.net/gml}Envelope
(any
- * CRS)georss:where/{http://www.opengis.net/gml}Envelope
(any CRS)geo:uid
). This requirement is a consequence of applying the
- * Filter-FES-KVP
conformance class to OpenSearch queries (see
- * Table 1).geo:uid
). This requirement is a
+ * consequence of applying the Filter-FES-KVP
conformance class to OpenSearch
+ * queries (see Table 1).
+ *
*
- *
*
*/
public class OpenSearchGeoTests extends CommonFixture {
- static final QName UID_PARAM = new QName(Namespaces.OS_GEO, "uid");
- private Document openSearchDescr;
- private List{geo:uid}
- * parameter. Any other template parameters are set to their default values.
- *
- * @see "OGC OpenSearch Geo and Time Extensions (OGC 10-032r8), 9.3.2:
- * Normal response XML encoding"
- */
- @Test(description = "OGC 12-176r6, Table 6")
- public void getResourceById() {
- List{geo:uid}
parameter. Any other template
+ * parameters are set to their default values.
+ *
+ * @see "OGC OpenSearch Geo and Time Extensions (OGC 10-032r8), 9.3.2: Normal response
+ * XML encoding"
+ */
+ @Test(description = "OGC 12-176r6, Table 6")
+ public void getResourceById() {
+ List{geo:box}
parameter. Any other
+ * template parameters are set to their default values.
+ *
+ * {geo:box}
parameter. Any other template parameters are set
- * to their default values.
- *
- * {@literal
+ *
+ *
+ * {@literal
- *
- *
- *
- *
- *
- * q={searchTerms}
startPosition={startIndex?}
maxRecords={count?}
bbox={geo:box}
recordIds={geo:uid}
q={searchTerms}
startPosition={startIndex?}
maxRecords={count?}
bbox={geo:box}
recordIds={geo:uid}
- *
*/
package org.opengis.cite.cat30.opensearch;
\ No newline at end of file
diff --git a/src/main/java/org/opengis/cite/cat30/package-info.java b/src/main/java/org/opengis/cite/cat30/package-info.java
index 53fdc1e..3ac141f 100644
--- a/src/main/java/org/opengis/cite/cat30/package-info.java
+++ b/src/main/java/org/opengis/cite/cat30/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.
*
- * Accept
header indicates a preference for the following
+ * media types:
+ *
+ *
+ * Accept
header indicates
- * a preference for the following media types:
- *
- *
- *
- *
- *
- * @return A NamespaceBindings object.
- */
- public static NamespaceBindings withStandardBindings() {
- NamespaceBindings nsBindings = new NamespaceBindings();
- nsBindings.addNamespaceBinding(Namespaces.OWS, "ows");
- nsBindings.addNamespaceBinding(Namespaces.OWS11, "ows11");
- nsBindings.addNamespaceBinding(Namespaces.XLINK, "xlink");
- nsBindings.addNamespaceBinding(Namespaces.GML, "gml");
- nsBindings.addNamespaceBinding(Namespaces.CSW, "csw");
- nsBindings.addNamespaceBinding(Namespaces.DCMES, "dc");
- nsBindings.addNamespaceBinding(Namespaces.DCMI, "dct");
- return nsBindings;
- }
+ /**
+ * Creates a NamespaceBindings object that is configured with the following namespace
+ * bindings:
+ *
+ *
+ *
+ * @return A NamespaceBindings object.
+ */
+ public static NamespaceBindings withStandardBindings() {
+ NamespaceBindings nsBindings = new NamespaceBindings();
+ nsBindings.addNamespaceBinding(Namespaces.OWS, "ows");
+ nsBindings.addNamespaceBinding(Namespaces.OWS11, "ows11");
+ nsBindings.addNamespaceBinding(Namespaces.XLINK, "xlink");
+ nsBindings.addNamespaceBinding(Namespaces.GML, "gml");
+ nsBindings.addNamespaceBinding(Namespaces.CSW, "csw");
+ nsBindings.addNamespaceBinding(Namespaces.DCMES, "dc");
+ nsBindings.addNamespaceBinding(Namespaces.DCMI, "dct");
+ return nsBindings;
+ }
+
+ @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/cat30/util/OpenSearchTemplateUtils.java b/src/main/java/org/opengis/cite/cat30/util/OpenSearchTemplateUtils.java
index dd5ca89..f2cd85a 100644
--- a/src/main/java/org/opengis/cite/cat30/util/OpenSearchTemplateUtils.java
+++ b/src/main/java/org/opengis/cite/cat30/util/OpenSearchTemplateUtils.java
@@ -23,172 +23,159 @@
*/
public class OpenSearchTemplateUtils {
- /**
- * Returns the qualified name of the given OpenSearch URL template
- * parameter.
- *
- * @param param A parameter in a URL template (e.g. "searchTerms",
- * "geo:box?").
- * @param contextNode The context node; this is used to perform a namespace
- * lookup if necessary.
- * @return A QName representing the name of the template parameter.
- */
- public static QName getTemplateParameterName(String param, Node contextNode) {
- QName paramName;
- String[] qName = param.split(":");
- if (qName.length > 1) {
- String nsPrefix = qName[0];
- String nsURI = contextNode.lookupNamespaceURI(nsPrefix);
- paramName = new QName(nsURI, qName[1].replace("?", ""), nsPrefix);
- } else {
- paramName = new QName(Namespaces.OSD11, qName[0].replace("?", ""));
- }
- return paramName;
- }
+ /**
+ * Returns the qualified name of the given OpenSearch URL template parameter.
+ * @param param A parameter in a URL template (e.g. "searchTerms", "geo:box?").
+ * @param contextNode The context node; this is used to perform a namespace lookup if
+ * necessary.
+ * @return A QName representing the name of the template parameter.
+ */
+ public static QName getTemplateParameterName(String param, Node contextNode) {
+ QName paramName;
+ String[] qName = param.split(":");
+ if (qName.length > 1) {
+ String nsPrefix = qName[0];
+ String nsURI = contextNode.lookupNamespaceURI(nsPrefix);
+ paramName = new QName(nsURI, qName[1].replace("?", ""), nsPrefix);
+ }
+ else {
+ paramName = new QName(Namespaces.OSD11, qName[0].replace("?", ""));
+ }
+ return paramName;
+ }
- /**
- * Filters a list of OpenSearch URL templates to include only those that
- * contain the specified parameter.
- *
- * @param urlTemplates A list of (Element) nodes representing URL templates.
- * @param paramName The qualified name of a template parameter.
- * @return A new list containing templates with the specified parameter.
- */
- public static List
+ * query = *( pchar / "/" / "?" )
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ *
+ * @param str The sequence of characters to be encoded.
+ * @return A percent-encoded string.
+ *
+ * @see RFC
+ * 3986, 2.1
+ */
+ public static String getPercentEncodedString(String str) {
+ String encoded = null;
+ try {
+ // URLEncoder is intended for HTML form encoding
+ encoded = URLEncoder.encode(str, "UTF-8").replaceAll("\\+", "%20");
+ }
+ catch (UnsupportedEncodingException ex) {
+ // UTF-8 is supported
+ }
+ return encoded;
+ }
- /**
- * Replaces characters not allowed in the query component of a URI with
- * their equivalent percent-encoded values (UTF-8). While this may encode
- * more "unsafe" characters than is strictly necessary according to RFC 3986
- * (see ABNF fragment below), it should not affect query processing.
- *
- *
- * query = *( pchar / "/" / "?" )
- * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
- *
- *
- * @param str The sequence of characters to be encoded.
- * @return A percent-encoded string.
- *
- * @see
- * RFC
- * 3986, 2.1
- */
- public static String getPercentEncodedString(String str) {
- String encoded = null;
- try {
- // URLEncoder is intended for HTML form encoding
- encoded = URLEncoder.encode(str, "UTF-8").replaceAll("\\+", "%20");
- } catch (UnsupportedEncodingException ex) {
- // UTF-8 is supported
- }
- return encoded;
- }
}
diff --git a/src/main/java/org/opengis/cite/cat30/util/ValidationUtils.java b/src/main/java/org/opengis/cite/cat30/util/ValidationUtils.java
index e22b5c9..97d4298 100644
--- a/src/main/java/org/opengis/cite/cat30/util/ValidationUtils.java
+++ b/src/main/java/org/opengis/cite/cat30/util/ValidationUtils.java
@@ -31,214 +31,189 @@
import org.xml.sax.SAXException;
/**
- * 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/cat30/";
- static final String FACTORY_RELAXNG_COMPACT
- = "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory";
- private static final XMLCatalogResolver SCH_RESOLVER = initCatalogResolver();
+ static final String ROOT_PKG = "/org/opengis/cite/cat30/";
+ static final String FACTORY_RELAXNG_COMPACT = "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory";
- 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);
- 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;
+ }
- /**
- * 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 Setnull
if it cannot be
- * constructed.
- */
- public static Schema createCSWSchema() {
- URL entityCatalog = ValidationUtils.class.getResource(ROOT_PKG
- + "schema-catalog.xml");
- XmlSchemaCompiler xsdCompiler = new XmlSchemaCompiler(entityCatalog);
- Schema appSchema = null;
- try {
- URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG
- + "xsd/opengis/cat/csw/3.0/csw-3.0.xsd");
- Source xsdSource = new StreamSource(schemaRef.toString());
- appSchema = xsdCompiler
- .compileXmlSchema(new Source[]{xsdSource});
- } catch (SAXException e) {
- TestSuiteLogger.log(Level.WARNING,
- "Failed to create CSW Schema object.", e);
- }
- return appSchema;
- }
+ /**
+ * 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 Setnull
if it cannot be
- * constructed.
- *
- * @see
- *
- * RFC 4287, Appendix B
- */
- public static Schema createAtomSchema() {
- SchemaFactory factory = SchemaFactory.newInstance(
- Constants.RELAXNG_COMPACT_URI, FACTORY_RELAXNG_COMPACT, null);
- URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG
- + "rnc/atom.rnc");
- Schema schema = null;
- try {
- schema = factory.newSchema(schemaRef);
- } catch (SAXException e) {
- TestSuiteLogger.log(Level.WARNING,
- "Failed to create Atom Schema object from RELAX NG (compact) grammar", e);
- }
- return schema;
- }
+ /**
+ * Creates a Schema object representing the complete set of constraints defined in the
+ * CSW 3.0 schema. It incorporates schema components from all relevant namespaces.
+ * @return An immutable Schema object, or null
if it cannot be
+ * constructed.
+ */
+ public static Schema createCSWSchema() {
+ URL entityCatalog = ValidationUtils.class.getResource(ROOT_PKG + "schema-catalog.xml");
+ XmlSchemaCompiler xsdCompiler = new XmlSchemaCompiler(entityCatalog);
+ Schema appSchema = null;
+ try {
+ URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG + "xsd/opengis/cat/csw/3.0/csw-3.0.xsd");
+ Source xsdSource = new StreamSource(schemaRef.toString());
+ appSchema = xsdCompiler.compileXmlSchema(new Source[] { xsdSource });
+ }
+ catch (SAXException e) {
+ TestSuiteLogger.log(Level.WARNING, "Failed to create CSW Schema object.", e);
+ }
+ return appSchema;
+ }
+
+ /**
+ * Creates a Schema object representing the constraints defined in RFC 4287 ("The Atom
+ * Syndication Format"). Appendix B provides an informative RELAX NG grammar (compact
+ * syntax); it can be used to validate either a feed or a stand-alone entry element.
+ * @return An immutable Schema object, or null
if it cannot be
+ * constructed.
+ *
+ * @see RFC
+ * 4287, Appendix B
+ */
+ public static Schema createAtomSchema() {
+ SchemaFactory factory = SchemaFactory.newInstance(Constants.RELAXNG_COMPACT_URI, FACTORY_RELAXNG_COMPACT, null);
+ URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG + "rnc/atom.rnc");
+ Schema schema = null;
+ try {
+ schema = factory.newSchema(schemaRef);
+ }
+ catch (SAXException e) {
+ TestSuiteLogger.log(Level.WARNING, "Failed to create Atom Schema object from RELAX NG (compact) grammar",
+ e);
+ }
+ return schema;
+ }
+
+ /**
+ * Creates a Schema object representing the constraints defined for an OpenSearch
+ * description document (1.1 Draft 5).
+ * @return An immutable Schema object, or null
if it cannot be
+ * constructed.
+ *
+ * @see OpenSearch 1.1
+ * Draft 5
+ */
+ public static Schema createOpenSearchSchema() {
+ SchemaFactory factory = SchemaFactory.newInstance(Constants.RELAXNG_COMPACT_URI, FACTORY_RELAXNG_COMPACT, null);
+ URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG + "rnc/osd-1.1-draft5.rnc");
+ Schema schema = null;
+ try {
+ schema = factory.newSchema(schemaRef);
+ }
+ catch (SAXException e) {
+ TestSuiteLogger.log(Level.WARNING,
+ "Failed to create OpenSearch Schema object from RELAX NG (compact) grammar", e);
+ }
+ return schema;
+ }
- /**
- * Creates a Schema object representing the constraints defined for an
- * OpenSearch description document (1.1 Draft 5).
- *
- * @return An immutable Schema object, or null
if it cannot be
- * constructed.
- *
- * @see
- *
- * OpenSearch 1.1 Draft 5
- */
- public static Schema createOpenSearchSchema() {
- SchemaFactory factory = SchemaFactory.newInstance(
- Constants.RELAXNG_COMPACT_URI, FACTORY_RELAXNG_COMPACT, null);
- URL schemaRef = ValidationUtils.class.getResource(ROOT_PKG
- + "rnc/osd-1.1-draft5.rnc");
- Schema schema = null;
- try {
- schema = factory.newSchema(schemaRef);
- } catch (SAXException e) {
- TestSuiteLogger.log(Level.WARNING,
- "Failed to create OpenSearch Schema object from RELAX NG (compact) grammar", e);
- }
- return schema;
- }
}
diff --git a/src/main/java/org/opengis/cite/cat30/util/XMLUtils.java b/src/main/java/org/opengis/cite/cat30/util/XMLUtils.java
index ad73285..9e46c5c 100644
--- a/src/main/java/org/opengis/cite/cat30/util/XMLUtils.java
+++ b/src/main/java/org/opengis/cite/cat30/util/XMLUtils.java
@@ -59,469 +59,435 @@
import net.sf.saxon.s9api.XsltTransformer;
/**
- * 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 XPathFactory initXPathFactory() {
- XPathFactory factory = XPathFactory.newInstance();
- return factory;
- }
+ private static final XMLInputFactory STAX_FACTORY = initXMLInputFactory();
- private static XMLInputFactory initXMLInputFactory() {
- XMLInputFactory factory = XMLInputFactory.newInstance();
- factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
- return factory;
- }
+ private static final XPathFactory XPATH_FACTORY = initXPathFactory();
- /**
- * 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();
- }
+ private static XPathFactory initXPathFactory() {
+ XPathFactory factory = XPathFactory.newInstance();
+ return factory;
+ }
- /**
- * 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);
- }
- }
+ private static XMLInputFactory initXMLInputFactory() {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
+ return factory;
+ }
- /**
- * 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,
- Mapnull
- * if the source is not an XML document or it cannot be read for some
- * reason.
- */
- public static QName nameOfDocumentElement(Source source) {
- XMLInputFactory factory = XMLInputFactory.newInstance();
- QName qName = null;
- try {
- XMLEventReader reader = factory.createXMLEventReader(source);
- // advance to document element
- StartElement docElem = reader.nextTag().asStartElement();
- qName = docElem.getName();
- } catch (XMLStreamException xse) {
- LOGR.log(Level.WARNING, "Failed to read Source.", xse);
- }
- return qName;
- }
+ /**
+ * Expands character entity ({@literal &name;}) and numeric references
+ * ({@literal hhhh;} 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("null
if the
+ * source is not an XML document or it cannot be read for some reason.
+ */
+ public static QName nameOfDocumentElement(Source source) {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ QName qName = null;
+ try {
+ XMLEventReader reader = factory.createXMLEventReader(source);
+ // advance to document element
+ StartElement docElem = reader.nextTag().asStartElement();
+ qName = docElem.getName();
+ }
+ catch (XMLStreamException xse) {
+ LOGR.log(Level.WARNING, "Failed to read Source.", xse);
+ }
+ return qName;
+ }
- /**
- * Writes the content of an XdmValue sequence to a string. Each item in the
- * sequence is either an atomic value or a node.
- *
- * @param value A value in the XDM data model.
- * @return A String representing the content of the sequence.
- *
- * @see
- * Saxon
- * API: XdmValue
- * @see
- * XQuery
- * 1.0 and XPath 2.0 Data Model (XDM) (Second Edition)
- */
- public static String writeXdmValueToString(XdmValue value) {
- StringBuilder str = new StringBuilder();
- for (XdmItem item : value) {
- if (item.isAtomicValue()) {
- str.append(item.getStringValue());
- } else {
- XdmNode node = (XdmNode) item;
- str.append(node.getNodeName()).append(": ");
- str.append(node.getStringValue());
- }
- str.append('\n');
- }
- return str.toString();
- }
+ /**
+ * Parses the content of the given Source and returns a DOM Document node.
+ * @param source The Source to read the XML content from.
+ * @return A Document node representing the XML content.
+ * @throws javax.xml.transform.TransformerException If the source cannot be parsed for
+ * any reason.
+ */
+ public static Document parse(Source source) throws TransformerException {
+ Transformer idt = TransformerFactory.newInstance().newTransformer();
+ DOMResult result = new DOMResult();
+ idt.transform(source, result);
+ Document doc = (Document) result.getNode();
+ if (null != doc) {
+ doc.setDocumentURI(source.getSystemId());
+ }
+ return doc;
+ }
- /**
- * Determines if the given media type is an XML-based media type.
- *
- * @param mediaType A MediaType object.
- * @return true if the type corresponds to an XML entity; false otherwise.
- *
- * @see RFC
- * 7303: XML Media Types
- */
- public static boolean isXML(final MediaType mediaType) {
- return mediaType.getSubtype().endsWith("xml");
- }
+ /**
+ * Returns a List view of the specified NodeList collection.
+ * @param nodeList An ordered collection of DOM nodes.
+ * @return A List containing the original sequence of Node objects.
+ */
+ public static List