001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, 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;
009: * version 2.1 of the License.
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: */
017: package org.geotools.data.geometryless;
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.io.InputStreamReader;
022: import java.sql.Connection;
023: import java.sql.PreparedStatement;
024: import java.sql.SQLException;
025: import java.sql.Statement;
026: import java.util.HashMap;
027: import java.util.NoSuchElementException;
028: import java.util.PropertyResourceBundle;
029: import java.util.logging.Level;
030: import java.util.logging.Logger;
031:
032: import javax.sql.DataSource;
033:
034: import junit.framework.Test;
035: import junit.framework.TestCase;
036: import junit.framework.TestSuite;
037:
038: import org.geotools.data.FeatureReader;
039: import org.geotools.data.FeatureWriter;
040: import org.geotools.data.SchemaNotFoundException;
041: import org.geotools.data.Transaction;
042: import org.geotools.data.jdbc.ConnectionPool;
043: import org.geotools.data.jdbc.ConnectionPoolManager;
044: import org.geotools.data.jdbc.datasource.DataSourceUtil;
045: import org.geotools.data.jdbc.fidmapper.BasicFIDMapper;
046: import org.geotools.data.jdbc.fidmapper.TypedFIDMapper;
047: import org.geotools.feature.FeatureType;
048: import org.geotools.feature.IllegalAttributeException; //import org.geotools.filter.CompareFilter;
049: import org.opengis.filter.PropertyIsEqualTo;
050: import org.opengis.filter.expression.Expression;
051: import org.opengis.filter.Filter;
052: import org.opengis.filter.FilterFactory;
053: import org.geotools.factory.CommonFactoryFinder;
054: import org.geotools.filter.IllegalFilterException;
055:
056: import com.vividsolutions.jts.geom.Coordinate;
057: import com.vividsolutions.jts.geom.GeometryFactory;
058: import com.vividsolutions.jts.geom.LinearRing;
059: import com.vividsolutions.jts.geom.MultiPolygon;
060: import com.vividsolutions.jts.geom.Polygon;
061:
062: /**
063: * Test for Geometryless generic JDBC Data store. Must use a locally available instance of JDBC database.
064: *
065: * @author Rob Atkinson
066: * @author Chris Holmes, TOPP
067: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/geometryless/src/test/java/org/geotools/data/geometryless/JDBCDataStoreTest.java $
068: */
069: public class JDBCDataStoreTest extends TestCase {
070: /** The logger for the filter module. */
071: private static final Logger LOGGER = org.geotools.util.logging.Logging
072: .getLogger("org.geotools.data.geometryless");
073: private static String FEATURE_TABLE = "testset";
074: private static String TEST_NS = "http://www.geotools.org/data/postgis";
075: //private static GeometryFactory geomFac = new GeometryFactory();
076: private FilterFactory filterFac = CommonFactoryFinder
077: .getFilterFactory(null);
078:
079: //private FeatureCollection collection = FeatureCollections.newCollection();
080: private FeatureType schema;
081: //private int srid = -1;
082: private JDBCConnectionFactory connFactory;
083: private JDBCDataStore dstore;
084: // private ConnectionPool connPool;
085: //private PropertyIsEqualTo tFilter;
086: private int addId = 32;
087:
088: // private org.geotools.filter.GeometryFilter geomFilter;
089:
090: public JDBCDataStoreTest(String testName) {
091: super (testName);
092: }
093:
094: public static void main(String[] args) {
095: junit.textui.TestRunner.run(suite());
096: }
097:
098: public static Test suite() {
099: LOGGER.info("starting suite...");
100:
101: TestSuite suite = new TestSuite(JDBCDataStoreTest.class);
102: LOGGER.info("made suite...");
103:
104: return suite;
105: }
106:
107: protected void setUp() throws Exception {
108:
109: HashMap local = new HashMap();
110: local.put("dbtype", "jdbc");
111:
112: PropertyResourceBundle resource = new PropertyResourceBundle(
113: this .getClass().getResourceAsStream(
114: "fixture.properties"));
115:
116: String namespace = resource.getString("namespace");
117: String user = resource.getString("user");
118: local.put("user", user);
119: String password = resource.getString("password");
120: local.put("passwd", password);
121:
122: String dbschema = resource.getString("schema");
123: local.put("schema", dbschema);
124:
125: String driver = resource.getString("driver");
126: local.put("driver", driver);
127:
128: String urlprefix = resource.getString("urlprefix");
129: local.put("urlprefix", urlprefix);
130:
131: if (namespace.equals("http://www.geotools.org/data/postgis")) {
132: throw new IllegalStateException(
133: "The fixture.properties file needs to be configured for your own database");
134: }
135:
136: /* connFactory = new JDBCConnectionFactory(urlprefix, Driver);
137:
138: //connFactory = new PostgisConnectionFactory("localhost", "5432",
139: // "testdb");
140: //LOGGER.info("created new db connection");
141: connFactory.setLogin(user, password);
142:
143: //LOGGER.info("set the login");
144: //LOGGER.info("created new datasource");
145: */
146: try {
147: LOGGER.fine("getting data source");
148: DataSource dataSource = DataSourceUtil
149: .buildDefaultDataSource(urlprefix, driver, user,
150: password, null);
151:
152: /* connPool = connFactory.getConnectionPool();
153: */
154: setupTestTable(dataSource.getConnection());
155: dstore = new JDBCDataStore(dataSource, dbschema, TEST_NS);
156:
157: dstore.setFIDMapper("testset", new TypedFIDMapper(
158: new BasicFIDMapper("gid", 255, true), "testset"));
159:
160: //LOGGER.fine("about to create ds");
161: //postgis = new PostgisDataSource(connection, FEATURE_TABLE);
162: //LOGGER.fine("created de");
163: schema = dstore.getSchema(FEATURE_TABLE);
164: } catch (Exception e) {
165: LOGGER.log(Level.INFO, "exception while making schema", e);
166: }
167: }
168:
169: /**
170: * @param connection
171: */
172: private void setupTestTable(Connection conn) throws IOException,
173: SQLException {
174: // gid;int4;4;0;;YES;;
175: // area;float8;8;0;;YES;;
176: // perimeter;float8;8;0;;YES;;
177: // testb_;int4;4;0;;YES;;
178: // testb_id;int4;4;0;;YES;;
179: // name;varchar;0;0;;YES;;
180: // pcedflag;int4;4;0;;YES;;
181: // dbdflag;int4;4;0;;YES;;
182: // the_geom;geometry;-1;0;;YES;;
183:
184: Statement st = null;
185: try {
186: st = conn.createStatement();
187: st.execute("DROP TABLE testset");
188:
189: } catch (Exception e) {
190:
191: } finally {
192: if (st != null)
193: st.close();
194: }
195:
196: st = conn.createStatement();
197: st
198: .execute("CREATE TABLE testset ( gid integer, area float, perimeter float, testb_ integer, "
199: + " testb_id integer, name varchar(255), pcedflag integer, dbdflag integer, x float, y float)");
200: st.close();
201: PreparedStatement ps = conn
202: .prepareStatement("INSERT into testset values(?, ?, ?, ?, ?, ?, ?, ?, ?,?)");
203: BufferedReader reader = new BufferedReader(
204: new InputStreamReader(this .getClass()
205: .getResourceAsStream("testdata.txt")));
206:
207: try {
208:
209: String line = null;
210: while ((line = reader.readLine()) != null) {
211: String[] values = line.split(";");
212: ps.setInt(1, Integer.parseInt(values[0]));
213: ps.setDouble(2, Double.parseDouble(values[1]));
214: ps.setDouble(3, Double.parseDouble(values[2]));
215: ps.setInt(4, Integer.parseInt(values[3]));
216: ps.setInt(5, Integer.parseInt(values[4]));
217: ps.setString(6, values[5]);
218: ps.setInt(7, Integer.parseInt(values[6]));
219: ps.setInt(8, Integer.parseInt(values[7]));
220: ps.setDouble(9, Double.parseDouble(values[8]));
221: ps.setDouble(10, Double.parseDouble(values[9]));
222: ps.execute();
223: }
224: } finally {
225: reader.close();
226: ps.close();
227: }
228: }
229:
230: protected void tearDown() {
231: try {
232: // dropTestTable(connPool.getConnection());
233: } catch (Exception e) {
234: } finally {
235: ConnectionPoolManager.getInstance().closeAll();
236: }
237: }
238:
239: public void dropTestTable(Connection conn) throws SQLException {
240: Statement st = conn.createStatement();
241: st.execute("DROP TABLE testset");
242: st.close();
243: }
244:
245: //todo assert on schema.
246: public void testFeatureTypes() throws Exception {
247: String[] types = dstore.getTypeNames();
248: FeatureType schema1 = dstore.getSchema(types[0]);
249:
250: //FeatureType schema2 = dstore.getSchema(types[1]);
251: //need to figure out spatial_ref_system and geometry_columns
252: LOGGER.fine("first schemas are: \n" + schema1); // + "\n" + schema2);
253:
254: try {
255: String badSchema = "bad-schema23";
256: dstore.getSchema(badSchema);
257: fail("should not have schema " + badSchema);
258: } catch (SchemaNotFoundException e) {
259: LOGGER.fine("succesfully caught exception: " + e);
260:
261: //catch the proper exception
262: }
263: }
264:
265: //tests todo: bad retyping. post filters.
266: public void testGetReader() throws Exception {
267: String testTable = FEATURE_TABLE;
268: LOGGER.fine("testTable " + testTable + " has schema "
269: + dstore.getSchema(testTable));
270:
271: FeatureReader reader = dstore.getFeatureReader(schema,
272: Filter.INCLUDE, Transaction.AUTO_COMMIT);
273: int numFeatures = count(reader);
274: assertEquals("Number of features off:", 6, numFeatures);
275: }
276:
277: public void testFilter() throws Exception {
278: PropertyIsEqualTo test1 = null;
279:
280: try {
281: Integer testInt = new Integer(0);
282: Expression testLiteral = filterFac.literal(testInt);
283: Expression testProperty = filterFac.property("pcedflag");
284: test1 = filterFac.equals(testLiteral, testProperty);
285:
286: // test1.addLeftValue(testLiteral);
287: // test1.addRightValue(filterFac.createAttributeExpression(schema, "pcedflag"));
288: } catch (IllegalFilterException e) {
289: fail("Illegal Filter Exception " + e);
290: }
291:
292: // Query query = new DefaultQuery(FEATURE_TABLE, test1);
293: FeatureReader reader = dstore.getFeatureReader(schema, test1,
294: Transaction.AUTO_COMMIT);
295: assertEquals("Number of filtered features off:", 2,
296: count(reader));
297: }
298:
299: int count(FeatureReader reader) throws NoSuchElementException,
300: IOException, IllegalAttributeException {
301: int count = 0;
302:
303: try {
304: while (reader.hasNext()) {
305: reader.next();
306: count++;
307: }
308: } finally {
309: reader.close();
310: }
311:
312: return count;
313: }
314:
315: int count(FeatureWriter writer) throws NoSuchElementException,
316: IOException, IllegalAttributeException {
317: int count = 0;
318:
319: try {
320: while (writer.hasNext()) {
321: writer.next();
322: count++;
323: }
324: } finally {
325: writer.close();
326: }
327:
328: return count;
329: }
330:
331: /*
332: public void testGetFeatureWriter() throws Exception {
333: Transaction trans = new DefaultTransaction();
334: JDBCTransactionState state = new JDBCTransactionState(connPool);
335: trans.putState(connPool, state);
336:
337: FeatureWriter writer = dstore.getFeatureWriter("testset", Filter.INCLUDE, trans);
338:
339: //count(writer);
340: assertEquals(6, count(writer));
341:
342: try {
343: assertFalse(writer.hasNext());
344: } catch (IOException expected) {
345: }
346:
347: //TODO: test that writer.next is an empty feature.
348: //try {
349: // writer.next();
350: // fail("Should not be able to use a closed writer");
351: //} catch (IOException expected) {
352: //}
353: }
354: */
355: public void testBadTypeName() throws Exception {
356: try {
357: String badType = "badType43";
358: FeatureWriter writer = dstore.getFeatureWriter(badType,
359: Filter.INCLUDE, Transaction.AUTO_COMMIT);
360: fail("should not have type " + badType);
361: } catch (SchemaNotFoundException e) {
362: LOGGER.fine("succesfully caught exception: " + e);
363:
364: //catch the proper exception
365: }
366: }
367:
368: /*
369: public void testOptimizedBounds() throws Exception {
370: FeatureSource source = dstore.getFeatureSource(FEATURE_TABLE);
371: CompareFilter test1 = null;
372:
373: try {
374: test1 = filterFac.createCompareFilter(Abstract FilterType.COMPARE_EQUALS);
375:
376: Integer testInt = new Integer(0);
377: Expression testLiteral = filterFac.createLiteralExpression(testInt);
378: test1.addLeftValue(testLiteral);
379: test1.addRightValue(filterFac.createAttributeExpression(schema, "pcedflag"));
380: } catch (IllegalFilterException e) {
381: fail("Illegal Filter Exception " + e);
382: }
383:
384: Query query = new DefaultQuery(FEATURE_TABLE, test1);
385: Envelope bounds = source.getBounds(query);
386: LOGGER.info("bounds on query " + query + " is " + bounds);
387:
388: Envelope fBounds = source.getBounds();
389: LOGGER.info("Bounds of source is " + fBounds);
390:
391: FeatureResults results = source.getFeatures(query);
392: LOGGER.info("bounds from feature results is " + results.getBounds());
393: }
394:
395: public void testGetFeaturesWriterModify() throws IOException, IllegalAttributeException {
396: Transaction trans = new DefaultTransaction();
397: JDBCTransactionState state = new JDBCTransactionState(connPool);
398: trans.putState(connPool, state);
399:
400: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE, Filter.INCLUDE, trans);
401: int attKeyPos = 0;
402: Integer attKey = new Integer(10);
403: String attName = "name";
404: String newAttVal = "LS 503";
405: Feature feature;
406:
407: while (writer.hasNext()) {
408: feature = writer.next();
409:
410: if (feature.getAttribute(attKeyPos).equals(attKey)) {
411: LOGGER.info("changing name of feature " + feature);
412: ;
413: feature.setAttribute(attName, newAttVal);
414: writer.write();
415: }
416: }
417:
418: //writer.close();
419: FeatureReader reader = dstore.getFeatureReader(schema, Filter.INCLUDE, trans);
420:
421: while (reader.hasNext()) {
422: feature = reader.next();
423:
424: if (feature.getAttribute(attKeyPos).equals(attKey)) {
425: LOGGER.fine("checking feature " + feature);
426: ;
427:
428: Object modAtt = feature.getAttribute(attName);
429:
430: //LOGGER.fine("modified attribute is " + modAtt);
431: assertEquals("attribute was not changed", newAttVal, (String) modAtt);
432: }
433: }
434:
435: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
436: //assertEquals( "changed", feature.getAttribute("name") );
437: state.rollback();
438: }
439:
440: public void testGetFeaturesWriterModifyGeometry()
441: throws IOException, IllegalAttributeException {
442: FeatureWriter writer =
443: dstore.getFeatureWriter("road", Filter.INCLUDE, Transaction.AUTO_COMMIT);
444: Feature feature;
445: Coordinate[] points =
446: {
447: new Coordinate(59, 59),
448: new Coordinate(17, 17),
449: new Coordinate(49, 39),
450: new Coordinate(57, 67),
451: new Coordinate(79, 79)};
452: LineString geom = geomFac.createLineString(points);
453:
454: while (writer.hasNext()) {
455: feature = writer.next();
456: LOGGER.info("looking at feature " + feature);
457:
458: if (feature.getAttribute(0).equals("asphalt")) {
459: LOGGER.info("changing name and geom");
460: feature.setAttribute("the_geom", geom);
461: writer.write();
462: }
463: }
464:
465: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
466: //assertEquals( "changed", feature.getAttribute("name") );
467: writer.close();
468: }
469:
470: public void testGetFeaturesWriterModifyMultipleAtts()
471: throws IOException, IllegalAttributeException {
472: FeatureWriter writer =
473: dstore.getFeatureWriter("road", Filter.INCLUDE, Transaction.AUTO_COMMIT);
474: Feature feature;
475: Coordinate[] points =
476: {
477: new Coordinate(32, 44),
478: new Coordinate(62, 51),
479: new Coordinate(45, 35),
480: new Coordinate(55, 65),
481: new Coordinate(73, 75)};
482: LineString geom = geomFac.createLineString(points);
483:
484: while (writer.hasNext()) {
485: feature = writer.next();
486: LOGGER.info("looking at feature " + feature);
487:
488: if (feature.getAttribute(0).equals("asphalt")) {
489: LOGGER.info("changing name and geom");
490: feature.setAttribute("the_geom", geom);
491: feature.setAttribute("name", "trick");
492: writer.write();
493: }
494: }
495:
496: //feature = (Feature) data.features( "road" ).get( "road.rd1" );
497: //assertEquals( "changed", feature.getAttribute("name") );
498: writer.close();
499: }
500:
501: public void testGetFeaturesWriterAdd() throws IOException, IllegalAttributeException {
502: Transaction trans = new DefaultTransaction();
503: JDBCTransactionState state = new JDBCTransactionState(connPool);
504: trans.putState(connPool, state);
505:
506: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE, Filter.INCLUDE, trans);
507: int count = 0;
508:
509: while (writer.hasNext()) {
510: Feature feature = writer.next();
511: count++;
512: }
513:
514: assertEquals("Checking num features before add", 6, count);
515: assertFalse(writer.hasNext());
516:
517: Feature feature = writer.next();
518: Object[] atts = getTestAtts("testAdd");
519: feature.setAttributes(atts);
520: writer.write();
521: assertFalse(writer.hasNext());
522:
523: //assertEquals( fixture.roadFeatures.length+1, data.features( "road" ).size() );
524: writer.close();
525:
526: FeatureReader reader = dstore.getFeatureReader(schema, Filter.INCLUDE, trans);
527: int numFeatures = count(reader);
528: assertEquals("Wrong number of features after add", 7, numFeatures);
529: state.rollback();
530: }
531: */
532: private Object[] getTestAtts(String name) {
533: Coordinate[] points = { new Coordinate(45, 45),
534: new Coordinate(45, 55), new Coordinate(55, 55),
535: new Coordinate(55, 45), new Coordinate(45, 45) };
536: GeometryFactory gf = new GeometryFactory();
537: LinearRing shell = gf.createLinearRing(points);
538: Polygon[] testPolys = { gf.createPolygon(shell, null) };
539: MultiPolygon the_geom = gf.createMultiPolygon(testPolys);
540: Integer gID = new Integer(addId);
541: Double area = new Double(100.0);
542: Double perimeter = new Double(40.0);
543: Integer testb_ = new Integer(22);
544: Integer testb_id = new Integer(4833);
545: Integer code = new Integer(0);
546:
547: Object[] attributes = { gID, area, perimeter, testb_, testb_id,
548: name, code, code, the_geom };
549:
550: return attributes;
551: }
552: /*
553: public void testGetFeatureWriterRemove() throws IOException, IllegalAttributeException {
554: Transaction trans = new DefaultTransaction();
555: JDBCTransactionState state = new JDBCTransactionState(connPool);
556: trans.putState(connPool, state);
557:
558: FeatureWriter writer = dstore.getFeatureWriter(FEATURE_TABLE, Filter.INCLUDE, trans);
559:
560: FeatureReader reader = dstore.getFeatureReader(schema, Filter.INCLUDE, trans);
561: int numFeatures = count(reader);
562:
563: //assertEquals("Wrong number of features before delete", 6, numFeatures);
564: Feature feature;
565:
566: while (writer.hasNext()) {
567: feature = writer.next();
568:
569: if (feature.getAttribute(0).equals(new Integer(4))) {
570: LOGGER.info("deleting feature " + feature);
571: writer.remove();
572: }
573: }
574:
575: writer.close();
576: reader = dstore.getFeatureReader(schema, Filter.INCLUDE, trans);
577: numFeatures = count(reader);
578: assertEquals("Wrong number of features after add", 5, numFeatures);
579: state.rollback();
580: }
581: */
582: //assertEquals( fixture.roadFeatures.length-1, data.features( "road" ).size() );
583: }
|