Skip to content

Commit

Permalink
[GEOS-8406] WFS 2.0 does not support GetFeature with alternate namesp…
Browse files Browse the repository at this point in the history
…ace prefixes
  • Loading branch information
aaime committed Nov 21, 2017
1 parent 9e18ea5 commit 2056a5d
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 11 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@


import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List; import java.util.List;


import javax.xml.XMLConstants; import javax.xml.XMLConstants;
Expand All @@ -20,14 +21,24 @@
* Parses a list of namespace declarations of the form {@code * Parses a list of namespace declarations of the form {@code
* <xmlns(foo=http://name.space1)[,xmlns(bar=http://name.space2)]+> } into a * <xmlns(foo=http://name.space1)[,xmlns(bar=http://name.space2)]+> } into a
* {@link NamespaceSupport}. * {@link NamespaceSupport}.
* Using the {@link PrefixNamespaceSeparator#COMMA} it's also possible to handle
* the WFS 2.0 suggested syntax, {@code
* <xmlns(foo,http://name.space1)[,xmlns(bar,http://name.space2)]+> }
* *
* @author groldan * @author groldan
* *
*/ */
public class NamespaceKvpParser extends KvpParser { public class NamespaceKvpParser extends KvpParser {


private final boolean useComma;

public NamespaceKvpParser(String key) { public NamespaceKvpParser(String key) {
this(key, false);
}

public NamespaceKvpParser(String key, boolean useComma) {
super(key, NamespaceSupport.class); super(key, NamespaceSupport.class);
this.useComma = useComma;
} }


/** /**
Expand All @@ -39,21 +50,28 @@ public NamespaceKvpParser(String key) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public NamespaceSupport parse(final String value) throws Exception { public NamespaceSupport parse(final String value) throws Exception {
List<String> decls = (List<String>) new FlatKvpParser("", String.class).parse(value); List<String> declarations;
if (useComma) {
String[] parts = value.split(",(?![^()]*+\\))");
declarations = Arrays.asList(parts);
} else {
declarations = (List<String>) new FlatKvpParser("", String.class).parse(value);
}
NamespaceSupport ctx = new NamespaceSupport(); NamespaceSupport ctx = new NamespaceSupport();


String[] parts; String[] parts;
String prefix; String prefix;
String uri; String uri;
for (String decl : decls) { for (String decl : declarations) {
decl = decl.trim(); decl = decl.trim();
if (!decl.startsWith("xmlns(") || !decl.endsWith(")")) { if (!decl.startsWith("xmlns(") || !decl.endsWith(")")) {
throw new ServiceException("Illegal namespace declaration, " throw new ServiceException("Illegal namespace declaration, "
+ "should be of the form xmlns(<prefix>=<ns uri>): " + decl, ServiceException.INVALID_PARAMETER_VALUE, getKey()); + "should be of the form xmlns(<prefix>=<ns uri>): " + decl, ServiceException.INVALID_PARAMETER_VALUE, getKey());
} }
decl = decl.substring("xmlns(".length()); decl = decl.substring("xmlns(".length());
decl = decl.substring(0, decl.length() - 1); decl = decl.substring(0, decl.length() - 1);
parts = decl.split("="); String separator = useComma ? "," : "=";
parts = decl.split(separator);
if (parts.length == 1) { if (parts.length == 1) {
prefix = XMLConstants.DEFAULT_NS_PREFIX; prefix = XMLConstants.DEFAULT_NS_PREFIX;
uri = parts[0]; uri = parts[0];
Expand All @@ -62,7 +80,7 @@ public NamespaceSupport parse(final String value) throws Exception {
uri = parts[1]; uri = parts[1];
} else { } else {
throw new ServiceException("Illegal namespace declaration, " throw new ServiceException("Illegal namespace declaration, "
+ "should be of the form prefix=<namespace uri>: " + decl, ServiceException.INVALID_PARAMETER_VALUE, getKey()); + "should be of the form prefix" + separator + "<namespace uri>: " + decl, ServiceException.INVALID_PARAMETER_VALUE, getKey());
} }


try { try {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -98,4 +98,14 @@ private List<String> getPrefixes(NamespaceSupport ctx) {
} }
return l; return l;
} }

@Test
public void testWfs20Syntax() throws Exception {
NamespaceKvpParser parser = new NamespaceKvpParser("namespaces", true);
NamespaceSupport ctx = parser
.parse("xmlns(http://bar), xmlns(ex,http://example.com),xmlns(gs,http://geoserver.org)");
assertEquals("http://bar", ctx.getURI(""));
assertEquals("http://example.com", ctx.getURI("ex"));
assertEquals("http://geoserver.org", ctx.getURI("gs"));
}
} }
6 changes: 4 additions & 2 deletions src/wfs/src/main/java/applicationContext.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@
<property name="request"><value>GetFeature</value></property> <property name="request"><value>GetFeature</value></property>
</bean> </bean>
<bean id="getFeature20NamespaceKvpParser" class="org.geoserver.ows.kvp.NamespaceKvpParser"> <bean id="getFeature20NamespaceKvpParser" class="org.geoserver.ows.kvp.NamespaceKvpParser">
<constructor-arg value="namespace"/> <constructor-arg value="namespaces"/>
<constructor-arg value="true"/>
<property name="service"><value>WFS</value></property> <property name="service"><value>WFS</value></property>
<property name="version"><value>2.0.0</value></property> <property name="version"><value>2.0.0</value></property>
<property name="request"><value>GetFeature</value></property> <property name="request"><value>GetFeature</value></property>
Expand All @@ -321,7 +322,8 @@
<property name="request"><value>DescribeFeatureType</value></property> <property name="request"><value>DescribeFeatureType</value></property>
</bean> </bean>
<bean id="dft20NamespaceKvpParser" class="org.geoserver.ows.kvp.NamespaceKvpParser"> <bean id="dft20NamespaceKvpParser" class="org.geoserver.ows.kvp.NamespaceKvpParser">
<constructor-arg value="namespace"/> <constructor-arg value="namespaces"/>
<constructor-arg value="true"/>
<property name="service"><value>WFS</value></property> <property name="service"><value>WFS</value></property>
<property name="version"><value>2.0.0</value></property> <property name="version"><value>2.0.0</value></property>
<property name="request"><value>DescribeFeatureType</value></property> <property name="request"><value>DescribeFeatureType</value></property>
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ public Object read(Object request, Map kvp, Map rawKvp) throws Exception {


// did the user supply alternate namespace prefixes? // did the user supply alternate namespace prefixes?
NamespaceSupport namespaces = null; NamespaceSupport namespaces = null;
if (kvp.containsKey("NAMESPACE")) { if (kvp.containsKey("NAMESPACE") || kvp.containsKey("NAMESPACES")) {
if (kvp.get("NAMESPACE") instanceof NamespaceSupport) { if (kvp.get("NAMESPACE") instanceof NamespaceSupport) {
namespaces = (NamespaceSupport) kvp.get("namespace"); namespaces = (NamespaceSupport) kvp.get("namespace");
} else if (kvp.get("NAMESPACES") instanceof NamespaceSupport) {
namespaces = (NamespaceSupport) kvp.get("namespaces");
} else { } else {
LOGGER.warning("There's a namespace parameter but it seems it wasn't parsed to a " LOGGER.warning("There's a namespace parameter but it seems it wasn't parsed to a "
+ NamespaceSupport.class.getName() + ": " + kvp.get("namespace")); + NamespaceSupport.class.getName() + ": " + kvp.get("namespace"));
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -119,9 +119,11 @@ public Object read(Object request, Map kvp, Map rawKvp) throws Exception {


// did the user supply alternate namespace prefixes? // did the user supply alternate namespace prefixes?
NamespaceSupport namespaces = null; NamespaceSupport namespaces = null;
if (kvp.containsKey("namespace")) { if (kvp.containsKey("namespace") || kvp.containsKey("namespaces")) {
if (kvp.get("namespace") instanceof NamespaceSupport) { if (kvp.get("namespace") instanceof NamespaceSupport) {
namespaces = (NamespaceSupport) kvp.get("namespace"); namespaces = (NamespaceSupport) kvp.get("namespace");
} else if (kvp.get("namespaces") instanceof NamespaceSupport) {
namespaces = (NamespaceSupport) kvp.get("namespaces");
} else { } else {
LOGGER.warning("There's a namespace parameter but it seems it wasn't parsed to a " LOGGER.warning("There's a namespace parameter but it seems it wasn't parsed to a "
+ NamespaceSupport.class.getName() + ": " + kvp.get("namespace")); + NamespaceSupport.class.getName() + ": " + kvp.get("namespace"));
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public void testUserSuppliedTypeNameNamespace() throws Exception {
final QName typeName = CiteTestData.POLYGONS; final QName typeName = CiteTestData.POLYGONS;
String path = "ows?service=WFS&version=2.0.0&request=DescribeFeatureType&" + String path = "ows?service=WFS&version=2.0.0&request=DescribeFeatureType&" +
"typeName=myPrefix:" + typeName.getLocalPart() + "typeName=myPrefix:" + typeName.getLocalPart() +
"&namespace=xmlns(myPrefix%3D" + URLEncoder.encode(typeName.getNamespaceURI(), "UTF-8") + ")"; "&namespaces=xmlns(myPrefix," + URLEncoder.encode(typeName.getNamespaceURI(), "UTF-8") + ")";


Document doc = getAsDOM(path); Document doc = getAsDOM(path);
assertSchema(doc, CiteTestData.POLYGONS); assertSchema(doc, CiteTestData.POLYGONS);
Expand Down
10 changes: 8 additions & 2 deletions src/wfs/src/test/java/org/geoserver/wfs/v2_0/GetFeatureTest.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ public void testGet() throws Exception {
testGetFifteenAll("wfs?request=GetFeature&typenames=cdf:Fifteen&version=2.0.0&service=wfs"); testGetFifteenAll("wfs?request=GetFeature&typenames=cdf:Fifteen&version=2.0.0&service=wfs");
testGetFifteenAll("wfs?request=GetFeature&typenames=(cdf:Fifteen)&version=2.0.0&service=wfs"); testGetFifteenAll("wfs?request=GetFeature&typenames=(cdf:Fifteen)&version=2.0.0&service=wfs");
} }

@Test
public void testAlternatePrefix() throws Exception {
testGetFifteenAll("wfs?request=GetFeature&typenames=abc:Fifteen&version=2.0.0&service=wfs&namespaces=xmlns(abc," + MockData.CDF_URI + ")");
testGetFifteenAll("wfs?request=GetFeature&typenames=abc:Fifteen&version=2.0.0&service=wfs&namespaces=xmlns(abc," + MockData.CDF_URI + "),xmlns(wfs," + WFS.NAMESPACE + ")");
testGetFifteenAll("wfs?request=GetFeature&typenames=Fifteen&version=2.0.0&service=wfs&namespaces=xmlns(" + MockData.CDF_URI + "),xmlns(wfs," + WFS.NAMESPACE + ")");
}


@Test @Test
public void testConcurrentGet() throws Exception { public void testConcurrentGet() throws Exception {
Expand Down Expand Up @@ -699,8 +706,7 @@ public void testLayerQualified() throws Exception {
@Test @Test
public void testUserSuppliedNamespacePrefix() throws Exception { public void testUserSuppliedNamespacePrefix() throws Exception {
testGetFifteenAll("wfs?request=GetFeature&typename=myPrefix:Fifteen&version=2.0.0&service=wfs&" testGetFifteenAll("wfs?request=GetFeature&typename=myPrefix:Fifteen&version=2.0.0&service=wfs&"
+ "namespace=xmlns(myPrefix%3D" // the '=' sign shall be encoded, hence '%3D' + "namespaces=xmlns(myPrefix," + URLEncoder.encode(MockData.FIFTEEN.getNamespaceURI(), "UTF-8") + ")");
+ URLEncoder.encode(MockData.FIFTEEN.getNamespaceURI(), "UTF-8") + ")");
} }


@Test @Test
Expand Down

0 comments on commit 2056a5d

Please sign in to comment.