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


001:        //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/datastore/sql/transaction/UpdateHandler.java $
002:        /*----------------    FILE HEADER  ------------------------------------------
003:
004:         This file is part of deegree.
005:         Copyright (C) 2001-2008 by:
006:         EXSE, Department of Geography, University of Bonn
007:         http://www.giub.uni-bonn.de/deegree/
008:         lat/lon GmbH
009:         http://www.lat-lon.de
010:
011:         This library is free software; you can redistribute it and/or
012:         modify it under the terms of the GNU Lesser General Public
013:         License as published by the Free Software Foundation; either
014:         version 2.1 of the License, or (at your option) any later version.
015:
016:         This library is distributed in the hope that it will be useful,
017:         but WITHOUT ANY WARRANTY; without even the implied warranty of
018:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:         Lesser General Public License for more details.
020:
021:         You should have received a copy of the GNU Lesser General Public
022:         License along with this library; if not, write to the Free Software
023:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         Contact:
026:
027:         Andreas Poth
028:         lat/lon GmbH
029:         Aennchenstraße 19
030:         53177 Bonn
031:         Germany
032:         E-Mail: poth@lat-lon.de
033:
034:         Prof. Dr. Klaus Greve
035:         Department of Geography
036:         University of Bonn
037:         Meckenheimer Allee 166
038:         53115 Bonn
039:         Germany
040:         E-Mail: greve@giub.uni-bonn.de
041:        
042:         ---------------------------------------------------------------------------*/
043:        package org.deegree.io.datastore.sql.transaction;
044:
045:        import java.sql.Connection;
046:        import java.sql.PreparedStatement;
047:        import java.sql.ResultSet;
048:        import java.sql.SQLException;
049:        import java.util.ArrayList;
050:        import java.util.List;
051:        import java.util.Map;
052:
053:        import org.deegree.datatypes.QualifiedName;
054:        import org.deegree.datatypes.Types;
055:        import org.deegree.framework.log.ILogger;
056:        import org.deegree.framework.log.LoggerFactory;
057:        import org.deegree.i18n.Messages;
058:        import org.deegree.io.datastore.DatastoreException;
059:        import org.deegree.io.datastore.FeatureId;
060:        import org.deegree.io.datastore.idgenerator.FeatureIdAssigner;
061:        import org.deegree.io.datastore.schema.MappedFeaturePropertyType;
062:        import org.deegree.io.datastore.schema.MappedFeatureType;
063:        import org.deegree.io.datastore.schema.MappedGeometryPropertyType;
064:        import org.deegree.io.datastore.schema.MappedPropertyType;
065:        import org.deegree.io.datastore.schema.MappedSimplePropertyType;
066:        import org.deegree.io.datastore.schema.TableRelation;
067:        import org.deegree.io.datastore.schema.TableRelation.FK_INFO;
068:        import org.deegree.io.datastore.schema.content.MappingField;
069:        import org.deegree.io.datastore.schema.content.MappingGeometryField;
070:        import org.deegree.io.datastore.schema.content.SimpleContent;
071:        import org.deegree.io.datastore.sql.AbstractRequestHandler;
072:        import org.deegree.io.datastore.sql.StatementBuffer;
073:        import org.deegree.io.datastore.sql.TableAliasGenerator;
074:        import org.deegree.io.datastore.sql.transaction.delete.DeleteHandler;
075:        import org.deegree.io.datastore.sql.transaction.insert.InsertHandler;
076:        import org.deegree.model.feature.Feature;
077:        import org.deegree.model.feature.FeatureProperty;
078:        import org.deegree.model.feature.schema.FeaturePropertyType;
079:        import org.deegree.model.filterencoding.Filter;
080:        import org.deegree.model.spatialschema.Geometry;
081:        import org.deegree.ogcbase.PropertyPath;
082:        import org.deegree.ogcwebservices.wfs.operation.transaction.Insert;
083:        import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
084:        import org.deegree.ogcwebservices.wfs.operation.transaction.Update;
085:
086:        /**
087:         * Handler for {@link Update} operations (usually contained in {@link Transaction} requests).
088:         * 
089:         * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
090:         * @author last edited by: $Author: apoth $
091:         * 
092:         * @version $Revision: 9342 $, $Date: 2007-12-27 04:32:57 -0800 (Thu, 27 Dec 2007) $
093:         */
094:        public class UpdateHandler extends AbstractRequestHandler {
095:
096:            private static final ILogger LOG = LoggerFactory
097:                    .getLogger(UpdateHandler.class);
098:
099:            private SQLTransaction dsTa;
100:
101:            private String lockId;
102:
103:            /**
104:             * Creates a new <code>UpdateHandler</code> from the given parameters.
105:             * 
106:             * @param dsTa
107:             * @param aliasGenerator
108:             * @param conn
109:             * @param lockId
110:             *            optional id of associated lock (may be null)
111:             */
112:            public UpdateHandler(SQLTransaction dsTa,
113:                    TableAliasGenerator aliasGenerator, Connection conn,
114:                    String lockId) {
115:                super (dsTa.getDatastore(), aliasGenerator, conn);
116:                this .dsTa = dsTa;
117:                this .lockId = lockId;
118:            }
119:
120:            /**
121:             * Performs an update operation against the associated datastore.
122:             * 
123:             * @param ft
124:             * @param replacementProps
125:             * @param filter
126:             * @return number of updated (root) feature instances
127:             * @throws DatastoreException
128:             */
129:            public int performUpdate(MappedFeatureType ft,
130:                    Map<PropertyPath, FeatureProperty> replacementProps,
131:                    Filter filter) throws DatastoreException {
132:
133:                List<FeatureId> fids = determineAffectedAndModifiableFIDs(ft,
134:                        filter, this .lockId);
135:
136:                LOG.logDebug("Updating: " + ft);
137:                for (PropertyPath property : replacementProps.keySet()) {
138:                    FeatureProperty propertyValue = replacementProps
139:                            .get(property);
140:                    for (FeatureId fid : fids) {
141:                        LOG.logDebug("Updating feature: " + fid);
142:                        performUpdate(fid, ft, property, propertyValue);
143:                    }
144:                }
145:                return fids.size();
146:            }
147:
148:            /**
149:             * Performs an update operation against the associated datastore.
150:             * <p>
151:             * The filter must match exactly one feature instance (or none) which is then replaced by the
152:             * specified replacement feature.
153:             * 
154:             * @param mappedFeatureType
155:             * @param replacementFeature
156:             * @param filter
157:             * @return number of updated (root) feature instances (0 or 1)
158:             * @throws DatastoreException
159:             */
160:            public int performUpdate(MappedFeatureType mappedFeatureType,
161:                    Feature replacementFeature, Filter filter)
162:                    throws DatastoreException {
163:
164:                LOG.logDebug("Updating (replace): " + mappedFeatureType);
165:                if (filter != null) {
166:                    LOG.logDebug(" filter: " + filter.toXML());
167:                }
168:
169:                List<FeatureId> fids = determineAffectedAndModifiableFIDs(
170:                        mappedFeatureType, filter, this .lockId);
171:
172:                if (fids.size() > 1) {
173:                    String msg = Messages
174:                            .getMessage("DATASTORE_MORE_THAN_ONE_FEATURE");
175:                    throw new DatastoreException(msg);
176:                }
177:                DeleteHandler deleteHandler = new DeleteHandler(this .dsTa,
178:                        this .aliasGenerator, this .conn, this .lockId);
179:                deleteHandler.performDelete(mappedFeatureType, filter);
180:
181:                // identify stored subfeatures / assign feature ids
182:                FeatureIdAssigner fidAssigner = new FeatureIdAssigner(
183:                        Insert.ID_GEN.GENERATE_NEW);
184:                fidAssigner.assignFID(replacementFeature, this .dsTa);
185:                // TODO remove this hack
186:                fidAssigner.markStoredFeatures();
187:
188:                InsertHandler insertHandler = new InsertHandler(this .dsTa,
189:                        this .aliasGenerator, this .conn);
190:                List<Feature> features = new ArrayList<Feature>();
191:                features.add(replacementFeature);
192:                insertHandler.performInsert(features);
193:
194:                return fids.size();
195:            }
196:
197:            /**
198:             * Performs the update (replacing of a property) of the given feature instance.
199:             * <p>
200:             * If the selected property is a direct property of the feature, the root feature is updated,
201:             * otherwise the targeted subfeatures have to be determined first.
202:             * 
203:             * @param fid
204:             * @param ft
205:             * @param propertyName
206:             * @param replacementProperty
207:             * @throws DatastoreException
208:             */
209:            private void performUpdate(FeatureId fid, MappedFeatureType ft,
210:                    PropertyPath propertyName,
211:                    FeatureProperty replacementProperty)
212:                    throws DatastoreException {
213:
214:                Object replacementValue = replacementProperty.getValue();
215:                LOG.logDebug("Updating fid: " + fid + ", propertyName: "
216:                        + propertyName + " -> " + replacementValue);
217:
218:                int steps = propertyName.getSteps();
219:                QualifiedName propName = propertyName.getStep(steps - 1)
220:                        .getPropertyName();
221:                if (steps > 2) {
222:                    QualifiedName subFtName = propertyName.getStep(steps - 2)
223:                            .getPropertyName();
224:                    MappedFeatureType subFt = this .datastore
225:                            .getFeatureType(subFtName);
226:                    MappedPropertyType pt = (MappedPropertyType) subFt
227:                            .getProperty(propName);
228:                    List<TableRelation> tablePath = getTablePath(ft,
229:                            propertyName);
230:                    List<FeatureId> subFids = determineAffectedFIDs(fid, subFt,
231:                            tablePath);
232:                    for (FeatureId subFid : subFids) {
233:                        updateProperty(subFid, subFt, pt, replacementValue);
234:                    }
235:                } else {
236:                    MappedPropertyType pt = (MappedPropertyType) ft
237:                            .getProperty(propName);
238:                    updateProperty(fid, ft, pt, replacementValue);
239:                }
240:            }
241:
242:            /**
243:             * Determines the subfeature instances that are targeted by the given PropertyName.
244:             * 
245:             * @param fid
246:             * @param subFt
247:             * @param propertyName
248:             * @return the matched feature ids
249:             * @throws DatastoreException
250:             */
251:            private List<FeatureId> determineAffectedFIDs(FeatureId fid,
252:                    MappedFeatureType subFt, List<TableRelation> path)
253:                    throws DatastoreException {
254:
255:                List<FeatureId> subFids = new ArrayList<FeatureId>();
256:
257:                this .aliasGenerator.reset();
258:                String[] tableAliases = this .aliasGenerator
259:                        .generateUniqueAliases(path.size() + 1);
260:                String toTableAlias = tableAliases[tableAliases.length - 1];
261:                StatementBuffer query = new StatementBuffer();
262:                query.append("SELECT ");
263:                appendFeatureIdColumns(subFt, toTableAlias, query);
264:                query.append(" FROM ");
265:                query.append(path.get(0).getFromTable());
266:                query.append(" ");
267:                query.append(tableAliases[0]);
268:                // append joins
269:                for (int i = 0; i < path.size(); i++) {
270:                    query.append(" JOIN ");
271:                    query.append(path.get(i).getToTable());
272:                    query.append(" ");
273:                    query.append(tableAliases[i + 1]);
274:                    query.append(" ON ");
275:                    MappingField[] fromFields = path.get(i).getFromFields();
276:                    MappingField[] toFields = path.get(i).getToFields();
277:                    for (int j = 0; j < fromFields.length; j++) {
278:                        query.append(tableAliases[i]);
279:                        query.append('.');
280:                        query.append(fromFields[j].getField());
281:                        query.append('=');
282:                        query.append(tableAliases[i + 1]);
283:                        query.append('.');
284:                        query.append(toFields[j].getField());
285:                    }
286:                }
287:                query.append(" WHERE ");
288:                MappingField[] fidFields = fid.getFidDefinition().getIdFields();
289:                for (int i = 0; i < fidFields.length; i++) {
290:                    query.append(tableAliases[0]);
291:                    query.append('.');
292:                    query.append(fidFields[i].getField());
293:                    query.append("=?");
294:                    query.addArgument(fid.getValue(i), fidFields[i].getType());
295:                    if (i != fidFields.length - 1) {
296:                        query.append(" AND ");
297:                    }
298:                }
299:
300:                PreparedStatement stmt = null;
301:                ResultSet rs = null;
302:                try {
303:                    stmt = this .datastore.prepareStatement(conn, query);
304:                    rs = stmt.executeQuery();
305:                    subFids = extractFeatureIds(rs, subFt);
306:                } catch (SQLException e) {
307:                    throw new DatastoreException(
308:                            "Error in determineAffectedFIDs(): "
309:                                    + e.getMessage());
310:                } finally {
311:                    try {
312:                        if (rs != null) {
313:                            try {
314:                                rs.close();
315:                            } catch (SQLException e) {
316:                                LOG.logError("Error closing result set: '"
317:                                        + e.getMessage() + "'.", e);
318:                            }
319:                        }
320:                    } finally {
321:                        if (stmt != null) {
322:                            try {
323:                                stmt.close();
324:                            } catch (SQLException e) {
325:                                LOG.logError("Error closing statement: '"
326:                                        + e.getMessage() + "'.", e);
327:                            }
328:                        }
329:                    }
330:                }
331:                return subFids;
332:            }
333:
334:            /**
335:             * Returns the relations (the "path") that lead from the feature type's table to the subfeature
336:             * table which is targeted by the specified property name.
337:             * 
338:             * @param ft
339:             *            source feature type
340:             * @param path
341:             *            property name
342:             * @return relations that lead from the feature type's table to the subfeature table
343:             */
344:            private List<TableRelation> getTablePath(MappedFeatureType ft,
345:                    PropertyPath path) {
346:                List<TableRelation> relations = new ArrayList<TableRelation>();
347:                for (int i = 1; i < path.getSteps() - 2; i += 2) {
348:                    QualifiedName propName = path.getStep(i).getPropertyName();
349:                    MappedFeaturePropertyType pt = (MappedFeaturePropertyType) ft
350:                            .getProperty(propName);
351:                    TableRelation[] tableRelations = pt.getTableRelations();
352:                    for (int j = 0; j < tableRelations.length; j++) {
353:                        relations.add(tableRelations[j]);
354:                    }
355:                    ft = pt.getFeatureTypeReference().getFeatureType();
356:                }
357:                return relations;
358:            }
359:
360:            /**
361:             * Replaces the specified feature's property with the given value.
362:             * 
363:             * @param fid
364:             * @param ft
365:             * @param pt
366:             * @param replacementValue
367:             * @throws DatastoreException
368:             */
369:            private void updateProperty(FeatureId fid, MappedFeatureType ft,
370:                    MappedPropertyType pt, Object replacementValue)
371:                    throws DatastoreException {
372:                LOG.logDebug("Updating property '" + pt.getName()
373:                        + "' of feature '" + fid + "'.");
374:
375:                if (!ft.isUpdatable()) {
376:                    String msg = Messages.getMessage(
377:                            "DATASTORE_FT_NOT_UPDATABLE", ft.getName());
378:                    throw new DatastoreException(msg);
379:                }
380:                TableRelation[] tablePath = pt.getTableRelations();
381:                if (pt instanceof  MappedSimplePropertyType) {
382:                    SimpleContent content = ((MappedSimplePropertyType) pt)
383:                            .getContent();
384:                    if (content.isUpdateable()) {
385:                        if (content instanceof  MappingField) {
386:                            updateProperty(fid, tablePath,
387:                                    (MappingField) content, replacementValue);
388:                        }
389:                    } else {
390:                        LOG.logInfo("Ignoring property '" + pt.getName()
391:                                + "' in update - is virtual.");
392:                    }
393:                } else if (pt instanceof  MappedGeometryPropertyType) {
394:                    MappingGeometryField dbField = ((MappedGeometryPropertyType) pt)
395:                            .getMappingField();
396:                    Object dbGeometry = this .datastore
397:                            .convertDeegreeToDBGeometry(
398:                                    (Geometry) replacementValue, dbField
399:                                            .getSRS(), this .conn);
400:                    // TODO remove this Oracle hack
401:                    if (this .datastore.getClass().getName().contains(
402:                            "OracleDatastore")) {
403:                        dbField = new MappingGeometryField(dbField.getTable(),
404:                                dbField.getField(), Types.STRUCT, dbField
405:                                        .getSRS());
406:                    }
407:                    updateProperty(fid, tablePath, dbField, dbGeometry);
408:                } else if (pt instanceof  FeaturePropertyType) {
409:                    updateProperty(fid, ft, (MappedFeaturePropertyType) pt,
410:                            (Feature) replacementValue);
411:                } else {
412:                    throw new DatastoreException(
413:                            "Internal error: Properties with type '"
414:                                    + pt.getClass()
415:                                    + "' are not handled in UpdateHandler.");
416:                }
417:            }
418:
419:            /**
420:             * Updates a simple / geometry property of the specified feature.
421:             * <p>
422:             * Three cases are distinguished (which all have to be handled differently):
423:             * <ol>
424:             * <li>property value stored in feature table</li>
425:             * <li>property value stored in property table, fk in property table</li>
426:             * <li>property value stored in property table, fk in feature table</li>
427:             * </ol>
428:             * 
429:             * @param fid
430:             * @param tablePath
431:             * @param dbField
432:             * @param replacementValue
433:             * @throws DatastoreException
434:             */
435:            private void updateProperty(FeatureId fid,
436:                    TableRelation[] tablePath, MappingField dbField,
437:                    Object replacementValue) throws DatastoreException {
438:
439:                if (tablePath.length == 0) {
440:                    updateProperty(fid, dbField, replacementValue);
441:                } else if (tablePath.length == 1) {
442:                    TableRelation relation = tablePath[0];
443:                    if (tablePath[0].getFKInfo() == FK_INFO.fkIsToField) {
444:                        Object[] keyValues = determineKeyValues(fid, relation);
445:                        if (keyValues != null) {
446:                            deletePropertyRows(relation, keyValues);
447:                        }
448:                        if (replacementValue != null) {
449:                            insertPropertyRow(relation, keyValues, dbField,
450:                                    replacementValue);
451:                        }
452:                    } else {
453:                        Object[] oldKeyValues = determineKeyValues(fid,
454:                                relation);
455:                        Object[] newKeyValues = findOrInsertPropertyRow(
456:                                relation, dbField, replacementValue);
457:                        updateFeatureRow(fid, relation, newKeyValues);
458:                        if (oldKeyValues != null) {
459:                            deleteOrphanedPropertyRows(relation, oldKeyValues);
460:                        }
461:                    }
462:                } else {
463:                    throw new DatastoreException(
464:                            "Updating of properties that are stored in "
465:                                    + "related tables using join tables is not "
466:                                    + "supported.");
467:                }
468:            }
469:
470:            private void updateFeatureRow(FeatureId fid,
471:                    TableRelation relation, Object[] newKeyValues)
472:                    throws DatastoreException {
473:
474:                StatementBuffer query = new StatementBuffer();
475:                query.append("UPDATE ");
476:                query.append(relation.getFromTable());
477:                query.append(" SET ");
478:                MappingField[] fromFields = relation.getFromFields();
479:                for (int i = 0; i < newKeyValues.length; i++) {
480:                    query.append(fromFields[i].getField());
481:                    query.append("=?");
482:                    query.addArgument(newKeyValues[i], fromFields[i].getType());
483:                }
484:                query.append(" WHERE ");
485:                appendFIDWhereCondition(query, fid);
486:
487:                LOG.logDebug("Performing update: " + query.getQueryString());
488:
489:                PreparedStatement stmt = null;
490:                try {
491:                    stmt = this .datastore.prepareStatement(conn, query);
492:                    stmt.execute();
493:                } catch (SQLException e) {
494:                    throw new DatastoreException("Error in performUpdate(): "
495:                            + e.getMessage());
496:                } finally {
497:                    if (stmt != null) {
498:                        try {
499:                            stmt.close();
500:                        } catch (SQLException e) {
501:                            LOG.logError("Error closing statement: '"
502:                                    + e.getMessage() + "'.", e);
503:                        }
504:                    }
505:                }
506:
507:            }
508:
509:            /**
510:             * Updates a simple / geometry property of the specified feature.
511:             * <p>
512:             * This method handles the case where the property is stored in the feature table itself, so a
513:             * single UPDATE statement is sufficient.
514:             * 
515:             * @param fid
516:             * @param dbField
517:             * @param replacementValue
518:             * @throws DatastoreException
519:             */
520:            private void updateProperty(FeatureId fid, MappingField dbField,
521:                    Object replacementValue) throws DatastoreException {
522:
523:                StatementBuffer query = new StatementBuffer();
524:                query.append("UPDATE ");
525:                query.append(dbField.getTable());
526:                query.append(" SET ");
527:                query.append(dbField.getField());
528:                query.append("=?");
529:                query.addArgument(replacementValue, dbField.getType());
530:                query.append(" WHERE ");
531:                appendFIDWhereCondition(query, fid);
532:
533:                LOG.logDebug("Performing update: " + query.getQueryString());
534:
535:                PreparedStatement stmt = null;
536:                try {
537:                    stmt = this .datastore.prepareStatement(conn, query);
538:                    stmt.execute();
539:                } catch (SQLException e) {
540:                    throw new DatastoreException("Error in performUpdate(): "
541:                            + e.getMessage());
542:                } finally {
543:                    if (stmt != null) {
544:                        try {
545:                            stmt.close();
546:                        } catch (SQLException e) {
547:                            LOG.logError("Error closing statement: '"
548:                                    + e.getMessage() + "'.", e);
549:                        }
550:                    }
551:                }
552:            }
553:
554:            /**
555:             * Determines the values for the key columns that are referenced by the given table relation (as
556:             * from fields).
557:             * 
558:             * @param fid
559:             * @param relation
560:             * @return the values for the key columns
561:             * @throws DatastoreException
562:             */
563:            private Object[] determineKeyValues(FeatureId fid,
564:                    TableRelation relation) throws DatastoreException {
565:
566:                StatementBuffer query = new StatementBuffer();
567:                query.append("SELECT ");
568:                MappingField[] fromFields = relation.getFromFields();
569:                for (int i = 0; i < fromFields.length; i++) {
570:                    query.append(fromFields[i].getField());
571:                    if (i != fromFields.length - 1) {
572:                        query.append(',');
573:                    }
574:                }
575:                query.append(" FROM ");
576:                query.append(relation.getFromTable());
577:                query.append(" WHERE ");
578:                appendFIDWhereCondition(query, fid);
579:
580:                Object[] keyValues = new Object[fromFields.length];
581:                LOG.logDebug("determineKeyValues: " + query.getQueryString());
582:                PreparedStatement stmt = null;
583:                try {
584:                    stmt = this .datastore.prepareStatement(conn, query);
585:                    ResultSet rs = stmt.executeQuery();
586:                    if (rs.next()) {
587:                        for (int i = 0; i < keyValues.length; i++) {
588:                            Object value = rs.getObject(i + 1);
589:                            if (value != null) {
590:                                keyValues[i] = value;
591:                            } else {
592:                                keyValues = null;
593:                                break;
594:                            }
595:                        }
596:                    } else {
597:                        LOG
598:                                .logError("Internal error. Result is empty (no rows).");
599:                        throw new SQLException();
600:                    }
601:                } catch (SQLException e) {
602:                    throw new DatastoreException("Error in performUpdate(): "
603:                            + e.getMessage());
604:                } finally {
605:                    if (stmt != null) {
606:                        try {
607:                            stmt.close();
608:                        } catch (SQLException e) {
609:                            LOG.logError("Error closing statement: '"
610:                                    + e.getMessage() + "'.", e);
611:                        }
612:                    }
613:                }
614:                return keyValues;
615:            }
616:
617:            private void deletePropertyRows(TableRelation relation,
618:                    Object[] keyValues) throws DatastoreException {
619:
620:                StatementBuffer query = new StatementBuffer();
621:                query.append("DELETE FROM ");
622:                query.append(relation.getToTable());
623:                query.append(" WHERE ");
624:                MappingField[] toFields = relation.getToFields();
625:                for (int i = 0; i < toFields.length; i++) {
626:                    query.append(toFields[i].getField());
627:                    query.append("=?");
628:                    query.addArgument(keyValues[i], toFields[i].getType());
629:                    if (i != toFields.length - 1) {
630:                        query.append(" AND ");
631:                    }
632:                }
633:
634:                PreparedStatement stmt = null;
635:                LOG.logDebug("deletePropertyRows: " + query.getQueryString());
636:                try {
637:                    stmt = this .datastore.prepareStatement(conn, query);
638:                    stmt.execute();
639:                } catch (SQLException e) {
640:                    throw new DatastoreException("Error in performUpdate(): "
641:                            + e.getMessage());
642:                } finally {
643:                    if (stmt != null) {
644:                        try {
645:                            stmt.close();
646:                        } catch (SQLException e) {
647:                            LOG.logError("Error closing statement: '"
648:                                    + e.getMessage() + "'.", e);
649:                        }
650:                    }
651:                }
652:            }
653:
654:            private void insertPropertyRow(TableRelation relation,
655:                    Object[] keyValues, MappingField dbField,
656:                    Object replacementValue) throws DatastoreException {
657:
658:                if (keyValues == null) {
659:                    if (relation.getFromFields().length > 1) {
660:                        throw new DatastoreException(
661:                                "Key generation for compound keys is not supported.");
662:                    }
663:                    // generate new primary key
664:                    keyValues = new Object[1];
665:                    keyValues[0] = relation.getIdGenerator().getNewId(dsTa);
666:                }
667:
668:                StatementBuffer query = new StatementBuffer();
669:                query.append("INSERT INTO ");
670:                query.append(relation.getToTable());
671:                query.append(" (");
672:                MappingField[] toFields = relation.getToFields();
673:                for (int i = 0; i < toFields.length; i++) {
674:                    query.append(toFields[i].getField());
675:                    query.append(',');
676:                }
677:                query.append(dbField.getField());
678:                query.append(") VALUES (");
679:                for (int i = 0; i < toFields.length; i++) {
680:                    query.append('?');
681:                    query.addArgument(keyValues[i], toFields[i].getType());
682:                    query.append(',');
683:                }
684:                query.append("?)");
685:                query.addArgument(replacementValue, dbField.getType());
686:
687:                PreparedStatement stmt = null;
688:                LOG.logDebug("insertPropertyRow: " + query.getQueryString());
689:                try {
690:                    stmt = this .datastore.prepareStatement(conn, query);
691:                    stmt.execute();
692:                } catch (SQLException e) {
693:                    throw new DatastoreException("Error in performUpdate(): "
694:                            + e.getMessage());
695:                } finally {
696:                    if (stmt != null) {
697:                        try {
698:                            stmt.close();
699:                        } catch (SQLException e) {
700:                            LOG.logError("Error closing statement: '"
701:                                    + e.getMessage() + "'.", e);
702:                        }
703:                    }
704:                }
705:            }
706:
707:            /**
708:             * Returns the foreign key value(s) for the row that stores the given property.
709:             * <p>
710:             * If the row already exists, the existing key is returned, otherwise a new row for the property
711:             * is inserted first.
712:             * 
713:             * @param relation
714:             * @param dbField
715:             * @param replacementValue
716:             * @return foreign key value(s) for the row that stores the given property
717:             * @throws DatastoreException
718:             */
719:            private Object[] findOrInsertPropertyRow(TableRelation relation,
720:                    MappingField dbField, Object replacementValue)
721:                    throws DatastoreException {
722:
723:                Object[] keyValues = null;
724:
725:                if (dbField.getType() != Types.GEOMETRY) {
726:                    StatementBuffer query = new StatementBuffer();
727:                    query.append("SELECT ");
728:                    MappingField[] toFields = relation.getToFields();
729:                    for (int i = 0; i < toFields.length; i++) {
730:                        query.append(toFields[i].getField());
731:                        if (i != toFields.length - 1) {
732:                            query.append(',');
733:                        }
734:                    }
735:                    query.append(" FROM ");
736:                    query.append(relation.getToTable());
737:                    query.append(" WHERE ");
738:                    query.append(dbField.getField());
739:                    query.append("=?");
740:                    query.addArgument(replacementValue, dbField.getType());
741:
742:                    PreparedStatement stmt = null;
743:                    LOG.logDebug("findOrInsertPropertyRow: "
744:                            + query.getQueryString());
745:                    try {
746:                        stmt = this .datastore.prepareStatement(conn, query);
747:                        ResultSet rs = stmt.executeQuery();
748:                        if (rs.next()) {
749:                            keyValues = new Object[toFields.length];
750:                            for (int i = 0; i < toFields.length; i++) {
751:                                keyValues[i] = rs.getObject(i + 1);
752:                            }
753:                        }
754:                    } catch (SQLException e) {
755:                        throw new DatastoreException(
756:                                "Error in findOrInsertPropertyRow(): "
757:                                        + e.getMessage());
758:                    } finally {
759:                        if (stmt != null) {
760:                            try {
761:                                stmt.close();
762:                            } catch (SQLException e) {
763:                                LOG.logError("Error closing statement: '"
764:                                        + e.getMessage() + "'.", e);
765:                            }
766:                        }
767:                    }
768:                    if (keyValues != null) {
769:                        return keyValues;
770:                    }
771:                }
772:
773:                if (relation.getToFields().length > 1) {
774:                    throw new DatastoreException(
775:                            "Key generation for compound keys is not supported.");
776:                }
777:
778:                // property does not yet exist (or it's a geometry)
779:                keyValues = new Object[1];
780:                // generate new PK
781:                keyValues[0] = relation.getNewPK(this .dsTa);
782:                insertPropertyRow(relation, keyValues, dbField,
783:                        replacementValue);
784:
785:                return keyValues;
786:            }
787:
788:            private void deleteOrphanedPropertyRows(TableRelation relation,
789:                    Object[] keyValues) throws DatastoreException {
790:                DeleteHandler deleteHandler = new DeleteHandler(this .dsTa,
791:                        this .aliasGenerator, this .conn, this .lockId);
792:                deleteHandler.deleteOrphanedPropertyRows(relation, keyValues);
793:            }
794:
795:            private void updateProperty(@SuppressWarnings("unused")
796:            FeatureId fid, @SuppressWarnings("unused")
797:            MappedFeatureType ft, @SuppressWarnings("unused")
798:            MappedFeaturePropertyType pt, @SuppressWarnings("unused")
799:            Feature replacementFeature) {
800:                throw new UnsupportedOperationException(
801:                        "Updating of feature properties is not implemented yet.");
802:            }
803:
804:            private void appendFIDWhereCondition(StatementBuffer query,
805:                    FeatureId fid) {
806:                MappingField[] fidFields = fid.getFidDefinition().getIdFields();
807:                for (int i = 0; i < fidFields.length; i++) {
808:                    query.append(fidFields[i].getField());
809:                    query.append("=?");
810:                    query.addArgument(fid.getValue(i), fidFields[i].getType());
811:                    if (i != fidFields.length - 1) {
812:                        query.append(" AND ");
813:                    }
814:                }
815:            }
816:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.