Skip to content

Commit

Permalink
NULL namespace prefixes used in AppSchema WFS GetFeature responses (#…
Browse files Browse the repository at this point in the history
…3072)

Review fixes
  • Loading branch information
fernandor777 authored and Nuno Oliveira committed Sep 3, 2018
1 parent be8abd3 commit 5fa1187
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
Expand Down Expand Up @@ -603,4 +605,20 @@ protected NestedFilterToSQL createNestedFilterEncoder(FeatureTypeMapping mapping
nestedFilterToSQL.setInline(true);
return nestedFilterToSQL;
}

/**
* Returns xml String from Document Object
*
* @param document
* @return
* @throws TransformerException
*/
protected String toString(Document document) throws TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
return writer.getBuffer().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.opengis.wfs20.StoredQueryDescriptionType;
import org.apache.commons.io.IOUtils;
import org.custommonkey.xmlunit.XpathEngine;
import org.geoserver.catalog.impl.NamespaceInfoImpl;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wfs.StoredQuery;
import org.geoserver.wfs.StoredQueryProvider;
import org.geotools.wfs.v2_0.WFS;
Expand Down Expand Up @@ -105,6 +108,13 @@ public void beforeTest() {
"http://www.opengis.net/gml/3.2");
}

@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
// inject a test namespace to check on responses
addTestNamespaceToCatalog();
}

/** * GetFeature tests ** */
@Override
protected StationsMockData createTestData() {
Expand Down Expand Up @@ -336,4 +346,80 @@ private void checkCount(
throw new RuntimeException("Error evaluating xpath.", exception);
}
}

/**
* Test a request with two queries (to different featureTypes and namespaces) Checks null
* prefixes issue on multiple query WFS 2.0.0 GML 3.2 versions
*/
@Test
public void testTwoQueriesNamespacesGml32() throws Exception {
String wfsQuery =
IOUtils.toString(
getClass()
.getClassLoader()
.getResourceAsStream(
"test-data/stations/stations_two_queries.xml"));
Document document = postAsDOM("wfs", wfsQuery);
checkCount(
WFS20_XPATH_ENGINE,
document,
1,
"//wfs:FeatureCollection/wfs:member/wfs:FeatureCollection/wfs:member/st_gml32:Station_gml32");

checkCount(
WFS20_XPATH_ENGINE,
document,
1,
"/wfs:FeatureCollection/wfs:member/wfs:FeatureCollection/wfs:member/"
+ "ms_gml32:Measurement_gml32");
// check prefixes:
String output = toString(document);
assertTrue(output.indexOf("null:Measurement_gml32") < 0);
assertTrue(output.indexOf("null:Station_gml32") < 0);
assertTrue(output.indexOf("ms_gml32:Measurement_gml32") > -1);
assertTrue(output.indexOf("st_gml32:Station_gml32") > -1);
// check test1 namespace injected:
assertTrue(output.indexOf("xmlns:test1=\"http://www.test1.org/test1\"") >= 0);
}

/**
* Test a request with two queries (to different featureTypes and namespaces) Checks null
* prefixes issue on multiple query WFS 1.1.0 GML 3.1 version
*/
@Test
public void testTwoQueriesNamespacesGml31() throws Exception {
String wfsQuery =
IOUtils.toString(
getClass()
.getClassLoader()
.getResourceAsStream(
"test-data/stations/stations_two_queries_1.1.xml"));
Document document = postAsDOM("wfs", wfsQuery);
String output = toString(document);
checkCount(
WFS11_XPATH_ENGINE,
document,
1,
"//wfs:FeatureCollection/gml:featureMember/st_gml31:Station_gml31");

checkCount(
WFS11_XPATH_ENGINE,
document,
1,
"/wfs:FeatureCollection/gml:featureMember/" + "ms_gml31:Measurement_gml31");
// check prefixes:
assertTrue(output.indexOf("null:Measurement_gml31") < 0);
assertTrue(output.indexOf("null:Station_gml31") < 0);
assertTrue(output.indexOf("ms_gml31:Measurement_gml31") > -1);
assertTrue(output.indexOf("st_gml31:Station_gml31") > -1);
// check test1 namespace injected:
assertTrue(output.indexOf("xmlns:test1=\"http://www.test1.org/test1\"") >= 0);
}

