Source Code Cross Referenced for DataUtilities.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2003-2006, GeoTools Project Managment Committee (PMC)
0005:         *    
0006:         *    This library is free software; you can redistribute it and/or
0007:         *    modify it under the terms of the GNU Lesser General Public
0008:         *    License as published by the Free Software Foundation;
0009:         *    version 2.1 of the License.
0010:         *
0011:         *    This library is distributed in the hope that it will be useful,
0012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         *    Lesser General Public License for more details.
0015:         */
0016:        package org.geotools.data;
0017:
0018:        import java.io.File;
0019:        import java.io.IOException;
0020:        import java.net.URI;
0021:        import java.net.URISyntaxException;
0022:        import java.net.URL;
0023:        import java.util.Arrays;
0024:        import java.util.Collection;
0025:        import java.util.Date;
0026:        import java.util.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.LinkedHashMap;
0030:        import java.util.LinkedList;
0031:        import java.util.List;
0032:        import java.util.Map;
0033:        import java.util.NoSuchElementException;
0034:        import java.util.Set;
0035:        import java.util.StringTokenizer;
0036:        import java.util.Map.Entry;
0037:
0038:        import org.geotools.data.collection.CollectionDataStore;
0039:        import org.geotools.factory.CommonFactoryFinder;
0040:        import org.geotools.feature.AttributeType;
0041:        import org.geotools.feature.AttributeTypeFactory;
0042:        import org.geotools.feature.DefaultFeatureType;
0043:        import org.geotools.feature.Feature;
0044:        import org.geotools.feature.FeatureCollection;
0045:        import org.geotools.feature.FeatureCollections;
0046:        import org.geotools.feature.FeatureIterator;
0047:        import org.geotools.feature.FeatureType;
0048:        import org.geotools.feature.FeatureTypeFactory;
0049:        import org.geotools.feature.GeometryAttributeType;
0050:        import org.geotools.feature.IllegalAttributeException;
0051:        import org.geotools.feature.SchemaException;
0052:        import org.geotools.feature.type.GeometricAttributeType;
0053:        import org.geotools.filter.FilterAttributeExtractor;
0054:        import org.geotools.filter.visitor.DefaultFilterVisitor;
0055:        import org.geotools.metadata.iso.citation.Citations;
0056:        import org.geotools.referencing.CRS;
0057:        import org.opengis.filter.And;
0058:        import org.opengis.filter.ExcludeFilter;
0059:        import org.opengis.filter.Filter;
0060:        import org.opengis.filter.FilterFactory;
0061:        import org.opengis.filter.FilterVisitor;
0062:        import org.opengis.filter.Id;
0063:        import org.opengis.filter.IncludeFilter;
0064:        import org.opengis.filter.Not;
0065:        import org.opengis.filter.Or;
0066:        import org.opengis.filter.PropertyIsBetween;
0067:        import org.opengis.filter.PropertyIsEqualTo;
0068:        import org.opengis.filter.PropertyIsGreaterThan;
0069:        import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
0070:        import org.opengis.filter.PropertyIsLessThan;
0071:        import org.opengis.filter.PropertyIsLessThanOrEqualTo;
0072:        import org.opengis.filter.PropertyIsLike;
0073:        import org.opengis.filter.PropertyIsNotEqualTo;
0074:        import org.opengis.filter.PropertyIsNull;
0075:        import org.opengis.filter.expression.Add;
0076:        import org.opengis.filter.expression.Divide;
0077:        import org.opengis.filter.expression.Expression;
0078:        import org.opengis.filter.expression.ExpressionVisitor;
0079:        import org.opengis.filter.expression.Function;
0080:        import org.opengis.filter.expression.Literal;
0081:        import org.opengis.filter.expression.Multiply;
0082:        import org.opengis.filter.expression.NilExpression;
0083:        import org.opengis.filter.expression.PropertyName;
0084:        import org.opengis.filter.expression.Subtract;
0085:        import org.opengis.filter.spatial.BBOX;
0086:        import org.opengis.filter.spatial.Beyond;
0087:        import org.opengis.filter.spatial.Contains;
0088:        import org.opengis.filter.spatial.Crosses;
0089:        import org.opengis.filter.spatial.DWithin;
0090:        import org.opengis.filter.spatial.Disjoint;
0091:        import org.opengis.filter.spatial.Equals;
0092:        import org.opengis.filter.spatial.Intersects;
0093:        import org.opengis.filter.spatial.Overlaps;
0094:        import org.opengis.filter.spatial.Touches;
0095:        import org.opengis.filter.spatial.Within;
0096:        import org.opengis.metadata.Identifier;
0097:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0098:
0099:        import com.vividsolutions.jts.geom.Coordinate;
0100:        import com.vividsolutions.jts.geom.Envelope;
0101:        import com.vividsolutions.jts.geom.Geometry;
0102:        import com.vividsolutions.jts.geom.GeometryCollection;
0103:        import com.vividsolutions.jts.geom.GeometryFactory;
0104:        import com.vividsolutions.jts.geom.LineString;
0105:        import com.vividsolutions.jts.geom.LinearRing;
0106:        import com.vividsolutions.jts.geom.MultiLineString;
0107:        import com.vividsolutions.jts.geom.MultiPoint;
0108:        import com.vividsolutions.jts.geom.MultiPolygon;
0109:        import com.vividsolutions.jts.geom.Point;
0110:        import com.vividsolutions.jts.geom.Polygon;
0111:
0112:        /**
0113:         * Utility functions for use when implementing working with data classes.
0114:         * <p>
0115:         * TODO: Move FeatureType manipulation to feature package
0116:         * </p>
0117:         * @author Jody Garnett, Refractions Research
0118:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/DataUtilities.java $
0119:         */
0120:        public class DataUtilities {
0121:            static Map typeMap = new LinkedHashMap();
0122:
0123:            static FilterFactory ff = CommonFactoryFinder
0124:                    .getFilterFactory(null);
0125:
0126:            static {
0127:                typeMap.put("String", String.class);
0128:                typeMap.put("string", String.class);
0129:                typeMap.put("\"\"", String.class);
0130:                typeMap.put("Integer", Integer.class);
0131:                typeMap.put("int", Integer.class);
0132:                typeMap.put("0", Integer.class);
0133:                typeMap.put("Double", Double.class);
0134:                typeMap.put("double", Double.class);
0135:                typeMap.put("0.0", Double.class);
0136:                typeMap.put("Float", Float.class);
0137:                typeMap.put("float", Float.class);
0138:                typeMap.put("0.0f", Float.class);
0139:                typeMap.put("Boolean", Boolean.class);
0140:                typeMap.put("true", Boolean.class);
0141:                typeMap.put("false", Boolean.class);
0142:                typeMap.put("Geometry", Geometry.class);
0143:                typeMap.put("Point", Point.class);
0144:                typeMap.put("LineString", LineString.class);
0145:                typeMap.put("Polygon", Polygon.class);
0146:                typeMap.put("MultiPoint", MultiPoint.class);
0147:                typeMap.put("MultiLineString", MultiLineString.class);
0148:                typeMap.put("MultiPolygon", MultiPolygon.class);
0149:                typeMap.put("GeometryCollection", GeometryCollection.class);
0150:                typeMap.put("Date", Date.class);
0151:            }
0152:
0153:            /**
0154:             * DOCUMENT ME!
0155:             *
0156:             * @param featureType DOCUMENT ME!
0157:             *
0158:             * @return DOCUMENT ME!
0159:             */
0160:            public static String[] attributeNames(FeatureType featureType) {
0161:                String[] names = new String[featureType.getAttributeCount()];
0162:                final int count = featureType.getAttributeCount();
0163:                for (int i = 0; i < count; i++) {
0164:                    names[i] = featureType.getAttributeType(i).getName();
0165:                }
0166:
0167:                return names;
0168:            }
0169:
0170:            /**
0171:             * Takes a URL and converts it to a File. The attempts to deal with 
0172:             * Windows UNC format specific problems, specifically files located
0173:             * on network shares and different drives.
0174:             * 
0175:             * If the URL.getAuthority() returns null or is empty, then only the
0176:             * url's path property is used to construct the file. Otherwise, the
0177:             * authority is prefixed before the path.
0178:             * 
0179:             * It is assumed that url.getProtocol returns "file".
0180:             * 
0181:             * Authority is the drive or network share the file is located on.
0182:             * Such as "C:", "E:", "\\fooServer"
0183:             * 
0184:             * @param url a URL object that uses protocol "file"
0185:             * @return a File that corresponds to the URL's location
0186:             */
0187:            public static File urlToFile(URL url) {
0188:                String auth = url.getAuthority();
0189:                String path = url.getPath();
0190:                File f = null;
0191:                if (auth != null && !auth.equals("")) {
0192:                    f = new File("//" + auth + path);
0193:                } else {
0194:                    f = new File(path);
0195:                }
0196:                return f;
0197:            }
0198:
0199:            /**
0200:             * Traverses the filter and returns any encoutered property names.
0201:             * <p>
0202:             * The feautre type is supplied as contexts used to lookup expressions in cases where the 
0203:             * attributeName does not match the actual name of the type.
0204:             * </p>
0205:             */
0206:            public static String[] attributeNames(Filter filter,
0207:                    final FeatureType featureType) {
0208:                if (filter == null) {
0209:                    return new String[0];
0210:                }
0211:                FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(
0212:                        featureType);
0213:                filter.accept(attExtractor, null);
0214:                String[] attributeNames = attExtractor.getAttributeNames();
0215:                return attributeNames;
0216:            }
0217:
0218:            /**
0219:             * Traverses the filter and returns any encoutered property names.
0220:             * @deprecated use {@link #attributeNames(Filter, FeatureType)}/
0221:             */
0222:            public static String[] attributeNames(Filter filter) {
0223:                return attributeNames(filter, null);
0224:            }
0225:
0226:            /**
0227:             * Traverses the expression and returns any encoutered property names.
0228:             * <p>
0229:             * The feautre type is supplied as contexts used to lookup expressions in cases where the 
0230:             * attributeName does not match the actual name of the type.
0231:             * </p>
0232:             */
0233:            public static String[] attributeNames(Expression expression,
0234:                    final FeatureType featureType) {
0235:                if (expression == null) {
0236:                    return new String[0];
0237:                }
0238:                FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(
0239:                        featureType);
0240:                expression.accept(attExtractor, null);
0241:                String[] attributeNames = attExtractor.getAttributeNames();
0242:                return attributeNames;
0243:            }
0244:
0245:            /**
0246:             * Traverses the expression and returns any encoutered property names.
0247:             * @deprecated use {@link #attributeNames(Expression, FeatureType)}/
0248:             */
0249:            public static String[] attributeNames(Expression expression) {
0250:                return attributeNames(expression, null);
0251:            }
0252:
0253:            /**
0254:             *
0255:             * @param filter DOCUMENT ME!
0256:             * @param visitor DOCUMENT ME!
0257:             */
0258:            public static void traverse(Filter filter, FilterVisitor visitor) {
0259:                traverse(traverseDepth(filter), visitor);
0260:            }
0261:
0262:            /**
0263:             *
0264:             * @param expression DOCUMENT ME!
0265:             * @param visitor DOCUMENT ME!
0266:             */
0267:            public static void traverse(Expression expression,
0268:                    FilterVisitor visitor) {
0269:                traverse(traverseDepth(expression), visitor);
0270:            }
0271:
0272:            /**
0273:             * Performs a depth first traversal on Filter.
0274:             * 
0275:             * <p>
0276:             * Filters can contain Expressions and other Filters, this method will call
0277:             * visitor.visit( Filter ) and visitor.visit( Expression )
0278:             * </p>
0279:             *
0280:             * @param set Set of Filter and Expression information
0281:             * @param visitor Vistor to traverse across set
0282:             */
0283:            public static void traverse(Set set, final FilterVisitor visitor) {
0284:                for (Iterator i = set.iterator(); i.hasNext();) {
0285:                    Object here = i.next();
0286:
0287:                    if (here instanceof  Filter) {
0288:                        ((Filter) here).accept(visitor, null);
0289:                    } else if (here instanceof  Expression) {
0290:                        if (!(visitor instanceof  ExpressionVisitor)) {
0291:                            throw new IllegalArgumentException(
0292:                                    "visitor is not an ExpressionVisitor");
0293:                        }
0294:                        ((Expression) here).accept((ExpressionVisitor) visitor,
0295:                                null);
0296:                    } else {
0297:                        throw new IllegalArgumentException(
0298:                                "Not a Filter or an Expression: " + here);
0299:                    }
0300:                    //            if (here instanceof BetweenFilter) {
0301:                    //                visitor.visit((BetweenFilter) here);
0302:                    //            } else if (here instanceof CompareFilter) {
0303:                    //                visitor.visit((CompareFilter) here);
0304:                    //            } else if (here instanceof GeometryFilter) {
0305:                    //                visitor.visit((GeometryFilter) here);
0306:                    //            } else if (here instanceof LikeFilter) {
0307:                    //                visitor.visit((LikeFilter) here);
0308:                    //            } else if (here instanceof LogicFilter) {
0309:                    //                visitor.visit((LogicFilter) here);
0310:                    //            } else if (here instanceof NullFilter) {
0311:                    //                visitor.visit((NullFilter) here);
0312:                    //            } else if (here instanceof FidFilter) {
0313:                    //                visitor.visit((FidFilter) here);
0314:                    //            } else if (here instanceof Filter) {
0315:                    //                visitor.visit((org.geotools.filter.Filter) here);
0316:                    //            } else if (here instanceof AttributeExpression) {
0317:                    //                visitor.visit((AttributeExpression) here);
0318:                    //            } else if (here instanceof LiteralExpression) {
0319:                    //                visitor.visit((LiteralExpression) here);
0320:                    //            } else if (here instanceof MathExpression) {
0321:                    //                visitor.visit((MathExpression) here);
0322:                    //            } else if (here instanceof FunctionExpression) {
0323:                    //                visitor.visit((FunctionExpression) here);
0324:                    //            } else if (here instanceof Expression) {
0325:                    //                visitor.visit((org.geotools.filter.Filter) here);
0326:                    //            }
0327:                }
0328:            }
0329:
0330:            /**
0331:             * Performs a depth first traversal of Filter.
0332:             *
0333:             * @param filter
0334:             *
0335:             * @return Set of Filters in traversing filter
0336:             */
0337:            public static Set traverseDepth(Filter filter) {
0338:                final Set set = new HashSet();
0339:                FilterVisitor traverse = new Traversal() {
0340:                    void traverse(Filter f) {
0341:                        set.add(f);
0342:                    }
0343:
0344:                    void traverse(Expression expression) {
0345:                        set.add(expression);
0346:                    }
0347:                };
0348:
0349:                filter.accept(traverse, null);
0350:
0351:                return set;
0352:            }
0353:
0354:            /**
0355:             * Performs a depth first traversal of Filter.
0356:             *
0357:             * @param expression
0358:             *
0359:             * @return Set of Filters in traversing filter
0360:             */
0361:            public static Set traverseDepth(Expression expression) {
0362:                final Set set = new HashSet();
0363:                ExpressionVisitor traverse = new Traversal() {
0364:                    void traverse(Filter f) {
0365:                        set.add(f);
0366:                    }
0367:
0368:                    void traverse(Expression expr) {
0369:                        set.add(expr);
0370:                    }
0371:                };
0372:
0373:                expression.accept(traverse, null);
0374:
0375:                return set;
0376:            }
0377:
0378:            /**
0379:             * Compare operation for FeatureType.
0380:             * 
0381:             * <p>
0382:             * Results in:
0383:             * </p>
0384:             * 
0385:             * <ul>
0386:             * <li>
0387:             * 1: if typeA is a sub type/reorder/renamespace of typeB
0388:             * </li>
0389:             * <li>
0390:             * 0: if typeA and typeB are the same type
0391:             * </li>
0392:             * <li>
0393:             * -1: if typeA is not subtype of typeB
0394:             * </li>
0395:             * </ul>
0396:             * 
0397:             * <p>
0398:             * Comparison is based on AttributeTypes, an IOException is thrown if the
0399:             * AttributeTypes are not compatiable.
0400:             * </p>
0401:             * 
0402:             * <p>
0403:             * Namespace is not considered in this opperations. You may still need to
0404:             * reType to get the correct namesapce, or reorder.
0405:             * </p>
0406:             *
0407:             * @param typeA FeatureType beind compared
0408:             * @param typeB FeatureType being compared against
0409:             *
0410:             */
0411:            public static int compare(FeatureType typeA, FeatureType typeB) {
0412:                if (typeA == typeB) {
0413:                    return 0;
0414:                }
0415:
0416:                if (typeA == null) {
0417:                    return -1;
0418:                }
0419:
0420:                if (typeB == null) {
0421:                    return -1;
0422:                }
0423:
0424:                int countA = typeA.getAttributeCount();
0425:                int countB = typeB.getAttributeCount();
0426:
0427:                if (countA > countB) {
0428:                    return -1;
0429:                }
0430:
0431:                // may still be the same featureType
0432:                // (Perhaps they differ on namespace?)
0433:                AttributeType a;
0434:
0435:                // may still be the same featureType
0436:                // (Perhaps they differ on namespace?)
0437:                int match = 0;
0438:
0439:                for (int i = 0; i < countA; i++) {
0440:                    a = typeA.getAttributeType(i);
0441:
0442:                    if (isMatch(a, typeB.getAttributeType(i))) {
0443:                        match++;
0444:                    } else if (isMatch(a, typeB.getAttributeType(a.getName()))) {
0445:                        // match was found in a different position
0446:                    } else {
0447:                        // cannot find any match for Attribute in typeA
0448:                        return -1;
0449:                    }
0450:                }
0451:
0452:                if ((countA == countB) && (match == countA)) {
0453:                    // all attributes in typeA agreed with typeB
0454:                    // (same order and type)
0455:                    //            if (typeA.getNamespace() == null) {
0456:                    //            	if(typeB.getNamespace() == null) {
0457:                    //            		return 0;
0458:                    //            	} else {
0459:                    //            		return 1;
0460:                    //            	}
0461:                    //            } else if(typeA.getNamespace().equals(typeB.getNamespace())) {
0462:                    //                return 0;
0463:                    //            } else {
0464:                    //                return 1;
0465:                    //            }
0466:                    return 0;
0467:                }
0468:
0469:                return 1;
0470:            }
0471:
0472:            /**
0473:             * DOCUMENT ME!
0474:             *
0475:             * @param a DOCUMENT ME!
0476:             * @param b DOCUMENT ME!
0477:             *
0478:             * @return DOCUMENT ME!
0479:             */
0480:            public static boolean isMatch(AttributeType a, AttributeType b) {
0481:                if (a == b) {
0482:                    return true;
0483:                }
0484:
0485:                if (b == null) {
0486:                    return false;
0487:                }
0488:
0489:                if (a == null) {
0490:                    return false;
0491:                }
0492:
0493:                if (a.equals(b)) {
0494:                    return true;
0495:                }
0496:
0497:                if (a.getName().equals(b.getName())
0498:                        && a.getClass().equals(b.getClass())) {
0499:                    return true;
0500:                }
0501:
0502:                return false;
0503:            }
0504:
0505:            /**
0506:             * Creates duplicate of feature adjusted to the provided featureType.
0507:             *
0508:             * @param featureType FeatureType requested
0509:             * @param feature Origional Feature from DataStore
0510:             *
0511:             * @return An instance of featureType based on feature
0512:             *
0513:             * @throws IllegalAttributeException If opperation could not be performed
0514:             */
0515:            public static Feature reType(FeatureType featureType,
0516:                    Feature feature) throws IllegalAttributeException {
0517:                FeatureType origional = feature.getFeatureType();
0518:
0519:                if (featureType.equals(origional)) {
0520:                    return featureType.duplicate(feature);
0521:                }
0522:
0523:                String id = feature.getID();
0524:                int numAtts = featureType.getAttributeCount();
0525:                Object[] attributes = new Object[numAtts];
0526:                String xpath;
0527:
0528:                for (int i = 0; i < numAtts; i++) {
0529:                    AttributeType curAttType = featureType.getAttributeType(i);
0530:                    xpath = curAttType.getName();
0531:                    attributes[i] = curAttType.duplicate(feature
0532:                            .getAttribute(xpath));
0533:                }
0534:
0535:                return featureType.create(attributes, id);
0536:            }
0537:
0538:            /**
0539:             * Constructs an empty feature to use as a Template for new content.
0540:             * 
0541:             * <p>
0542:             * We may move this functionality to FeatureType.create( null )?
0543:             * </p>
0544:             *
0545:             * @param featureType Type of feature we wish to create
0546:             *
0547:             * @return A new Feature of type featureType
0548:             *
0549:             * @throws IllegalAttributeException if we could not create featureType
0550:             *         instance with acceptable default values
0551:             */
0552:            public static Feature template(FeatureType featureType)
0553:                    throws IllegalAttributeException {
0554:                return featureType.create(defaultValues(featureType));
0555:            }
0556:
0557:            /**
0558:             * DOCUMENT ME!
0559:             *
0560:             * @param featureType DOCUMENT ME!
0561:             * @param featureID DOCUMENT ME!
0562:             *
0563:             * @return DOCUMENT ME!
0564:             *
0565:             * @throws IllegalAttributeException DOCUMENT ME!
0566:             */
0567:            public static Feature template(FeatureType featureType,
0568:                    String featureID) throws IllegalAttributeException {
0569:                return featureType
0570:                        .create(defaultValues(featureType), featureID);
0571:            }
0572:
0573:            /**
0574:             * DOCUMENT ME!
0575:             *
0576:             * @param featureType DOCUMENT ME!
0577:             *
0578:             * @return DOCUMENT ME!
0579:             *
0580:             * @throws IllegalAttributeException DOCUMENT ME!
0581:             */
0582:            public static Object[] defaultValues(FeatureType featureType)
0583:                    throws IllegalAttributeException {
0584:                return defaultValues(featureType, null);
0585:            }
0586:
0587:            /**
0588:             * DOCUMENT ME!
0589:             *
0590:             * @param featureType DOCUMENT ME!
0591:             * @param atts DOCUMENT ME!
0592:             *
0593:             * @return DOCUMENT ME!
0594:             *
0595:             * @throws IllegalAttributeException DOCUMENT ME!
0596:             */
0597:            public static Feature template(FeatureType featureType,
0598:                    Object[] atts) throws IllegalAttributeException {
0599:                return featureType.create(defaultValues(featureType, atts));
0600:            }
0601:
0602:            /**
0603:             * DOCUMENT ME!
0604:             *
0605:             * @param featureType DOCUMENT ME!
0606:             * @param featureID DOCUMENT ME!
0607:             * @param atts DOCUMENT ME!
0608:             *
0609:             * @return DOCUMENT ME!
0610:             *
0611:             * @throws IllegalAttributeException DOCUMENT ME!
0612:             */
0613:            public static Feature template(FeatureType featureType,
0614:                    String featureID, Object[] atts)
0615:                    throws IllegalAttributeException {
0616:                return featureType.create(defaultValues(featureType, atts),
0617:                        featureID);
0618:            }
0619:
0620:            /**
0621:             * DOCUMENT ME!
0622:             *
0623:             * @param featureType DOCUMENT ME!
0624:             * @param values DOCUMENT ME!
0625:             *
0626:             * @return DOCUMENT ME!
0627:             *
0628:             * @throws IllegalAttributeException DOCUMENT ME!
0629:             * @throws ArrayIndexOutOfBoundsException DOCUMENT ME!
0630:             */
0631:            public static Object[] defaultValues(FeatureType featureType,
0632:                    Object[] values) throws IllegalAttributeException {
0633:                if (values == null) {
0634:                    values = new Object[featureType.getAttributeCount()];
0635:                } else if (values.length != featureType.getAttributeCount()) {
0636:                    throw new ArrayIndexOutOfBoundsException("values");
0637:                }
0638:
0639:                for (int i = 0; i < featureType.getAttributeCount(); i++) {
0640:                    values[i] = defaultValue(featureType.getAttributeType(i));
0641:                }
0642:
0643:                return values;
0644:            }
0645:
0646:            /**
0647:             * Provides a defautlValue for attributeType.
0648:             * 
0649:             * <p>
0650:             * Will return null if attributeType isNillable(), or attempt to use
0651:             * Reflection, or attributeType.parse( null )
0652:             * </p>
0653:             *
0654:             * @param attributeType
0655:             *
0656:             * @return null for nillable attributeType, attempt at reflection
0657:             *
0658:             * @throws IllegalAttributeException If value cannot be constructed for
0659:             *         attribtueType
0660:             */
0661:            public static Object defaultValue(AttributeType attributeType)
0662:                    throws IllegalAttributeException {
0663:                Object value = attributeType.createDefaultValue();
0664:
0665:                if (value == null && !attributeType.isNillable()) {
0666:                    throw new IllegalAttributeException(
0667:                            "Got null default value for non-null type.");
0668:                }
0669:                return value;
0670:            }
0671:
0672:            /**
0673:             * Returns a non-null default value for the class that is passed in.  This is a helper class an can't create a 
0674:             * default class for any type but it does support:
0675:             * <ul>
0676:             * <li>String</li>
0677:             * <li>Object - will return empty string</li>
0678:             * <li>Number</li>
0679:             * <li>Character</li>
0680:             * <li>JTS Geometries</li>
0681:             * </ul>
0682:             * 
0683:             *
0684:             * @param type
0685:             * @return
0686:             */
0687:            public static Object defaultValue(Class type) {
0688:                if (type == String.class || type == Object.class) {
0689:                    return "";
0690:                }
0691:                if (type == Integer.class) {
0692:                    return new Integer(0);
0693:                }
0694:                if (type == Double.class) {
0695:                    return new Double(0);
0696:                }
0697:                if (type == Long.class) {
0698:                    return new Long(0);
0699:                }
0700:                if (type == Short.class) {
0701:                    return new Short((short) 0);
0702:                }
0703:                if (type == Float.class) {
0704:                    return new Float(0.0f);
0705:                }
0706:                if (type == Character.class) {
0707:                    return new Character(' ');
0708:                }
0709:
0710:                GeometryFactory fac = new GeometryFactory();
0711:                Coordinate coordinate = new Coordinate(0, 0);
0712:                Point point = fac.createPoint(coordinate);
0713:
0714:                if (type == Point.class) {
0715:                    return point;
0716:                }
0717:                if (type == MultiPoint.class) {
0718:                    return fac.createMultiPoint(new Point[] { point });
0719:                }
0720:                if (type == LineString.class) {
0721:                    return fac.createLineString(new Coordinate[] { coordinate,
0722:                            coordinate, coordinate, coordinate });
0723:                }
0724:                LinearRing linearRing = fac.createLinearRing(new Coordinate[] {
0725:                        coordinate, coordinate, coordinate, coordinate });
0726:                if (type == LinearRing.class) {
0727:                    return linearRing;
0728:                }
0729:                if (type == MultiLineString.class) {
0730:                    return fac
0731:                            .createMultiLineString(new LineString[] { linearRing });
0732:                }
0733:                Polygon polygon = fac.createPolygon(linearRing,
0734:                        new LinearRing[0]);
0735:                if (type == Polygon.class) {
0736:                    return polygon;
0737:                }
0738:                if (type == MultiPolygon.class) {
0739:                    return fac.createMultiPolygon(new Polygon[] { polygon });
0740:                }
0741:
0742:                throw new IllegalArgumentException(type
0743:                        + " is not supported by this method");
0744:            }
0745:
0746:            /**
0747:             * Creates a FeatureReader for testing.
0748:             *
0749:             * @param features Array of features
0750:             *
0751:             * @return FeatureReader spaning provided feature array
0752:             *
0753:             * @throws IOException If provided features Are null or empty
0754:             * @throws NoSuchElementException DOCUMENT ME!
0755:             */
0756:            public static FeatureReader reader(final Feature[] features)
0757:                    throws IOException {
0758:                if ((features == null) || (features.length == 0)) {
0759:                    throw new IOException("Provided features where empty");
0760:                }
0761:
0762:                return new FeatureReader() {
0763:                    Feature[] array = features;
0764:                    int offset = -1;
0765:
0766:                    public FeatureType getFeatureType() {
0767:                        return features[0].getFeatureType();
0768:                    }
0769:
0770:                    public Feature next() {
0771:                        if (!hasNext()) {
0772:                            throw new NoSuchElementException("No more features");
0773:                        }
0774:
0775:                        return array[++offset];
0776:                    }
0777:
0778:                    public boolean hasNext() {
0779:                        return (array != null) && (offset < (array.length - 1));
0780:                    }
0781:
0782:                    public void close() {
0783:                        array = null;
0784:                        offset = -1;
0785:                    }
0786:                };
0787:            }
0788:
0789:            /**
0790:             * DOCUMENT ME!
0791:             *
0792:             * @param featureArray DOCUMENT ME!
0793:             *
0794:             * @return DOCUMENT ME!
0795:             *
0796:             * @throws IOException DOCUMENT ME!
0797:             * @throws RuntimeException DOCUMENT ME!
0798:             */
0799:            public static FeatureSource source(final Feature[] featureArray) {
0800:                final FeatureType featureType;
0801:
0802:                if ((featureArray == null) || (featureArray.length == 0)) {
0803:                    featureType = DefaultFeatureType.EMPTY;
0804:                } else {
0805:                    featureType = featureArray[0].getFeatureType();
0806:                }
0807:
0808:                DataStore arrayStore = new AbstractDataStore() {
0809:                    public String[] getTypeNames() {
0810:                        return new String[] { featureType.getTypeName() };
0811:                    }
0812:
0813:                    public FeatureType getSchema(String typeName)
0814:                            throws IOException {
0815:                        if ((typeName != null)
0816:                                && typeName.equals(featureType.getTypeName())) {
0817:                            return featureType;
0818:                        }
0819:
0820:                        throw new IOException(typeName + " not available");
0821:                    }
0822:
0823:                    protected FeatureReader getFeatureReader(String typeName)
0824:                            throws IOException {
0825:                        return reader(featureArray);
0826:                    }
0827:                };
0828:
0829:                try {
0830:                    return arrayStore.getFeatureSource(arrayStore
0831:                            .getTypeNames()[0]);
0832:                } catch (IOException e) {
0833:                    throw new RuntimeException(
0834:                            "Something is wrong with the geotools code, "
0835:                                    + "this exception should not happen", e);
0836:                }
0837:            }
0838:
0839:            /**
0840:             * DOCUMENT ME!
0841:             *
0842:             * @param collection DOCUMENT ME!
0843:             *
0844:             * @return DOCUMENT ME!
0845:             *
0846:             * @throws NullPointerException DOCUMENT ME!
0847:             * @throws RuntimeException DOCUMENT ME!
0848:             */
0849:            public static FeatureSource source(
0850:                    final FeatureCollection collection) {
0851:                if (collection == null) {
0852:                    throw new NullPointerException();
0853:                }
0854:
0855:                DataStore store = new CollectionDataStore(collection);
0856:
0857:                try {
0858:                    return store.getFeatureSource(store.getTypeNames()[0]);
0859:                } catch (IOException e) {
0860:                    throw new RuntimeException(
0861:                            "Something is wrong with the geotools code, "
0862:                                    + "this exception should not happen", e);
0863:                }
0864:            }
0865:
0866:            public static FeatureCollection results(Feature[] featureArray) {
0867:                return results(collection(featureArray));
0868:            }
0869:
0870:            /**
0871:             * Returns collection if non empty.
0872:             *
0873:             * @param collection
0874:             *
0875:             * @return provided collection
0876:             *
0877:             * @throws IOException Raised if collection was empty
0878:             */
0879:            public static FeatureCollection results(
0880:                    final FeatureCollection collection) {
0881:                if (collection.size() == 0) {
0882:                    //throw new IOException("Provided collection was empty");
0883:                }
0884:                return collection;
0885:            }
0886:
0887:            /**
0888:             * DOCUMENT ME!
0889:             *
0890:             * @param collection DOCUMENT ME!
0891:             *
0892:             * @return DOCUMENT ME!
0893:             *
0894:             * @throws IOException DOCUMENT ME!
0895:             */
0896:            public static FeatureReader reader(Collection collection)
0897:                    throws IOException {
0898:                return reader((Feature[]) collection
0899:                        .toArray(new Feature[collection.size()]));
0900:            }
0901:
0902:            /**
0903:             * Copies the provided features into a FeatureCollection.
0904:             * <p>
0905:             * Often used when gathering features for FeatureStore:<pre><code>
0906:             * featureStore.addFeatures( DataUtilities.collection(array));
0907:             * </code></pre>
0908:             * 
0909:             * @param features Array of features
0910:             * @return FeatureCollection
0911:             */
0912:            public static FeatureCollection collection(Feature[] features) {
0913:                FeatureCollection collection = FeatureCollections
0914:                        .newCollection();
0915:                final int length = features.length;
0916:                for (int i = 0; i < length; i++) {
0917:                    collection.add(features[i]);
0918:                }
0919:                return collection;
0920:            }
0921:
0922:            /**
0923:             * Copies the provided features into a FeatureCollection.
0924:             * <p>
0925:             * Often used when gathering features for FeatureStore:<pre><code>
0926:             * featureStore.addFeatures( DataUtilities.collection(feature));
0927:             * </code></pre>
0928:             * 
0929:             * @param features Array of features
0930:             * @return FeatureCollection
0931:             */
0932:            public static FeatureCollection collection(Feature feature) {
0933:                FeatureCollection collection = FeatureCollections
0934:                        .newCollection();
0935:                collection.add(feature);
0936:                return collection;
0937:            }
0938:
0939:            /**
0940:             * Copies the provided reader into a FeatureCollection, reader will be closed.
0941:             * <p>
0942:             * Often used when gathering features for FeatureStore:<pre><code>
0943:             * featureStore.addFeatures( DataUtilities.collection(reader));
0944:             * </code></pre>
0945:             * 
0946:             * @param features Array of features
0947:             * @return FeatureCollection
0948:             */
0949:            public static FeatureCollection collection(FeatureReader reader)
0950:                    throws IOException {
0951:                FeatureCollection collection = FeatureCollections
0952:                        .newCollection();
0953:                try {
0954:                    while (reader.hasNext()) {
0955:                        try {
0956:                            collection.add(reader.next());
0957:                        } catch (NoSuchElementException e) {
0958:                            throw (IOException) new IOException("EOF")
0959:                                    .initCause(e);
0960:                        } catch (IllegalAttributeException e) {
0961:                            throw (IOException) new IOException().initCause(e);
0962:                        }
0963:                    }
0964:                } finally {
0965:                    reader.close();
0966:                }
0967:                return collection;
0968:            }
0969:
0970:            /**
0971:             * Copies the provided reader into a FeatureCollection, reader will be closed.
0972:             * <p>
0973:             * Often used when gathering features for FeatureStore:<pre><code>
0974:             * featureStore.addFeatures( DataUtilities.collection(reader));
0975:             * </code></pre>
0976:             * 
0977:             * @param features Array of features
0978:             * @return FeatureCollection
0979:             */
0980:            public static FeatureCollection collection(FeatureIterator reader)
0981:                    throws IOException {
0982:                FeatureCollection collection = FeatureCollections
0983:                        .newCollection();
0984:                try {
0985:                    while (reader.hasNext()) {
0986:                        try {
0987:                            collection.add(reader.next());
0988:                        } catch (NoSuchElementException e) {
0989:                            throw (IOException) new IOException("EOF")
0990:                                    .initCause(e);
0991:                        }
0992:                    }
0993:                } finally {
0994:                    reader.close();
0995:                }
0996:                return collection;
0997:            }
0998:
0999:            /**
1000:             * DOCUMENT ME!
1001:             *
1002:             * @param att DOCUMENT ME!
1003:             * @param otherAtt DOCUMENT ME!
1004:             *
1005:             * @return DOCUMENT ME!
1006:             */
1007:            public static boolean attributesEqual(Object att, Object otherAtt) {
1008:                if (att == null) {
1009:                    if (otherAtt != null) {
1010:                        return false;
1011:                    }
1012:                } else {
1013:                    if (!att.equals(otherAtt)) {
1014:                        if (att instanceof  Geometry
1015:                                && otherAtt instanceof  Geometry) {
1016:                            // we need to special case Geometry
1017:                            // as JTS is broken
1018:                            // Geometry.equals( Object ) and Geometry.equals( Geometry )
1019:                            // are different 
1020:                            // (We should fold this knowledge into AttributeType...)
1021:                            // 
1022:                            if (!((Geometry) att).equals((Geometry) otherAtt)) {
1023:                                return false;
1024:                            }
1025:                        } else {
1026:                            return false;
1027:                        }
1028:                    }
1029:                }
1030:
1031:                return true;
1032:            }
1033:
1034:            /**
1035:             * Create a derived FeatureType
1036:             * 
1037:             * <p></p>
1038:             *
1039:             * @param featureType
1040:             * @param properties - if null, every property of the feature type in input will be used
1041:             * @param override
1042:             *
1043:             *
1044:             * @throws SchemaException
1045:             */
1046:            public static FeatureType createSubType(FeatureType featureType,
1047:                    String[] properties, CoordinateReferenceSystem override)
1048:                    throws SchemaException {
1049:                return createSubType(featureType, properties, override,
1050:                        featureType.getTypeName(), featureType.getNamespace());
1051:            }
1052:
1053:            public static FeatureType createSubType(FeatureType featureType,
1054:                    String[] properties, CoordinateReferenceSystem override,
1055:                    String typeName, URI namespace) throws SchemaException {
1056:
1057:                if ((properties == null) && (override == null)) {
1058:                    return featureType;
1059:                }
1060:
1061:                if (properties == null) {
1062:                    properties = new String[featureType.getAttributeCount()];
1063:                    for (int i = 0; i < properties.length; i++) {
1064:                        properties[i] = featureType.getAttributeType(i)
1065:                                .getName();
1066:                    }
1067:                }
1068:
1069:                boolean same = featureType.getAttributeCount() == properties.length
1070:                        && featureType.getTypeName().equals(typeName)
1071:                        && featureType.getNamespace().equals(namespace);
1072:
1073:                for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
1074:                    AttributeType type = featureType.getAttributeType(i);
1075:                    same = type.getName().equals(properties[i])
1076:                            && (((override != null) && type instanceof  GeometryAttributeType) ? assertEquals(
1077:                                    override, ((GeometryAttributeType) type)
1078:                                            .getCoordinateSystem())
1079:                                    : true);
1080:                }
1081:
1082:                if (same) {
1083:                    return featureType;
1084:                }
1085:
1086:                AttributeType[] types = new AttributeType[properties.length];
1087:
1088:                for (int i = 0; i < properties.length; i++) {
1089:                    types[i] = featureType.getAttributeType(properties[i]);
1090:
1091:                    if ((override != null)
1092:                            && types[i] instanceof  GeometryAttributeType) {
1093:                        types[i] = new GeometricAttributeType(
1094:                                (GeometricAttributeType) types[i], override);
1095:                    }
1096:                }
1097:
1098:                if (typeName == null)
1099:                    typeName = featureType.getTypeName();
1100:                if (namespace == null)
1101:                    namespace = featureType.getNamespace();
1102:
1103:                return FeatureTypeFactory.newFeatureType(types, typeName,
1104:                        namespace);
1105:            }
1106:
1107:            private static boolean assertEquals(Object o1, Object o2) {
1108:                return o1 == null && o2 == null ? true : (o1 != null ? o1
1109:                        .equals(o2) : false);
1110:            }
1111:
1112:            /**
1113:             * DOCUMENT ME!
1114:             *
1115:             * @param featureType DOCUMENT ME!
1116:             * @param properties DOCUMENT ME!
1117:             *
1118:             * @return DOCUMENT ME!
1119:             *
1120:             * @throws SchemaException DOCUMENT ME!
1121:             */
1122:            public static FeatureType createSubType(FeatureType featureType,
1123:                    String[] properties) throws SchemaException {
1124:                if (properties == null) {
1125:                    return featureType;
1126:                }
1127:
1128:                boolean same = featureType.getAttributeCount() == properties.length;
1129:
1130:                for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
1131:                    same = featureType.getAttributeType(i).getName().equals(
1132:                            properties[i]);
1133:                }
1134:
1135:                if (same) {
1136:                    return featureType;
1137:                }
1138:
1139:                AttributeType[] types = new AttributeType[properties.length];
1140:
1141:                for (int i = 0; i < properties.length; i++) {
1142:                    types[i] = featureType.getAttributeType(properties[i]);
1143:                }
1144:                return FeatureTypeFactory.newFeatureType(types, featureType
1145:                        .getTypeName(), featureType.getNamespace());
1146:            }
1147:
1148:            /**
1149:             * Utility method for FeatureType construction.
1150:             * 
1151:             * <p>
1152:             * Will parse a String of the form: <i>"name:Type,name2:Type2,..."</i>
1153:             * </p>
1154:             * 
1155:             * <p>
1156:             * Where <i>Type</i> is defined by createAttribute.
1157:             * </p>
1158:             * 
1159:             * <p>
1160:             * You may indicate the default Geometry with an astrix: "*geom:Geometry".
1161:             * </p>
1162:             * 
1163:             * <p>
1164:             * Example:<code>name:"",age:0,geom:Geometry,centroid:Point,url:java.io.URL"</code>
1165:             * </p>
1166:             *
1167:             * @param identification identification of FeatureType:
1168:             *        (<i>namesapce</i>).<i>typeName</i>
1169:             * @param typeSpec Specification for FeatureType
1170:             *
1171:             *
1172:             * @throws SchemaException
1173:             */
1174:            public static FeatureType createType(String identification,
1175:                    String typeSpec) throws SchemaException {
1176:                int split = identification.lastIndexOf('.');
1177:                String namespace = (split == -1) ? null : identification
1178:                        .substring(0, split);
1179:                String typeName = (split == -1) ? identification
1180:                        : identification.substring(split + 1);
1181:
1182:                FeatureTypeFactory typeFactory = FeatureTypeFactory
1183:                        .newInstance(typeName);
1184:                try {
1185:                    if (namespace != null) {
1186:                        typeFactory.setNamespace(new URI(namespace));
1187:                    }
1188:                } catch (URISyntaxException badNamespace) {
1189:                    throw new SchemaException(badNamespace);
1190:                }
1191:                typeFactory.setName(typeName);
1192:
1193:                String[] types = typeSpec.split(",");
1194:                int geometryIndex = -1; // records * specified goemetry 
1195:                AttributeType attributeType;
1196:                GeometryAttributeType geometryAttribute = null; // records guess 
1197:
1198:                for (int i = 0; i < types.length; i++) {
1199:                    if (types[i].startsWith("*")) {
1200:                        types[i] = types[i].substring(1);
1201:                        geometryIndex = i;
1202:                    }
1203:
1204:                    attributeType = createAttribute(types[i]);
1205:                    typeFactory.addType(attributeType);
1206:
1207:                    if ((geometryAttribute == null)
1208:                            && attributeType instanceof  GeometryAttributeType) {
1209:                        if (geometryIndex == -1) {
1210:                            geometryAttribute = (GeometryAttributeType) attributeType;
1211:                        } else if (geometryIndex == i) {
1212:                            geometryAttribute = (GeometryAttributeType) attributeType;
1213:                        }
1214:                    }
1215:                }
1216:
1217:                if (geometryAttribute != null) {
1218:                    typeFactory.setDefaultGeometry(geometryAttribute);
1219:                }
1220:
1221:                return typeFactory.getFeatureType();
1222:            }
1223:
1224:            /**
1225:             * DOCUMENT ME!
1226:             *
1227:             * @param type DOCUMENT ME!
1228:             * @param fid DOCUMENT ME!
1229:             * @param text DOCUMENT ME!
1230:             *
1231:             * @return DOCUMENT ME!
1232:             *
1233:             * @throws IllegalAttributeException DOCUMENT ME!
1234:             */
1235:            public static Feature parse(FeatureType type, String fid,
1236:                    String[] text) throws IllegalAttributeException {
1237:                Object[] attributes = new Object[text.length];
1238:
1239:                for (int i = 0; i < text.length; i++) {
1240:                    attributes[i] = type.getAttributeType(i).parse(text[i]);
1241:                }
1242:
1243:                return type.create(attributes, fid);
1244:            }
1245:
1246:            /**
1247:             * Record typeSpec for the provided featureType
1248:             *
1249:             * @param featureType DOCUMENT ME!
1250:             *
1251:             * @return DOCUMENT ME!
1252:             */
1253:            public static String spec(FeatureType featureType) {
1254:                AttributeType[] types = featureType.getAttributeTypes();
1255:                StringBuffer buf = new StringBuffer();
1256:
1257:                for (int i = 0; i < types.length; i++) {
1258:                    buf.append(types[i].getName());
1259:                    buf.append(":");
1260:                    buf.append(typeMap(types[i].getType()));
1261:                    if (types[i] instanceof  GeometryAttributeType) {
1262:                        GeometryAttributeType gat = (GeometryAttributeType) types[i];
1263:                        if (gat.getCoordinateSystem() != null
1264:                                && gat.getCoordinateSystem().getIdentifiers() != null) {
1265:                            for (Iterator it = gat.getCoordinateSystem()
1266:                                    .getIdentifiers().iterator(); it.hasNext();) {
1267:                                Identifier id = (Identifier) it.next();
1268:
1269:                                if ((id.getAuthority() != null)
1270:                                        && id.getAuthority().getTitle().equals(
1271:                                                Citations.EPSG.getTitle())) {
1272:                                    buf.append(":srid=" + id.getCode());
1273:                                    break;
1274:                                }
1275:
1276:                            }
1277:                        }
1278:                    }
1279:
1280:                    if (i < (types.length - 1)) {
1281:                        buf.append(",");
1282:                    }
1283:                }
1284:
1285:                return buf.toString();
1286:            }
1287:
1288:            static Class type(String typeName) throws ClassNotFoundException {
1289:                if (typeMap.containsKey(typeName)) {
1290:                    return (Class) typeMap.get(typeName);
1291:                }
1292:
1293:                return Class.forName(typeName);
1294:            }
1295:
1296:            static String typeMap(Class type) {
1297:                for (Iterator i = typeMap.entrySet().iterator(); i.hasNext();) {
1298:                    Map.Entry entry = (Entry) i.next();
1299:
1300:                    if (entry.getValue().equals(type)) {
1301:                        return (String) entry.getKey();
1302:                    }
1303:                }
1304:
1305:                return type.getName();
1306:            }
1307:
1308:            /**
1309:             * Takes two {@link Query}objects and produce a new one by mixing the
1310:             * restrictions of both of them.
1311:             * 
1312:             * <p>
1313:             * The policy to mix the queries components is the following:
1314:             * 
1315:             * <ul>
1316:             * <li>
1317:             * typeName: type names MUST match (not checked if some or both queries
1318:             * equals to <code>Query.ALL</code>)
1319:             * </li>
1320:             * <li>
1321:             * handle: you must provide one since no sensible choice can be done
1322:             * between the handles of both queries
1323:             * </li>
1324:             * <li>
1325:             * maxFeatures: the lower of the two maxFeatures values will be used (most
1326:             * restrictive)
1327:             * </li>
1328:             * <li>
1329:             * attributeNames: the attributes of both queries will be joined in a
1330:             * single set of attributes. IMPORTANT: only <b><i>explicitly</i></b>
1331:             * requested attributes will be joint, so, if the method
1332:             * <code>retrieveAllProperties()</code> of some of the queries returns
1333:             * <code>true</code> it does not means that all the properties will be
1334:             * joined. You must create the query with the names of the properties you
1335:             * want to load.
1336:             * </li>
1337:             * <li>
1338:             * filter: the filtets of both queries are or'ed
1339:             * </li>
1340:             * </ul>
1341:             * </p>
1342:             *
1343:             * @param firstQuery Query against this DataStore
1344:             * @param secondQuery DOCUMENT ME!
1345:             * @param handle DOCUMENT ME!
1346:             *
1347:             * @return Query restricted to the limits of definitionQuery
1348:             *
1349:             * @throws NullPointerException if some of the queries is null
1350:             * @throws IllegalArgumentException if the type names of both queries do
1351:             *         not match
1352:             */
1353:            public static Query mixQueries(Query firstQuery, Query secondQuery,
1354:                    String handle) {
1355:                if ((firstQuery == null) || (secondQuery == null)) {
1356:                    throw new NullPointerException("got a null query argument");
1357:                }
1358:
1359:                if (firstQuery.equals(Query.ALL)) {
1360:                    return secondQuery;
1361:                } else if (secondQuery.equals(Query.ALL)) {
1362:                    return firstQuery;
1363:                }
1364:
1365:                if ((firstQuery.getTypeName() != null)
1366:                        && (secondQuery.getTypeName() != null)) {
1367:                    if (!firstQuery.getTypeName().equals(
1368:                            secondQuery.getTypeName())) {
1369:                        String msg = "Type names do not match: "
1370:                                + firstQuery.getTypeName() + " != "
1371:                                + secondQuery.getTypeName();
1372:                        throw new IllegalArgumentException(msg);
1373:                    }
1374:                }
1375:
1376:                // mix versions, if possible
1377:                String version;
1378:                if (firstQuery.getVersion() != null) {
1379:                    if (secondQuery.getVersion() != null
1380:                            && !secondQuery.getVersion().equals(
1381:                                    firstQuery.getVersion()))
1382:                        throw new IllegalArgumentException(
1383:                                "First and second query refer different versions");
1384:                    version = firstQuery.getVersion();
1385:                } else {
1386:                    version = secondQuery.getVersion();
1387:                }
1388:
1389:                //none of the queries equals Query.ALL, mix them
1390:                //use the more restrictive max features field
1391:                int maxFeatures = Math.min(firstQuery.getMaxFeatures(),
1392:                        secondQuery.getMaxFeatures());
1393:
1394:                //join attributes names
1395:                String[] propNames = joinAttributes(firstQuery
1396:                        .getPropertyNames(), secondQuery.getPropertyNames());
1397:
1398:                //join filters
1399:                Filter filter = firstQuery.getFilter();
1400:                Filter filter2 = secondQuery.getFilter();
1401:
1402:                if ((filter == null) || filter.equals(Filter.INCLUDE)) {
1403:                    filter = filter2;
1404:                } else if ((filter2 != null) && !filter2.equals(Filter.INCLUDE)) {
1405:                    filter = ff.and(filter, filter2);
1406:                }
1407:
1408:                //build the mixed query
1409:                String typeName = firstQuery.getTypeName() != null ? firstQuery
1410:                        .getTypeName() : secondQuery.getTypeName();
1411:
1412:                DefaultQuery mixed = new DefaultQuery(typeName, filter,
1413:                        maxFeatures, propNames, handle);
1414:                mixed.setVersion(version);
1415:                return mixed;
1416:            }
1417:
1418:            /**
1419:             * Creates a set of attribute names from the two input lists of names,
1420:             * maintaining the order of the first list and appending the non repeated
1421:             * names of the second.
1422:             * <p>
1423:             * In the case where both lists are <code>null</code>, <code>null</code> 
1424:             * is returned.
1425:             * </p>
1426:             *
1427:             * @param atts1 the first list of attribute names, who's order will be
1428:             *        maintained
1429:             * @param atts2 the second list of attribute names, from wich the non
1430:             *        repeated names will be appended to the resulting list
1431:             *
1432:             * @return Set of attribute names from <code>atts1</code> and
1433:             *         <code>atts2</code>
1434:             */
1435:            private static String[] joinAttributes(String[] atts1,
1436:                    String[] atts2) {
1437:                String[] propNames = null;
1438:
1439:                if (atts1 == null && atts2 == null) {
1440:                    return null;
1441:                }
1442:
1443:                List atts = new LinkedList();
1444:
1445:                if (atts1 != null) {
1446:                    atts.addAll(Arrays.asList(atts1));
1447:                }
1448:
1449:                if (atts2 != null) {
1450:                    for (int i = 0; i < atts2.length; i++) {
1451:                        if (!atts.contains(atts2[i])) {
1452:                            atts.add(atts2[i]);
1453:                        }
1454:                    }
1455:                }
1456:
1457:                propNames = new String[atts.size()];
1458:                atts.toArray(propNames);
1459:
1460:                return propNames;
1461:            }
1462:
1463:            /**
1464:             * Returns AttributeType based on String specification (based on UML).
1465:             * 
1466:             * <p>
1467:             * Will parse a String of the form: <i>"name:Type:hint"</i>
1468:             * </p>
1469:             * 
1470:             * <p>
1471:             * Where <i>Type</i> is:
1472:             * </p>
1473:             * 
1474:             * <ul>
1475:             * <li>
1476:             * 0,Interger,int: represents Interger
1477:             * </li>
1478:             * <li>
1479:             * 0.0, Double, double: represents Double
1480:             * </li>
1481:             * <li>
1482:             * "",String,string: represents String
1483:             * </li>
1484:             * <li>
1485:             * Geometry: represents Geometry
1486:             * </li>
1487:             * <li>
1488:             * <i>full.class.path</i>: represents java type
1489:             * </li>
1490:             * </ul>
1491:             * 
1492:             * <p>
1493:             * Where <i>hint</i> is "hint1;hint2;...;hintN", in which "hintN" is one 
1494:             * of:
1495:             * <ul>
1496:             *  <li><code>nillable</code></li>
1497:             *  <li><code>srid=<#></code></li>
1498:             * </ul>
1499:             * </p>
1500:             *
1501:             * @param typeSpec
1502:             *
1503:             *
1504:             * @throws SchemaException If typeSpect could not be interpreted
1505:             */
1506:            static AttributeType createAttribute(String typeSpec)
1507:                    throws SchemaException {
1508:                int split = typeSpec.indexOf(":");
1509:
1510:                String name;
1511:                String type;
1512:                String hint = null;
1513:
1514:                if (split == -1) {
1515:                    name = typeSpec;
1516:                    type = "String";
1517:                } else {
1518:                    name = typeSpec.substring(0, split);
1519:
1520:                    int split2 = typeSpec.indexOf(":", split + 1);
1521:
1522:                    if (split2 == -1) {
1523:                        type = typeSpec.substring(split + 1);
1524:                    } else {
1525:                        type = typeSpec.substring(split + 1, split2);
1526:                        hint = typeSpec.substring(split2 + 1);
1527:                    }
1528:                }
1529:
1530:                try {
1531:                    boolean nillable = true;
1532:                    CoordinateReferenceSystem crs = null;
1533:
1534:                    if (hint != null) {
1535:                        StringTokenizer st = new StringTokenizer(hint, ";");
1536:                        while (st.hasMoreTokens()) {
1537:                            String h = st.nextToken();
1538:                            h = h.trim();
1539:
1540:                            //nillable?
1541:                            //JD: i am pretty sure this hint is useless since the 
1542:                            // default is to make attributes nillable
1543:                            if (h.equals("nillable")) {
1544:                                nillable = true;
1545:                            }
1546:                            //spatial reference identieger?
1547:                            if (h.startsWith("srid=")) {
1548:                                String srid = h.split("=")[1];
1549:                                Integer.parseInt(srid);
1550:                                try {
1551:                                    crs = CRS.decode("EPSG:" + srid);
1552:                                } catch (Exception e) {
1553:                                    String msg = "Error decoding srs: " + srid;
1554:                                    throw new SchemaException(msg, e);
1555:                                }
1556:                            }
1557:                        }
1558:                    }
1559:
1560:                    return AttributeTypeFactory.newAttributeType(name,
1561:                            type(type), nillable, Integer.MAX_VALUE, null, crs);
1562:                } catch (ClassNotFoundException e) {
1563:                    throw new SchemaException("Could not type " + name + " as:"
1564:                            + type);
1565:                }
1566:            }
1567:
1568:            //    /**
1569:            //     * A quick and dirty FilterVisitor.
1570:            //     * 
1571:            //     * <p>
1572:            //     * This is useful when creating FilterVisitors for use with traverseDepth(
1573:            //     * Filter, FilterVisitor ) method.
1574:            //     * </p>
1575:            //     * 
1576:            //     * <p>
1577:            //     * visit( Filter ) and visit( Expression ) will pass their arguments off to
1578:            //     * more specialized functions.
1579:            //     * </p>
1580:            //     * @deprecated TODO: Traversal 
1581:            //     */
1582:            //    abstract static class AbstractFilterVisitor implements FilterVisitor {
1583:            //        /**
1584:            //         * DOCUMENT ME!
1585:            //         *
1586:            //         * @param filter DOCUMENT ME!
1587:            //         */
1588:            //        public void visit(Filter filter) {
1589:            //            if (filter instanceof BetweenFilter) {
1590:            //                visit((BetweenFilter) filter);
1591:            //            } else if (filter instanceof CompareFilter) {
1592:            //                visit((CompareFilter) filter);
1593:            //            } else if (filter instanceof GeometryFilter) {
1594:            //                visit((GeometryFilter) filter);
1595:            //            } else if (filter instanceof LikeFilter) {
1596:            //                visit((LikeFilter) filter);
1597:            //            } else if (filter instanceof LogicFilter) {
1598:            //                visit((LogicFilter) filter);
1599:            //            } else if (filter instanceof NullFilter) {
1600:            //                visit((NullFilter) filter);
1601:            //            } else if (filter instanceof FidFilter) {
1602:            //                visit((FidFilter) filter);
1603:            //            }
1604:            //        }
1605:            //
1606:            //        /**
1607:            //         * DOCUMENT ME!
1608:            //         *
1609:            //         * @param betweenFilter DOCUMENT ME!
1610:            //         */
1611:            //        public void visit(BetweenFilter betweenFilter) {
1612:            //            // DOCUMENT ME!
1613:            //        }
1614:            //
1615:            //        /**
1616:            //         * DOCUMENT ME!
1617:            //         *
1618:            //         * @param comparefilter DOCUMENT ME!
1619:            //         */
1620:            //        public void visit(CompareFilter comparefilter) {
1621:            //            // DOCUMENT ME!
1622:            //        }
1623:            //
1624:            //        /**
1625:            //         * DOCUMENT ME!
1626:            //         *
1627:            //         * @param geometryFilter DOCUMENT ME!
1628:            //         */
1629:            //        public void visit(GeometryFilter geometryFilter) {
1630:            //            // DOCUMENT ME!
1631:            //        }
1632:            //
1633:            //        /**
1634:            //         * DOCUMENT ME!
1635:            //         *
1636:            //         * @param likeFilter DOCUMENT ME!
1637:            //         */
1638:            //        public void visit(LikeFilter likeFilter) {
1639:            //            // DOCUMENT ME!
1640:            //        }
1641:            //
1642:            //        /**
1643:            //         * DOCUMENT ME!
1644:            //         *
1645:            //         * @param logicFilter DOCUMENT ME!
1646:            //         */
1647:            //        public void visit(LogicFilter logicFilter) {
1648:            //            // DOCUMENT ME!
1649:            //        }
1650:            //
1651:            //        /**
1652:            //         * DOCUMENT ME!
1653:            //         *
1654:            //         * @param nullFilter DOCUMENT ME!
1655:            //         */
1656:            //        public void visit(NullFilter nullFilter) {
1657:            //            // DOCUMENT ME!
1658:            //        }
1659:            //
1660:            //        /**
1661:            //         * DOCUMENT ME!
1662:            //         *
1663:            //         * @param fidFilter DOCUMENT ME!
1664:            //         */
1665:            //        public void visit(FidFilter fidFilter) {
1666:            //            // DOCUMENT ME!
1667:            //        }
1668:            //
1669:            //        /**
1670:            //         * DOCUMENT ME!
1671:            //         *
1672:            //         * @param attributeExpression DOCUMENT ME!
1673:            //         */
1674:            //        public void visit(AttributeExpression attributeExpression) {
1675:            //            // DOCUMENT ME!
1676:            //        }
1677:            //
1678:            //        /**
1679:            //         * DOCUMENT ME!
1680:            //         *
1681:            //         * @param expression DOCUMENT ME!
1682:            //         */
1683:            //        public void visit(Expression expression) {
1684:            //            if (expression instanceof AttributeExpression) {
1685:            //                visit((AttributeExpression) expression);
1686:            //            } else if (expression instanceof LiteralExpression) {
1687:            //                visit((LiteralExpression) expression);
1688:            //            } else if (expression instanceof MathExpression) {
1689:            //                visit((MathExpression) expression);
1690:            //            } else if (expression instanceof FunctionExpression) {
1691:            //                visit((FunctionExpression) expression);
1692:            //            }
1693:            //        }
1694:            //
1695:            //        /**
1696:            //         * DOCUMENT ME!
1697:            //         *
1698:            //         * @param literalExpression DOCUMENT ME!
1699:            //         */
1700:            //        public void visit(LiteralExpression literalExpression) {
1701:            //            // DOCUMENT ME!
1702:            //        }
1703:            //
1704:            //        /**
1705:            //         * DOCUMENT ME!
1706:            //         *
1707:            //         * @param mathExpression DOCUMENT ME!
1708:            //         */
1709:            //        public void visit(MathExpression mathExpression) {
1710:            //            // DOCUMENT ME!
1711:            //        }
1712:            //
1713:            //        /**
1714:            //         * DOCUMENT ME!
1715:            //         *
1716:            //         * @param functionExpression DOCUMENT ME!
1717:            //         */
1718:            //        public void visit(FunctionExpression functionExpression) {
1719:            //            // DOCUMENT ME!
1720:            //        }
1721:            //    }
1722:            //
1723:            //    /**
1724:            //     * Will traverse the entire data structure
1725:            //     * 
1726:            //     * @deprecated Please use org.geotools.filter.visitor.AbstractFilterVisitor
1727:            //     */
1728:            //    abstract static class Traversal extends AbstractFilterVisitor {
1729:            //        abstract void traverse(Filter filter);
1730:            //
1731:            //        abstract void traverse(Expression expression);
1732:            //
1733:            //        /**
1734:            //         * DOCUMENT ME!
1735:            //         *
1736:            //         * @param betweenFilter DOCUMENT ME!
1737:            //         */
1738:            //        public void visit(BetweenFilter betweenFilter) {
1739:            //            traverse(betweenFilter.getLeftValue());
1740:            //            visit(betweenFilter.getLeftValue());
1741:            //
1742:            //            traverse(betweenFilter.getMiddleValue());
1743:            //            visit(betweenFilter.getMiddleValue());
1744:            //
1745:            //            traverse(betweenFilter.getRightValue());
1746:            //            visit(betweenFilter.getRightValue());
1747:            //        }
1748:            //
1749:            //        /**
1750:            //         * DOCUMENT ME!
1751:            //         *
1752:            //         * @param compareFilter DOCUMENT ME!
1753:            //         */
1754:            //        public void visit(CompareFilter compareFilter) {
1755:            //            traverse(compareFilter.getLeftValue());
1756:            //            visit(compareFilter.getLeftValue());
1757:            //
1758:            //            traverse(compareFilter.getRightValue());
1759:            //            visit(compareFilter.getRightValue());
1760:            //        }
1761:            //
1762:            //        /**
1763:            //         * DOCUMENT ME!
1764:            //         *
1765:            //         * @param geometryFilter DOCUMENT ME!
1766:            //         */
1767:            //        public void visit(GeometryFilter geometryFilter) {
1768:            //            traverse(geometryFilter.getLeftGeometry());
1769:            //            visit(geometryFilter.getLeftGeometry());
1770:            //
1771:            //            traverse(geometryFilter.getRightGeometry());
1772:            //            visit(geometryFilter.getRightGeometry());
1773:            //        }
1774:            //
1775:            //        /**
1776:            //         * DOCUMENT ME!
1777:            //         *
1778:            //         * @param likeFilter DOCUMENT ME!
1779:            //         */
1780:            //        public void visit(LikeFilter likeFilter) {
1781:            //            traverse(likeFilter.getValue());
1782:            //            visit(likeFilter.getValue());
1783:            //        }
1784:            //
1785:            //        /**
1786:            //         * DOCUMENT ME!
1787:            //         *
1788:            //         * @param logicFilter DOCUMENT ME!
1789:            //         */
1790:            //        public void visit(LogicFilter logicFilter) {
1791:            //            for (Iterator i = logicFilter.getFilterIterator(); i.hasNext();) {
1792:            //                // GR: LogicFilters are the only ones whose members are Filters
1793:            //                // instead of Expressions, so it was causing ClassCastExceptions
1794:            //                Filter f = (Filter) i.next();
1795:            //                traverse(f);
1796:            //                visit((org.geotools.filter.Filter) f);
1797:            //            }
1798:            //        }
1799:            //
1800:            //        /**
1801:            //         * DOCUMENT ME!
1802:            //         *
1803:            //         * @param nullFilter DOCUMENT ME!
1804:            //         */
1805:            //        public void visit(NullFilter nullFilter) {
1806:            //            traverse(nullFilter.getNullCheckValue());
1807:            //            visit(nullFilter.getNullCheckValue());
1808:            //        }
1809:            //
1810:            //        /**
1811:            //         * DOCUMENT ME!
1812:            //         *
1813:            //         * @param mathExpression DOCUMENT ME!
1814:            //         */
1815:            //        public void visit(MathExpression mathExpression) {
1816:            //            traverse(mathExpression.getLeftValue());
1817:            //            visit(mathExpression.getLeftValue());
1818:            //
1819:            //            traverse(mathExpression.getRightValue());
1820:            //            visit(mathExpression.getRightValue());
1821:            //        }
1822:            //
1823:            //        /**
1824:            //         * DOCUMENT ME!
1825:            //         *
1826:            //         * @param functionExpression DOCUMENT ME!
1827:            //         */
1828:            //        public void visit(FunctionExpression functionExpression) {
1829:            //            Expression[] args = functionExpression.getArgs();
1830:            //
1831:            //            for (int i = 0; i < args.length; i++) {
1832:            //                traverse(args[i]);
1833:            //                visit(args[i]);
1834:            //            }
1835:            //        }
1836:            //    }
1837:            //	
1838:
1839:            /**
1840:             * Will traverse the entire data structure
1841:             */
1842:            abstract static class Traversal extends DefaultFilterVisitor {
1843:                abstract void traverse(Filter filter);
1844:
1845:                abstract void traverse(Expression expression);
1846:
1847:                public Object visit(ExcludeFilter filter, Object data) {
1848:                    traverse(filter);
1849:                    return super .visit(filter, data);
1850:                }
1851:
1852:                public Object visit(IncludeFilter filter, Object data) {
1853:                    traverse(filter);
1854:                    return super .visit(filter, data);
1855:                }
1856:
1857:                public Object visit(And filter, Object data) {
1858:                    traverse(filter);
1859:                    return super .visit(filter, data);
1860:                }
1861:
1862:                public Object visit(Id filter, Object data) {
1863:                    traverse(filter);
1864:                    return super .visit(filter, data);
1865:                }
1866:
1867:                public Object visit(Not filter, Object data) {
1868:                    traverse(filter);
1869:                    return super .visit(filter, data);
1870:                }
1871:
1872:                public Object visit(Or filter, Object data) {
1873:                    traverse(filter);
1874:                    return super .visit(filter, data);
1875:                }
1876:
1877:                public Object visit(PropertyIsBetween filter, Object data) {
1878:                    traverse(filter);
1879:                    return super .visit(filter, data);
1880:                }
1881:
1882:                public Object visit(PropertyIsEqualTo filter, Object data) {
1883:                    traverse(filter);
1884:                    return super .visit(filter, data);
1885:                }
1886:
1887:                public Object visit(PropertyIsNotEqualTo filter, Object data) {
1888:                    traverse(filter);
1889:                    return super .visit(filter, data);
1890:                }
1891:
1892:                public Object visit(PropertyIsGreaterThan filter, Object data) {
1893:                    traverse(filter);
1894:                    return super .visit(filter, data);
1895:                }
1896:
1897:                public Object visit(PropertyIsGreaterThanOrEqualTo filter,
1898:                        Object data) {
1899:                    traverse(filter);
1900:                    return super .visit(filter, data);
1901:                }
1902:
1903:                public Object visit(PropertyIsLessThan filter, Object data) {
1904:                    traverse(filter);
1905:                    return super .visit(filter, data);
1906:                }
1907:
1908:                public Object visit(PropertyIsLessThanOrEqualTo filter,
1909:                        Object data) {
1910:                    traverse(filter);
1911:                    return super .visit(filter, data);
1912:                }
1913:
1914:                public Object visit(PropertyIsLike filter, Object data) {
1915:                    traverse(filter);
1916:                    return super .visit(filter, data);
1917:                }
1918:
1919:                public Object visit(PropertyIsNull filter, Object data) {
1920:                    traverse(filter);
1921:                    return super .visit(filter, data);
1922:                }
1923:
1924:                public Object visit(BBOX filter, Object data) {
1925:                    traverse(filter);
1926:                    return super .visit(filter, data);
1927:                }
1928:
1929:                public Object visit(Beyond filter, Object data) {
1930:                    traverse(filter);
1931:                    return super .visit(filter, data);
1932:                }
1933:
1934:                public Object visit(Contains filter, Object data) {
1935:                    traverse(filter);
1936:                    return super .visit(filter, data);
1937:                }
1938:
1939:                public Object visit(Crosses filter, Object data) {
1940:                    traverse(filter);
1941:                    return super .visit(filter, data);
1942:                }
1943:
1944:                public Object visit(Disjoint filter, Object data) {
1945:                    traverse(filter);
1946:                    return super .visit(filter, data);
1947:                }
1948:
1949:                public Object visit(DWithin filter, Object data) {
1950:                    traverse(filter);
1951:                    return super .visit(filter, data);
1952:                }
1953:
1954:                public Object visit(Equals filter, Object data) {
1955:                    traverse(filter);
1956:                    return super .visit(filter, data);
1957:                }
1958:
1959:                public Object visit(Intersects filter, Object data) {
1960:                    traverse(filter);
1961:                    return super .visit(filter, data);
1962:                }
1963:
1964:                public Object visit(Overlaps filter, Object data) {
1965:                    traverse(filter);
1966:                    return super .visit(filter, data);
1967:                }
1968:
1969:                public Object visit(Touches filter, Object data) {
1970:                    traverse(filter);
1971:                    return super .visit(filter, data);
1972:                }
1973:
1974:                public Object visit(Within filter, Object data) {
1975:                    traverse(filter);
1976:                    return super .visit(filter, data);
1977:                }
1978:
1979:                public Object visitNullFilter(Object data) {
1980:                    return super .visitNullFilter(data);
1981:                }
1982:
1983:                public Object visit(NilExpression expr, Object data) {
1984:                    traverse(expr);
1985:                    return super .visit(expr, data);
1986:                }
1987:
1988:                public Object visit(Add expr, Object data) {
1989:                    traverse(expr);
1990:                    return super .visit(expr, data);
1991:                }
1992:
1993:                public Object visit(Divide expr, Object data) {
1994:                    traverse(expr);
1995:                    return super .visit(expr, data);
1996:                }
1997:
1998:                public Object visit(Function expr, Object data) {
1999:                    traverse(expr);
2000:                    return super .visit(expr, data);
2001:                }
2002:
2003:                public Object visit(Literal expr, Object data) {
2004:                    traverse(expr);
2005:                    return super .visit(expr, data);
2006:                }
2007:
2008:                public Object visit(Multiply expr, Object data) {
2009:                    traverse(expr);
2010:                    return super .visit(expr, data);
2011:                }
2012:
2013:                public Object visit(PropertyName expr, Object data) {
2014:                    traverse(expr);
2015:                    return super .visit(expr, data);
2016:                }
2017:
2018:                public Object visit(Subtract expr, Object data) {
2019:                    traverse(expr);
2020:                    return super .visit(expr, data);
2021:                }
2022:            }
2023:
2024:            /**
2025:             * Manually calculates the bounds of a feature collection.
2026:             * @param collection
2027:             * @return
2028:             */
2029:            public static Envelope bounds(FeatureCollection collection) {
2030:                Iterator i = collection.iterator();
2031:                try {
2032:                    Envelope bounds = new Envelope();
2033:                    if (!i.hasNext()) {
2034:                        bounds.setToNull();
2035:                        return bounds;
2036:                    }
2037:
2038:                    bounds.init(((Feature) i.next()).getBounds());
2039:                    return bounds;
2040:                } finally {
2041:                    collection.close(i);
2042:                }
2043:            }
2044:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.