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

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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005:         * 
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.data.postgis;
017:
018:        import java.io.IOException;
019:        import java.sql.Connection;
020:        import java.sql.SQLException;
021:        import java.sql.Statement;
022:        import java.util.Collections;
023:        import java.util.Date;
024:        import java.util.HashMap;
025:        import java.util.HashSet;
026:        import java.util.Iterator;
027:        import java.util.Set;
028:        import java.util.logging.Logger;
029:
030:        import org.geotools.data.DataSourceException;
031:        import org.geotools.data.FeatureWriter;
032:        import org.geotools.data.Transaction;
033:        import org.geotools.data.jdbc.JDBCTransactionState;
034:        import org.geotools.data.jdbc.JDBCUtils;
035:        import org.geotools.factory.CommonFactoryFinder;
036:        import org.geotools.feature.Feature;
037:        import org.geotools.feature.FeatureType;
038:        import org.geotools.feature.IllegalAttributeException;
039:        import org.geotools.geometry.jts.ReferencedEnvelope;
040:        import org.geotools.referencing.crs.DefaultGeographicCRS;
041:        import org.opengis.filter.Filter;
042:        import org.opengis.filter.FilterFactory;
043:        import org.opengis.referencing.operation.TransformException;
044:
045:        import com.vividsolutions.jts.geom.Envelope;
046:        import com.vividsolutions.jts.geom.Geometry;
047:        import com.vividsolutions.jts.geom.GeometryFactory;
048:
049:        /**
050:         * JDBC Transaction state that holds current revision, modified bounding box and the list of dirty
051:         * feature types. On commit, these are update on the db.
052:         * 
053:         * @author aaime
054:         * @since 2.4
055:         * 
056:         */
057:        class VersionedJdbcTransactionState extends JDBCTransactionState {
058:
059:            /** The logger for the postgis module. */
060:            protected static final Logger LOGGER = org.geotools.util.logging.Logging
061:                    .getLogger("org.geotools.data.postgis");
062:
063:            private long revision;
064:
065:            private ReferencedEnvelope bbox;
066:
067:            private HashSet dirtyTypes;
068:
069:            private HashMap dirtyFids;
070:
071:            private WrappedPostgisDataStore wrapped;
072:
073:            private Transaction transaction;
074:
075:            private static final double EPS = 0.000001;
076:
077:            public VersionedJdbcTransactionState(Connection connection,
078:                    WrappedPostgisDataStore wrapped) throws IOException {
079:                super (connection);
080:                this .wrapped = wrapped;
081:                reset();
082:            }
083:
084:            /**
085:             * Resets this state so that a new revision information is ready to be built
086:             */
087:            private void reset() {
088:                this .revision = Long.MIN_VALUE;
089:                this .bbox = new ReferencedEnvelope(DefaultGeographicCRS.WGS84);
090:                this .dirtyTypes = new HashSet();
091:                this .dirtyFids = new HashMap();
092:            }
093:
094:            /**
095:             * Returns the revision currently created during the transaction, eventually creating the
096:             * changesets record if not available
097:             * 
098:             * @throws IOException
099:             */
100:            public long getRevision() throws IOException {
101:                if (revision == Long.MIN_VALUE) {
102:                    revision = writeRevision(transaction, bbox);
103:                    transaction.putProperty(VersionedPostgisDataStore.REVISION,
104:                            new Long(revision));
105:                    transaction.putProperty(VersionedPostgisDataStore.VERSION,
106:                            String.valueOf(revision));
107:                }
108:                return revision;
109:            }
110:
111:            /**
112:             * Marks the specified type name as dirty, modified during the transaction
113:             * 
114:             * @param typeName
115:             */
116:            public void setTypeNameDirty(String typeName) {
117:                dirtyTypes.add(typeName);
118:            }
119:
120:            /**
121:             * Expands the current lat/lon dirty area
122:             * 
123:             * @param envelope
124:             *            a new dirtied area, expressed in EPSG:4326 crs
125:             */
126:            public void expandDirtyBounds(Envelope envelope) {
127:                bbox.expandToInclude(envelope);
128:            }
129:
130:            /**
131:             * Marks a specified FID as dirty. This is used to avoid to do versioned operations
132:             * on the same feature multiple times in the same transaction. The first must create 
133:             * the new versions, the others should operate against the new record
134:             * @param ft
135:             * @param fid
136:             */
137:            public void setFidDirty(String typeName, String fid) {
138:                Set fids = (Set) dirtyFids.get(typeName);
139:                if (fids == null) {
140:                    fids = new HashSet();
141:                    dirtyFids.put(typeName, fids);
142:                }
143:                fids.add(fid);
144:            }
145:
146:            /**
147:             * Returns true if a specific feature has already been modified during this transaction
148:             * @param typeName
149:             * @param fid
150:             * @return
151:             */
152:            public boolean isFidDirty(String typeName, String fid) {
153:                Set fids = (Set) dirtyFids.get(typeName);
154:                if (fids == null)
155:                    return false;
156:                return fids.contains(fid);
157:            }
158:
159:            public void setTransaction(Transaction transaction) {
160:                super .setTransaction(transaction);
161:                this .transaction = transaction;
162:                if (transaction == null) {
163:                    // setup for fail fast if anyone tries to keep using this state
164:                    // object
165:                    // afer the transaction has been closed
166:                    bbox = null;
167:                    dirtyTypes = null;
168:                }
169:            }
170:
171:            public void commit() throws IOException {
172:                // first, check we touched at least one versioned table
173:                if (!dirtyTypes.isEmpty()) {
174:                    // first write down modified envelope
175:                    Feature f = null;
176:                    FeatureWriter writer = null;
177:                    try {
178:                        // build filter to extract the appropriate changeset record
179:                        FilterFactory ff = CommonFactoryFinder
180:                                .getFilterFactory(null);
181:                        Filter revisionFilter = ff.id(Collections.singleton(ff
182:                                .featureId(String.valueOf(getRevision()))));
183:
184:                        // get a writer for the changeset record we want to update
185:                        writer = wrapped.getFeatureWriter(
186:                                VersionedPostgisDataStore.TBL_CHANGESETS,
187:                                (org.geotools.filter.Filter) revisionFilter,
188:                                transaction);
189:                        if (!writer.hasNext()) {
190:                            // who ate my changeset record ?!?
191:                            throw new IOException(
192:                                    "Could not find the changeset record "
193:                                            + "that should have been set in the versioned datastore on "
194:                                            + "versioned jdbc state creation");
195:                        }
196:
197:                        // update it
198:                        f = writer.next();
199:                        f.setDefaultGeometry(toLatLonRectange(bbox));
200:                        writer.write();
201:                    } catch (IllegalAttributeException e) {
202:                        // if this happens there's a programming error
203:                        throw new DataSourceException(
204:                                "Could not set an attribute in changesets, "
205:                                        + "most probably the table schema has been tampered with.",
206:                                e);
207:                    } finally {
208:                        if (writer != null)
209:                            writer.close();
210:                    }
211:
212:                    // then write down the modified feature types
213:                    Statement st = null;
214:                    try {
215:                        st = getConnection().createStatement();
216:                        for (Iterator it = dirtyTypes.iterator(); it.hasNext();) {
217:                            String typeName = (String) it.next();
218:                            execute(
219:                                    st,
220:                                    "INSERT INTO "
221:                                            + VersionedPostgisDataStore.TBL_TABLESCHANGED
222:                                            + " "
223:                                            + "SELECT "
224:                                            + revision
225:                                            + ", id "
226:                                            + "FROM "
227:                                            + VersionedPostgisDataStore.TBL_VERSIONEDTABLES
228:                                            + " WHERE SCHEMA = '"
229:                                            + wrapped.getConfig()
230:                                                    .getDatabaseSchemaName()
231:                                            + "' " + "AND NAME = '" + typeName
232:                                            + "'");
233:                        }
234:                    } catch (SQLException e) {
235:                        throw new DataSourceException(
236:                                "Error occurred while trying to save modified tables for "
237:                                        + "this changeset. This should not happen, probaly there's a "
238:                                        + "bug at work here.", e);
239:                    } finally {
240:                        JDBCUtils.close(st);
241:                    }
242:                }
243:
244:                // aah, all right, now we can really commit this transaction and be happy
245:                super .commit();
246:                // reset revision, we create a new revision for each new commit
247:                reset();
248:            }
249:
250:            public boolean isRevisionSet() {
251:                return revision == Long.MIN_VALUE;
252:            }
253:
254:            /**
255:             * Takes a referenced envelope and turns it into a lat/lon Polygon
256:             * 
257:             * @param envelope
258:             * @return
259:             * @throws TransformException
260:             */
261:            Geometry toLatLonRectange(final ReferencedEnvelope env)
262:                    throws IOException {
263:                ReferencedEnvelope envelope = new ReferencedEnvelope(env);
264:                try {
265:                    // since we cannot work with a null geometry in commits to
266:                    // changesets, let's return a very small envelope...
267:                    // an empty envelope gets turned into a point
268:                    if (envelope == null || envelope.isEmpty()) {
269:                        envelope = new ReferencedEnvelope(new Envelope(0, EPS,
270:                                0, EPS), DefaultGeographicCRS.WGS84);
271:                    } else {
272:                        envelope = envelope.transform(
273:                                DefaultGeographicCRS.WGS84, true);
274:                        if (envelope.getHeight() == 0.0
275:                                || envelope.getWidth() == 0.0)
276:                            envelope.expandBy(EPS);
277:                    }
278:
279:                    GeometryFactory gf = new GeometryFactory();
280:                    return gf.toGeometry(envelope);
281:                } catch (Exception e) {
282:                    throw new DataSourceException(
283:                            "An error occurred while trying to builds a "
284:                                    + "lat/lon polygon equivalent to "
285:                                    + envelope, e);
286:                }
287:            }
288:
289:            /**
290:             * Stores a commit message in the CHANGESETS table and return the associated revision number.
291:             * TODO: this may well be moved to the {@link VersionedJdbcTransactionState} class?
292:             * 
293:             * @param conn
294:             * @return
295:             * @throws IOException
296:             */
297:            protected long writeRevision(Transaction t, ReferencedEnvelope bbox)
298:                    throws IOException {
299:                Feature f = null;
300:                FeatureWriter writer = null;
301:                String author = (String) t
302:                        .getProperty(VersionedPostgisDataStore.AUTHOR);
303:                String message = (String) t
304:                        .getProperty(VersionedPostgisDataStore.MESSAGE);
305:                try {
306:                    writer = wrapped.getFeatureWriterAppend(
307:                            VersionedPostgisDataStore.TBL_CHANGESETS, t);
308:                    f = writer.next();
309:                    f.setAttribute("author", author);
310:                    f.setAttribute("message", message);
311:                    f.setAttribute("date", new Date());
312:
313:                    f.setDefaultGeometry(toLatLonRectange(bbox));
314:                    writer.write();
315:                } catch (IllegalAttributeException e) {
316:                    // if this happens there's a programming error
317:                    throw new IOException(
318:                            "Could not set an attribute in changesets, "
319:                                    + "most probably the table schema has been tampered with.");
320:                } finally {
321:                    if (writer != null)
322:                        writer.close();
323:                }
324:
325:                return ((Long) f.getAttribute("revision")).longValue();
326:            }
327:
328:            /**
329:             * Logs the sql at info level, then executes the command
330:             * 
331:             * @param st
332:             * @param sql
333:             * @throws SQLException
334:             */
335:            protected void execute(Statement st, String sql)
336:                    throws SQLException {
337:                LOGGER.fine(sql);
338:                st.execute(sql);
339:            }
340:
341:            /**
342:             * Returns the transaction associated to this state
343:             * 
344:             * @return
345:             */
346:            Transaction getTransaction() {
347:                return transaction;
348:            }
349:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.