001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-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;
017:
018: import java.util.Arrays;
019: import java.util.Collections;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Set;
024:
025: import org.geotools.factory.CommonFactoryFinder;
026: import org.geotools.feature.Feature;
027: import org.geotools.feature.FeatureCollection;
028: import org.geotools.feature.FeatureType;
029: import org.geotools.feature.FeatureTypes;
030: import org.geotools.feature.IllegalAttributeException;
031: import org.geotools.feature.SchemaException;
032: import org.geotools.filter.IllegalFilterException;
033: import org.geotools.filter.visitor.DefaultFilterVisitor;
034: import org.geotools.referencing.CRS;
035: import org.opengis.filter.And;
036: import org.opengis.filter.BinaryLogicOperator;
037: import org.opengis.filter.Filter;
038: import org.opengis.filter.FilterFactory;
039: import org.opengis.filter.FilterVisitor;
040: import org.opengis.filter.Id;
041: import org.opengis.filter.Not;
042: import org.opengis.filter.PropertyIsBetween;
043: import org.opengis.filter.PropertyIsEqualTo;
044: import org.opengis.filter.PropertyIsLike;
045: import org.opengis.filter.PropertyIsNull;
046: import org.opengis.filter.expression.Add;
047: import org.opengis.filter.expression.Expression;
048: import org.opengis.filter.expression.Function;
049: import org.opengis.filter.expression.Literal;
050: import org.opengis.filter.expression.PropertyName;
051: import org.opengis.referencing.crs.CoordinateReferenceSystem;
052:
053: import com.vividsolutions.jts.geom.Geometry;
054:
055: /**
056: * Tests cases for DataUtilities.
057: *
058: * @author Jody Garnett, Refractions Research
059: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/test/java/org/geotools/data/DataUtilitiesTest.java $
060: */
061: public class DataUtilitiesTest extends DataTestCase {
062: /**
063: * Constructor for DataUtilitiesTest.
064: *
065: * @param arg0
066: */
067: public DataUtilitiesTest(String arg0) {
068: super (arg0);
069: }
070:
071: /**
072: * Test for {@link DataUtilities#attributeNames(FeatureType)}
073: */
074: public void testAttributeNamesFeatureType() {
075: String[] names;
076:
077: names = DataUtilities.attributeNames(roadType);
078: assertEquals(3, names.length);
079: assertEquals("id", names[0]);
080: assertEquals("geom", names[1]);
081: assertEquals("name", names[2]);
082:
083: names = DataUtilities.attributeNames(subRoadType);
084: assertEquals(2, names.length);
085: assertEquals("id", names[0]);
086: assertEquals("geom", names[1]);
087: }
088:
089: /*
090: * Test for String[] attributeNames(Filter)
091: */
092: public void testAttributeNamesFilter()
093: throws IllegalFilterException {
094: FilterFactory factory = CommonFactoryFinder
095: .getFilterFactory(null);
096: String[] names;
097:
098: Filter filter = null;
099:
100: // check null
101: names = DataUtilities.attributeNames(filter);
102: assertEquals(names.length, 0);
103:
104: Id fidFilter = factory.id(Collections.singleton(factory
105: .featureId("fid")));
106:
107: // check fidFilter
108: names = DataUtilities.attributeNames(fidFilter);
109: assertEquals(0, names.length);
110:
111: PropertyName id = factory.property("id");
112: PropertyName name = factory.property("name");
113: PropertyName geom = factory.property("geom");
114:
115: // check nullFilter
116: PropertyIsNull nullFilter = factory.isNull(id);
117: names = DataUtilities.attributeNames(nullFilter);
118: assertEquals(1, names.length);
119: assertEquals("id", names[0]);
120:
121: PropertyIsEqualTo equal = factory.equals(name, id);
122: names = DataUtilities.attributeNames(equal);
123: assertEquals(2, names.length);
124: List list = Arrays.asList(names);
125: assertTrue(list.contains("name"));
126: assertTrue(list.contains("id"));
127:
128: Function fnCall = factory.function("Max", new Expression[] {
129: id, name });
130:
131: PropertyIsLike fn = factory.like(fnCall, "does-not-matter");
132: names = DataUtilities.attributeNames(fn);
133: list = Arrays.asList(names);
134: assertTrue(list.contains("name"));
135: assertTrue(list.contains("id"));
136:
137: PropertyIsBetween between = factory.between(name, id, geom);
138: names = DataUtilities.attributeNames(between);
139: assertEquals(3, names.length);
140: list = Arrays.asList(names);
141: assertTrue(list.contains("name"));
142: assertTrue(list.contains("id"));
143: assertTrue(list.contains("geom"));
144:
145: // check logic filter
146: PropertyIsNull geomNull = factory.isNull(geom);
147: names = DataUtilities.attributeNames(factory.and(geomNull,
148: equal));
149: assertEquals(3, names.length);
150: list = Arrays.asList(names);
151: assertTrue(list.contains("name"));
152: assertTrue(list.contains("id"));
153: assertTrue(list.contains("geom"));
154:
155: // check not filter
156: names = DataUtilities.attributeNames(factory.not(geomNull));
157: assertEquals(1, names.length);
158: assertEquals("geom", names[0]);
159:
160: //check with namespace qualified name
161: PropertyIsEqualTo equalToWithPrefix = factory.equals(factory
162: .property("gml:name"), id);
163: names = DataUtilities.attributeNames(equalToWithPrefix,
164: roadType);
165: assertEquals(2, names.length);
166: list = Arrays.asList(names);
167: assertTrue(list.contains("name"));
168: assertTrue(list.contains("id"));
169: }
170:
171: /**
172: * Test for {@link DataUtilities#attributeNames(Filter, FeatureType)}
173: */
174: public void testAttributeNamesFilterFeatureType() {
175: FilterFactory factory = CommonFactoryFinder
176: .getFilterFactory(null);
177: Filter filter = factory.equals(factory.property("id"), factory
178: .add(factory.property("geom"), factory
179: .property("gml:name")));
180:
181: String[] names;
182:
183: names = DataUtilities.attributeNames(filter, roadType);
184: assertEquals(3, names.length);
185: List namesList = Arrays.asList(names);
186: assertTrue(namesList.contains("id"));
187: assertTrue(namesList.contains("geom"));
188: assertTrue(namesList.contains("name"));
189: }
190:
191: /**
192: * Test for {@link DataUtilities#attributeNames(Expression, FeatureType)}
193: */
194: public void testAttributeExpressionFilterFeatureType() {
195: FilterFactory factory = CommonFactoryFinder
196: .getFilterFactory(null);
197: Expression expression = factory.add(factory.property("geom"),
198: factory.property("gml:name"));
199:
200: String[] names;
201:
202: names = DataUtilities.attributeNames(expression, roadType);
203: assertEquals(2, names.length);
204: List namesList = Arrays.asList(names);
205: assertTrue(namesList.contains("geom"));
206: assertTrue(namesList.contains("name"));
207: }
208:
209: /*
210: * Test for void traverse(Filter, FilterVisitor)
211: */
212: public void testTraverseFilterFilterVisitor() {
213: FilterFactory factory = CommonFactoryFinder
214: .getFilterFactory(null);
215:
216: final Literal exp1 = factory.literal(1);
217: final PropertyName exp2 = factory.property("ammount");
218: final PropertyIsEqualTo filter1 = factory.equals(exp1, exp2);
219:
220: final Not testFilter = factory.not(filter1);
221:
222: class TestVisitor extends DefaultFilterVisitor {
223: boolean exp1Called = false;
224:
225: boolean exp2Called = false;
226:
227: boolean filter1Called = false;
228:
229: boolean filter2Called = false;
230:
231: public Object visit(Literal exp, Object data) {
232: exp1Called = exp1 == exp;
233: return data;
234: }
235:
236: public Object visit(PropertyName exp, Object data) {
237: exp2Called = exp2 == exp;
238: return data;
239: }
240:
241: public Object visit(PropertyIsEqualTo filter, Object data) {
242: filter1Called = filter1 == filter;
243: return data;
244: }
245:
246: public Object visit(Not filter, Object data) {
247: filter2Called = testFilter == filter;
248: return data;
249: }
250: }
251: ;
252:
253: TestVisitor visitor = new TestVisitor();
254: DataUtilities.traverse(testFilter, visitor);
255:
256: assertTrue(visitor.exp1Called);
257: assertTrue(visitor.exp2Called);
258: assertTrue(visitor.filter1Called);
259: assertTrue(visitor.filter2Called);
260: }
261:
262: /*
263: * Test for void traverse(Set, FilterVisitor)
264: */
265: public void testTraverseSetFilterVisitor() {
266: FilterFactory factory = CommonFactoryFinder
267: .getFilterFactory(null);
268:
269: final Literal exp1 = factory.literal(1);
270: final PropertyName exp2 = factory.property("ammount");
271: // the filters are unrelated to the above expressions to avoid
272: // the expressions being called as a side effect of the filters
273: // being called and thus not being sure if traverse(Set, FilterVisitor)
274: // actually called them directly
275: final PropertyIsEqualTo filter1 = factory.equals(factory
276: .property("p1"), factory.property("p2"));
277: final Not filter2 = factory.not(factory.id(Collections
278: .singleton(factory.featureId("id1"))));
279:
280: Set set = new HashSet();
281: set.add(exp1);
282: set.add(exp2);
283: set.add(filter1);
284: set.add(filter2);
285:
286: class TestVisitor extends DefaultFilterVisitor {
287: boolean exp1Called = false;
288: boolean exp2Called = false;
289: boolean filter1Called = false;
290: boolean filter2Called = false;
291:
292: public Object visit(Literal exp, Object data) {
293: exp1Called = exp1 == exp;
294: return data;
295: }
296:
297: public Object visit(PropertyName exp, Object data) {
298: exp2Called = exp2 == exp;
299: return data;
300: }
301:
302: public Object visit(PropertyIsEqualTo filter, Object data) {
303: filter1Called = filter1 == filter;
304: return data;
305: }
306:
307: public Object visit(Not filter, Object data) {
308: filter2Called = filter2 == filter;
309: return data;
310: }
311: }
312: ;
313:
314: TestVisitor visitor = new TestVisitor();
315: DataUtilities.traverse(set, visitor);
316:
317: assertTrue(visitor.exp1Called);
318: assertTrue(visitor.exp2Called);
319: assertTrue(visitor.filter1Called);
320: assertTrue(visitor.filter2Called);
321: }
322:
323: public void testTraverseDepth() {
324: FilterFactory factory = CommonFactoryFinder
325: .getFilterFactory(null);
326:
327: Expression exp1 = factory.literal(1);
328: Expression exp2 = factory.property("ammount");
329: Expression exp3 = factory.literal(4);
330: Expression exp4 = factory.add(exp1, exp2);
331:
332: Filter filter1 = factory.equals(exp4, exp3);
333: Filter filter2 = factory.not(filter1);
334:
335: Set set = DataUtilities.traverseDepth(filter2);
336: assertTrue(set.contains(exp1));
337: assertTrue(set.contains(exp2));
338: assertTrue(set.contains(exp3));
339: assertTrue(set.contains(exp4));
340: assertTrue(set.contains(filter1));
341: assertTrue(set.contains(filter2));
342: }
343:
344: public void testCompare() throws SchemaException {
345: assertEquals(0, DataUtilities.compare(null, null));
346: assertEquals(-1, DataUtilities.compare(roadType, null));
347: assertEquals(-1, DataUtilities.compare(null, roadType));
348: assertEquals(-1, DataUtilities.compare(riverType, roadType));
349: assertEquals(-1, DataUtilities.compare(roadType, riverType));
350: assertEquals(0, DataUtilities.compare(roadType, roadType));
351: assertEquals(1, DataUtilities.compare(subRoadType, roadType));
352:
353: // different order
354: FeatureType road2 = DataUtilities.createType("namespace.road",
355: "geom:LineString,name:String,id:0");
356: assertEquals(1, DataUtilities.compare(road2, roadType));
357:
358: // different namespace
359: FeatureType road3 = DataUtilities.createType("test.road",
360: "id:0,geom:LineString,name:String");
361: assertEquals(0, DataUtilities.compare(road3, roadType));
362: }
363:
364: public void testIsMatch() {
365: }
366:
367: public void testReType() throws Exception {
368: Feature rd1 = roadFeatures[0];
369: assertEquals(rd1, rd1);
370:
371: Feature rdDuplicate = roadType.duplicate(rd1);
372:
373: assertEquals(rd1, rdDuplicate);
374: assertNotSame(rd1, rdDuplicate);
375:
376: Feature rd2 = DataUtilities.reType(roadType, rd1);
377:
378: assertEquals(rd1, rd2);
379: assertNotSame(rd1, rd2);
380:
381: Feature rd3 = DataUtilities.reType(subRoadType, rd1);
382:
383: assertFalse(rd1.equals(rd3));
384: assertEquals(2, rd3.getNumberOfAttributes());
385: assertEquals(rd1.getID(), rd3.getID());
386: assertEquals(rd1.getAttribute("id"), rd3.getAttribute("id"));
387: assertEquals((Geometry) rd1.getAttribute("geom"),
388: (Geometry) rd3.getAttribute("geom"));
389: assertNotNull(rd3.getDefaultGeometry());
390:
391: Feature rv1 = riverFeatures[0];
392: assertEquals(rv1, rv1);
393:
394: Feature rvDuplicate = riverType.duplicate(rv1);
395:
396: assertEquals(rv1, rvDuplicate);
397: assertNotSame(rv1, rvDuplicate);
398:
399: Feature rv2 = DataUtilities.reType(riverType, rv1);
400:
401: assertEquals(rv1, rv2);
402: assertNotSame(rv1, rv2);
403:
404: Feature rv3 = DataUtilities.reType(subRiverType, rv1);
405:
406: assertFalse(rv1.equals(rv3));
407: assertEquals(2, rv3.getNumberOfAttributes());
408: assertEquals(rv1.getID(), rv3.getID());
409: assertEquals(rv1.getAttribute("name"), rv3.getAttribute("name"));
410: assertEquals(rv1.getAttribute("flow"), rv3.getAttribute("flow"));
411: assertNull(rv3.getDefaultGeometry());
412: }
413:
414: /*
415: * Test for Feature template(FeatureType)
416: */
417: public void testTemplateFeatureType()
418: throws IllegalAttributeException {
419: Feature feature = DataUtilities.template(roadType);
420: assertNotNull(feature);
421: assertEquals(roadType.getAttributeCount(), feature
422: .getNumberOfAttributes());
423: }
424:
425: /*
426: * Test for Feature template(FeatureType, String)
427: */
428: public void testTemplateFeatureTypeString()
429: throws IllegalAttributeException {
430: Feature feature = DataUtilities.template(roadType, "Foo");
431: assertNotNull(feature);
432: assertEquals(roadType.getAttributeCount(), feature
433: .getNumberOfAttributes());
434: assertEquals("Foo", feature.getID());
435: assertNull(feature.getAttribute("name"));
436: assertNull(feature.getAttribute("id"));
437: assertNull(feature.getAttribute("geom"));
438: }
439:
440: public void testDefaultValues() throws IllegalAttributeException {
441: Object[] values = DataUtilities.defaultValues(roadType);
442: assertNotNull(values);
443: assertEquals(values.length, roadType.getAttributeCount());
444: }
445:
446: public void testDefaultValue() throws IllegalAttributeException {
447: assertNull(DataUtilities.defaultValue(roadType
448: .getAttributeType("name")));
449: assertNull(DataUtilities.defaultValue(roadType
450: .getAttributeType("id")));
451: assertNull(DataUtilities.defaultValue(roadType
452: .getAttributeType("geom")));
453: }
454:
455: public void testCollection() {
456: FeatureCollection collection = DataUtilities
457: .collection(roadFeatures);
458: assertEquals(roadFeatures.length, collection.size());
459: }
460:
461: public void testReaderFeatureArray() throws Exception {
462: FeatureReader reader = DataUtilities.reader(roadFeatures);
463: assertEquals(roadFeatures.length, count(reader));
464: }
465:
466: public void testReaderCollection() throws Exception {
467: FeatureCollection collection = DataUtilities
468: .collection(roadFeatures);
469: assertEquals(roadFeatures.length, collection.size());
470:
471: FeatureReader reader = DataUtilities.reader(collection);
472: assertEquals(roadFeatures.length, count(reader));
473: }
474:
475: public void testCreateType() {
476: // TODO impelment test
477: }
478:
479: public void testType() {
480: // TODO impelment test
481: }
482:
483: public void testCreateAttribute() {
484: // TODO impelment test
485: }
486:
487: public void testSource() throws Exception {
488: FeatureSource s = DataUtilities.source(roadFeatures);
489: assertEquals(-1, s.getCount(Query.ALL));
490: assertEquals(3, s.getFeatures().size());
491: assertEquals(3, s.getFeatures(Query.ALL).size());
492: assertEquals(3, s.getFeatures(Filter.INCLUDE).size());
493: assertEquals(0, s.getFeatures(Filter.EXCLUDE).size());
494: assertEquals(1, s.getFeatures(rd1Filter).size());
495: assertEquals(2, s.getFeatures(rd12Filter).size());
496: }
497:
498: /**
499: * tests the policy of DataUtilities.mixQueries
500: * @throws Exception
501: */
502: public void testMixQueries() throws Exception {
503: Query firstQuery;
504: Query secondQuery;
505:
506: firstQuery = new DefaultQuery("typeName", Filter.EXCLUDE, 100,
507: new String[] { "att1", "att2", "att3" }, "handle");
508: secondQuery = new DefaultQuery("typeName", Filter.EXCLUDE, 20,
509: new String[] { "att1", "att2", "att4" }, "handle2");
510:
511: Query mixed = DataUtilities.mixQueries(firstQuery, secondQuery,
512: "newhandle");
513:
514: //the passed handle
515: assertEquals("newhandle", mixed.getHandle());
516: //the lower of both
517: assertEquals(20, mixed.getMaxFeatures());
518: //att1, 2, 3 and 4
519: assertEquals(4, mixed.getPropertyNames().length);
520:
521: //now use some filters
522: Filter filter1 = null;
523: Filter filter2 = null;
524: FilterFactory ffac = CommonFactoryFinder.getFilterFactory(null);
525:
526: String typeSpec = "geom:Point,att1:String,att2:String,att3:String,att4:String";
527: FeatureType testType = DataUtilities.createType("testType",
528: typeSpec);
529: //System.err.println("created test type: " + testType);
530:
531: filter1 = ffac.equals(ffac.property("att1"), ffac
532: .literal("val1"));
533: filter2 = ffac.equals(ffac.property("att2"), ffac
534: .literal("val2"));
535:
536: firstQuery = new DefaultQuery("typeName", filter1, 100, null,
537: "handle");
538: secondQuery = new DefaultQuery("typeName", filter2, 20,
539: new String[] { "att1", "att2", "att4" }, "handle2");
540:
541: mixed = DataUtilities.mixQueries(firstQuery, secondQuery,
542: "newhandle");
543:
544: //the passed handle
545: assertEquals("newhandle", mixed.getHandle());
546: //the lower of both
547: assertEquals(20, mixed.getMaxFeatures());
548: //att1, 2 and 4
549: assertEquals(3, mixed.getPropertyNames().length);
550:
551: Filter mixedFilter = mixed.getFilter();
552: assertNotNull(mixedFilter);
553: assertTrue(mixedFilter instanceof BinaryLogicOperator);
554: BinaryLogicOperator f = (BinaryLogicOperator) mixedFilter;
555:
556: assertTrue(f instanceof And);
557: for (Iterator fit = f.getChildren().iterator(); fit.hasNext();) {
558: Filter subFilter = (Filter) fit.next();
559: assertTrue(filter1.equals(subFilter)
560: || filter2.equals(subFilter));
561: }
562: }
563:
564: public void testSpecNoCRS() throws Exception {
565: String spec = "id:String,polygonProperty:Polygon";
566: FeatureType ft = DataUtilities.createType("testType", spec);
567: assertEquals(spec, DataUtilities.spec(ft));
568: }
569:
570: public void testSpecCRS() throws Exception {
571: String spec = "id:String,polygonProperty:Polygon:srid=32615";
572: FeatureType ft = DataUtilities.createType("testType", spec);
573: assertEquals(spec, DataUtilities.spec(ft));
574: }
575:
576: public void testSpecNotIdentifiable() throws Exception {
577: String spec = "id:String,polygonProperty:Polygon:srid=32615";
578: FeatureType ft = DataUtilities.createType("testType", spec);
579: CoordinateReferenceSystem crsNoId = CRS
580: .parseWKT("PROJCS[\"Geoscience Australia Standard National Scale Lambert Projection\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS_1978\",6378135,298.26],TOWGS84[0,0,0]],PRIMEM[\"Greenwich\",0],UNIT[\"Decimal_Degree\",0.0174532925199433]],PROJECTION[\"Lambert_Conformal_Conic_2SP\"],PARAMETER[\"central_meridian\",134.0],PARAMETER[\"latitude_of_origin\",0.0],PARAMETER[\"standard_parallel_1\",-18.0],PARAMETER[\"standard_parallel_2\",-36.0],UNIT[\"Meter\",1]]");
581: FeatureType transformedFt = FeatureTypes.transform(ft, crsNoId);
582: // since we cannot go back to a code with do a best effort encoding
583: assertEquals("id:String,polygonProperty:Polygon", DataUtilities
584: .spec(transformedFt));
585: }
586:
587: public static void main(String[] args) {
588: junit.textui.TestRunner.run(DataUtilitiesTest.class);
589: }
590:
591: }
|