Source Code Cross Referenced for AbstractRequestHandler.java in  » GIS » deegree » org » deegree » io » datastore » sql » 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 » deegree » org.deegree.io.datastore.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/datastore/sql/AbstractRequestHandler.java $
0002:        /*----------------    FILE HEADER  ------------------------------------------
0003:
0004:         This file is part of deegree.
0005:         Copyright (C) 2001-2008 by:
0006:         EXSE, Department of Geography, University of Bonn
0007:         http://www.giub.uni-bonn.de/deegree/
0008:         lat/lon GmbH
0009:         http://www.lat-lon.de
0010:
0011:         This library is free software; you can redistribute it and/or
0012:         modify it under the terms of the GNU Lesser General Public
0013:         License as published by the Free Software Foundation; either
0014:         version 2.1 of the License, or (at your option) any later version.
0015:
0016:         This library is distributed in the hope that it will be useful,
0017:         but WITHOUT ANY WARRANTY; without even the implied warranty of
0018:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019:         Lesser General Public License for more details.
0020:
0021:         You should have received a copy of the GNU Lesser General Public
0022:         License along with this library; if not, write to the Free Software
0023:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0024:
0025:         Contact:
0026:
0027:         Andreas Poth
0028:         lat/lon GmbH
0029:         Aennchenstraße 19
0030:         53177 Bonn
0031:         Germany
0032:         E-Mail: poth@lat-lon.de
0033:
0034:         Prof. Dr. Klaus Greve
0035:         Department of Geography
0036:         University of Bonn
0037:         Meckenheimer Allee 166
0038:         53115 Bonn
0039:         Germany
0040:         E-Mail: greve@giub.uni-bonn.de
0041:        
0042:         ---------------------------------------------------------------------------*/
0043:        package org.deegree.io.datastore.sql;
0044:
0045:        import java.sql.Connection;
0046:        import java.sql.PreparedStatement;
0047:        import java.sql.ResultSet;
0048:        import java.sql.SQLException;
0049:        import java.util.ArrayList;
0050:        import java.util.HashMap;
0051:        import java.util.HashSet;
0052:        import java.util.List;
0053:        import java.util.Map;
0054:        import java.util.Set;
0055:
0056:        import org.deegree.framework.log.ILogger;
0057:        import org.deegree.framework.log.LoggerFactory;
0058:        import org.deegree.i18n.Messages;
0059:        import org.deegree.io.datastore.DatastoreException;
0060:        import org.deegree.io.datastore.FeatureId;
0061:        import org.deegree.io.datastore.LockManager;
0062:        import org.deegree.io.datastore.schema.MappedFeaturePropertyType;
0063:        import org.deegree.io.datastore.schema.MappedFeatureType;
0064:        import org.deegree.io.datastore.schema.MappedGMLId;
0065:        import org.deegree.io.datastore.schema.MappedGMLSchema;
0066:        import org.deegree.io.datastore.schema.MappedPropertyType;
0067:        import org.deegree.io.datastore.schema.TableRelation;
0068:        import org.deegree.io.datastore.schema.content.MappingField;
0069:        import org.deegree.io.datastore.sql.wherebuilder.WhereBuilder;
0070:        import org.deegree.model.feature.schema.FeatureType;
0071:        import org.deegree.model.feature.schema.PropertyType;
0072:        import org.deegree.model.filterencoding.Filter;
0073:
0074:        /**
0075:         * This abstract class implements some common SQL functionality needed by request handlers for SQL based datastores.
0076:         * 
0077:         * @see QueryHandler
0078:         * 
0079:         * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
0080:         * @author last edited by: $Author: aschmitz $
0081:         * 
0082:         * @version $Revision: 10299 $, $Date: 2008-02-26 00:42:07 -0800 (Tue, 26 Feb 2008) $
0083:         */
0084:        public class AbstractRequestHandler {
0085:
0086:            private static final ILogger LOG = LoggerFactory
0087:                    .getLogger(AbstractRequestHandler.class);
0088:
0089:            /**
0090:             * Column used for disambiguation of feature properties that contain features that have more than one concrete type.
0091:             */
0092:            protected static final String FT_COLUMN = "featuretype";
0093:
0094:            /**
0095:             * Column prefix used for disambiguation of feature properties that contain features that have more than one
0096:             * concrete type.
0097:             */
0098:            protected static final String FT_PREFIX = "FT_";
0099:
0100:            protected AbstractSQLDatastore datastore;
0101:
0102:            protected TableAliasGenerator aliasGenerator;
0103:
0104:            protected Connection conn;
0105:
0106:            /**
0107:             * Creates a new instance of <code>AbstractRequestHandler</code> from the given parameters.
0108:             * 
0109:             * @param ds
0110:             * @param aliasGenerator
0111:             * @param conn
0112:             */
0113:            public AbstractRequestHandler(AbstractSQLDatastore ds,
0114:                    TableAliasGenerator aliasGenerator, Connection conn) {
0115:                this .datastore = ds;
0116:                this .aliasGenerator = aliasGenerator;
0117:                this .conn = conn;
0118:            }
0119:
0120:            /**
0121:             * Determines the feature ids that are matched by the given filter.
0122:             * 
0123:             * @param ft
0124:             *            non-abstract feature type
0125:             * @param filter
0126:             *            constraints the feature instances
0127:             * @return the feature ids that are matched by the given filter
0128:             * @throws DatastoreException
0129:             */
0130:            public List<FeatureId> determineAffectedFIDs(MappedFeatureType ft,
0131:                    Filter filter) throws DatastoreException {
0132:
0133:                assert !ft.isAbstract();
0134:
0135:                TableAliasGenerator aliasGenerator = new TableAliasGenerator();
0136:                VirtualContentProvider vcProvider = new VirtualContentProvider(
0137:                        filter, this .datastore, this .conn);
0138:                WhereBuilder whereBuilder = this .datastore.getWhereBuilder(
0139:                        new MappedFeatureType[] { ft }, null, filter, null,
0140:                        aliasGenerator, vcProvider);
0141:
0142:                // if no filter is given
0143:                StatementBuffer query = buildInitialFIDSelect(ft, whereBuilder);
0144:                LOG.logDebug("Determine affected feature id query: '" + query
0145:                        + "'");
0146:
0147:                List<FeatureId> fids = null;
0148:                PreparedStatement stmt = null;
0149:                ResultSet rs = null;
0150:                try {
0151:                    stmt = this .datastore.prepareStatement(conn, query);
0152:                    rs = stmt.executeQuery();
0153:                    fids = extractFeatureIds(rs, ft);
0154:                } catch (SQLException e) {
0155:                    throw new DatastoreException(
0156:                            "Error while determining affected features of type: '"
0157:                                    + ft.getName() + "': " + e.getMessage());
0158:                } finally {
0159:                    try {
0160:                        if (rs != null) {
0161:                            try {
0162:                                rs.close();
0163:                            } catch (SQLException e) {
0164:                                LOG.logError("Error closing result set: '"
0165:                                        + e.getMessage() + "'.", e);
0166:                            }
0167:                        }
0168:                    } finally {
0169:                        if (stmt != null) {
0170:                            try {
0171:                                stmt.close();
0172:                            } catch (SQLException e) {
0173:                                LOG.logError("Error closing statement: '"
0174:                                        + e.getMessage() + "'.", e);
0175:                            }
0176:                        }
0177:                    }
0178:                }
0179:                return fids;
0180:            }
0181:
0182:            /**
0183:             * Determines the feature ids that are matched by the given filter and that are either not locked or locked by the
0184:             * specified lockId.
0185:             * 
0186:             * @param ft
0187:             *            non-abstract feature type
0188:             * @param filter
0189:             *            constraints the feature instances
0190:             * @param lockId
0191:             *            optional id of associated lock (may be null)
0192:             * @return the feature ids that are matched by the given filter
0193:             * @throws DatastoreException
0194:             */
0195:            public List<FeatureId> determineAffectedAndModifiableFIDs(
0196:                    MappedFeatureType ft, Filter filter, String lockId)
0197:                    throws DatastoreException {
0198:
0199:                List<FeatureId> affectedFids = determineAffectedFIDs(ft, filter);
0200:                List<FeatureId> modifiableFids = new ArrayList<FeatureId>(
0201:                        affectedFids.size());
0202:                for (FeatureId fid : affectedFids) {
0203:                    String lockedBy = LockManager.getInstance().getLockId(fid);
0204:                    if (lockedBy != null && !lockedBy.equals(lockId)) {
0205:                        String msg = Messages.getMessage(
0206:                                "DATASTORE_FEATURE_NOT_MODIFIABLE", fid,
0207:                                lockedBy);
0208:                        LOG.logInfo(msg);
0209:                    } else {
0210:                        modifiableFids.add(fid);
0211:                    }
0212:                }
0213:                return modifiableFids;
0214:            }
0215:
0216:            /**
0217:             * Determines all complex properties and contained subfeature ids for a certain feature.
0218:             * 
0219:             * @param fid
0220:             *            id of the feature
0221:             * @return all complex properties and contained subfeature ids of the feature
0222:             * @throws DatastoreException
0223:             */
0224:            public Map<MappedFeaturePropertyType, List<FeatureId>> determineSubFeatures(
0225:                    FeatureId fid) throws DatastoreException {
0226:
0227:                LOG.logDebug("Determining sub features of feature '" + fid
0228:                        + "'...");
0229:                Map<MappedFeaturePropertyType, List<FeatureId>> ptToSubFids = new HashMap<MappedFeaturePropertyType, List<FeatureId>>();
0230:                PropertyType[] properties = fid.getFeatureType()
0231:                        .getProperties();
0232:                for (PropertyType property : properties) {
0233:                    MappedPropertyType pt = (MappedPropertyType) property;
0234:                    if (pt instanceof  MappedFeaturePropertyType) {
0235:                        LOG.logDebug("Complex property '" + pt.getName()
0236:                                + "'...");
0237:                        MappedFeaturePropertyType fPt = (MappedFeaturePropertyType) pt;
0238:                        List<FeatureId> subFids = determineSubFIDs(fid, fPt);
0239:                        ptToSubFids.put(fPt, subFids);
0240:                    }
0241:                }
0242:                return ptToSubFids;
0243:            }
0244:
0245:            /**
0246:             * Determines the {@link FeatureId}s of the subfeatures contained in a specified feature's property.
0247:             * 
0248:             * @param fid
0249:             *            id of the feature (for which the subfeatures will be determined)
0250:             * @param pt
0251:             *            property type of the feature (that contains the subfeatures)
0252:             * @return the matched subfeature's ids (with concrete feature types)
0253:             * @throws DatastoreException
0254:             */
0255:            private List<FeatureId> determineSubFIDs(FeatureId fid,
0256:                    MappedFeaturePropertyType pt) throws DatastoreException {
0257:
0258:                LOG.logDebug("Determining sub feature ids for feature: " + fid
0259:                        + " and property " + pt.getName());
0260:
0261:                List<FeatureId> subFids = null;
0262:                MappedFeatureType containedFt = pt.getFeatureTypeReference()
0263:                        .getFeatureType();
0264:                MappedFeatureType[] concreteFts = containedFt
0265:                        .getConcreteSubstitutions();
0266:                if (concreteFts.length > 1) {
0267:                    subFids = determineSubFIDs(fid, pt, concreteFts);
0268:                } else {
0269:                    subFids = determineSubFIDs(fid, pt, containedFt);
0270:                }
0271:                return subFids;
0272:            }
0273:
0274:            /**
0275:             * Determines all super features (as {@link FeatureId} instances) for a certain feature.
0276:             * 
0277:             * @param fid
0278:             *            id of the feature
0279:             * @return all super feature ids of the feature
0280:             * @throws DatastoreException
0281:             */
0282:            public Set<FeatureId> determineSuperFeatures(FeatureId fid)
0283:                    throws DatastoreException {
0284:
0285:                LOG.logDebug("Determining super features of feature "
0286:                        + fid.getAsString());
0287:                Set<FeatureId> super Features = new HashSet<FeatureId>();
0288:                MappedFeatureType subFt = fid.getFeatureType();
0289:                Set<FeatureType> substitutableFts = subFt.getGMLSchema()
0290:                        .getSubstitutables(subFt);
0291:                Set<MappedFeatureType> super Fts = determineSuperFeatureTypes(substitutableFts);
0292:
0293:                for (MappedFeatureType super Ft : super Fts) {
0294:                    List<MappedFeaturePropertyType> featureProps = determineProperties(
0295:                            super Ft, subFt);
0296:                    for (MappedFeaturePropertyType featureProp : featureProps) {
0297:                        super Features.addAll(determineSuperFids(super Ft,
0298:                                featureProp, fid));
0299:                    }
0300:                }
0301:                return super Features;
0302:            }
0303:
0304:            /**
0305:             * Determines all concrete feature types that can contain one or more of the given feature types inside a property.
0306:             * 
0307:             * @param subFts
0308:             * @return all concrete feature types that can contain the given feature type
0309:             */
0310:            private Set<MappedFeatureType> determineSuperFeatureTypes(
0311:                    Set<FeatureType> subFts) {
0312:                Set<MappedFeatureType> super Fts = new HashSet<MappedFeatureType>();
0313:                for (FeatureType subFt : subFts) {
0314:                    super Fts
0315:                            .addAll(determineSuperFeatureTypes((MappedFeatureType) subFt));
0316:                }
0317:                return super Fts;
0318:            }
0319:
0320:            /**
0321:             * Determines all concrete feature types that can contain the given feature type inside a property.
0322:             * 
0323:             * @param subFt
0324:             * @return all concrete feature types that can contain the given feature type
0325:             */
0326:            private Set<MappedFeatureType> determineSuperFeatureTypes(
0327:                    MappedFeatureType subFt) {
0328:                Set<MappedFeatureType> super Fts = new HashSet<MappedFeatureType>();
0329:                MappedGMLSchema schema = subFt.getGMLSchema();
0330:                FeatureType[] fts = schema.getFeatureTypes();
0331:                for (int i = 0; i < fts.length; i++) {
0332:                    MappedFeatureType ft = (MappedFeatureType) fts[i];
0333:                    if (!ft.isAbstract()) {
0334:                        PropertyType[] properties = ft.getProperties();
0335:                        for (int j = 0; j < properties.length; j++) {
0336:                            MappedPropertyType property = (MappedPropertyType) properties[j];
0337:                            if (property instanceof  MappedFeaturePropertyType) {
0338:                                MappedFeaturePropertyType ftProperty = (MappedFeaturePropertyType) property;
0339:                                if (ftProperty.getFeatureTypeReference()
0340:                                        .getName().equals(subFt.getName())) {
0341:                                    super Fts.add(ft);
0342:                                }
0343:                            }
0344:                        }
0345:                    }
0346:
0347:                }
0348:                return super Fts;
0349:            }
0350:
0351:            /**
0352:             * Determines all {@link MappedFeaturePropertyType} instances that the super feature type has and which contain
0353:             * features that may be substituted for features of the given sub feature type.
0354:             * 
0355:             * @param superFt
0356:             * @param subFt
0357:             * @return corresponding property types
0358:             */
0359:            private List<MappedFeaturePropertyType> determineProperties(
0360:                    MappedFeatureType super Ft, MappedFeatureType subFt) {
0361:                List<MappedFeaturePropertyType> featureProps = new ArrayList<MappedFeaturePropertyType>();
0362:                PropertyType[] properties = super Ft.getProperties();
0363:                for (PropertyType property : properties) {
0364:                    if (property instanceof  MappedFeaturePropertyType) {
0365:                        MappedFeaturePropertyType featureProperty = (MappedFeaturePropertyType) property;
0366:                        MappedFeatureType containedFt = featureProperty
0367:                                .getFeatureTypeReference().getFeatureType();
0368:                        if (subFt.getGMLSchema().isValidSubstitution(
0369:                                containedFt, subFt)) {
0370:                            featureProps.add(featureProperty);
0371:                        }
0372:                    }
0373:                }
0374:                return featureProps;
0375:            }
0376:
0377:            /**
0378:             * Determines all features (as {@link FeatureId}s) of the super feature type which contain the given feature
0379:             * instance in the also specified property.
0380:             * 
0381:             * @param superFt
0382:             * @param featureProp
0383:             * @param subFid
0384:             * @return corresponding <code>DeleteNodes</code>
0385:             */
0386:            private List<FeatureId> determineSuperFids(
0387:                    MappedFeatureType super Ft,
0388:                    MappedFeaturePropertyType featureProp, FeatureId subFid)
0389:                    throws DatastoreException {
0390:                this .aliasGenerator.reset();
0391:                TableRelation[] relations = featureProp.getTableRelations();
0392:
0393:                String super FtAlias = this .aliasGenerator.generateUniqueAlias();
0394:                String[] joinTableAliases = this .aliasGenerator
0395:                        .generateUniqueAliases(relations.length);
0396:                String subFtAlias = joinTableAliases[joinTableAliases.length - 1];
0397:
0398:                StatementBuffer query = new StatementBuffer();
0399:                query.append("SELECT DISTINCT ");
0400:                appendFeatureIdColumns(super Ft, super FtAlias, query);
0401:                query.append(" FROM ");
0402:                query.append(super Ft.getTable());
0403:                query.append(" ");
0404:                query.append(super FtAlias);
0405:                String fromAlias = super FtAlias;
0406:                for (int i = 0; i < relations.length; i++) {
0407:                    String toAlias = joinTableAliases[i];
0408:                    query.append(" JOIN ");
0409:                    if (i == relations.length - 1) {
0410:                        query.append(subFid.getFeatureType().getTable());
0411:                    } else {
0412:                        query.append(relations[i].getToTable());
0413:                    }
0414:                    query.append(" ");
0415:                    query.append(toAlias);
0416:                    query.append(" ON ");
0417:                    appendJoinCondition(relations[i], fromAlias, toAlias, query);
0418:                    fromAlias = toAlias;
0419:                }
0420:
0421:                query.append(" WHERE ");
0422:                MappedGMLId gmlId = subFid.getFidDefinition();
0423:                MappingField[] idFields = gmlId.getIdFields();
0424:                for (int i = 0; i < idFields.length; i++) {
0425:                    query.append(subFtAlias);
0426:                    query.append('.');
0427:                    query.append(idFields[i].getField());
0428:                    query.append("=?");
0429:                    query
0430:                            .addArgument(subFid.getValue(i), idFields[i]
0431:                                    .getType());
0432:                    if (i != idFields.length - 1) {
0433:                        query.append(" AND ");
0434:                    }
0435:                }
0436:
0437:                List<FeatureId> fids = null;
0438:                PreparedStatement stmt = null;
0439:                ResultSet rs = null;
0440:                try {
0441:                    stmt = this .datastore.prepareStatement(conn, query);
0442:                    LOG.logDebug("Performing: " + query);
0443:                    rs = stmt.executeQuery();
0444:                    fids = extractFeatureIds(rs, super Ft);
0445:                } catch (SQLException e) {
0446:                    LOG.logInfo(e.getMessage(), e);
0447:                    throw new DatastoreException(
0448:                            "Error in determineSuperFeatures(): "
0449:                                    + e.getMessage());
0450:                } finally {
0451:                    try {
0452:                        if (rs != null) {
0453:                            try {
0454:                                rs.close();
0455:                            } catch (SQLException e) {
0456:                                LOG.logError("Error closing result set: '"
0457:                                        + e.getMessage() + "'.", e);
0458:                            }
0459:                        }
0460:                    } finally {
0461:                        if (stmt != null) {
0462:                            try {
0463:                                stmt.close();
0464:                            } catch (SQLException e) {
0465:                                LOG.logError("Error closing statement: '"
0466:                                        + e.getMessage() + "'.", e);
0467:                            }
0468:                        }
0469:                    }
0470:                }
0471:                return fids;
0472:            }
0473:
0474:            /**
0475:             * Determines the {@link FeatureId}s of the subfeatures contained in the given feature property.
0476:             * 
0477:             * @param fid
0478:             *            id of the feature
0479:             * @param pt
0480:             *            table relation from the feature table to the subfeature table
0481:             * @param concreteFt
0482:             *            concrete (non-abstract) type that is contained in the feature property
0483:             * @return the <code>FeatureId</code> or null (if there is no such subfeature)
0484:             * @throws DatastoreException
0485:             */
0486:            private List<FeatureId> determineSubFIDs(FeatureId fid,
0487:                    MappedFeaturePropertyType pt, MappedFeatureType concreteFt)
0488:                    throws DatastoreException {
0489:
0490:                TableRelation[] relations = pt.getTableRelations();
0491:
0492:                this .aliasGenerator.reset();
0493:                String[] aliases = this .aliasGenerator
0494:                        .generateUniqueAliases(relations.length + 1);
0495:
0496:                StatementBuffer query = new StatementBuffer();
0497:                query.append("SELECT ");
0498:                appendFeatureIdColumns(concreteFt, aliases[aliases.length - 1],
0499:                        query);
0500:                query.append(" FROM ");
0501:                query.append(relations[0].getFromTable());
0502:                query.append(" ");
0503:                query.append(aliases[0]);
0504:
0505:                // append JOINs
0506:                String fromAlias = aliases[0];
0507:                for (int i = 0; i < relations.length; i++) {
0508:                    String toAlias = aliases[i + 1];
0509:                    query.append(" JOIN ");
0510:                    if (i == relations.length - 1) {
0511:                        query.append(concreteFt.getTable());
0512:                    } else {
0513:                        query.append(relations[i].getToTable());
0514:                    }
0515:                    query.append(" ");
0516:                    query.append(toAlias);
0517:                    query.append(" ON ");
0518:                    appendJoinCondition(relations[i], fromAlias, toAlias, query);
0519:                    fromAlias = toAlias;
0520:                }
0521:
0522:                query.append(" WHERE ");
0523:                appendFeatureIdConstraint(query, fid, aliases[0]);
0524:
0525:                List<FeatureId> subFids = null;
0526:                PreparedStatement stmt = null;
0527:                ResultSet rs = null;
0528:                try {
0529:                    stmt = this .datastore.prepareStatement(conn, query);
0530:                    LOG.logDebug("Determining subfeature ids: " + query);
0531:                    rs = stmt.executeQuery();
0532:                    subFids = extractFeatureIds(rs, concreteFt);
0533:                } catch (SQLException e) {
0534:                    LOG.logDebug(e.getMessage(), e);
0535:                    throw new DatastoreException(
0536:                            "Error in #determineSubFIDs(): " + e.getMessage());
0537:                } finally {
0538:                    try {
0539:                        if (rs != null) {
0540:                            try {
0541:                                rs.close();
0542:                            } catch (SQLException e) {
0543:                                LOG.logError("Error closing result set: '"
0544:                                        + e.getMessage() + "'.", e);
0545:                            }
0546:                        }
0547:                    } finally {
0548:                        if (stmt != null) {
0549:                            try {
0550:                                stmt.close();
0551:                            } catch (SQLException e) {
0552:                                LOG.logError("Error closing statement: '"
0553:                                        + e.getMessage() + "'.", e);
0554:                            }
0555:                        }
0556:                    }
0557:                }
0558:                return subFids;
0559:            }
0560:
0561:            /**
0562:             * Determines the feature ids of the subfeatures contained in the given feature property (that may contain features
0563:             * of different concrete types).
0564:             * 
0565:             * @param fid
0566:             *            id of the feature
0567:             * @param pt
0568:             *            complex property that contains the subfeatures
0569:             * @param concreteSubFts
0570:             *            all possible non-abstract feature types of the subfeatures
0571:             * @return the ids of the subfeatures
0572:             * @throws DatastoreException
0573:             */
0574:            private List<FeatureId> determineSubFIDs(FeatureId fid,
0575:                    MappedFeaturePropertyType pt,
0576:                    MappedFeatureType[] concreteSubFts)
0577:                    throws DatastoreException {
0578:
0579:                List<FeatureId> subFids = null;
0580:
0581:                TableRelation[] relations = pt.getTableRelations();
0582:                LOG.logDebug("Determining sub feature ids for feature " + fid
0583:                        + ": relations.length: " + relations.length);
0584:
0585:                switch (relations.length) {
0586:                case 1: {
0587:                    // subfeature disambiguator in feature table (only zero or one subfeatures)
0588:                    MappedFeatureType concreteSubFt = determineSubFt(fid, pt,
0589:                            concreteSubFts);
0590:                    subFids = new ArrayList<FeatureId>(1);
0591:                    if (concreteSubFt != null) {
0592:                        FeatureId subFid = determineSubFID(fid, relations[0],
0593:                                concreteSubFt);
0594:                        if (subFid != null) {
0595:                            subFids.add(subFid);
0596:                        }
0597:                    }
0598:                    break;
0599:                }
0600:                case 2: {
0601:                    // subfeature disambiguator in join table (any number of subfeatures)
0602:                    subFids = determineSubFIDs(fid, pt, concreteSubFts,
0603:                            relations);
0604:                    break;
0605:                }
0606:                default: {
0607:                    String msg = Messages.getMessage(
0608:                            "DATASTORE_SUBFT_TOO_MANY_RELATIONS", fid
0609:                                    .getFeatureType().getName(), pt.getName());
0610:                    throw new DatastoreException(msg);
0611:                }
0612:                }
0613:                return subFids;
0614:            }
0615:
0616:            /**
0617:             * Determine the concrete type of the subfeature that is stored in the specified property of a certain feature.
0618:             * <p>
0619:             * The relation to the sub feature table must be specified via a single step (join).
0620:             * 
0621:             * @param fid
0622:             *            id of the feature for which the concrete subfeature type is needed
0623:             * @param pt
0624:             *            property of the feature that contains the subfeature
0625:             * @param concreteSubFts
0626:             *            concrete types that may be contained in the property
0627:             * @return concrete type of the subfeature, or null if feature has no such property
0628:             * @throws DatastoreException
0629:             */
0630:            private MappedFeatureType determineSubFt(FeatureId fid,
0631:                    MappedFeaturePropertyType pt,
0632:                    MappedFeatureType[] concreteSubFts)
0633:                    throws DatastoreException {
0634:
0635:                assert (pt.getTableRelations().length == 1);
0636:                TableRelation relation = pt.getTableRelations()[0];
0637:
0638:                assert (relation.getFromFields().length == 1);
0639:                String fkColumn = relation.getFromFields()[0].getField();
0640:                String subFtColumn = FT_PREFIX + fkColumn;
0641:
0642:                StatementBuffer query = new StatementBuffer();
0643:                query.append("SELECT ");
0644:                query.append(subFtColumn);
0645:                query.append(" FROM ");
0646:                query.append(fid.getFeatureType().getTable());
0647:                query.append(" WHERE ");
0648:                appendFeatureIdConstraint(query, fid);
0649:
0650:                String localSubFtName = null;
0651:                PreparedStatement stmt = null;
0652:                ResultSet rs = null;
0653:                try {
0654:                    stmt = this .datastore.prepareStatement(conn, query);
0655:                    LOG.logDebug("Determining concrete subfeature type: "
0656:                            + query);
0657:                    rs = stmt.executeQuery();
0658:                    rs.next();
0659:                    localSubFtName = rs.getString(1);
0660:                } catch (SQLException e) {
0661:                    LOG.logDebug(e.getMessage(), e);
0662:                    throw new DatastoreException(
0663:                            "Error in determineConcreteSubFt() "
0664:                                    + e.getMessage());
0665:                } finally {
0666:                    try {
0667:                        if (rs != null) {
0668:                            try {
0669:                                rs.close();
0670:                            } catch (SQLException e) {
0671:                                LOG.logError("Error closing result set: '"
0672:                                        + e.getMessage() + "'.", e);
0673:                            }
0674:                        }
0675:                    } finally {
0676:                        if (stmt != null) {
0677:                            try {
0678:                                stmt.close();
0679:                            } catch (SQLException e) {
0680:                                LOG.logError("Error closing statement: '"
0681:                                        + e.getMessage() + "'.", e);
0682:                            }
0683:                        }
0684:                    }
0685:                }
0686:
0687:                MappedFeatureType concreteSubFt = null;
0688:
0689:                if (localSubFtName != null) {
0690:                    for (MappedFeatureType type : concreteSubFts) {
0691:                        if (type.getName().getLocalName()
0692:                                .equals(localSubFtName)) {
0693:                            concreteSubFt = fid.getFeatureType().getGMLSchema()
0694:                                    .getFeatureType(localSubFtName);
0695:                            break;
0696:                        }
0697:                    }
0698:                    if (concreteSubFt == null) {
0699:                        String msg = Messages.getMessage(
0700:                                "DATASTORE_FEATURE_TYPE_INFO_INCONSISTENT", pt
0701:                                        .getName(), fid, subFtColumn,
0702:                                localSubFtName, pt.getFeatureTypeReference()
0703:                                        .getName());
0704:                        throw new DatastoreException(msg);
0705:                    }
0706:                }
0707:
0708:                return concreteSubFt;
0709:            }
0710:
0711:            /**
0712:             * Determines the {@link FeatureId} of the subfeature contained in the given feature property (if the feature has
0713:             * such a subfeature).
0714:             * 
0715:             * @param fid
0716:             *            id of the feature
0717:             * @param relation
0718:             *            table relation from the feature table to the subfeature table
0719:             * @param concreteFt
0720:             *            concrete (non-abstract) type that is contained in the feature property
0721:             * @return the <code>FeatureId</code> or null (if there is no such subfeature)
0722:             * @throws DatastoreException
0723:             */
0724:            private FeatureId determineSubFID(FeatureId fid,
0725:                    TableRelation relation, MappedFeatureType concreteFt)
0726:                    throws DatastoreException {
0727:
0728:                this .aliasGenerator.reset();
0729:                String fromAlias = this .aliasGenerator.generateUniqueAlias();
0730:                String toAlias = this .aliasGenerator.generateUniqueAlias();
0731:
0732:                StatementBuffer query = new StatementBuffer();
0733:                query.append("SELECT ");
0734:                appendFeatureIdColumns(concreteFt, toAlias, query);
0735:                query.append(" FROM ");
0736:                query.append(relation.getFromTable());
0737:                query.append(" ");
0738:                query.append(fromAlias);
0739:                query.append(" JOIN ");
0740:                query.append(concreteFt.getTable());
0741:                query.append(" ");
0742:                query.append(toAlias);
0743:                query.append(" ON ");
0744:                appendJoinCondition(relation, fromAlias, toAlias, query);
0745:                query.append(" WHERE ");
0746:                appendFeatureIdConstraint(query, fid, fromAlias);
0747:
0748:                FeatureId subFid = null;
0749:                PreparedStatement stmt = null;
0750:                ResultSet rs = null;
0751:                try {
0752:                    stmt = this .datastore.prepareStatement(conn, query);
0753:                    LOG.logDebug("Determining subfeature id: " + query);
0754:                    rs = stmt.executeQuery();
0755:                    if (rs.next()) {
0756:                        subFid = extractFeatureId(rs, concreteFt);
0757:                    }
0758:                } catch (SQLException e) {
0759:                    LOG.logDebug(e.getMessage(), e);
0760:                    throw new DatastoreException(
0761:                            "Error in #determineSubFID(): " + e.getMessage());
0762:                } finally {
0763:                    try {
0764:                        if (rs != null) {
0765:                            try {
0766:                                rs.close();
0767:                            } catch (SQLException e) {
0768:                                LOG.logError("Error closing result set: '"
0769:                                        + e.getMessage() + "'.", e);
0770:                            }
0771:                        }
0772:                    } finally {
0773:                        if (stmt != null) {
0774:                            try {
0775:                                stmt.close();
0776:                            } catch (SQLException e) {
0777:                                LOG.logError("Error closing statement: '"
0778:                                        + e.getMessage() + "'.", e);
0779:                            }
0780:                        }
0781:                    }
0782:                }
0783:                return subFid;
0784:            }
0785:
0786:            /**
0787:             * Determines the feature ids of the subfeatures contained in the given feature property (that may contain features
0788:             * of different concrete types and is connected via a join table with feature type disambiguation column).
0789:             * 
0790:             * @param fid
0791:             * @param pt
0792:             * @return the matched subfeatures' ids
0793:             * @throws DatastoreException
0794:             */
0795:            private List<FeatureId> determineSubFIDs(FeatureId fid,
0796:                    MappedFeaturePropertyType pt,
0797:                    MappedFeatureType[] concreteSubFts,
0798:                    TableRelation[] relations) throws DatastoreException {
0799:                this .aliasGenerator.reset();
0800:                String fromAlias = this .aliasGenerator.generateUniqueAlias();
0801:                String jtAlias = this .aliasGenerator.generateUniqueAlias();
0802:
0803:                StatementBuffer query = new StatementBuffer();
0804:                query.append("SELECT ");
0805:
0806:                // select feature type disambiguation column and from fields of second table relation
0807:                appendQualifiedColumn(query, jtAlias, FT_COLUMN);
0808:                MappingField[] fromFields = relations[1].getFromFields();
0809:                for (int i = 0; i < fromFields.length; i++) {
0810:                    query.append(',');
0811:                    appendQualifiedColumn(query, jtAlias, fromFields[i]
0812:                            .getField());
0813:                }
0814:
0815:                query.append(" FROM ");
0816:                query.append(relations[0].getFromTable());
0817:                query.append(" ");
0818:                query.append(fromAlias);
0819:                query.append(" JOIN ");
0820:                query.append(relations[0].getToTable());
0821:                query.append(" ");
0822:                query.append(jtAlias);
0823:                query.append(" ON ");
0824:                appendJoinCondition(relations[0], fromAlias, jtAlias, query);
0825:                query.append(" WHERE ");
0826:                appendFeatureIdConstraint(query, fid, fromAlias);
0827:
0828:                List<FeatureId> subFids = new ArrayList<FeatureId>();
0829:                PreparedStatement stmt = null;
0830:                ResultSet rs = null;
0831:                try {
0832:                    stmt = this .datastore.prepareStatement(conn, query);
0833:                    LOG
0834:                            .logDebug("Determining concrete subfeature types and join keys: "
0835:                                    + query);
0836:                    rs = stmt.executeQuery();
0837:                    Object[] keyComponents = new Object[relations[1]
0838:                            .getFromFields().length];
0839:                    while (rs.next()) {
0840:                        String localSubFtName = rs.getString(1);
0841:                        for (int i = 0; i < keyComponents.length; i++) {
0842:                            keyComponents[i] = rs.getObject(i + 2);
0843:                        }
0844:                        MappedFeatureType concreteSubFt = null;
0845:                        for (MappedFeatureType type : concreteSubFts) {
0846:                            if (type.getName().getLocalName().equals(
0847:                                    localSubFtName)) {
0848:                                concreteSubFt = fid.getFeatureType()
0849:                                        .getGMLSchema().getFeatureType(
0850:                                                localSubFtName);
0851:                                break;
0852:                            }
0853:                        }
0854:                        if (concreteSubFt == null) {
0855:                            String msg = Messages.getMessage(
0856:                                    "DATASTORE_FEATURE_TYPE_INFO_INCONSISTENT",
0857:                                    pt.getName(), fid, FT_COLUMN,
0858:                                    localSubFtName, pt
0859:                                            .getFeatureTypeReference()
0860:                                            .getName());
0861:                            throw new DatastoreException(msg);
0862:                        }
0863:
0864:                        subFids.add(determineSubFID(concreteSubFt,
0865:                                relations[1], keyComponents));
0866:                    }
0867:                } catch (SQLException e) {
0868:                    LOG.logDebug(e.getMessage(), e);
0869:                    throw new DatastoreException(
0870:                            "Error in #determineSubFIDs(): " + e.getMessage());
0871:                } finally {
0872:                    try {
0873:                        if (rs != null) {
0874:                            try {
0875:                                rs.close();
0876:                            } catch (SQLException e) {
0877:                                LOG.logError("Error closing result set: '"
0878:                                        + e.getMessage() + "'.", e);
0879:                            }
0880:                        }
0881:                    } finally {
0882:                        if (stmt != null) {
0883:                            try {
0884:                                stmt.close();
0885:                            } catch (SQLException e) {
0886:                                LOG.logError("Error closing statement: '"
0887:                                        + e.getMessage() + "'.", e);
0888:                            }
0889:                        }
0890:                    }
0891:                }
0892:                return subFids;
0893:            }
0894:
0895:            /**
0896:             * Determines the {@link FeatureId} of the subfeature referenced by the given {@link TableRelation}.
0897:             * 
0898:             * @param concreteFt
0899:             *            conrete (non-abstract) type that is contained in the feature property
0900:             * @param relation
0901:             *            table relation from the join table to the subfeature table
0902:             * @param keyComponents
0903:             * @return the <code>FeatureId</code> or null (if there is no such subfeature)
0904:             * @throws DatastoreException
0905:             */
0906:            private FeatureId determineSubFID(MappedFeatureType concreteSubFt,
0907:                    TableRelation relation, Object[] keyComponents)
0908:                    throws DatastoreException {
0909:                this .aliasGenerator.reset();
0910:                String fromAlias = this .aliasGenerator.generateUniqueAlias();
0911:                String toAlias = this .aliasGenerator.generateUniqueAlias();
0912:
0913:                StatementBuffer query = new StatementBuffer();
0914:                query.append("SELECT ");
0915:                appendFeatureIdColumns(concreteSubFt, toAlias, query);
0916:                query.append(" FROM ");
0917:                query.append(relation.getFromTable());
0918:                query.append(" ");
0919:                query.append(fromAlias);
0920:                query.append(" JOIN ");
0921:                query.append(concreteSubFt.getTable());
0922:                query.append(" ");
0923:                query.append(toAlias);
0924:                query.append(" ON ");
0925:                appendJoinCondition(relation, fromAlias, toAlias, query);
0926:                query.append(" WHERE ");
0927:                for (int i = 0; i < keyComponents.length; i++) {
0928:                    appendQualifiedColumn(query, fromAlias, relation
0929:                            .getFromFields()[i].getField());
0930:                    query.append("=?");
0931:                    query.addArgument(keyComponents[i], relation
0932:                            .getFromFields()[i].getType());
0933:                    if (i != keyComponents.length - 1) {
0934:                        query.append(" AND ");
0935:                    }
0936:                }
0937:                FeatureId subFid = null;
0938:                PreparedStatement stmt = null;
0939:                ResultSet rs = null;
0940:                try {
0941:                    stmt = this .datastore.prepareStatement(conn, query);
0942:                    LOG.logDebug("Determining subfeature id: " + query);
0943:                    rs = stmt.executeQuery();
0944:                    if (rs.next()) {
0945:                        subFid = extractFeatureId(rs, concreteSubFt);
0946:                    }
0947:                } catch (SQLException e) {
0948:                    LOG.logDebug(e.getMessage(), e);
0949:                    throw new DatastoreException(
0950:                            "Error in #determineSubFID(): " + e.getMessage());
0951:                } finally {
0952:                    try {
0953:                        if (rs != null) {
0954:                            try {
0955:                                rs.close();
0956:                            } catch (SQLException e) {
0957:                                LOG.logError("Error closing result set: '"
0958:                                        + e.getMessage() + "'.", e);
0959:                            }
0960:                        }
0961:                    } finally {
0962:                        if (stmt != null) {
0963:                            try {
0964:                                stmt.close();
0965:                            } catch (SQLException e) {
0966:                                LOG.logError("Error closing statement: '"
0967:                                        + e.getMessage() + "'.", e);
0968:                            }
0969:                        }
0970:                    }
0971:                }
0972:                return subFid;
0973:            }
0974:
0975:            /**
0976:             * Builds the initial SELECT statement that retrieves the feature ids that are matched by the given
0977:             * <code>WhereBuilder</code>.
0978:             * <p>
0979:             * The statement is structured like this:
0980:             * <ul>
0981:             * <li><code>SELECT</code></li>
0982:             * <li>comma-separated list of qualified fid fields</li>
0983:             * <li><code>FROM</code></li>
0984:             * <li>comma-separated list of tables and their aliases (this is needed to constrain the paths to selected
0985:             * XPath-PropertyNames)</li>
0986:             * <li><code>WHERE</code></li>
0987:             * <li>SQL representation of the Filter expression</li>
0988:             * </ul>
0989:             * 
0990:             * @param rootFt
0991:             * @param whereBuilder
0992:             * @return initial SELECT statement to retrieve the feature ids
0993:             * @throws DatastoreException
0994:             */
0995:            private StatementBuffer buildInitialFIDSelect(
0996:                    MappedFeatureType rootFt, WhereBuilder whereBuilder)
0997:                    throws DatastoreException {
0998:
0999:                String tableAlias = whereBuilder.getRootTableAlias(0);
1000:                StatementBuffer query = new StatementBuffer();
1001:                query.append("SELECT ");
1002:                appendFeatureIdColumns(rootFt, tableAlias, query);
1003:                query.append(" FROM ");
1004:                whereBuilder.appendJoinTableList(query);
1005:                whereBuilder.appendWhereCondition(query);
1006:                return query;
1007:            }
1008:
1009:            /**
1010:             * Appends the alias qualified columns that make up the feature id to the given query.
1011:             * 
1012:             * @param featureType
1013:             * @param tableAlias
1014:             * @param query
1015:             */
1016:            protected void appendFeatureIdColumns(
1017:                    MappedFeatureType featureType, String tableAlias,
1018:                    StatementBuffer query) {
1019:                MappingField[] fidFields = featureType.getGMLId().getIdFields();
1020:                for (int i = 0; i < fidFields.length; i++) {
1021:                    query.append(tableAlias);
1022:                    query.append('.');
1023:                    query.append(fidFields[i].getField());
1024:                    if (i != fidFields.length - 1) {
1025:                        query.append(',');
1026:                    }
1027:                }
1028:            }
1029:
1030:            /**
1031:             * Extracts the FeatureId in the current row of the given {@link ResultSet}.
1032:             * 
1033:             * @param rs
1034:             * @param ft
1035:             *            feature type (may not be abstract)
1036:             * @return feature ids
1037:             * @throws SQLException
1038:             * @throws DatastoreException
1039:             */
1040:            protected FeatureId extractFeatureId(ResultSet rs,
1041:                    MappedFeatureType ft) throws SQLException,
1042:                    DatastoreException {
1043:
1044:                MappedGMLId gmlId = ft.getGMLId();
1045:                MappingField[] idFields = gmlId.getIdFields();
1046:
1047:                Object[] idValues = new Object[idFields.length];
1048:                for (int i = 0; i < idValues.length; i++) {
1049:                    Object idValue = rs.getObject(i + 1);
1050:                    if (idValue == null) {
1051:                        String msg = Messages.getMessage(
1052:                                "DATASTORE_FEATURE_ID_NULL", ft.getTable(), ft
1053:                                        .getName(), idFields[i].getField());
1054:                        throw new DatastoreException(msg);
1055:                    }
1056:                    idValues[i] = idValue;
1057:                }
1058:
1059:                return new FeatureId(ft, idValues);
1060:            }
1061:
1062:            /**
1063:             * Extracts the feature ids in the given {@link ResultSet} as a List of FeatureIds.
1064:             * <p>
1065:             * If the given feature type is abstract, it is expected that the first column of the result set contains the local
1066:             * name of the feature type.
1067:             * 
1068:             * @param rs
1069:             * @param ft
1070:             *            feature type (may be abstract)
1071:             * @return feature ids
1072:             * @throws SQLException
1073:             * @throws DatastoreException
1074:             */
1075:            protected List<FeatureId> extractFeatureIds(ResultSet rs,
1076:                    MappedFeatureType ft) throws SQLException,
1077:                    DatastoreException {
1078:                List<FeatureId> featureIdList = new ArrayList<FeatureId>();
1079:                MappedGMLId gmlId = ft.getGMLId();
1080:                MappingField[] idFields = gmlId.getIdFields();
1081:
1082:                boolean needsDisambiguation = ft.hasSeveralImplementations();
1083:
1084:                while (rs.next()) {
1085:                    int offset = 1;
1086:                    if (needsDisambiguation) {
1087:                        String localFtName = rs.getString(1);
1088:                        ft = ft.getGMLSchema().getFeatureType(localFtName);
1089:                        gmlId = ft.getGMLId();
1090:                        idFields = gmlId.getIdFields();
1091:                        offset = 2;
1092:                    }
1093:                    Object[] idValues = new Object[idFields.length];
1094:                    for (int i = 0; i < idValues.length; i++) {
1095:                        Object idValue = rs.getObject(i + offset);
1096:                        if (idValue == null) {
1097:                            String msg = Messages.getMessage(
1098:                                    "DATASTORE_FEATURE_ID_NULL", ft.getTable(),
1099:                                    ft.getName(), idFields[i].getField());
1100:                            throw new DatastoreException(msg);
1101:                        }
1102:                        idValues[i] = idValue;
1103:                    }
1104:                    featureIdList.add(new FeatureId(ft, idValues));
1105:                }
1106:                return featureIdList;
1107:            }
1108:
1109:            protected void appendJoins(TableRelation[] tableRelation,
1110:                    String fromAlias, String[] toAliases, StatementBuffer query) {
1111:                for (int i = 0; i < toAliases.length; i++) {
1112:                    String toAlias = toAliases[i];
1113:                    appendJoin(tableRelation[i], fromAlias, toAlias, query);
1114:                    fromAlias = toAlias;
1115:                }
1116:            }
1117:
1118:            private void appendJoin(TableRelation tableRelation,
1119:                    String fromAlias, String toAlias, StatementBuffer query) {
1120:                query.append(" JOIN ");
1121:                query.append(tableRelation.getToTable());
1122:                query.append(" ");
1123:                query.append(toAlias);
1124:                query.append(" ON ");
1125:                appendJoinCondition(tableRelation, fromAlias, toAlias, query);
1126:            }
1127:
1128:            protected void appendJoinCondition(TableRelation tableRelation,
1129:                    String fromAlias, String toAlias, StatementBuffer query) {
1130:
1131:                MappingField[] fromFields = tableRelation.getFromFields();
1132:                MappingField[] toFields = tableRelation.getToFields();
1133:                for (int i = 0; i < fromFields.length; i++) {
1134:                    query.append(toAlias);
1135:                    query.append(".");
1136:                    query.append(toFields[i].getField());
1137:                    query.append("=");
1138:                    query.append(fromAlias);
1139:                    query.append(".");
1140:                    query.append(fromFields[i].getField());
1141:                    if (i != fromFields.length - 1) {
1142:                        query.append(" AND ");
1143:                    }
1144:                }
1145:            }
1146:
1147:            protected void appendFeatureIdConstraint(StatementBuffer query,
1148:                    FeatureId fid) {
1149:                MappingField[] idFields = fid.getFidDefinition().getIdFields();
1150:                for (int i = 0; i < idFields.length; i++) {
1151:                    query.append(idFields[i].getField());
1152:                    query.append("=?");
1153:                    query.addArgument(fid.getValue(i), idFields[i].getType());
1154:                    if (i < idFields.length - 1) {
1155:                        query.append(" AND ");
1156:                    }
1157:                }
1158:            }
1159:
1160:            protected void appendFeatureIdConstraint(StatementBuffer query,
1161:                    FeatureId fid, String tableAlias) {
1162:                MappingField[] idFields = fid.getFidDefinition().getIdFields();
1163:                for (int i = 0; i < idFields.length; i++) {
1164:                    query.append(tableAlias);
1165:                    query.append('.');
1166:                    query.append(idFields[i].getField());
1167:                    query.append("=?");
1168:                    query.addArgument(fid.getValue(i), idFields[i].getType());
1169:                    if (i < idFields.length - 1) {
1170:                        query.append(" AND ");
1171:                    }
1172:                }
1173:            }
1174:
1175:            /**
1176:             * Appends the specified columns as a comma-separated list to the given query.
1177:             * 
1178:             * @param query
1179:             *            StatementBuffer that the list is appended to
1180:             * @param columns
1181:             *            array of column names
1182:             */
1183:            public void appendColumnsList(StatementBuffer query,
1184:                    String[] columns) {
1185:                for (int i = 0; i < columns.length; i++) {
1186:                    if (columns[i].indexOf('$') != -1) {
1187:                        // function call
1188:                        String column = columns[i];
1189:                        column = column.replaceAll("\\$\\.", "");
1190:                        query.append(column);
1191:
1192:                    } else {
1193:                        query.append(columns[i]);
1194:                    }
1195:
1196:                    if (i != columns.length - 1) {
1197:                        query.append(',');
1198:                    }
1199:                }
1200:            }
1201:
1202:            /**
1203:             * Appends the specified columns as alias-qualified, comma-separated list to the given query.
1204:             * 
1205:             * @param query
1206:             *            StatementBuffer that the list is appended to
1207:             * @param tableAlias
1208:             *            alias to use as qualifier (alias.field)
1209:             * @param columns
1210:             *            array of column names
1211:             */
1212:            public void appendQualifiedColumnsList(StatementBuffer query,
1213:                    String tableAlias, String[] columns) {
1214:                for (int i = 0; i < columns.length; i++) {
1215:                    appendQualifiedColumn(query, tableAlias, columns[i]);
1216:                    if (i != columns.length - 1) {
1217:                        query.append(',');
1218:                    }
1219:                }
1220:            }
1221:
1222:            /**
1223:             * Appends the specified column to the given query.
1224:             * 
1225:             * @param query
1226:             *            StatementBuffer that the list is appended to
1227:             * @param tableAlias
1228:             *            alias to use as qualifier (alias.field)
1229:             * @param column
1230:             *            column name
1231:             */
1232:            public void appendQualifiedColumn(StatementBuffer query,
1233:                    String tableAlias, String column) {
1234:                query.append(tableAlias);
1235:                query.append('.');
1236:                query.append(column);
1237:            }
1238:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.