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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2005-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.referencing.factory.epsg;
017:
018:        // J2SE dependencies
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.io.InputStream;
022:        import java.io.OutputStream;
023:        import java.io.BufferedReader;
024:        import java.io.FileInputStream;
025:        import java.io.FileOutputStream;
026:        import java.io.InputStreamReader;
027:        import java.sql.ResultSet;
028:        import java.sql.Statement;
029:        import java.sql.Connection;
030:        import java.sql.SQLException;
031:        import javax.sql.DataSource;
032:        import java.util.Properties;
033:        import java.util.logging.Level;
034:        import java.util.logging.Logger;
035:
036:        // Geotools dependencies
037:        import org.geotools.util.Version;
038:        import org.geotools.factory.Hints;
039:        import org.geotools.resources.i18n.Errors;
040:        import org.geotools.resources.i18n.ErrorKeys;
041:        import org.geotools.resources.i18n.Logging;
042:        import org.geotools.resources.i18n.LoggingKeys;
043:        import org.geotools.referencing.factory.AbstractAuthorityFactory;
044:
045:        // HSQL dependencies
046:        import org.hsqldb.jdbc.jdbcDataSource;
047:
048:        /**
049:         * Connection to the EPSG database in HSQL database engine format using JDBC. The EPSG
050:         * database can be downloaded from <A HREF="http://www.epsg.org">http://www.epsg.org</A>.
051:         * The SQL scripts (modified for the HSQL syntax as <A HREF="doc-files/HSQL.html">explained
052:         * here</A>) are bundled into this plugin. The database version is given in the
053:         * {@linkplain org.opengis.metadata.citation.Citation#getEdition edition attribute}
054:         * of the {@linkplain org.opengis.referencing.AuthorityFactory#getAuthority authority}.
055:         * The HSQL database is read only.
056:         * <P>
057:         * <H3>Implementation note</H3>
058:         * The SQL scripts are executed the first time a connection is required. The database
059:         * is then created as cached tables ({@code HSQL.properties} and {@code HSQL.data} files)
060:         * in a temporary directory. Future connections to the EPSG database while reuse the cached
061:         * tables, if available. Otherwise, the scripts will be executed again in order to recreate
062:         * them.
063:         * <p>
064:         * If the EPSG database should be created in a different directory (or already exists in that
065:         * directory), it may be specified as a {@linkplain System#getProperty(String) system property}
066:         * nammed {@value #DIRECTORY_KEY}.
067:         *
068:         * @since 2.4
069:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/FactoryOnHSQL.java $
070:         * @version $Id: FactoryOnHSQL.java 27863 2007-11-12 20:34:34Z desruisseaux $
071:         * @author Martin Desruisseaux
072:         * @author Didier Richard
073:         *
074:         * @deprecated Will be renamed as {@code ThreadedHsqlEpsgFactory} in Geotools 2.5.
075:         */
076:        public class FactoryOnHSQL extends DefaultFactory {
077:            /**
078:             * Current version of EPSG-HSQL plugin. This is usually the same version number than the
079:             * one in the EPSG database bundled in this plugin. However this field may contains
080:             * additional minor version number if there is some changes related to the EPSG-HSQL
081:             * plugin rather then the EPSG database itself (for example additional database index).
082:             *
083:             * @since 2.4
084:             */
085:            public static final Version VERSION = new Version("6.12.0");
086:
087:            /**
088:             * The key for fetching the database directory from {@linkplain System#getProperty(String)
089:             * system properties}.
090:             */
091:            public static final String DIRECTORY_KEY = "EPSG-HSQL.directory";
092:
093:            /**
094:             * The name of the SQL file to read in order to create the cached database.
095:             */
096:            private static final String SQL_FILE = "EPSG.sql";
097:
098:            /**
099:             * The database name.
100:             */
101:            public static final String DATABASE_NAME = "EPSG";
102:
103:            /**
104:             * The prefix to put in front of URL to the database.
105:             */
106:            private static final String PREFIX = "jdbc:hsqldb:file:";
107:
108:            /**
109:             * The logger name.
110:             */
111:            private static final String LOGGER = "org.geotools.referencing.factory.epsg";
112:
113:            /**
114:             * Creates a new instance of this factory. If the {@value #DIRECTORY_KEY}
115:             * {@linkplain System#getProperty(String) system property} is defined and contains
116:             * the name of a directory with a valid {@linkplain File#getParent parent}, then the
117:             * {@value #DATABASE_NAME} database will be saved in that directory. Otherwise, a
118:             * temporary directory will be used.
119:             */
120:            public FactoryOnHSQL() {
121:                this (null);
122:            }
123:
124:            /**
125:             * Creates a new instance of this data source using the specified hints. The priority
126:             * is set to a lower value than the {@linkplain FactoryOnAccess}'s one in order to give
127:             * precedence to the Access-backed database, if presents. Priorities are set that way
128:             * because:
129:             * <ul>
130:             *   <li>The MS-Access format is the primary EPSG database format.</li>
131:             *   <li>If a user downloads the MS-Access database himself, he probably wants to use it.</li>
132:             * </ul>
133:             */
134:            public FactoryOnHSQL(final Hints hints) {
135:                super (hints, PRIORITY + 1);
136:            }
137:
138:            /**
139:             * Returns the default directory for the EPSG database. If the {@value #DIRECTORY_KEY}
140:             * {@linkplain System#getProperty(String) system property} is defined and contains the
141:             * name of a directory with a valid {@linkplain File#getParent parent}, then the
142:             * {@value #DATABASE_NAME} database will be saved in that directory. Otherwise,
143:             * a temporary directory will be used.
144:             */
145:            private static File getDirectory() {
146:                try {
147:                    final String property = System.getProperty(DIRECTORY_KEY);
148:                    if (property != null) {
149:                        final File directory = new File(property);
150:                        /*
151:                         * Creates the directory if needed (mkdir), but NOT the parent directories (mkdirs)
152:                         * because a missing parent directory may be a symptom of an installation problem.
153:                         * For example if 'directory' is a subdirectory in the temporary directory (~/tmp/),
154:                         * this temporary directory should already exists. If it doesn't, an administrator
155:                         * should probably looks at this problem.
156:                         */
157:                        if (directory.isDirectory() || directory.mkdir()) {
158:                            return directory;
159:                        }
160:                    }
161:                } catch (SecurityException e) {
162:                    /*
163:                     * Can't fetch the base directory from system properties.
164:                     * Fallback on the default temporary directory.
165:                     */
166:                }
167:                return getTemporaryDirectory();
168:            }
169:
170:            /**
171:             * Returns the directory to uses in the temporary directory folder.
172:             */
173:            private static File getTemporaryDirectory() {
174:                File directory = new File(System.getProperty("java.io.tmpdir",
175:                        "."), "Geotools");
176:                if (directory.isDirectory() || directory.mkdir()) {
177:                    directory = new File(directory, "Databases/HSQL");
178:                    if (directory.isDirectory() || directory.mkdirs()) {
179:                        return directory;
180:                    }
181:                }
182:                return null;
183:            }
184:
185:            /**
186:             * Extract the directory from the specified data source, or {@code null} if this
187:             * information is not available.
188:             */
189:            private static File getDirectory(final DataSource source) {
190:                if (source instanceof  jdbcDataSource) {
191:                    String path = ((jdbcDataSource) source).getDatabase();
192:                    if (path != null
193:                            && PREFIX.regionMatches(true, 0, path, 0, PREFIX
194:                                    .length())) {
195:                        path = path.substring(PREFIX.length());
196:                        return new File(path).getParentFile();
197:                    }
198:                }
199:                return null;
200:            }
201:
202:            /**
203:             * Returns a data source for the HSQL database.
204:             */
205:            protected DataSource createDataSource() throws SQLException {
206:                DataSource candidate = super .createDataSource();
207:                if (candidate instanceof  jdbcDataSource) {
208:                    return candidate;
209:                }
210:                final jdbcDataSource source = new jdbcDataSource();
211:                File directory = getDirectory();
212:                if (directory != null) {
213:                    /*
214:                     * Constructs the full path to the HSQL database. Note: we do not use
215:                     * File.toURI() because HSQL doesn't seem to expect an encoded URL
216:                     * (e.g. "%20" instead of spaces).
217:                     */
218:                    final StringBuffer url = new StringBuffer(PREFIX);
219:                    final String path = directory.getAbsolutePath().replace(
220:                            File.separatorChar, '/');
221:                    if (path.length() == 0 || path.charAt(0) != '/') {
222:                        url.append('/');
223:                    }
224:                    url.append(path);
225:                    if (url.charAt(url.length() - 1) != '/') {
226:                        url.append('/');
227:                    }
228:                    url.append(DATABASE_NAME);
229:                    source.setDatabase(url.toString());
230:                    assert directory.equals(getDirectory(source)) : url;
231:                }
232:                /*
233:                 * If the temporary directory do not exists or can't be created, lets the 'database'
234:                 * attribute unset. If the user do not set it explicitly (through JNDI or by overrding
235:                 * this method), an exception will be thrown when 'createBackingStore()' will be invoked.
236:                 */
237:                source.setUser("SA"); // System administrator. No password.
238:                return source;
239:            }
240:
241:            /**
242:             * Returns {@code true} if the database contains data. This method returns {@code false}
243:             * if an empty EPSG database has been automatically created by HSQL and not yet populated.
244:             */
245:            private static boolean dataExists(final Connection connection)
246:                    throws SQLException {
247:                final ResultSet tables = connection.getMetaData().getTables(
248:                        null, null, "EPSG_%", new String[] { "TABLE" });
249:                final boolean exists = tables.next();
250:                tables.close();
251:                return exists;
252:            }
253:
254:            /**
255:             * Compares the {@code "epsg.version"} property in the specified file with the expected
256:             * {@link #VERSION}. If the version found in the property file is equals or higher than
257:             * the expected one, then this method do nothing. Otherwise or if no version information
258:             * is found in the property file, then this method clean the temporary directory
259:             * containing the cached database.
260:             */
261:            private static void deleteIfOutdated(final File directory,
262:                    final File propertyFile) {
263:                if (directory == null
264:                        || !directory.equals(getTemporaryDirectory())) {
265:                    /*
266:                     * Never touch to the directory if it is not in the temporary directory.
267:                     * It may be a user file!
268:                     */
269:                    return;
270:                }
271:                if (propertyFile.isFile())
272:                    try {
273:                        final InputStream propertyIn = new FileInputStream(
274:                                propertyFile);
275:                        final Properties properties = new Properties();
276:                        properties.load(propertyIn);
277:                        propertyIn.close();
278:                        final String version = properties
279:                                .getProperty("epsg.version");
280:                        if (version != null) {
281:                            if (new Version(version).compareTo(VERSION) >= 0) {
282:                                return;
283:                            }
284:                        }
285:                    } catch (IOException exception) {
286:                        /*
287:                         * Failure to read the property file. This is just a warning, not an error, because
288:                         * we will attempt to rebuild the whole database. Note: "createBackingStore" is the
289:                         * public method that invoked this method, so we use it for the logging message.
290:                         */
291:                        org.geotools.util.logging.Logging.unexpectedException(
292:                                LOGGER, FactoryOnHSQL.class,
293:                                "createBackingStore", exception);
294:                    }
295:                delete(directory);
296:            }
297:
298:            /**
299:             * Deletes the specified directory and all sub-directories. Used for
300:             * cleaning the temporary directory containing the cached database only.
301:             */
302:            private static void delete(final File directory) {
303:                if (directory != null) {
304:                    final File[] files = directory.listFiles();
305:                    if (files != null) {
306:                        for (int i = 0; i < files.length; i++) {
307:                            delete(files[i]);
308:                        }
309:                    }
310:                    directory.delete();
311:                }
312:            }
313:
314:            /**
315:             * Returns the backing-store factory for HSQL syntax. If the cached tables are not available,
316:             * they will be created now from the SQL scripts bundled in this plugin.
317:             *
318:             * @param  hints A map of hints, including the low-level factories to use for CRS creation.
319:             * @return The EPSG factory using HSQL syntax.
320:             * @throws SQLException if connection to the database failed.
321:             */
322:            protected AbstractAuthorityFactory createBackingStore(
323:                    final Hints hints) throws SQLException {
324:                final DataSource source = getDataSource();
325:                final File directory = getDirectory(source);
326:                final File propertyFile = new File(directory, DATABASE_NAME
327:                        + ".properties");
328:                deleteIfOutdated(directory, propertyFile);
329:                Connection connection = source.getConnection();
330:                if (!dataExists(connection)) {
331:                    /*
332:                     * HSQL has created automatically an empty database. We need to populate it.
333:                     * Executes the SQL scripts bundled in the JAR. In theory, each line contains
334:                     * a full SQL statement. For this plugin however, we have compressed "INSERT
335:                     * INTO" statements using Compactor class in this package.
336:                     */
337:                    org.geotools.util.logging.Logging
338:                            .getLogger(LOGGER)
339:                            .log(
340:                                    Logging
341:                                            .format(
342:                                                    Level.INFO,
343:                                                    LoggingKeys.CREATING_CACHED_EPSG_DATABASE_$1,
344:                                                    VERSION));
345:                    final Statement statement = connection.createStatement();
346:                    try {
347:                        final BufferedReader in = new BufferedReader(
348:                                new InputStreamReader(FactoryOnHSQL.class
349:                                        .getResourceAsStream(SQL_FILE),
350:                                        "ISO-8859-1"));
351:                        StringBuffer insertStatement = null;
352:                        String line;
353:                        while ((line = in.readLine()) != null) {
354:                            line = line.trim();
355:                            final int length = line.length();
356:                            if (length != 0) {
357:                                if (line.startsWith("INSERT INTO")) {
358:                                    /*
359:                                     * We are about to insert many rows into a single table.
360:                                     * The row values appear in next lines; the current line
361:                                     * should stop right after the VALUES keyword.
362:                                     */
363:                                    insertStatement = new StringBuffer(line);
364:                                    continue;
365:                                }
366:                                if (insertStatement != null) {
367:                                    /*
368:                                     * We are about to insert a row. Prepend the "INSERT INTO"
369:                                     * statement and check if we will have more rows to insert
370:                                     * after this one.
371:                                     */
372:                                    final int values = insertStatement.length();
373:                                    insertStatement.append(line);
374:                                    final boolean hasMore = (line
375:                                            .charAt(length - 1) == ',');
376:                                    if (hasMore) {
377:                                        insertStatement
378:                                                .setLength(insertStatement
379:                                                        .length() - 1);
380:                                    }
381:                                    line = insertStatement.toString();
382:                                    insertStatement.setLength(values);
383:                                    if (!hasMore) {
384:                                        insertStatement = null;
385:                                    }
386:                                }
387:                                statement.execute(line);
388:                            }
389:                        }
390:                        in.close();
391:                        /*
392:                         * The database has been fully created. Now, make it read-only.
393:                         */
394:                        if (directory != null) {
395:                            final InputStream propertyIn = new FileInputStream(
396:                                    propertyFile);
397:                            final Properties properties = new Properties();
398:                            properties.load(propertyIn);
399:                            propertyIn.close();
400:                            properties.put("epsg.version", VERSION.toString());
401:                            properties.put("readonly", "true");
402:                            final OutputStream out = new FileOutputStream(
403:                                    propertyFile);
404:                            properties.store(out, "EPSG database on HSQL");
405:                            out.close();
406:
407:                            final File backup = new File(directory,
408:                                    DATABASE_NAME + ".backup");
409:                            if (backup.exists()) {
410:                                backup.delete();
411:                            }
412:                        }
413:                    } catch (IOException exception) {
414:                        statement.close();
415:                        SQLException e = new SQLException(Errors.format(
416:                                ErrorKeys.CANT_READ_$1, SQL_FILE));
417:                        e.initCause(exception);
418:                        throw e;
419:                    }
420:                    statement.close();
421:                    connection.close();
422:                    connection = source.getConnection();
423:                    assert dataExists(connection);
424:                }
425:                return new FactoryUsingHSQL(hints, connection);
426:            }
427:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.