/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.v2_0;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.Map;
import javax.xml.namespace.QName;
import org.custommonkey.xmlunit.XMLAssert;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.data.test.CiteTestData;
import org.geoserver.data.test.SystemTestData;
import org.geotools.data.DataStore;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.filter.v2_0.FES;
import org.geotools.gml3.v3_2.GML;
import org.geotools.wfs.v2_0.WFS;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.vividsolutions.jts.geom.Point;
public class TransactionTest extends WFS20TestSupport {
public static final QName WITH_GML = new QName(SystemTestData.SF_URI,
"WithGMLProperties", SystemTestData.SF_PREFIX);
@Before
public void revert() throws Exception {
revertLayer(CiteTestData.ROAD_SEGMENTS);
getTestData().addVectorLayer(WITH_GML, Collections.EMPTY_MAP,
org.geoserver.wfs.v1_1.TransactionTest.class, getCatalog());
}
@Test
public void testInsert1() throws Exception {
String xml = "<wfs:Transaction service='WFS' version='2.0.0' "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:sf='http://cite.opengeospatial.org/gmlsf'>"
+ "<wfs:Insert handle='insert-1'>"
+ " <sf:PrimitiveGeoFeature gml:id='cite.gmlsf0-f01'>"
+ " <gml:description>"
+ "Fusce tellus ante, tempus nonummy, ornare sed, accumsan nec, leo."
+ "Vivamus pulvinar molestie nisl."
+ "</gml:description>"
+ "<gml:name>Aliquam condimentum felis sit amet est.</gml:name>"
//+ "<gml:name codeSpace='http://cite.opengeospatial.org/gmlsf'>cite.gmlsf0-f01</gml:name>"
+ "<sf:curveProperty>"
+ " <gml:LineString gml:id='cite.gmlsf0-g01' srsName='urn:x-fes:def:crs:EPSG:6.11.2:4326'>"
+ " <gml:posList>47.608284 19.034142 51.286873 16.7836 49.849854 15.764992</gml:posList>"
+ " </gml:LineString>"
+ "</sf:curveProperty>"
+ "<sf:intProperty>1025</sf:intProperty>"
+ "<sf:measurand>7.405E2</sf:measurand>"
+ "<sf:dateTimeProperty>2006-06-23T12:43:12+01:00</sf:dateTimeProperty>"
+ "<sf:decimalProperty>90.62</sf:decimalProperty>"
+ "</sf:PrimitiveGeoFeature>"
+ "</wfs:Insert>"
+ "<wfs:Insert handle='insert-2'>"
+ "<sf:AggregateGeoFeature gml:id='cite.gmlsf0-f02'>"
+ " <gml:description>"
+ "Duis nulla nisi, molestie vel, rhoncus a, ullamcorper eu, justo. Sed bibendum."
+ " Ut sem. Mauris nec nunc a eros aliquet pharetra. Mauris nonummy, pede et"
+ " tincidunt ultrices, mauris lectus fermentum massa, in ullamcorper lectus"
+ "felis vitae metus. Sed imperdiet sollicitudin dolor."
+ " </gml:description>"
+ " <gml:name codeSpace='http://cite.opengeospatial.org/gmlsf'>cite.gmlsf0-f02</gml:name>"
+ " <gml:name>Quisqué viverra</gml:name>"
+ " <gml:boundedBy>"
+ " <gml:Envelope srsName='urn:x-fes:def:crs:EPSG:6.11.2:4326'>"
+ " <gml:lowerCorner>36.1 8.0</gml:lowerCorner>"
+ " <gml:upperCorner>52.0 21.1</gml:upperCorner>"
+ " </gml:Envelope>"
+ " </gml:boundedBy>"
+ " <sf:multiPointProperty>"
+ "<gml:MultiPoint srsName='urn:x-fes:def:crs:EPSG:6.11.2:4326'>"
+ "<gml:pointMember>"
+ " <gml:Point><gml:pos>49.325176 21.036873</gml:pos></gml:Point>"
+ "</gml:pointMember>"
+ "<gml:pointMember>"
+ " <gml:Point><gml:pos>36.142586 13.56189</gml:pos></gml:Point>"
+ "</gml:pointMember>"
+ "<gml:pointMember>"
+ " <gml:Point><gml:pos>51.920937 8.014193</gml:pos></gml:Point>"
+ "</gml:pointMember>"
+ "</gml:MultiPoint>"
+ "</sf:multiPointProperty>"
+
"<sf:doubleProperty>2012.78</sf:doubleProperty>"
+ " <sf:intRangeProperty>43</sf:intRangeProperty>"
+ " <sf:strProperty>"
+ "Donec ligulä pede, sodales iń, vehicula eu, sodales et, lêo."
+ "</sf:strProperty>"
+ "<sf:featureCode>AK121</sf:featureCode>"
+ "</sf:AggregateGeoFeature>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM("wfs", xml);
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertTrue(dom.getElementsByTagName("fes:ResourceId").getLength() > 0);
}
@Test
public void testInsertWithNoSRS() throws Exception {
// 1. do a getFeature
String getFeature =
"<wfs:GetFeature service='WFS' version='2.0.0' "
+ "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
+ "xmlns:fes='" + FES.NAMESPACE + "' xmlns:wfs='" + WFS.NAMESPACE + "'>"
+ "<wfs:Query typeNames=\"cgf:Points\"> "
+ "<wfs:ValueReference>cite:id</wfs:ValueReference> " + "</wfs:Query> "
+ "</wfs:GetFeature>";
Document dom = postAsDOM("wfs", getFeature);
int n = dom.getElementsByTagName("cgf:Points").getLength();
// perform an insert
String insert =
"<wfs:Transaction service='WFS' version='2.0.0' "
+ "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
+ "xmlns:fes='" + FES.NAMESPACE + "' "
+ "xmlns:wfs='" + WFS.NAMESPACE + "' "
+ "xmlns:gml='" + GML.NAMESPACE + "'> "
+ "<wfs:Insert > "
+ "<cgf:Points>"
+ "<cgf:pointProperty>"
+ "<gml:Point>"
+ "<gml:pos>20 40</gml:pos>"
+ "</gml:Point>"
+ "</cgf:pointProperty>"
+ "<cgf:id>t0002</cgf:id>"
+ "</cgf:Points>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
dom = postAsDOM("wfs", insert);
NodeList numberInserteds = dom.getElementsByTagName("wfs:totalInserted");
Element numberInserted = (Element) numberInserteds.item(0);
assertNotNull(numberInserted);
assertEquals("1", numberInserted.getFirstChild().getNodeValue());
String fid = getFirstElementByTagName(dom, "fes:ResourceId").getAttribute("rid");
// check insertion occurred
dom = postAsDOM("wfs", getFeature);
assertEquals(n + 1, dom.getElementsByTagName("cgf:Points").getLength());
// check coordinate order is preserved
getFeature = "<wfs:GetFeature service='WFS' version='2.0.0' "
+ "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
+ "xmlns:fes='" + FES.NAMESPACE + "' "
+ "xmlns:wfs='" + WFS.NAMESPACE + "'>"
+ "<wfs:Query typeNames=\"cgf:Points\"> "
+ "<fes:Filter>"
+ "<fes:PropertyIsEqualTo>"
+ "<fes:ValueReference>cgf:id</fes:ValueReference>"
+ "<fes:Literal>t0002</fes:Literal>"
+ "</fes:PropertyIsEqualTo>"
+ "</fes:Filter>"
+ "</wfs:Query> "
+ "</wfs:GetFeature>";
dom = postAsDOM("wfs", getFeature);
assertEquals("20 40", getFirstElementByTagName(dom, "gml:pos").getFirstChild()
.getNodeValue());
}
@Test
public void testInsertWithSRS() throws Exception {
// 1. do a getFeature
String getFeature =
"<wfs:GetFeature service='WFS' version='2.0.0' xmlns:cgf='http://www.opengis.net/cite/geometry' " +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "'> " +
" <wfs:Query typeNames='cgf:Points'/> " +
"</wfs:GetFeature> ";
Document dom = postAsDOM("wfs", getFeature);
// print(dom);
int n = dom.getElementsByTagName("cgf:Points").getLength();
// perform an insert
String insert =
"<wfs:Transaction service='WFS' version='2.0.0' xmlns:cgf='http://www.opengis.net/cite/geometry' " +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "' " +
" xmlns:gml='" + GML.NAMESPACE + "'> " +
" <wfs:Insert srsName='EPSG:32615'> " +
" <cgf:Points> " +
" <cgf:pointProperty> " +
" <gml:Point> " +
" <gml:pos>1 1</gml:pos> " +
" </gml:Point> " +
" </cgf:pointProperty> " +
" <cgf:id>t0003</cgf:id> " +
" </cgf:Points> " +
" </wfs:Insert> " +
"</wfs:Transaction>";
dom = postAsDOM("wfs", insert);
NodeList numberInserteds = dom.getElementsByTagName("wfs:totalInserted");
Element numberInserted = (Element) numberInserteds.item(0);
assertNotNull(numberInserted);
assertEquals("1", numberInserted.getFirstChild().getNodeValue());
// do another get feature
getFeature = "<wfs:GetFeature " + "service=\"WFS\" version=\"2.0.0\" "
+ "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" " +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "' " +
" xmlns:gml='" + GML.NAMESPACE + "'> " +
"<wfs:Query typeNames=\"cgf:Points\"> "
+ "</wfs:Query> "
+ "</wfs:GetFeature>";
dom = postAsDOM("wfs", getFeature);
NodeList pointsList = dom.getElementsByTagName("cgf:Points");
assertEquals(n + 1, pointsList.getLength());
}
@Test
public void testInsertWithGMLProperties() throws Exception {
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" " +
"xmlns:wfs='" + WFS.NAMESPACE + "' " +
"xmlns:sf=\"http://cite.opengeospatial.org/gmlsf\" " +
"xmlns:gml='" + GML.NAMESPACE + "'>" +
"<wfs:Insert>" +
"<sf:WithGMLProperties>" +
"<gml:location>" +
"<gml:Point>" +
"<gml:coordinates>2,2</gml:coordinates>" +
"</gml:Point>" +
"</gml:location>" +
"<gml:name>two</gml:name>" +
"<sf:foo>2</sf:foo>" +
"</sf:WithGMLProperties>" +
"</wfs:Insert>" +
"</wfs:Transaction>";
Document dom = postAsDOM("wfs", xml);
assertEquals( "wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
Element inserted = getFirstElementByTagName(dom, "wfs:totalInserted");
assertEquals( "1", inserted.getFirstChild().getNodeValue());
dom = getAsDOM("wfs?request=getfeature&service=wfs&version=1.1.0&typename=sf:WithGMLProperties");
NodeList features = dom.getElementsByTagName("sf:WithGMLProperties");
assertEquals( 2, features.getLength() );
Element feature = (Element) features.item( 1 );
assertEquals( "two", getFirstElementByTagName(feature, "gml:name" ).getFirstChild().getNodeValue());
assertEquals( "2", getFirstElementByTagName(feature, "sf:foo" ).getFirstChild().getNodeValue());
Element location = getFirstElementByTagName( feature, "gml:location" );
Element pos = getFirstElementByTagName(location, "gml:pos");
assertEquals("2 2", pos.getFirstChild().getNodeValue());
xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" " +
"xmlns:wfs='" + WFS.NAMESPACE + "' " +
"xmlns:sf=\"http://cite.opengeospatial.org/gmlsf\" " +
"xmlns:gml='" + GML.NAMESPACE + "'>" +
"<wfs:Insert>" +
"<sf:WithGMLProperties>" +
"<sf:location>" +
"<gml:Point>" +
"<gml:coordinates>3,3</gml:coordinates>" +
"</gml:Point>" +
"</sf:location>" +
"<sf:name>three</sf:name>" +
"<sf:foo>3</sf:foo>" +
"</sf:WithGMLProperties>" +
"</wfs:Insert>" +
"</wfs:Transaction>";
dom = postAsDOM("wfs", xml);
assertEquals( "wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
dom = getAsDOM("wfs?request=getfeature&service=wfs&version=2.0.0&typename=sf:WithGMLProperties");
features = dom.getElementsByTagName("sf:WithGMLProperties");
assertEquals( 3, features.getLength() );
feature = (Element) features.item( 2 );
assertEquals( "three", getFirstElementByTagName(feature, "gml:name" ).getFirstChild().getNodeValue());
assertEquals( "3", getFirstElementByTagName(feature, "sf:foo" ).getFirstChild().getNodeValue());
location = getFirstElementByTagName( feature, "gml:location" );
pos = getFirstElementByTagName(location, "gml:pos");
assertEquals("3 3", pos.getFirstChild().getNodeValue());
}
@Test
public void testUpdateWithGMLProperties() throws Exception {
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\" " +
"xmlns:sf=\"http://cite.opengeospatial.org/gmlsf\" " +
"xmlns:wfs='" + WFS.NAMESPACE + "' " +
"xmlns:fes='" + FES.NAMESPACE + "' " +
"xmlns:gml='" + GML.NAMESPACE + "'>" +
" <wfs:Update typeName=\"sf:WithGMLProperties\">" +
" <wfs:Property>" +
" <wfs:ValueReference>gml:name</wfs:ValueReference>" +
" <wfs:Value>two</wfs:Value>" +
" </wfs:Property>" +
" <wfs:Property>" +
" <wfs:ValueReference>gml:location</wfs:ValueReference>" +
" <wfs:Value>" +
" <gml:Point>" +
" <gml:coordinates>2,2</gml:coordinates>" +
" </gml:Point>" +
" </wfs:Value>" +
" </wfs:Property>" +
" <wfs:Property>" +
" <wfs:ValueReference>sf:foo</wfs:ValueReference>" +
" <wfs:Value>2</wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>foo</fes:ValueReference>" +
" <fes:Literal>1</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals( "wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
Element updated = getFirstElementByTagName(dom, "wfs:totalUpdated");
assertEquals( "1", updated.getFirstChild().getNodeValue());
dom = getAsDOM("wfs?request=getfeature&service=wfs&version=2.0.0&typename=sf:WithGMLProperties");
NodeList features = dom.getElementsByTagName("sf:WithGMLProperties");
assertEquals( 1, features.getLength() );
Element feature = (Element) features.item( 0 );
assertEquals( "two", getFirstElementByTagName(feature, "gml:name" ).getFirstChild().getNodeValue());
assertEquals( "2", getFirstElementByTagName(feature, "sf:foo" ).getFirstChild().getNodeValue());
Element location = getFirstElementByTagName( feature, "gml:location" );
Element pos = getFirstElementByTagName(location, "gml:pos");
assertEquals("2 2", pos.getFirstChild().getNodeValue());
xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\" " +
"xmlns:sf=\"http://cite.opengeospatial.org/gmlsf\" " +
"xmlns:wfs='" + WFS.NAMESPACE + "' " +
"xmlns:fes='" + FES.NAMESPACE + "' " +
"xmlns:gml='" + GML.NAMESPACE + "'>" +
" <wfs:Update typeName=\"sf:WithGMLProperties\">" +
" <wfs:Property>" +
" <wfs:ValueReference>sf:name</wfs:ValueReference>" +
" <wfs:Value>trhee</wfs:Value>" +
" </wfs:Property>" +
" <wfs:Property>" +
" <wfs:ValueReference>sf:location</wfs:ValueReference>" +
" <wfs:Value>" +
" <gml:Point>" +
" <gml:coordinates>3,3</gml:coordinates>" +
" </gml:Point>" +
" </wfs:Value>" +
" </wfs:Property>" +
" <wfs:Property>" +
" <wfs:ValueReference>sf:foo</wfs:ValueReference>" +
" <wfs:Value>3</wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>foo</fes:ValueReference>" +
" <fes:Literal>2</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
dom = postAsDOM( "wfs", xml );
assertEquals( "wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
updated = getFirstElementByTagName(dom, "wfs:totalUpdated");
assertEquals( "1", updated.getFirstChild().getNodeValue());
dom = getAsDOM("wfs?request=getfeature&service=wfs&version=2.0.0&typename=sf:WithGMLProperties");
features = dom.getElementsByTagName("sf:WithGMLProperties");
assertEquals( 1, features.getLength() );
feature = (Element) features.item( 0 );
assertEquals( "trhee", getFirstElementByTagName(feature, "gml:name" ).getFirstChild().getNodeValue());
assertEquals( "3", getFirstElementByTagName(feature, "sf:foo" ).getFirstChild().getNodeValue());
location = getFirstElementByTagName( feature, "gml:location" );
pos = getFirstElementByTagName(location, "gml:pos");
assertEquals("3 3", pos.getFirstChild().getNodeValue());
}
@Test
public void testInsertWithBoundedBy() throws Exception {
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite=\"http://www.opengis.net/cite\">"
+ "<wfs:Insert>"
+ " <cite:BasicPolygons>"
+ " <gml:boundedBy>"
+ " <gml:Envelope>"
+ "<gml:lowerCorner>-1.0 2.0</gml:lowerCorner>"
+ "<gml:upperCorner>2.0 5.0</gml:upperCorner>"
+ " </gml:Envelope>"
+ " </gml:boundedBy>"
+ " <cite:the_geom>"
+ " <gml:MultiPolygon>"
+ " <gml:polygonMember>"
+ " <gml:Polygon>"
+ "<gml:exterior>"
+ "<gml:LinearRing>"
+ "<gml:posList>-1.0 5.0 2.0 5.0 2.0 2.0 -1.0 2.0 -1.0 5.0</gml:posList>"
+ "</gml:LinearRing>"
+ "</gml:exterior>"
+ " </gml:Polygon>"
+ " </gml:polygonMember>"
+ " </gml:MultiPolygon>"
+ " </cite:the_geom>"
+ " <cite:ID>foo</cite:ID>"
+ " </cite:BasicPolygons>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM("wfs", xml);
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalInserted").getFirstChild().getNodeValue());
assertTrue(dom.getElementsByTagName("fes:ResourceId").getLength() > 0);
}
@Test
public void testInsert2() throws Exception {
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite=\"http://www.opengis.net/cite\">"
+ "<wfs:Insert>"
+ " <cite:RoadSegments>"
+ " <cite:the_geom>"
+ "<gml:MultiCurve srsName=\"EPSG:4326\">"
+ " <gml:curveMember>"
+ " <gml:LineString>"
+ " <gml:posList>4.2582 52.0643 4.2584 52.0648</gml:posList>"
+ " </gml:LineString>"
+ " </gml:curveMember>"
+ "</gml:MultiCurve>"
+ " </cite:the_geom>"
+ " <cite:FID>foo</cite:FID>"
+ " <cite:NAME>bar</cite:NAME>"
+ " </cite:RoadSegments>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalInserted").getFirstChild().getNodeValue());
dom = getAsDOM( "wfs?version=2.0.0&request=getfeature&typename=cite:RoadSegments&srsName=EPSG:4326&" +
"cql_filter=FID%3D'foo'");
print(dom);
assertEquals( "wfs:FeatureCollection", dom.getDocumentElement().getNodeName() );
assertEquals( 1, dom.getElementsByTagName("cite:RoadSegments").getLength() );
Element roadSegment = getFirstElementByTagName(dom, "cite:RoadSegments" );
Element posList = getFirstElementByTagName( roadSegment, "gml:posList" );
String[] pos = posList.getFirstChild().getTextContent().split( " " );
assertEquals( 4, pos.length );
assertEquals( 4.2582, Double.parseDouble( pos[0] ), 1E-4 );
assertEquals( 52.0643, Double.parseDouble( pos[1] ), 1E-4 );
assertEquals( 4.2584, Double.parseDouble( pos[2] ), 1E-4 );
assertEquals( 52.0648, Double.parseDouble( pos[3] ), 1E-4 );
}
@Test
public void testInsert3() throws Exception {
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite=\"http://www.opengis.net/cite\">"
+ "<wfs:Insert>"
+ " <cite:Buildings>"
+ " <cite:the_geom>" +
"<gml:MultiSurface> " +
" <gml:surfaceMember> " +
" <gml:Polygon> " +
" <gml:exterior> " +
" <gml:LinearRing> " +
" <gml:posList>-123.9 40.0 -124.0 39.9 -124.1 40.0 -124.0 40.1 -123.9 40.0</gml:posList>" +
" </gml:LinearRing> " +
" </gml:exterior> " +
" </gml:Polygon> " +
" </gml:surfaceMember> " +
"</gml:MultiSurface> "
+ " </cite:the_geom>"
+ " <cite:FID>115</cite:FID>"
+ " <cite:ADDRESS>987 Foo St</cite:ADDRESS>"
+ " </cite:Buildings>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalInserted").getFirstChild().getNodeValue());
dom = getAsDOM( "wfs?version=2.0.0&request=getfeature&typename=cite:Buildings&srsName=EPSG:4326&" +
"cql_filter=FID%3D'115'");
assertEquals( "wfs:FeatureCollection", dom.getDocumentElement().getNodeName() );
assertEquals( 1, dom.getElementsByTagName("cite:Buildings").getLength() );
XMLAssert.assertXpathExists("//gml:Polygon",dom);
Element posList = getFirstElementByTagName( dom.getDocumentElement(), "gml:posList" );
String[] pos = posList.getFirstChild().getTextContent().split( " " );
assertEquals( 10, pos.length );
assertEquals( -123.9, Double.parseDouble( pos[0] ), 1E-1 );
assertEquals( 40.0, Double.parseDouble( pos[1] ), 1E-1 );
assertEquals( -124.0, Double.parseDouble( pos[2] ), 1E-1 );
assertEquals( 39.9, Double.parseDouble( pos[3] ), 1E-1 );
assertEquals( -124.1, Double.parseDouble( pos[4] ), 1E-1 );
assertEquals( 40.0, Double.parseDouble( pos[5] ), 1E-1 );
assertEquals( -124.0, Double.parseDouble( pos[6] ), 1E-1 );
assertEquals( 40.1, Double.parseDouble( pos[7] ), 1E-1 );
assertEquals( -123.9, Double.parseDouble( pos[8] ), 1E-1 );
assertEquals( 40.0, Double.parseDouble( pos[9] ), 1E-1 );
}
@Test
public void testUpdateForcedSRS() throws Exception {
testUpdate("srsName=\"EPSG:4326\"");
}
@Test
public void testUpdateNoSRS() throws Exception {
testUpdate("");
}
private void testUpdate(String srs) throws Exception {
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\" " +
"xmlns:cite=\"http://www.opengis.net/cite\" " +
"xmlns:fes='" + FES.NAMESPACE + "' " +
"xmlns:wfs='" + WFS.NAMESPACE + "' " +
"xmlns:gml='" + GML.NAMESPACE + "'>" +
" <wfs:Update typeName=\"cite:RoadSegments\">" +
" <wfs:Property>" +
" <wfs:ValueReference>cite:the_geom</wfs:ValueReference>" +
" <wfs:Value>" +
" <gml:MultiCurve " + srs + ">" +
" <gml:curveMember>" +
" <gml:LineString>" +
" <gml:posList>4.2582 52.0643 4.2584 52.0648</gml:posList>" +
" </gml:LineString>" +
" </gml:curveMember>" +
" </gml:MultiCurve>" +
" </wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>FID</fes:ValueReference>" +
" <fes:Literal>102</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalUpdated").getFirstChild().getNodeValue());
String srsBlock = "".equals(srs) ? "" : "&" + srs.replaceAll("\"", "");
dom = getAsDOM( "wfs?version=2.0.0&request=getfeature&typename=cite:RoadSegments" + srsBlock + "&" +
"cql_filter=FID%3D'102'");
assertEquals( "wfs:FeatureCollection", dom.getDocumentElement().getNodeName() );
assertEquals( 1, dom.getElementsByTagName("cite:RoadSegments").getLength() );
Element roadSegment = getFirstElementByTagName(dom, "cite:RoadSegments" );
Element posList = getFirstElementByTagName( roadSegment, "gml:posList" );
String[] pos = posList.getFirstChild().getTextContent().split( " " );
assertEquals( 4, pos.length );
assertEquals( 4.2582, Double.parseDouble( pos[0] ), 1E-4 );
assertEquals( 52.0643, Double.parseDouble( pos[1] ), 1E-4 );
assertEquals( 4.2584, Double.parseDouble( pos[2] ), 1E-4 );
assertEquals( 52.0648, Double.parseDouble( pos[3] ), 1E-4 );
}
@Test
public void testUpdateWithInvalidProperty() throws Exception {
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\"" +
" xmlns:cite=\"http://www.opengis.net/cite\"" +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "' " +
" xmlns:gml='" + GML.NAMESPACE + "'>" +
" <wfs:Update typeName=\"cite:RoadSegments\">" +
" <wfs:Property>" +
" <wfs:ValueReference>INVALID</wfs:ValueReference>" +
" <wfs:Value>INVALID</wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>FID</fes:ValueReference>" +
" <fes:Literal>102</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals("ows:ExceptionReport", dom.getDocumentElement().getNodeName());
}
@Test
public void testInsertLayerQualified() throws Exception {
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\" "
+ " xmlns:fes='" + FES.NAMESPACE + "' "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite=\"http://www.opengis.net/cite\">"
+ "<wfs:Insert>"
+ " <cite:RoadSegments>"
+ " <cite:the_geom>"
+ "<gml:MultiCurve xmlns:gml=\"http://www.opengis.net/gml\""
+ " srsName=\"EPSG:4326\">"
+ " <gml:curveMember>"
+ " <gml:LineString>"
+ " <gml:posList>4.2582 52.0643 4.2584 52.0648</gml:posList>"
+ " </gml:LineString>"
+ " </gml:curveMember>"
+ " </gml:MultiCurve>"
+ " </cite:the_geom>"
+ " <cite:FID>foo</cite:FID>"
+ " <cite:NAME>bar</cite:NAME>"
+ " </cite:RoadSegments>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM( "cite/Forests/wfs", xml );
XMLAssert.assertXpathEvaluatesTo("1", "count(//ows:ExceptionReport)", dom);
dom = postAsDOM( "cite/RoadSegments/wfs", xml );
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalInserted").getFirstChild().getNodeValue());
}
@Test
public void testUpdateLayerQualified() throws Exception {
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\""
+ " xmlns:fes='" + FES.NAMESPACE + "' "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite=\"http://www.opengis.net/cite\">" +
" <wfs:Update typeName=\"RoadSegments\">" +
" <wfs:Property>" +
" <wfs:ValueReference>cite:the_geom</wfs:ValueReference>" +
" <wfs:Value>" +
" <gml:MultiCurve xmlns:gml=\"http://www.opengis.net/gml\">" +
" <gml:curveMember>" +
" <gml:LineString>" +
" <gml:posList>4.2582 52.0643 4.2584 52.0648</gml:posList>" +
" </gml:LineString>" +
" </gml:curveMember>" +
" </gml:MultiCurve>" +
" </wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>FID</fes:ValueReference>" +
" <fes:Literal>102</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
Document dom = postAsDOM( "cite/Forests/wfs", xml );
XMLAssert.assertXpathEvaluatesTo("1", "count(//ows:ExceptionReport)", dom);
dom = postAsDOM("cite/RoadSegments/wfs", xml);
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
assertEquals( "1", getFirstElementByTagName(dom, "wfs:totalUpdated").getFirstChild().getNodeValue());
}
@Test
public void testUpdateWithDifferentPrefix() throws Exception {
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\"" +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "' " +
" xmlns:gml='" + GML.NAMESPACE + "'>" +
" <wfs:Update xmlns:foo=\"http://www.opengis.net/cite\" typeName=\"foo:RoadSegments\">" +
" <wfs:Property>" +
" <wfs:ValueReference>foo:the_geom</wfs:ValueReference>" +
" <wfs:Value>" +
" </wfs:Value>" +
" </wfs:Property>" +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>FID</fes:ValueReference>" +
" <fes:Literal>102</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Update>" +
"</wfs:Transaction>";
Document dom = postAsDOM( "wfs", xml );
assertEquals( "wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
Element updated = getFirstElementByTagName(dom, "wfs:totalUpdated");
assertEquals( "1", updated.getFirstChild().getNodeValue());
}
@Test
public void testReplace() throws Exception {
Document dom = getAsDOM("wfs?service=wfs&version=2.0.0&request=getfeature&typename=cite:RoadSegments" +
"&cql_filter=FID+EQ+'102'");
XMLAssert.assertXpathExists("//cite:RoadSegments/cite:FID[text() = '102']", dom);
String xml =
"<wfs:Transaction service=\"WFS\" version=\"2.0.0\"" +
" xmlns:fes='" + FES.NAMESPACE + "' " +
" xmlns:wfs='" + WFS.NAMESPACE + "' " +
" xmlns:gml='" + GML.NAMESPACE + "' " +
" xmlns:cite='http://www.opengis.net/cite'>" +
" <wfs:Replace>" +
" <cite:RoadSegments gml:id='RoadSegments.1107532045088'> " +
" <cite:the_geom> " +
" <gml:MultiCurve srsDimension='2' srsName='urn:x-ogc:def:crs:EPSG:4326'> " +
" <gml:curveMember> " +
" <gml:LineString> " +
" <gml:posList>1 2 3 5 6 7</gml:posList> " +
" </gml:LineString> " +
" </gml:curveMember> " +
" </gml:MultiCurve> " +
" </cite:the_geom> " +
" <cite:FID>1234</cite:FID> " +
" <cite:NAME>Route 1234</cite:NAME> " +
" </cite:RoadSegments> " +
" <fes:Filter>" +
" <fes:PropertyIsEqualTo>" +
" <fes:ValueReference>FID</fes:ValueReference>" +
" <fes:Literal>102</fes:Literal>" +
" </fes:PropertyIsEqualTo>" +
" </fes:Filter>" +
" </wfs:Replace>" +
"</wfs:Transaction>";
dom = postAsDOM("wfs", xml);
assertEquals("wfs:TransactionResponse", dom.getDocumentElement().getNodeName());
XMLAssert.assertXpathExists("//wfs:totalReplaced[text() = 1]", dom);
XMLAssert.assertXpathExists("//wfs:ReplaceResults/wfs:Feature/fes:ResourceId", dom);
dom = getAsDOM("wfs?service=wfs&version=2.0.0&request=getfeature&typename=cite:RoadSegments" +
"&cql_filter=FID+EQ+'102'");
XMLAssert.assertXpathNotExists("//cite:RoadSegments/cite:FID[text() = '102']", dom);
dom = getAsDOM("wfs?service=wfs&version=2.0.0&request=getfeature&typename=cite:RoadSegments" +
"&cql_filter=FID+EQ+'1234'");
XMLAssert.assertXpathExists("//cite:RoadSegments/cite:FID[text() = '1234']", dom);
}
@Test
public void testSOAP() throws Exception {
String xml =
"<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'> " +
" <soap:Header/> " +
" <soap:Body>"
+ "<wfs:Transaction service='WFS' version='2.0.0' "
+ "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
+ "xmlns:fes='" + FES.NAMESPACE + "' "
+ "xmlns:wfs='" + WFS.NAMESPACE + "' "
+ "xmlns:gml='" + GML.NAMESPACE + "'> "
+ "<wfs:Insert > "
+ "<cgf:Points>"
+ "<cgf:pointProperty>"
+ "<gml:Point>"
+ "<gml:pos>20 40</gml:pos>"
+ "</gml:Point>"
+ "</cgf:pointProperty>"
+ "<cgf:id>t0002</cgf:id>"
+ "</cgf:Points>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>" +
" </soap:Body> " +
"</soap:Envelope> ";
MockHttpServletResponse resp = postAsServletResponse("wfs", xml, "application/soap+xml");
assertEquals("application/soap+xml", resp.getContentType());
Document dom = dom(new ByteArrayInputStream(resp.getContentAsString().getBytes()));
assertEquals("soap:Envelope", dom.getDocumentElement().getNodeName());
assertEquals(1, dom.getElementsByTagName("wfs:TransactionResponse").getLength());
}
@Test
public void elementHandlerOrder() throws Exception {
Catalog cat = getCatalog();
DataStoreInfo ds = cat.getFactory().createDataStore();
ds.setName("foo");
ds.setWorkspace(cat.getDefaultWorkspace());
ds.setEnabled(true);
Map params = ds.getConnectionParameters();
params.put("dbtype", "h2");
params.put("database", getTestData().getDataDirectoryRoot().getAbsolutePath());
cat.add(ds);
DataStore store = (DataStore) ds.getDataStore(null);
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setName("bar");
tb.add("name", String.class);
tb.add("geom", Point.class);
store.createSchema(tb.buildFeatureType());
CatalogBuilder cb = new CatalogBuilder(cat);
cb.setStore(ds);
SimpleFeatureStore fs = (SimpleFeatureStore) store.getFeatureSource("bar");
FeatureTypeInfo ft = cb.buildFeatureType(fs);
cat.add(ft);
String xml = "<wfs:Transaction service=\"WFS\" version=\"2.0.0\""
+ " xmlns:fes='" + FES.NAMESPACE + "' "
+ " xmlns:wfs='" + WFS.NAMESPACE + "' "
+ " xmlns:gml='" + GML.NAMESPACE + "' "
+ " xmlns:cite='http://www.opengis.net/cite'"
+ " xmlns:gs='" + SystemTestData.DEFAULT_URI + "'>"
+ "<wfs:Insert idgen='UseExisting'>"
+ " <gs:bar gml:id='1'>"
+ " <gs:name>acme</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='2'>"
+ " <gs:name>wiley</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='3'>"
+ " <gs:name>bugs</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='4'>"
+ " <gs:name>roadrunner</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='5'>"
+ " <gs:name>daffy</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='6'>"
+ " <gs:name>elmer</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='7'>"
+ " <gs:name>tweety</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='8'>"
+ " <gs:name>sylvester</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='9'>"
+ " <gs:name>marvin</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='10'>"
+ " <gs:name>yosemite</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='11'>"
+ " <gs:name>porky</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='12'>"
+ " <gs:name>speedy</gs:name>"
+ " </gs:bar>"
+ " <gs:bar gml:id='13'>"
+ " <gs:name>taz</gs:name>"
+ " </gs:bar>"
+ "</wfs:Insert>"
+ "</wfs:Transaction>";
Document dom = postAsDOM("wfs", xml);
dom = getAsDOM("wfs?request=GetFeature&service=wfs&version=2.0.0&typeNames=gs:bar");
NodeList elementsByTagName = dom.getElementsByTagName("gs:bar");
for (int i=1; i<=elementsByTagName.getLength(); i++) {
String id = elementsByTagName.item(i-1).getAttributes().item(0).getNodeValue();
assertEquals("bar."+i, id );
}
dom = getAsDOM("wfs?request=GetFeature&version=2.0.0&service=wfs&typeNames=gs:bar&featureId=bar.5");
XMLAssert.assertXpathEvaluatesTo("daffy", "//gml:name/text()", dom);
}
}