001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.wfs;
017:
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.net.ConnectException;
021: import java.net.MalformedURLException;
022: import java.net.NoRouteToHostException;
023: import java.net.URL;
024: import java.net.UnknownHostException;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.Map;
029: import java.util.NoSuchElementException;
030: import java.util.Set;
031: import java.util.logging.Level;
032: import java.util.logging.Logger;
033:
034: import junit.framework.TestCase;
035:
036: import org.geotools.data.DataStore;
037: import org.geotools.data.DataUtilities;
038: import org.geotools.data.DefaultQuery;
039: import org.geotools.data.DefaultTransaction;
040: import org.geotools.data.FeatureEvent;
041: import org.geotools.data.FeatureListener;
042: import org.geotools.data.FeatureReader;
043: import org.geotools.data.FeatureSource;
044: import org.geotools.data.FeatureStore;
045: import org.geotools.data.Query;
046: import org.geotools.data.Transaction;
047: import org.geotools.factory.CommonFactoryFinder;
048: import org.geotools.factory.GeoTools;
049: import org.geotools.feature.Feature;
050: import org.geotools.feature.FeatureCollection;
051: import org.geotools.feature.FeatureIterator;
052: import org.geotools.feature.FeatureType;
053: import org.geotools.feature.IllegalAttributeException;
054: import org.geotools.filter.IllegalFilterException;
055: import org.opengis.filter.Filter;
056: import org.opengis.filter.FilterFactory2;
057: import org.opengis.filter.Id;
058: import org.opengis.filter.PropertyIsNull;
059: import org.opengis.filter.expression.PropertyName;
060: import org.opengis.filter.identity.FeatureId;
061: import org.xml.sax.SAXException;
062:
063: import com.vividsolutions.jts.geom.Coordinate;
064: import com.vividsolutions.jts.geom.Envelope;
065: import com.vividsolutions.jts.geom.GeometryFactory;
066: import com.vividsolutions.jts.geom.LinearRing;
067: import com.vividsolutions.jts.geom.MultiPolygon;
068: import com.vividsolutions.jts.geom.Polygon;
069:
070: public class GeoServerOnlineTest extends TestCase {
071:
072: public static final String SERVER_URL = "http://localhost:8080/geoserver/wfs?REQUEST=GetCapabilities";
073: public static final String TO_EDIT_TYPE = "topp:states";
074: public static final String ATTRIBUTE_TO_EDIT = "STATE_FIPS";
075: public static final String NEW_EDIT_VALUE = "newN";
076: private static final int EPSG_CODE = 4326;
077: private URL url = null;
078:
079: public void setUp() throws MalformedURLException {
080: url = new URL(SERVER_URL);
081: if (url != null && url.toString().indexOf("localhost") != -1) {
082: InputStream stream = null;
083: try {
084: stream = url.openStream();
085: } catch (Throwable t) {
086: System.err
087: .println("Warning you local geoserver is not available - "
088: + getName() + " test disabled ");
089: url = null;
090: } finally {
091: if (stream != null)
092: try {
093: stream.close();
094: } catch (IOException e) {
095: // whatever
096: }
097: }
098: }
099: }
100:
101: public void testTypes() throws IOException, NoSuchElementException {
102: if (url == null)
103: return;
104: WFSDataStore wfs;
105: try {
106: wfs = WFSDataStoreReadTest.getDataStore(url);
107: } catch (ConnectException e) {
108: e.printStackTrace(System.err);
109: return;
110: } catch (UnknownHostException e) {
111: e.printStackTrace(System.err);
112: return;
113: } catch (NoRouteToHostException e) {
114: e.printStackTrace(System.err);
115: return;
116: }
117: String types[] = wfs.getTypeNames();
118: String typeName = "unknown";
119: for (int i = 0; i < types.length; i++) {
120: typeName = types[i];
121: if (typeName.equals("topp:geometrytype"))
122: continue;
123: FeatureType type = wfs.getSchema(typeName);
124: type.getTypeName();
125: type.getNamespace();
126:
127: FeatureSource source = wfs.getFeatureSource(typeName);
128: source.getBounds();
129:
130: FeatureCollection features = source.getFeatures();
131: features.getBounds();
132: features.getSchema();
133: features.getFeatureType();
134:
135: DefaultQuery query = new DefaultQuery(typeName,
136: Filter.INCLUDE, 20, Query.ALL_NAMES, "work already");
137: features = source.getFeatures(query);
138: features.size();
139: Iterator reader = features.iterator();
140: while (reader.hasNext()) {
141: Feature feature = (Feature) reader.next();
142: }
143: features.close(reader);
144:
145: FeatureIterator iterator = features.features();
146: while (iterator.hasNext()) {
147: Feature feature = iterator.next();
148: }
149: features.close(iterator);
150: }
151: }
152:
153: public void testSingleType() throws IOException,
154: NoSuchElementException {
155: WFSDataStore wfs;
156: try {
157: wfs = WFSDataStoreReadTest.getDataStore(url);
158: } catch (ConnectException e) {
159: e.printStackTrace(System.err);
160: return;
161: } catch (UnknownHostException e) {
162: e.printStackTrace(System.err);
163: return;
164: } catch (NoRouteToHostException e) {
165: e.printStackTrace(System.err);
166: return;
167: }
168: String typeName = "tiger:poi";
169: FeatureType type = wfs.getSchema(typeName);
170: type.getTypeName();
171: type.getNamespace();
172:
173: FeatureSource source = wfs.getFeatureSource(typeName);
174: source.getBounds();
175:
176: FeatureCollection features = source.getFeatures();
177: features.getBounds();
178: features.getSchema();
179: features.getFeatureType();
180:
181: DefaultQuery query = new DefaultQuery(typeName, Filter.INCLUDE,
182: 20, Query.ALL_NAMES, "work already");
183: features = source.getFeatures(query);
184: features.size();
185:
186: Iterator reader = features.iterator();
187: while (reader.hasNext()) {
188: Feature feature = (Feature) reader.next();
189: System.out.println(feature);
190: }
191: features.close(reader);
192:
193: FeatureIterator iterator = features.features();
194: while (iterator.hasNext()) {
195: Feature feature = iterator.next();
196: }
197: features.close(iterator);
198: }
199:
200: public void testFeatureType() throws NoSuchElementException,
201: IOException, SAXException {
202:
203: WFSDataStoreReadTest.doFeatureType(url, true, true, 0);
204: }
205:
206: public void testFeatureReader() throws NoSuchElementException,
207: IOException, IllegalAttributeException, SAXException {
208: WFSDataStoreReadTest.doFeatureReader(url, true, true, 0);
209: }
210:
211: public void testFeatureReaderWithFilter()
212: throws NoSuchElementException, IllegalAttributeException,
213: IOException, SAXException {
214: WFSDataStoreReadTest.doFeatureReaderWithQuery(url, true, true,
215: 0);
216: }
217:
218: public void testFeatureReaderWithFilterGET()
219: throws NoSuchElementException, IllegalAttributeException,
220: IOException, SAXException {
221: WFSDataStoreReadTest.doFeatureReaderWithQuery(url, true, false,
222: 0);
223: }
224:
225: public void testFeatureReaderWithFilterPOST()
226: throws NoSuchElementException, IllegalAttributeException,
227: IOException, SAXException {
228: WFSDataStoreReadTest.doFeatureReaderWithQuery(url, false, true,
229: 0);
230: }
231:
232: // RR change the data?
233: // NOPE, it's in Lat-Long for the Env, BCAlbers for the data
234: public void testFeatureReaderWithFilterBBoxGET()
235: throws NoSuchElementException, IllegalAttributeException,
236: IOException, SAXException, IllegalFilterException {
237: // minx,miny,maxx,maxy
238:
239: Map m = new HashMap();
240: m.put(WFSDataStoreFactory.URL.key, url);
241: m.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(100000));
242: DataStore post = (WFSDataStore) (new WFSDataStoreFactory())
243: .createNewDataStore(m);
244:
245: Envelope bbox = post.getFeatureSource(post.getTypeNames()[0])
246: .getBounds();
247: WFSDataStoreReadTest.doFeatureReaderWithBBox(url, true, false,
248: 0, bbox);
249: }
250:
251: public void testFeatureReaderWithFilterBBoxPOST()
252: throws NoSuchElementException, IllegalAttributeException,
253: IOException, SAXException, IllegalFilterException {
254:
255: Map m = new HashMap();
256: m.put(WFSDataStoreFactory.URL.key, url);
257: m.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(100000));
258: DataStore post = (WFSDataStore) (new WFSDataStoreFactory())
259: .createNewDataStore(m);
260:
261: Envelope bbox = post.getFeatureSource(post.getTypeNames()[0])
262: .getBounds();
263:
264: WFSDataStoreReadTest.doFeatureReaderWithBBox(url, true, false,
265: 0, bbox);
266: }
267:
268: /**
269: * Tests case where filter is makes use of 2 different attributes but Query object only requests 1 of the two
270: * attributes. This is a fix for a bug that has occurred.
271: */
272: public void testFeatureReaderWithQuery() throws Exception {
273: Map m = new HashMap();
274: m.put(WFSDataStoreFactory.URL.key, url);
275: m.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(100000));
276: WFSDataStore wfs = (WFSDataStore) (new WFSDataStoreFactory())
277: .createNewDataStore(m);
278: FilterFactory2 fac = CommonFactoryFinder
279: .getFilterFactory2(GeoTools.getDefaultHints());
280:
281: Filter filter = fac.equals(fac.property("NAME"), fac
282: .literal("E 58th St"));
283:
284: Query query = new DefaultQuery("tiger:tiger_roads", filter);
285: FeatureReader reader = wfs.getFeatureReader(query,
286: new DefaultTransaction());
287: int expected = 0;
288: while (reader.hasNext()) {
289: expected++;
290: reader.next();
291: }
292: query = new DefaultQuery("tiger:tiger_roads", filter, 100,
293: new String[] { "CFCC" }, "");
294: reader = wfs.getFeatureReader(query, new DefaultTransaction());
295: int count = 0;
296: while (reader.hasNext()) {
297: count++;
298: reader.next();
299: }
300:
301: assertEquals(expected, count);
302: }
303:
304: /**
305: * Writing test that only engages against a remote geoserver.
306: * <p>
307: * Makes reference to the standard featureTypes that geoserver ships with.
308: * </p>
309: */
310: public void testWrite() throws NoSuchElementException,
311: IllegalFilterException, IOException,
312: IllegalAttributeException {
313:
314: Map m = new HashMap();
315: m.put(WFSDataStoreFactory.URL.key, url);
316: m.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(10000000));
317: DataStore post = (WFSDataStore) (new WFSDataStoreFactory())
318: .createNewDataStore(m);
319: String typename = TO_EDIT_TYPE;
320: FeatureType ft = post.getSchema(typename);
321: FeatureSource fs = post.getFeatureSource(typename);
322: class Watcher implements FeatureListener {
323: public int count = 0;
324:
325: public void changed(FeatureEvent featureEvent) {
326: System.out.println("Event " + featureEvent);
327: count++;
328: }
329: }
330: Watcher watcher = new Watcher();
331: fs.addFeatureListener(watcher);
332:
333: Id startingFeatures = createFidFilter(fs);
334: FilterFactory2 filterFac = CommonFactoryFinder
335: .getFilterFactory2(GeoTools.getDefaultHints());
336: try {
337: GeometryFactory gf = new GeometryFactory();
338: MultiPolygon mp = gf.createMultiPolygon(new Polygon[] { gf
339: .createPolygon(
340: gf
341: .createLinearRing(new Coordinate[] {
342: new Coordinate(-88.071564,
343: 37.51099),
344: new Coordinate(-88.467644,
345: 37.400757),
346: new Coordinate(-90.638329,
347: 42.509361),
348: new Coordinate(-89.834618,
349: 42.50346),
350: new Coordinate(-88.071564,
351: 37.51099) }),
352: new LinearRing[] {}) });
353: mp.setUserData("http://www.opengis.net/gml/srs/epsg.xml#"
354: + EPSG_CODE);
355:
356: PropertyName geometryAttributeExpression = filterFac
357: .property(ft.getDefaultGeometry().getName());
358: PropertyIsNull geomNullCheck = filterFac
359: .isNull(geometryAttributeExpression);
360: Query query = new DefaultQuery(typename, filterFac
361: .not(geomNullCheck), 1, Query.ALL_NAMES, null);
362: FeatureIterator inStore = fs.getFeatures(query).features();
363:
364: Feature f, f2;
365: try {
366: Feature feature = inStore.next();
367: f = ft.create(ft.duplicate(feature).getAttributes(
368: new Object[ft.getAttributeCount()]));
369: f2 = ft.create(ft.duplicate(feature).getAttributes(
370: new Object[ft.getAttributeCount()]));
371: assertFalse("Max Feature failed", inStore.hasNext());
372: } finally {
373: inStore.close();
374: }
375:
376: org.geotools.util.logging.Logging.getLogger(
377: "org.geotools.data.wfs").setLevel(Level.FINE);
378: FeatureCollection inserts = DataUtilities
379: .collection(new Feature[] { f, f2 });
380: Id fp = WFSDataStoreWriteOnlineTest.doInsert(post, ft,
381: inserts);
382:
383: /// okay now count ...
384: FeatureReader count = post.getFeatureReader(
385: new DefaultQuery(ft.getTypeName()),
386: Transaction.AUTO_COMMIT);
387: int i = 0;
388: while (count.hasNext() && i < 3) {
389: f = count.next();
390: i++;
391: }
392: count.close();
393:
394: WFSDataStoreWriteOnlineTest.doDelete(post, ft, fp);
395: WFSDataStoreWriteOnlineTest.doUpdate(post, ft,
396: ATTRIBUTE_TO_EDIT, NEW_EDIT_VALUE);
397: // assertFalse("events not fired", watcher.count == 0);
398: } finally {
399: try {
400: ((FeatureStore) fs).removeFeatures(filterFac
401: .not(startingFeatures));
402: } catch (Exception e) {
403: System.out.println(e);
404: }
405: }
406: }
407:
408: private Id createFidFilter(FeatureSource fs) throws IOException {
409: FeatureIterator iter = fs.getFeatures().features();
410: FilterFactory2 ffac = CommonFactoryFinder
411: .getFilterFactory2(GeoTools.getDefaultHints());
412: Set fids = new HashSet();
413: try {
414: while (iter.hasNext()) {
415: String id = iter.next().getID();
416: FeatureId fid = ffac.featureId(id);
417: fids.add(fid);
418: }
419: Id filter = ffac.id(fids);
420: return filter;
421: } finally {
422: iter.close();
423: }
424: }
425: }
|