Skip to content

Commit

Permalink
[GEOS-8709] WFS 2.0 Join using custom prefixes on primary feature typ…
Browse files Browse the repository at this point in the history
…e fails to run
  • Loading branch information
aaime committed Apr 20, 2018
1 parent f437296 commit babd1af
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
38 changes: 35 additions & 3 deletions src/wfs/src/main/java/org/geoserver/wfs/JoinExtractingVisitor.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;


import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.FeatureTypeInfo;
Expand All @@ -37,6 +38,7 @@
import org.opengis.filter.expression.PropertyName; import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.spatial.BinarySpatialOperator; import org.opengis.filter.spatial.BinarySpatialOperator;
import org.opengis.filter.temporal.BinaryTemporalOperator; import org.opengis.filter.temporal.BinaryTemporalOperator;
import org.xml.sax.helpers.NamespaceSupport;


import javax.xml.namespace.QName; import javax.xml.namespace.QName;


Expand Down Expand Up @@ -358,8 +360,34 @@ List<Filter> rewriteAndSortJoinFilters(List<Filter> filters) {
private Set<String> getFilterPrefixes(Filter filter) { private Set<String> getFilterPrefixes(Filter filter) {
FilterAttributeExtractor extractor = new FilterAttributeExtractor(); FilterAttributeExtractor extractor = new FilterAttributeExtractor();
filter.accept(extractor, null); filter.accept(extractor, null);
Set<String> attributeNames = extractor.getAttributeNameSet(); Set<PropertyName> attributeNames = extractor.getPropertyNameSet();
Set<String> prefixes = getPrefixes(attributeNames); Set<String> prefixes = new HashSet<>();
for (PropertyName attributeName : attributeNames) {
String name = attributeName.getPropertyName();
int idx = name.indexOf('/');
if (idx > 0) {
String prefix = name.substring(0, idx);
idx = prefix.indexOf(":");
if (idx > 0) {
String localNsPrefix = prefix.substring(0, idx);
NamespaceSupport namespaceSupport = attributeName.getNamespaceContext();
if (namespaceSupport != null) {
String ns = namespaceSupport.getURI(localNsPrefix);
if (ns != null) {
Optional<String> wsName = featureTypes.stream().filter(ft -> ns.equals(ft
.getQualifiedName().getNamespaceURI())).map(ft -> ft.getStore()
.getWorkspace().getName()).findFirst();
if (wsName.isPresent()) {
prefix = wsName.get() + ":" + prefix.substring(idx + 1);
}
}
}

}
prefixes.add(prefix);

}
}
return prefixes; return prefixes;
} }


Expand Down Expand Up @@ -452,12 +480,16 @@ private Map<String, String> buildNameToAlias() {
Map<String, String> nameToAlias = new HashMap<>(); Map<String, String> nameToAlias = new HashMap<>();
nameToAlias.put(primaryFeatureType.prefixedName(), primaryAlias); nameToAlias.put(primaryFeatureType.prefixedName(), primaryAlias);
nameToAlias.put(primaryFeatureType.getName(), primaryAlias); nameToAlias.put(primaryFeatureType.getName(), primaryAlias);
String localTypeName = getLocalTypeName(primaryFeatureType);
if (localTypeName != null) {
nameToAlias.put(localTypeName, primaryAlias);
}
for (int i = 0; i < aliases.size(); i++) { for (int i = 0; i < aliases.size(); i++) {
String alias = aliases.get(i); String alias = aliases.get(i);
FeatureTypeInfo ft = featureTypes.get(i); FeatureTypeInfo ft = featureTypes.get(i);
nameToAlias.put(ft.getName(), alias); nameToAlias.put(ft.getName(), alias);
nameToAlias.put(ft.prefixedName(), alias); nameToAlias.put(ft.prefixedName(), alias);
String localTypeName = getLocalTypeName(ft); localTypeName = getLocalTypeName(ft);
if (localTypeName != null) { if (localTypeName != null) {
nameToAlias.put(localTypeName, alias); nameToAlias.put(localTypeName, alias);
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -202,6 +202,33 @@ public void testSpatialJoinPOST() throws Exception {
XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Forests/gs:NAME[text() = 'Foo Forest']", dom); XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Forests/gs:NAME[text() = 'Foo Forest']", dom);
XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Lakes/gs:NAME[text() = 'Green Lake']", dom); XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Lakes/gs:NAME[text() = 'Green Lake']", dom);
} }

@Test
public void testSpatialJoinNoAliasesCustomPrefixes() throws Exception {
String xml =
"<wfs:GetFeature xmlns:wfs='" + WFS.NAMESPACE + "' xmlns:fes='" + FES.NAMESPACE + "'" +
" xmlns:gs='" + SystemTestData.DEFAULT_URI + "'" +
" xmlns:ns123='" + SystemTestData.DEFAULT_URI + "' version='2.0.0'>" +
"<wfs:Query typeNames='ns123:Forests ns123:Lakes'>" +
"<fes:Filter> " +
"<fes:Intersects> " +
"<fes:ValueReference>ns123:Forests/the_geom</fes:ValueReference> " +
"<fes:ValueReference>ns123:Lakes/the_geom</fes:ValueReference>" +
"</fes:Intersects> " +
"</fes:Filter> " +
"</wfs:Query>" +
"</wfs:GetFeature>";

Document dom = postAsDOM("wfs", xml);
// print(dom);
XMLAssert.assertXpathEvaluatesTo("2", "count(//wfs:Tuple)", dom);

XMLAssert.assertXpathExists("//wfs:Tuple[position() = 1]/wfs:member/gs:Forests/gs:NAME[text() = 'Green Forest']", dom);
XMLAssert.assertXpathExists("//wfs:Tuple[position() = 1]/wfs:member/gs:Lakes/gs:NAME[text() = 'Blue Lake']", dom);

XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Forests/gs:NAME[text() = 'Foo Forest']", dom);
XMLAssert.assertXpathExists("wfs:FeatureCollection/wfs:member[position()=2]/wfs:Tuple//gs:Lakes/gs:NAME[text() = 'Green Lake']", dom);
}


@Test @Test
public void testSpatialJoinGET() throws Exception { public void testSpatialJoinGET() throws Exception {
Expand Down

0 comments on commit babd1af

Please sign in to comment.