private void addTestNamespaceToCatalog() {
NamespaceInfoImpl ns1 = new NamespaceInfoImpl();
ns1.setURI("http://www.test1.org/test1");
ns1.setPrefix("test1");
getCatalog().add(ns1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<GetFeature version="2.0.0" service="WFS" handle="Filter on element test with PropertyIsNull deegree"
xmlns="http://www.opengis.net/wfs/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:ms_gml32="http://www.measurements_gml32.org/1.0"
xmlns:st_gml32="http://www.stations_gml32.org/1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd">
<Query typeNames="ms_gml32:Measurement_gml32">
<Filter xmlns="http://www.opengis.net/fes/2.0">
<PropertyIsEqualTo>
<ValueReference>Measurement_gml32/@gml:id</ValueReference>
<Literal>ms.1</Literal>
</PropertyIsEqualTo>
</Filter>
</Query>
<Query typeNames="st_gml32:Station_gml32">
<Filter xmlns="http://www.opengis.net/fes/2.0">
<PropertyIsEqualTo>
<ValueReference>Station_gml32/@gml:id</ValueReference>
<Literal>st.1</Literal>
</PropertyIsEqualTo>
</Filter>
</Query>
</GetFeature>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<wfs:GetFeature service="WFS" version="1.1.0"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:ms_gml31="http://www.measurements_gml31.org/1.0"
xmlns:st_gml31="http://www.stations_gml31.org/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
<wfs:Query typeName="ms_gml31:Measurement_gml31">
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>Measurement_gml31/@gml:id</ogc:PropertyName>
<ogc:Literal>ms.1</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
</wfs:Query>
<wfs:Query typeName="st_gml31:Station_gml31">
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>Station_gml31/@gml:id</ogc:PropertyName>
<ogc:Literal>st.1</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
</wfs:Query>
</wfs:GetFeature>
Original file line number Diff line number Diff line change
Expand Up @@ -192,36 +192,11 @@ public final XSDSchema buildSchemaInternal(
schema.setTargetNamespace(targetNamespace);
schema.getQNamePrefixToNamespaceMap().put(targetPrefix, targetNamespace);

boolean simple = true;
for (int i = 0; i < featureTypeInfos.length && simple; i++) {
try {
simple = featureTypeInfos[i].getFeatureType() instanceof SimpleFeatureType;
} catch (IOException e) {
// ignore so that broken feature types don't prevent others from continuing to
// work
}
}
boolean simple = isSimpleFeature(featureTypeInfos);

if (!simple) {
// complex features may belong to different workspaces
WorkspaceInfo localWorkspace = LocalWorkspace.get();
if (localWorkspace != null) {
// deactivate workspace filtering
LocalWorkspace.remove();
}
// add secondary namespaces from the full catalog
try {
for (NamespaceInfo nameSpaceinfo : catalog.getNamespaces()) {
if (!schema.getQNamePrefixToNamespaceMap()
.containsKey(nameSpaceinfo.getPrefix())) {
schema.getQNamePrefixToNamespaceMap()
.put(nameSpaceinfo.getPrefix(), nameSpaceinfo.getURI());
}
}
} finally {
// make sure local workspace filtering is repositioned
LocalWorkspace.set(localWorkspace);
}
addAllNamespacesFromCatalog(schema);
}

// would result in some xsd:include or xsd:import if schema location is specified
Expand Down Expand Up @@ -280,6 +255,11 @@ public final XSDSchema buildSchemaInternal(
}
}
} else {
// if complex features, add all namespaces
if (!isSimpleFeature(featureTypeInfos)) {
addAllNamespacesFromCatalog(schema);
}

// different namespaces, write out import statements

// set the first namespace as the target one
Expand Down Expand Up @@ -384,6 +364,39 @@ public final XSDSchema buildSchemaInternal(
return schema;
}

private void addAllNamespacesFromCatalog(XSDSchema schema) {
WorkspaceInfo localWorkspace = LocalWorkspace.get();
if (localWorkspace != null) {
// deactivate workspace filtering
LocalWorkspace.remove();
}
// add secondary namespaces from the full catalog
try {
for (NamespaceInfo nameSpaceinfo : catalog.getNamespaces()) {
if (!schema.getQNamePrefixToNamespaceMap().containsKey(nameSpaceinfo.getPrefix())) {
schema.getQNamePrefixToNamespaceMap()
.put(nameSpaceinfo.getPrefix(), nameSpaceinfo.getURI());
}
}
} finally {
// make sure local workspace filtering is repositioned
LocalWorkspace.set(localWorkspace);
}
}

private boolean isSimpleFeature(FeatureTypeInfo[] featureTypeInfos) {
boolean simple = true;
for (int i = 0; i < featureTypeInfos.length && simple; i++) {
try {
simple = featureTypeInfos[i].getFeatureType() instanceof SimpleFeatureType;
} catch (IOException e) {
// ignore so that broken feature types don't prevent others from continuing to
// work
}
}
return simple;
}

protected void importGMLSchema(XSDSchema schema, XSDFactory factory, String baseUrl) {
XSDImport imprt = factory.createXSDImport();
imprt.setNamespace(gmlNamespace);
Expand Down

0 comments on commit 5fa1187

Please sign in to comment.