Source Code Cross Referenced for SQLBuilder.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » jdbc » 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.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.geotools.data.jdbc;
0002:
0003:        import java.io.IOException;
0004:        import java.util.ArrayList;
0005:        import java.util.Iterator;
0006:        import java.util.List;
0007:        import java.util.logging.Level;
0008:
0009:        import org.geotools.factory.CommonFactoryFinder;
0010:        import org.geotools.feature.AttributeType;
0011:        import org.geotools.feature.FeatureType;
0012:        import org.geotools.filter.LikeFilterImpl;
0013:        import org.geotools.geometry.jts.JTS;
0014:        import org.geotools.referencing.CRS;
0015:        import org.geotools.util.Converters;
0016:        import org.opengis.filter.And;
0017:        import org.opengis.filter.BinaryComparisonOperator;
0018:        import org.opengis.filter.BinaryLogicOperator;
0019:        import org.opengis.filter.ExcludeFilter;
0020:        import org.opengis.filter.Filter;
0021:        import org.opengis.filter.FilterFactory;
0022:        import org.opengis.filter.FilterVisitor;
0023:        import org.opengis.filter.Id;
0024:        import org.opengis.filter.IncludeFilter;
0025:        import org.opengis.filter.Not;
0026:        import org.opengis.filter.Or;
0027:        import org.opengis.filter.PropertyIsBetween;
0028:        import org.opengis.filter.PropertyIsEqualTo;
0029:        import org.opengis.filter.PropertyIsGreaterThan;
0030:        import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
0031:        import org.opengis.filter.PropertyIsLessThan;
0032:        import org.opengis.filter.PropertyIsLessThanOrEqualTo;
0033:        import org.opengis.filter.PropertyIsLike;
0034:        import org.opengis.filter.PropertyIsNotEqualTo;
0035:        import org.opengis.filter.PropertyIsNull;
0036:        import org.opengis.filter.expression.Add;
0037:        import org.opengis.filter.expression.BinaryExpression;
0038:        import org.opengis.filter.expression.Divide;
0039:        import org.opengis.filter.expression.ExpressionVisitor;
0040:        import org.opengis.filter.expression.Function;
0041:        import org.opengis.filter.expression.Literal;
0042:        import org.opengis.filter.expression.Multiply;
0043:        import org.opengis.filter.expression.NilExpression;
0044:        import org.opengis.filter.expression.PropertyName;
0045:        import org.opengis.filter.expression.Subtract;
0046:        import org.opengis.filter.spatial.BBOX;
0047:        import org.opengis.filter.spatial.Beyond;
0048:        import org.opengis.filter.spatial.BinarySpatialOperator;
0049:        import org.opengis.filter.spatial.Contains;
0050:        import org.opengis.filter.spatial.Crosses;
0051:        import org.opengis.filter.spatial.DWithin;
0052:        import org.opengis.filter.spatial.Disjoint;
0053:        import org.opengis.filter.spatial.DistanceBufferOperator;
0054:        import org.opengis.filter.spatial.Equals;
0055:        import org.opengis.filter.spatial.Intersects;
0056:        import org.opengis.filter.spatial.Overlaps;
0057:        import org.opengis.filter.spatial.Touches;
0058:        import org.opengis.filter.spatial.Within;
0059:        import org.opengis.metadata.Identifier;
0060:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0061:
0062:        import com.vividsolutions.jts.geom.Envelope;
0063:        import com.vividsolutions.jts.geom.Geometry;
0064:        import com.vividsolutions.jts.io.WKTWriter;
0065:
0066:        /**
0067:         * Builds raw sql statements.
0068:         * <p>
0069:         * This class should be subclasses to accomodate different dialects of sql. 
0070:         * </p>
0071:         * <p>
0072:         * This class maintains state and is <b>not thread safe</b>. 
0073:         * </p>
0074:         * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
0075:         *
0076:         */
0077:        public class SQLBuilder implements  ExpressionVisitor, FilterVisitor {
0078:            /**
0079:             * The data store
0080:             */
0081:            JDBCDataStore dataStore;
0082:
0083:            /**
0084:             * Filter factory used to create filters
0085:             */
0086:            FilterFactory filterFactory = CommonFactoryFinder
0087:                    .getFilterFactory(null);
0088:
0089:            //internal state
0090:            /**
0091:             * SQL statement buffer
0092:             */
0093:            StringBuffer sql;
0094:            /**
0095:             * Feature type being worked on
0096:             */
0097:            FeatureType featureType;
0098:            /**
0099:             * Post-processing filter
0100:             */
0101:            Filter postFilter;
0102:
0103:            public SQLBuilder(JDBCDataStore dataStore) {
0104:                this .dataStore = dataStore;
0105:            }
0106:
0107:            public void setFilterFactory(FilterFactory filterFactory) {
0108:                this .filterFactory = filterFactory;
0109:            }
0110:
0111:            public FilterFactory getFilterFactory() {
0112:                return filterFactory;
0113:            }
0114:
0115:            /**
0116:             * Initializes the state of the builder.
0117:             */
0118:            protected void init() {
0119:                sql = new StringBuffer();
0120:                postFilter = null;
0121:                featureType = null;
0122:            }
0123:
0124:            /**
0125:             * Initializes the state of the builder setting the feature type being
0126:             * worked on.
0127:             * 
0128:             */
0129:            protected void init(FeatureType featureType) {
0130:                init();
0131:                this .featureType = featureType;
0132:            }
0133:
0134:            //
0135:            // Methods for encoding full statements
0136:            /**
0137:             * Builds a "CREATE TABLE" statement.
0138:             * <p>
0139:             * 
0140:             * </p>
0141:             *
0142:             * @return A statement of the form "CREATE TABLE ...".
0143:             */
0144:            public String createTable(FeatureType featureType) {
0145:                init(featureType);
0146:
0147:                sql.append("CREATE TABLE ");
0148:
0149:                //table name
0150:                table(featureType.getTypeName());
0151:
0152:                //table definition
0153:                String[] sqlTypeNames = null;
0154:
0155:                try {
0156:                    sqlTypeNames = JDBCUtils.sqlTypeNames(featureType,
0157:                            dataStore);
0158:                } catch (Exception e) {
0159:                    throw new RuntimeException(e);
0160:                }
0161:
0162:                sql.append(" ( ");
0163:
0164:                for (int i = 0; i < sqlTypeNames.length; i++) {
0165:                    AttributeType type = featureType.getAttributeType(i);
0166:
0167:                    //the column name
0168:                    name(type.getName());
0169:                    sql.append(" ");
0170:
0171:                    //sql type name
0172:                    sql.append(sqlTypeNames[i]);
0173:
0174:                    if (i < (sqlTypeNames.length - 1)) {
0175:                        sql.append(", ");
0176:                    }
0177:                }
0178:
0179:                sql.append(" )");
0180:                return sql.toString();
0181:            }
0182:
0183:            /**
0184:             * Builds a "DROP TABLE" statement.
0185:             *
0186:             * @return A statement of the form "DROP TABLE ...".
0187:             */
0188:            public String dropTable(FeatureType featureType) {
0189:                init(featureType);
0190:
0191:                sql.append("DROP TABLE ");
0192:
0193:                //table name
0194:                table(featureType.getTypeName());
0195:
0196:                return sql.toString();
0197:            }
0198:
0199:            /**
0200:             * Builds a query which selects the envelope or bounding box of every 
0201:             * feature / row in a table. 
0202:             * <p>
0203:             * Convenience for <code>bounds(featureType,null)</code>.
0204:             * </p>
0205:             * 
0206:             * @return A statement of the form "SELECT envelope(...) FROM ..."
0207:             */
0208:            public String bounds(FeatureType featureType) {
0209:                return bounds(featureType, null);
0210:            }
0211:
0212:            /**
0213:             * Builds a query which selects the envelope or bounding box of a subset of 
0214:             * features / rows in a table. 
0215:             * <p>
0216:             * The <tt>filter</tt> argument can be used to filter those rows / features
0217:             * returned or can be <code>null</code> to return all rows.
0218:             * </p>
0219:             * 
0220:             * @return A statement of the form "SELECT envelope(...) FROM ... WHERE ..."
0221:             */
0222:            public String bounds(FeatureType featureType, Filter filter) {
0223:                init(featureType);
0224:
0225:                //select
0226:                sql.append("SELECT envelope(");
0227:                geometry(featureType);
0228:                sql.append(")");
0229:
0230:                //from
0231:                from(featureType);
0232:
0233:                //where
0234:                if (filter != null && filter != Filter.INCLUDE) {
0235:                    where(filter);
0236:                }
0237:
0238:                return sql.toString();
0239:            }
0240:
0241:            /**
0242:             * Builds a query which selects the bound of all rows / features in a table.
0243:             * <p>
0244:             * Convenience for <code>count(null)</code>
0245:             * </p>
0246:             * @return A statement of the form "SELECT count(*) FROM ..."
0247:             */
0248:            public String count(FeatureType featureType) {
0249:                return count(featureType, null);
0250:            }
0251:
0252:            /**
0253:             * Builds a query which selects the count of a subset of rows / features in 
0254:             * a table.
0255:             * <p>
0256:             * The <tt>filter</tt> argument can be used to filter those rows / features
0257:             * included in the count, or <code>null</code> to include all rows.
0258:             * </p>
0259:             *
0260:             * @return A statement of the form "SELECT count(*) FROM ... WHERE ..."
0261:             */
0262:            public String count(FeatureType featureType, Filter filter) {
0263:                init(featureType);
0264:
0265:                //select
0266:                sql.append("SELECT count(*)");
0267:
0268:                //from
0269:                from(featureType);
0270:
0271:                //where
0272:                if (filter != null && filter != Filter.INCLUDE) {
0273:                    where(filter);
0274:                }
0275:
0276:                return sql.toString();
0277:            }
0278:
0279:            /**
0280:             * Builds a statement of the form "SELECT att1,att2,...,attN FROM ... WHERE ...";
0281:             * <p>
0282:             * The <tt>filter</tt> parameter may be null to omit the where clause.
0283:             * </p>
0284:             * 
0285:             */
0286:            public String select(FeatureType featureType, Filter filter) {
0287:                init(featureType);
0288:
0289:                PrimaryKey pkey;
0290:                try {
0291:                    pkey = dataStore.getPrimaryKey(featureType);
0292:                } catch (IOException e) {
0293:                    String msg = "Unable to obtain primary key";
0294:                    throw new RuntimeException(msg, e);
0295:                }
0296:
0297:                //select
0298:                int n = pkey.columns.length;
0299:                String[] propertyNames = new String[n
0300:                        + featureType.getAttributeTypes().length];
0301:
0302:                //primary key columns
0303:                for (int i = 0; i < n; i++) {
0304:                    propertyNames[i] = pkey.columns[i].name;
0305:                }
0306:                //attribute columns
0307:                for (int i = n; i < propertyNames.length; i++) {
0308:                    propertyNames[i] = featureType.getAttributeType(i - n)
0309:                            .getName();
0310:                }
0311:                select(featureType, propertyNames);
0312:
0313:                //from
0314:                from(featureType);
0315:
0316:                //where
0317:                if (filter != null && filter != Filter.INCLUDE) {
0318:                    where(filter);
0319:                }
0320:
0321:                return sql.toString();
0322:            }
0323:
0324:            /**
0325:             * Builds a statement of the form "DELETE FROM ... WHERE ...";
0326:             * <p>
0327:             * The <tt>filter</tt> parameter may be null to omit the where clause.
0328:             * </p>
0329:             * 
0330:             */
0331:            public void delete(FeatureType featureType, Filter filter) {
0332:                init(featureType);
0333:
0334:                //delete
0335:                sql.append("DELETE ");
0336:
0337:                //from
0338:                from(featureType);
0339:
0340:                //where
0341:                if (filter != null && filter != Filter.INCLUDE) {
0342:                    where(filter);
0343:                }
0344:
0345:            }
0346:
0347:            //	public String select(Query query) {
0348:            //        init();
0349:            //
0350:            //        //select
0351:            //        select(query.getPropertyNames());
0352:            //
0353:            //        //from
0354:            //        from();
0355:            //
0356:            //        //where
0357:            //        if ((query.getFilter() != null) && (query.getFilter() != Filter.INCLUDE)) {
0358:            //            where(query.getFilter());
0359:            //        }
0360:            //
0361:            //        //order by
0362:            //        if ((query.getSortBy() != null) && (query.getSortBy().length > 0)) {
0363:            //            sortBy(query.getSortBy());
0364:            //        }
0365:            //
0366:            //        return sql.toString();
0367:            //    }
0368:            //	
0369:            //
0370:            // Methods for encoding partial statements
0371:            //
0372:            /**
0373:             * Encodes the select clause of a query.
0374:             * <p>
0375:             * If <param>propertyNames</param> is null or empty then "*" is used.
0376:             * </p>
0377:             * @param propertyNames The array of properties / columns in the select.
0378:             */
0379:            protected void select(FeatureType featureType,
0380:                    String[] propertyNames) {
0381:                sql.append("SELECT ");
0382:
0383:                if ((propertyNames == null) || (propertyNames.length == 0)) {
0384:                    sql.append("*");
0385:                } else {
0386:                    for (int i = 0; i < propertyNames.length; i++) {
0387:                        PropertyName propertyName = filterFactory
0388:                                .property(propertyNames[i]);
0389:
0390:                        //get the attribute type
0391:                        AttributeType attributeType = (AttributeType) propertyName
0392:                                .evaluate(featureType);
0393:
0394:                        if (attributeType != null) {
0395:                            //check for geometry, because it is encided differnently
0396:                            if (Geometry.class.isAssignableFrom(attributeType
0397:                                    .getType())) {
0398:
0399:                            }
0400:                        }
0401:
0402:                        //encode it
0403:                        propertyName.accept(this , null);
0404:
0405:                        if (i < (propertyNames.length - 1)) {
0406:                            sql.append(", ");
0407:                        }
0408:                    }
0409:                }
0410:            }
0411:
0412:            /**
0413:             * Encodes "FROM <table>".
0414:             *
0415:             */
0416:            protected void from(FeatureType featureType) {
0417:                sql.append(" FROM ");
0418:                table(featureType.getTypeName());
0419:            }
0420:
0421:            /**
0422:             * Encodes the table name of a query qualifying it with the database schema
0423:             * name if set.
0424:             * 
0425:             * @param name The name of the table.
0426:             * 
0427:             */
0428:            protected void table(String name) {
0429:                //qualify with schema
0430:                if (dataStore.getDatabaseSchema() != null) {
0431:                    name(dataStore.getDatabaseSchema());
0432:                    sql.append(".");
0433:                }
0434:
0435:                //local part
0436:                name(name);
0437:            }
0438:
0439:            /**
0440:             * Encodes the WHERE clause of a query.
0441:             *
0442:             * @param filter The filter defining the where clause, non-null.
0443:             *
0444:             */
0445:            protected void where(Filter filter) {
0446:                sql.append(" WHERE ");
0447:                filter.accept(this , null);
0448:            }
0449:
0450:            /**
0451:             * Encodes the name of the default geometry in a statement.
0452:             * <p>
0453:             * </p>
0454:             *
0455:             */
0456:            protected void geometry(FeatureType featureType) {
0457:                if (featureType.getDefaultGeometry() == null) {
0458:                    String msg = "No geometry column to encode";
0459:                    throw new IllegalStateException(msg);
0460:                }
0461:
0462:                name(featureType.getDefaultGeometry().getName());
0463:            }
0464:
0465:            /**
0466:             * Encodes a name to be used in an sql statement.
0467:             * <p>
0468:             * This implementation wraps the name in double quotes.
0469:             * <p>
0470:             *
0471:             * @param raw The raw name.
0472:             *
0473:             */
0474:            protected void name(String raw) {
0475:                sql.append("\"" + raw + "\"");
0476:            }
0477:
0478:            /**
0479:             * Encodes a string to be used in an sql statement.
0480:             *
0481:             * @param raw The raw string.
0482:             * @param sql The sql statement buffer
0483:             *
0484:             */
0485:            protected void string(String raw, StringBuffer sql) {
0486:                sql.append("'" + raw + "'");
0487:            }
0488:
0489:            /**
0490:             * Encodes a geometry with a known srid to be used in an sql statement.
0491:             *
0492:             * @param geometry The geometry to encode.
0493:             * @param srid The spatial reference id of the geometry
0494:             * @param sql HTe sql statement buffer
0495:             */
0496:            protected void geometry(Geometry geometry, String srid,
0497:                    StringBuffer sql) {
0498:                String wkt = new WKTWriter().write(geometry);
0499:                sql.append("GeometryFromText( '" + wkt + "', ");
0500:                srid(srid, sql);
0501:                sql.append(" )");
0502:            }
0503:
0504:            /**
0505:             * Encodes a srid to be used in an sql statement
0506:             *
0507:             * @param srid The raw spatial reference id of the geometry
0508:             * @param sql HTe sql statement buffer
0509:             */
0510:            protected void srid(String raw, StringBuffer sql) {
0511:                if (raw == null) {
0512:                    sql.append("0");
0513:                } else if (raw.matches("[0-9]+")) {
0514:                    sql.append(raw);
0515:                } else if (raw.matches(".*:[0-9]+")) {
0516:                    raw = raw.replaceAll(".*:([0-9]+)", "$1");
0517:                    sql.append(raw);
0518:                }
0519:            }
0520:
0521:            /**
0522:             * Encodes <code>nulL</code> to be used in an sql statement.
0523:             *
0524:             * @param sql The sql statement buffer
0525:             */
0526:            protected void nil(StringBuffer sql) {
0527:                sql.append("NULL");
0528:            }
0529:
0530:            /**
0531:             * @return The current sql buffer.
0532:             */
0533:            protected StringBuffer getSQL() {
0534:                return sql;
0535:            }
0536:
0537:            //
0538:            // ExpressionVisitor methods
0539:            //
0540:            /**
0541:             * Encodes a {@link PropertyName} in an sql statement.
0542:             * <p>
0543:             * If the AttributeType can be infered from {@link #featureType} then its name
0544:             * is used directly.
0545:             * </p>
0546:             *
0547:             * @return The class binding of the attribute type, or <code>null</code> if unknown.
0548:             */
0549:            public Object visit(PropertyName propertyName, Object data) {
0550:                try {
0551:                    //1. evaluate against the type to get the AttributeType
0552:                    AttributeType attributeType = (AttributeType) propertyName
0553:                            .evaluate(featureType);
0554:
0555:                    if (attributeType != null) {
0556:                        //encode the name of the attribute, not the property name itself
0557:                        name(attributeType.getName());
0558:
0559:                        //return the type as the return 
0560:                        return attributeType.getType();
0561:                    }
0562:
0563:                    //2. not in type, could it be a primary key?
0564:                    PrimaryKey key = dataStore.getPrimaryKey(featureType);
0565:
0566:                    //serach for the property in the primary key, encode it and return its type
0567:                    for (int i = 0; i < key.columns.length; i++) {
0568:                        String name = key.columns[i].name;
0569:
0570:                        if (propertyName.getPropertyName().equals(name)) {
0571:                            //encode it
0572:                            name(propertyName.getPropertyName());
0573:
0574:                            //return the type
0575:                            return key.columns[i].type;
0576:                        }
0577:                    }
0578:
0579:                    //3. give up, just encode directly
0580:                    name(propertyName.getPropertyName());
0581:
0582:                    //return nothing
0583:                    return null;
0584:                } catch (Exception e) {
0585:                    throw new RuntimeException(e);
0586:                }
0587:            }
0588:
0589:            //
0590:            // Arithmetic operators
0591:            //
0592:            public Object visit(Add add, Object data) {
0593:                return visit(add, data, "+");
0594:            }
0595:
0596:            public Object visit(Subtract subtract, Object data) {
0597:                return visit(subtract, data, "-");
0598:            }
0599:
0600:            public Object visit(Multiply multiply, Object data) {
0601:                return visit(multiply, data, "*");
0602:            }
0603:
0604:            public Object visit(Divide divide, Object data) {
0605:                return visit(divide, data, "/");
0606:            }
0607:
0608:            protected Object visit(BinaryExpression expression, Object data,
0609:                    String operator) {
0610:                sql.append("( ");
0611:                data = expression.getExpression1().accept(this , data);
0612:
0613:                sql.append(" ) " + operator + " ( ");
0614:                data = expression.getExpression2().accept(this , data);
0615:
0616:                sql.append(" )");
0617:
0618:                return data;
0619:            }
0620:
0621:            public Object visit(Literal literal, Object data) {
0622:                Object value = null;
0623:
0624:                //was the type passed in as a hint?
0625:                if (data instanceof  Class) {
0626:                    //special case for numerics, let the database do the conversions
0627:                    // it needs to
0628:                    if (Number.class.isAssignableFrom((Class) data)) {
0629:                        //value = literal.evaluate( null, BigDecimal.class );
0630:                        value = literal.evaluate(null, Number.class);
0631:                    } else {
0632:                        //non numeric, just convert
0633:                        value = literal.evaluate(null, (Class) data);
0634:                    }
0635:                } else {
0636:                    //just evaluate
0637:                    value = literal.evaluate(null);
0638:                }
0639:
0640:                //check for string
0641:                if (value instanceof  String) {
0642:                    string((String) value, sql);
0643:
0644:                    return data;
0645:                }
0646:
0647:                //check for geometry
0648:                if (value instanceof  Geometry) {
0649:                    //figure out srid
0650:                    CoordinateReferenceSystem crs = null;
0651:
0652:                    //passed in?
0653:                    if (data instanceof  CoordinateReferenceSystem) {
0654:                        crs = (CoordinateReferenceSystem) data;
0655:                    } else {
0656:                        //check the feature type
0657:                        if (featureType.getDefaultGeometry() != null) {
0658:                            crs = featureType.getDefaultGeometry()
0659:                                    .getCoordinateSystem();
0660:                        }
0661:                    }
0662:
0663:                    //convert to a postgis srid
0664:                    String srid = null;
0665:
0666:                    if (crs != null) {
0667:                        srid = encode(crs);
0668:                    }
0669:
0670:                    geometry((Geometry) value, srid, sql);
0671:
0672:                    return data;
0673:                }
0674:
0675:                //convert to string
0676:                String encoded = (String) Converters.convert(value,
0677:                        String.class);
0678:
0679:                if (encoded == null) {
0680:                    //fall back to toString()
0681:                    encoded = value.toString();
0682:                }
0683:
0684:                sql.append(encoded);
0685:
0686:                return data;
0687:            }
0688:
0689:            public Object visit(NilExpression expression, Object extraData) {
0690:                // TODO Auto-generated method stub
0691:                return null;
0692:            }
0693:
0694:            public Object visit(Function expression, Object extraData) {
0695:                // TODO Auto-generated method stub
0696:                return null;
0697:            }
0698:
0699:            /**
0700:             * Helper method to encode a crs. Can we have this on CRS?
0701:             */
0702:            String encode(CoordinateReferenceSystem crs) {
0703:                if (crs == null) {
0704:                    return null;
0705:                }
0706:
0707:                for (Iterator i = crs.getIdentifiers().iterator(); i.hasNext();) {
0708:                    Identifier id = (Identifier) i.next();
0709:
0710:                    return id.toString();
0711:                }
0712:
0713:                return null;
0714:            }
0715:
0716:            //
0717:            // FilterVisitor api
0718:            //
0719:            public Object visitNullFilter(Object data) {
0720:                return null;
0721:            }
0722:
0723:            public Object visit(ExcludeFilter exclude, Object data) {
0724:                sql.append("1 = 0");
0725:
0726:                return data;
0727:            }
0728:
0729:            public Object visit(IncludeFilter include, Object data) {
0730:                sql.append("1 = 1");
0731:
0732:                return data;
0733:            }
0734:
0735:            //
0736:            // logical operators
0737:            //
0738:            public Object visit(Not not, Object data) {
0739:                sql.append("NOT ( ");
0740:                data = not.getFilter().accept(this , data);
0741:                sql.append(" )");
0742:
0743:                return data;
0744:            }
0745:
0746:            public Object visit(And and, Object data) {
0747:                return visit(and, data, "AND");
0748:            }
0749:
0750:            public Object visit(Or or, Object data) {
0751:                return visit(or, data, "OR");
0752:            }
0753:
0754:            protected Object visit(BinaryLogicOperator logic, Object data,
0755:                    String operator) {
0756:                boolean parentheses = logic.getChildren().size() > 1;
0757:
0758:                //encode each child
0759:                for (Iterator f = logic.getChildren().iterator(); f.hasNext();) {
0760:                    Filter filter = (Filter) f.next();
0761:
0762:                    if (parentheses) {
0763:                        sql.append("( ");
0764:                    }
0765:
0766:                    data = filter.accept(this , data);
0767:
0768:                    if (parentheses) {
0769:                        sql.append(" )");
0770:                    }
0771:
0772:                    if (f.hasNext()) {
0773:                        sql.append(" " + operator + " ");
0774:                    }
0775:                }
0776:
0777:                return data;
0778:            }
0779:
0780:            //
0781:            //id filter
0782:            //
0783:            public Object visit(Id id, Object data) {
0784:                try {
0785:                    //get the primary key
0786:                    PrimaryKey key = dataStore.getPrimaryKey(featureType);
0787:
0788:                    //prepare each column as a property name
0789:                    PropertyName[] columnNames = new PropertyName[key.columns.length];
0790:
0791:                    for (int i = 0; i < columnNames.length; i++) {
0792:                        columnNames[i] = filterFactory
0793:                                .property(key.columns[i].name);
0794:                    }
0795:
0796:                    //process each fid, creating an OR filter
0797:                    List or = new ArrayList();
0798:
0799:                    for (Iterator f = id.getIDs().iterator(); f.hasNext();) {
0800:                        String fid = (String) f.next();
0801:
0802:                        //map to values
0803:                        Object[] values = key.decode(fid);
0804:
0805:                        //create an "AND" filter for each property name
0806:                        List and = new ArrayList();
0807:
0808:                        for (int i = 0; i < values.length; i++) {
0809:                            //create an equalTo filter
0810:                            PropertyName name = columnNames[i];
0811:                            Literal literal = filterFactory.literal(values[i]);
0812:                            and.add(filterFactory.equals(name, literal));
0813:                        }
0814:
0815:                        //add to or
0816:                        or.add(filterFactory.and(and));
0817:                    }
0818:
0819:                    //encode it
0820:                    return filterFactory.or(or).accept(this , data);
0821:                } catch (Exception e) {
0822:                    throw new RuntimeException(e);
0823:                }
0824:            }
0825:
0826:            //
0827:            // binary comparison operators
0828:            //
0829:            public Object visit(PropertyIsBetween between, Object data) {
0830:                sql.append("( ");
0831:
0832:                data = between.getExpression().accept(this , data);
0833:                sql.append(" ) BETWEEN ( ");
0834:
0835:                data = between.getLowerBoundary().accept(this , data);
0836:                sql.append(" ) AND ( ");
0837:
0838:                data = between.getUpperBoundary().accept(this , data);
0839:                sql.append(" )");
0840:
0841:                return data;
0842:            }
0843:
0844:            public Object visit(PropertyIsEqualTo equalTo, Object data) {
0845:                return visit(equalTo, data, "=");
0846:            }
0847:
0848:            public Object visit(PropertyIsNotEqualTo notEqualTo, Object data) {
0849:                return visit(notEqualTo, data, "!=");
0850:            }
0851:
0852:            public Object visit(PropertyIsGreaterThan greaterThan, Object data) {
0853:                return visit(greaterThan, data, ">");
0854:            }
0855:
0856:            public Object visit(
0857:                    PropertyIsGreaterThanOrEqualTo greaterThanOrEqualTo,
0858:                    Object data) {
0859:                return visit(greaterThanOrEqualTo, data, ">=");
0860:            }
0861:
0862:            public Object visit(PropertyIsLessThan lessThan, Object data) {
0863:                return visit(lessThan, data, "<");
0864:            }
0865:
0866:            public Object visit(PropertyIsLessThanOrEqualTo lessThanOrEqualTo,
0867:                    Object data) {
0868:                return visit(lessThanOrEqualTo, data, "<=");
0869:            }
0870:
0871:            protected Object visit(BinaryComparisonOperator comparison,
0872:                    Object data, String operator) {
0873:                sql.append("( ");
0874:
0875:                //left
0876:                data = comparison.getExpression1().accept(this , data);
0877:
0878:                //operator
0879:                sql.append(" ) " + operator + " ( ");
0880:
0881:                //right
0882:                data = comparison.getExpression2().accept(this , data);
0883:
0884:                sql.append(" )");
0885:
0886:                return data;
0887:            }
0888:
0889:            public Object visit(PropertyIsLike like, Object data) {
0890:                String pattern = LikeFilterImpl.convertToSQL92(like.getEscape()
0891:                        .charAt(0), like.getWildCard().charAt(0), like
0892:                        .getSingleChar().charAt(0), like.getLiteral());
0893:
0894:                //evaluate left hande
0895:                data = like.getExpression().accept(this , data);
0896:
0897:                sql.append(" LIKE ");
0898:
0899:                //encode pattern as string
0900:                string(pattern, sql);
0901:
0902:                return data;
0903:            }
0904:
0905:            public Object visit(PropertyIsNull isNull, Object data) {
0906:                data = isNull.getExpression().accept(this , data);
0907:                sql.append(" IS ");
0908:                nil(sql);
0909:
0910:                return data;
0911:            }
0912:
0913:            //
0914:            // spatial operators
0915:            //
0916:            public Object visit(BBOX bbox, Object data) {
0917:                //create a property name + geometry
0918:                PropertyName name = filterFactory.property(bbox
0919:                        .getPropertyName());
0920:                Envelope e = new Envelope(bbox.getMinX(), bbox.getMaxX(), bbox
0921:                        .getMinY(), bbox.getMaxY());
0922:
0923:                if (bbox.getSRS() != null) {
0924:                    CoordinateReferenceSystem crs;
0925:
0926:                    try {
0927:                        crs = CRS.decode(bbox.getSRS());
0928:                        data = crs;
0929:                    } catch (Exception ex) {
0930:                        dataStore.getLogger().log(Level.WARNING,
0931:                                ex.getLocalizedMessage(), ex);
0932:                    }
0933:                }
0934:
0935:                return visit(name, JTS.toGeometry(e), data);
0936:            }
0937:
0938:            protected Object visit(PropertyName name, Geometry geometry,
0939:                    Object data) {
0940:                //encode the property ( dont carry back data )
0941:                name.accept(this , data);
0942:
0943:                //bbox operator
0944:                sql.append(" && ");
0945:
0946:                //encode the geometry
0947:                Literal literal = filterFactory.literal(geometry);
0948:
0949:                return literal.accept(this , data);
0950:            }
0951:
0952:            public Object visit(Beyond beyond, Object data) {
0953:                return visit(beyond, data, ">", false);
0954:            }
0955:
0956:            public Object visit(DWithin dwithin, Object data) {
0957:                return visit(dwithin, data, "<=", true);
0958:            }
0959:
0960:            protected Object visit(DistanceBufferOperator distance,
0961:                    Object data, String operator, boolean index) {
0962:                data = visit((BinarySpatialOperator) distance, data,
0963:                        "distance", index);
0964:                sql.append(" " + operator + " " + distance.getDistance());
0965:
0966:                return data;
0967:            }
0968:
0969:            public Object visit(Disjoint disjoint, Object data) {
0970:                return visit(disjoint, data, "disjoint", false);
0971:            }
0972:
0973:            public Object visit(Contains contains, Object data) {
0974:                return visit(contains, data, "contains", true);
0975:            }
0976:
0977:            public Object visit(Crosses crosses, Object data) {
0978:                return visit(crosses, data, "crosses", true);
0979:            }
0980:
0981:            public Object visit(Equals equals, Object data) {
0982:                return visit(equals, data, "equals", true);
0983:            }
0984:
0985:            public Object visit(Intersects intersects, Object data) {
0986:                return visit(intersects, data, "intersects", true);
0987:            }
0988:
0989:            public Object visit(Overlaps overlaps, Object data) {
0990:                return visit(overlaps, data, "overlaps", true);
0991:            }
0992:
0993:            public Object visit(Touches touches, Object data) {
0994:                return visit(touches, data, "touches", true);
0995:            }
0996:
0997:            public Object visit(Within within, Object data) {
0998:                return visit(within, data, "within", true);
0999:            }
1000:
1001:            protected Object visit(BinarySpatialOperator comparison,
1002:                    Object data, String operator, boolean index) {
1003:                //use the index for this comparison?
1004:                if (index) {
1005:                    //figure out the property name, and geometry
1006:                    PropertyName propertyName = null;
1007:                    Geometry geometry = null;
1008:
1009:                    if (comparison.getExpression1() instanceof  PropertyName) {
1010:                        propertyName = (PropertyName) comparison
1011:                                .getExpression1();
1012:                        geometry = (Geometry) comparison.getExpression2()
1013:                                .evaluate(null, Geometry.class);
1014:                    } else if (comparison.getExpression2() instanceof  PropertyName) {
1015:                        propertyName = (PropertyName) comparison
1016:                                .getExpression2();
1017:                        geometry = (Geometry) comparison.getExpression1()
1018:                                .evaluate(null, Geometry.class);
1019:                    }
1020:
1021:                    if ((propertyName != null) && (geometry != null)) {
1022:                        data = visit(propertyName, geometry, data);
1023:                        sql.append(" AND ");
1024:                    }
1025:                }
1026:
1027:                //operator
1028:                sql.append(operator + "( ( ");
1029:
1030:                //left
1031:                data = comparison.getExpression1().accept(this , data);
1032:
1033:                sql.append(" ) , ( ");
1034:
1035:                //right
1036:                data = comparison.getExpression2().accept(this , data);
1037:
1038:                sql.append(" ) )");
1039:
1040:                return data;
1041:            }
1042:
1043:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.