Source Code Cross Referenced for ThreadedEpsgFactory.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:         *    (C) 2001, Institut de Recherche pour le Développement
006:         *   
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation;
010:         *    version 2.1 of the License.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.referencing.factory.epsg;
018:
019:        // J2SE dependencies
020:        import java.sql.Connection;
021:        import java.sql.DatabaseMetaData;
022:        import java.sql.SQLException;
023:        import javax.sql.DataSource;
024:        import java.util.Iterator;
025:        import java.util.Comparator;
026:        import java.util.Collections;
027:        import java.util.logging.Level;
028:        import java.util.logging.LogRecord;
029:        import javax.imageio.spi.ServiceRegistry;
030:        import javax.naming.InitialContext;
031:        import javax.naming.NameNotFoundException;
032:        import javax.naming.NamingException;
033:        import javax.naming.NoInitialContextException;
034:
035:        // OpenGIS dependencies
036:        import org.opengis.metadata.citation.Citation;
037:        import org.opengis.referencing.FactoryException;
038:        import org.opengis.referencing.cs.CSAuthorityFactory;
039:        import org.opengis.referencing.crs.CRSAuthorityFactory;
040:        import org.opengis.referencing.datum.DatumAuthorityFactory;
041:        import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
042:
043:        // Geotools dependencies
044:        import org.geotools.factory.GeoTools;
045:        import org.geotools.factory.Hints;
046:        import org.geotools.factory.FactoryRegistry;
047:        import org.geotools.metadata.iso.citation.Citations;
048:        import org.geotools.referencing.ReferencingFactoryFinder;
049:        import org.geotools.referencing.factory.FactoryGroup;
050:        import org.geotools.referencing.factory.AbstractAuthorityFactory;
051:        import org.geotools.referencing.factory.DeferredAuthorityFactory;
052:        import org.geotools.referencing.factory.FactoryNotFoundException;
053:        import org.geotools.resources.i18n.Errors;
054:        import org.geotools.resources.i18n.ErrorKeys;
055:        import org.geotools.resources.i18n.Logging;
056:        import org.geotools.resources.i18n.LoggingKeys;
057:        import org.geotools.resources.i18n.Vocabulary;
058:        import org.geotools.resources.i18n.VocabularyKeys;
059:
060:        /**
061:         * Base class for EPSG factories to be registered in {@link ReferencingFactoryFinder}.
062:         * Various subclasses are defined for different database backends: Access, PostgreSQL,
063:         * HSQL, <cite>etc.</cite>.
064:         * <p>
065:         * Users should not creates instance of this class directly. They should invoke one of
066:         * <code>{@linkplain ReferencingFactoryFinder}.getFooAuthorityFactory("EPSG")</code>
067:         * methods instead.
068:         * <p>
069:         * This class will change in Geotools 2.5; avoid direct dependence if possible. The current
070:         * {@code ThreadedEpsgFactory} name does not reflect its actual behavior in Geotools 2.4.
071:         * It should reflect the behavior expected in Geotools 2.5.
072:         *
073:         * @since 2.4
074:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/ThreadedEpsgFactory.java $
075:         * @version $Id: ThreadedEpsgFactory.java 26328 2007-07-24 16:57:19Z desruisseaux $
076:         * @author Martin Desruisseaux
077:         */
078:        public class ThreadedEpsgFactory extends DeferredAuthorityFactory
079:                implements  CRSAuthorityFactory, CSAuthorityFactory,
080:                DatumAuthorityFactory, CoordinateOperationAuthorityFactory {
081:            /**
082:             * The default JDBC {@linkplain DataSource data source} name in JNDI.
083:             * This is the name used if no other name were specified through the
084:             * {@link Hints#EPSG_DATA_SOURCE EPSG_DATA_SOURCE} hint.
085:             *
086:             * @see #createDataSource
087:             */
088:            public static final String DATASOURCE_NAME = "jdbc/EPSG"; //TODO: default should be provided by the Hint
089:
090:            /**
091:             * {@code true} if automatic registration of {@link #datasourceName} is allowed.
092:             * Set to {@code false} for now because the registration has not been correctly
093:             * tested in JEE environment.
094:             *
095:             * @todo Consider removing completly the code related to JNDI binding. In such
096:             *       case, this field and the {@link #registerInto} field would be removed.
097:             */
098:            private static final boolean ALLOW_REGISTRATION = false;
099:
100:            /**
101:             * The factory registry for EPSG data sources. Will be created only when first needed.
102:             *
103:             * @deprecated To remove when other deprecated methods will have been removed.
104:             */
105:            private static FactoryRegistry datasources;
106:
107:            /**
108:             * The default priority level for this factory.
109:             */
110:            static final int PRIORITY = MAXIMUM_PRIORITY - 10;
111:
112:            /**
113:             * The factories to be given to the backing store.
114:             */
115:            private final FactoryGroup factories;
116:
117:            /**
118:             * The context where to register {@link #datasource}, or {@code null} if it should
119:             * not be registered. This is used only as a way to pass "hiden" return value between
120:             * {@link #createDataSource()} and {@link #createBackingStore()}.
121:             */
122:            private transient InitialContext registerInto;
123:
124:            /**
125:             * The data source name. If it was not specified by the {@link Hints#EPSG_DATA_SOURCE
126:             * EPSG_DATA_SOURCE} hint, then this is the {@value #DATASOURCE_NAME} value.
127:             */
128:            private String datasourceName;
129:
130:            /**
131:             * The data source, or {@code null} if the connection has not yet been etablished.
132:             */
133:            private DataSource datasource;
134:
135:            /**
136:             * The shutdown hook, or {@code null} if none.
137:             */
138:            private Thread shutdown;
139:
140:            /**
141:             * Constructs an authority factory using the default set of factories.
142:             */
143:            public ThreadedEpsgFactory() {
144:                this (null);
145:            }
146:
147:            /**
148:             * Constructs an authority factory with the default priority.
149:             */
150:            public ThreadedEpsgFactory(final Hints userHints) {
151:                this (userHints, PRIORITY);
152:            }
153:
154:            /**
155:             * Constructs an authority factory using a set of factories created from the specified hints.
156:             * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
157:             * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
158:             * {@code FACTORY} hints, in addition of {@link Hints#EPSG_DATA_SOURCE EPSG_DATA_SOURCE}.
159:             *
160:             * @param userHints An optional set of hints, or {@code null} if none.
161:             * @param priority The priority for this factory, as a number between
162:             *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
163:             *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
164:             */
165:            public ThreadedEpsgFactory(final Hints userHints, final int priority) {
166:                super (userHints, priority);
167:                if (userHints != null) {
168:                    datasourceName = (String) userHints
169:                            .get(Hints.EPSG_DATA_SOURCE);
170:                }
171:                if (datasourceName == null) {
172:                    datasourceName = DATASOURCE_NAME;
173:                }
174:                hints.put(Hints.EPSG_DATA_SOURCE, datasourceName);
175:                factories = FactoryGroup.createInstance(userHints);
176:                setTimeout(30 * 60 * 1000L); // Close the connection after at least 30 minutes of inactivity.
177:            }
178:
179:            /**
180:             * Returns the authority for this EPSG database.
181:             * This authority will contains the database version in the {@linkplain Citation#getEdition
182:             * edition} attribute, together with the {@linkplain Citation#getEditionDate edition date}.
183:             */
184:            public Citation getAuthority() {
185:                final Citation authority = super .getAuthority();
186:                return (authority != null) ? authority : Citations.EPSG;
187:            }
188:
189:            /**
190:             * Returns the data source for the EPSG database. If no data source has been previously
191:             * {@linkplain #setDataSource set}, then this method invokes {@link #createDataSource}.
192:             * <strong>Note:</strong> invoking this method may force immediate connection to the EPSG
193:             * database.
194:             *
195:             * @return The data source.
196:             * @throws SQLException if the connection to the EPSG database failed.
197:             *
198:             * @see #setDataSource
199:             * @see #createDataSource
200:             */
201:            public final synchronized DataSource getDataSource()
202:                    throws SQLException {
203:                if (datasource == null) {
204:                    // Force the creation of the underlying backing store. It will invokes
205:                    // (indirectly) createBackingStore, which will fetch the DataSource.
206:                    if (!super .isAvailable()) {
207:                        // Connection failed, but the exception is not available.
208:                        datasource = null;
209:                        throw new SQLException(Errors
210:                                .format(ErrorKeys.NO_DATA_SOURCE));
211:                    }
212:                }
213:                return datasource;
214:            }
215:
216:            /**
217:             * Set the data source for the EPSG database. If an other EPSG database was already in use,
218:             * it will be disconnected. Users should not invoke this method on the factory returned by
219:             * {@link ReferencingFactoryFinder}, since it could have a system-wide effect.
220:             *
221:             * @param  datasource The new datasource.
222:             * @throws SQLException if an error occured.
223:             */
224:            public synchronized void setDataSource(final DataSource datasource)
225:                    throws SQLException {
226:                if (datasource != this .datasource) {
227:                    try {
228:                        dispose();
229:                    } catch (FactoryException exception) {
230:                        final Throwable cause = exception.getCause();
231:                        if (cause instanceof  SQLException) {
232:                            throw (SQLException) cause;
233:                        }
234:                        if (cause instanceof  RuntimeException) {
235:                            throw (RuntimeException) cause;
236:                        }
237:                        // Not really an SQL exception, but we should not reach this point anyway.
238:                        final SQLException e = new SQLException(exception
239:                                .getLocalizedMessage());
240:                        e.initCause(exception);
241:                        throw e;
242:                    }
243:                    this .datasource = datasource;
244:                }
245:            }
246:
247:            /**
248:             * Returns a data source from the factory registry. This method is invoked by
249:             * {@link #createBackingStore()} only if no EPSG data source was found in the
250:             * JNDI (Java Naming and Directory). This method scans for plugins the first
251:             * time it is invoked.
252:             *
253:             * @return All registered data sources.
254:             *
255:             * @deprecated To be deleted after we removed the {@code org.geotools...DataSource} interface.
256:             */
257:            private static synchronized Iterator getDataSources() {
258:                final Class category = org.geotools.referencing.factory.epsg.DataSource.class;
259:                if (datasources == null) {
260:                    datasources = new FactoryRegistry(Collections
261:                            .singleton(category));
262:                    datasources.scanForPlugins();
263:                    datasources.setOrdering(category, new Comparator() {
264:                        public int compare(final Object f1, final Object f2) {
265:                            return ((org.geotools.referencing.factory.epsg.DataSource) f1)
266:                                    .getPriority()
267:                                    - ((org.geotools.referencing.factory.epsg.DataSource) f2)
268:                                            .getPriority();
269:                        }
270:                    });
271:                }
272:                return datasources.getServiceProviders(category, true);
273:            }
274:
275:            /**
276:             * Setup a data source for a connection to the EPSG database. This method is invoked by
277:             * {@link #getDataSource()} when no data source has been {@linkplain #setDataSource
278:             * explicitly set}. The default implementation searchs for a {@link DataSource} instance
279:             * binded to the {@link Hints#EPSG_DATA_SOURCE} name
280:             * (<code>{@value #DATASOURCE_NAME}</code> by default) using <cite>Java Naming and
281:             * Directory Interfaces</cite> (JNDI). If no data source were found, then this method
282:             * returns {@code null}.
283:             * <p>
284:             * Subclasses override this method in order to initialize a default data source when none were
285:             * found with JNDI. For example {@code plugin/epsg-access} defines a default data source using
286:             * the JDBC-ODBC bridge, which expects an "{@code EPSG}" database registered as an ODBC data
287:             * source (see the {@linkplain org.geotools.referencing.factory.epsg package javadoc} for
288:             * installation instructions). Example for a PostgreSQL data source:
289:             *
290:             * <blockquote><pre>
291:             * protected DataSource createDataSource() throws SQLException {
292:             *     DataSource candidate = super.createDataSource();
293:             *     if (candidate instanceof Jdbc3SimpleDataSource) {
294:             *         return candidate;
295:             *     }
296:             *     Jdbc3SimpleDataSource ds = new Jdbc3SimpleDataSource();
297:             *     ds.setServerName("localhost");
298:             *     ds.setDatabaseName("EPSG");
299:             *     ds.setUser("postgre");
300:             *     return ds;
301:             * }
302:             * </pre></blockquote>
303:             *
304:             * @return The EPSG data source, or {@code null} if none where found.
305:             * @throws SQLException if an error occured while creating the data source.
306:             */
307:            protected DataSource createDataSource() throws SQLException {
308:                InitialContext context = null;
309:                DataSource source = null;
310:                try {
311:                    context = GeoTools.getInitialContext(new Hints(hints));
312:                    source = (DataSource) context.lookup(datasourceName);
313:                } catch (NoInitialContextException exception) {
314:                    // Fall back on 'return null' below.
315:                } catch (NameNotFoundException exception) {
316:                    registerInto = context;
317:                    // Fall back on 'return null' below.
318:                } catch (NamingException exception) {
319:                    SQLException e = new SQLException(Errors.format(
320:                            ErrorKeys.CANT_GET_DATASOURCE_$1, datasourceName));
321:                    e.initCause(exception);
322:                    throw e;
323:                }
324:                return source;
325:            }
326:
327:            /**
328:             * Creates the backing store for the specified data source. This method usually returns
329:             * a new instance of {@link AccessDialectEpsgFactory} or {@link AnsiDialectEpsgFactory}.
330:             * Subclasses may override this method in order to returns an instance tuned for the
331:             * SQL syntax of the underlying database. Example for a PostgreSQL data source:
332:             *
333:             * <blockquote><pre>
334:             * protected AbstractAuthorityFactory createBackingStore(Hints hints) throws SQLException {
335:             *     return new AnsiDialectEpsgFactory(hints, getDataSource().getConnection());
336:             * }
337:             * </pre></blockquote>
338:             *
339:             * @param  hints A map of hints, including the low-level factories to use for CRS creation.
340:             *         This argument should be given unchanged to {@code DirectEpsgFactory} constructor.
341:             * @return The {@linkplain DirectEpsgFactory EPSG factory} using SQL queries appropriate
342:             *         for this data source.
343:             * @throws SQLException if connection to the database failed.
344:             */
345:            protected AbstractAuthorityFactory createBackingStore(
346:                    final Hints hints) throws SQLException {
347:                final DataSource source = getDataSource();
348:                // The next two lines will be removed after org.geotools...DataSource interface removal.
349:                if (source instanceof  org.geotools.referencing.factory.epsg.DataSource) {
350:                    return ((org.geotools.referencing.factory.epsg.DataSource) source)
351:                            .createFactory(hints);
352:                }
353:                final Connection connection = source.getConnection();
354:                final String quote = connection.getMetaData()
355:                        .getIdentifierQuoteString();
356:                if (quote.equals("\"")) {
357:                    /*
358:                     * PostgreSQL quotes the indentifiers with "..." while MS-Access quotes the
359:                     * identifiers with [...], so we use the identifier quote string metadata as
360:                     * a way to distinguish the two cases. However I'm not sure that it is a robust
361:                     * criterion. Subclasses should always override as a safety.
362:                     */
363:                    return new FactoryUsingAnsiSQL(hints, connection);
364:                }
365:                return new FactoryUsingSQL(hints, connection);
366:            }
367:
368:            /**
369:             * Gets the EPSG factory implementation connected to the database. This method is invoked
370:             * automatically by {@link #createBackingStore()}.
371:             *
372:             * @return The connection to the EPSG database.
373:             * @throws FactoryException if no data source were found.
374:             * @throws SQLException if this method failed to etablish a connection.
375:             *
376:             * @todo Inline this method into {@link #createBackingStore()} after we removed the
377:             *       deprecated code.
378:             */
379:            private AbstractAuthorityFactory createBackingStore0()
380:                    throws FactoryException, SQLException {
381:                assert Thread.holdsLock(this );
382:                final Hints sourceHints = new Hints(hints);
383:                sourceHints.putAll(factories.getImplementationHints());
384:                if (datasource != null) {
385:                    return createBackingStore(sourceHints);
386:                }
387:                /*
388:                 * Try to gets the DataSource from JNDI. In case of success, it will be tried
389:                 * for a connection before any DataSource declared in META-INF/services/.
390:                 */
391:                DataSource source;
392:                final InitialContext context;
393:                try {
394:                    source = createDataSource();
395:                    context = registerInto;
396:                } finally {
397:                    registerInto = null;
398:                }
399:                /*
400:                 * Iterate through all DataSources, begining with the one found in JNDI (if any).
401:                 * We will retain the first successfull connection. If all DataSource fails, the
402:                 * exception thrown by the first DataSource will be retrown, since it is usually
403:                 * the main DataSource.
404:                 */
405:                if (false) {
406:                    /*
407:                     * TODO: All the block after // --- Begin deprecated code ----
408:                     *       should be replaced by this code after we deleted the
409:                     *       deprecated org.geotools...DataSource interface:
410:                     */
411:                    if (source == null) {
412:                        throw new FactoryNotFoundException(Errors
413:                                .format(ErrorKeys.NO_DATA_SOURCE));
414:                    }
415:                    final AbstractAuthorityFactory factory;
416:                    try {
417:                        datasource = source;
418:                        factory = createBackingStore(sourceHints);
419:                    } finally {
420:                        datasource = null;
421:                    }
422:                }
423:                // ---- Begin deprecated code to delete (up to the next block comment) --------------------
424:                Iterator sources = null;
425:                AbstractAuthorityFactory factory = null;
426:                SQLException failure = null;
427:                while (true) {
428:                    if (source != null)
429:                        try {
430:                            try {
431:                                datasource = source;
432:                                factory = createBackingStore(sourceHints);
433:                            } finally {
434:                                datasource = null;
435:                            }
436:                            break; // Found a successfull connection: stop the loop.
437:                        } catch (SQLException exception) {
438:                            // Keep only the exception from the first data source.
439:                            if (failure == null) {
440:                                failure = exception;
441:                            }
442:                        }
443:                    // Setup the iterator (if not already done) and test next DataSources.
444:                    if (sources == null) {
445:                        sources = getDataSources();
446:                    }
447:                    if (!sources.hasNext()) {
448:                        if (failure != null) {
449:                            throw failure;
450:                        }
451:                        throw new FactoryNotFoundException(Errors
452:                                .format(ErrorKeys.NO_DATA_SOURCE));
453:                    }
454:                    source = (DataSource) sources.next();
455:                }
456:                ;
457:                /*
458:                 * We now have a working connection. If a naming directory is running but didn't contains
459:                 * the "jdbc/EPSG" entry, add it now. In such case, a message is prepared and logged.
460:                 */
461:                LogRecord record;
462:                if (ALLOW_REGISTRATION && context != null) {
463:                    try {
464:                        context.bind(datasourceName, source);
465:                        record = Logging.format(Level.INFO,
466:                                LoggingKeys.CREATED_DATASOURCE_ENTRY_$1,
467:                                datasourceName);
468:                    } catch (NamingException exception) {
469:                        record = Logging.format(Level.WARNING,
470:                                LoggingKeys.CANT_BIND_DATASOURCE_$1,
471:                                datasourceName);
472:                        record.setThrown(exception);
473:                    }
474:                    log(record);
475:                }
476:                this .datasource = source; // Stores the data source only after success.
477:                return factory;
478:            }
479:
480:            /**
481:             * Creates the backing store authority factory.
482:             *
483:             * @return The backing store to uses in {@code createXXX(...)} methods.
484:             * @throws FactoryException if the constructor failed to connect to the EPSG database.
485:             *         This exception usually has a {@link SQLException} as its cause.
486:             */
487:            protected AbstractAuthorityFactory createBackingStore()
488:                    throws FactoryException {
489:                final AbstractAuthorityFactory factory;
490:                String product = '<' + Vocabulary.format(VocabularyKeys.UNKNOW) + '>';
491:                String url = product;
492:                try {
493:                    factory = createBackingStore0();
494:                    if (factory instanceof  DirectEpsgFactory) {
495:                        final DatabaseMetaData info = ((DirectEpsgFactory) factory).connection
496:                                .getMetaData();
497:                        product = info.getDatabaseProductName();
498:                        url = info.getURL();
499:                    }
500:                } catch (SQLException exception) {
501:                    throw new FactoryException(Errors.format(
502:                            ErrorKeys.CANT_CONNECT_DATABASE_$1, "EPSG"),
503:                            exception);
504:                }
505:                log(Logging.format(Level.CONFIG,
506:                        LoggingKeys.CONNECTED_EPSG_DATABASE_$2, url, product));
507:                if (factory instanceof  DirectEpsgFactory) {
508:                    ((DirectEpsgFactory) factory).buffered = this ;
509:                }
510:                return factory;
511:            }
512:
513:            /**
514:             * For internal use by {@link #createFactory()} and {@link #createBackingStore()} only.
515:             */
516:            private static void log(final LogRecord record) {
517:                record.setSourceClassName(ThreadedEpsgFactory.class.getName());
518:                record.setSourceMethodName("createBackingStore"); // The public caller.
519:                LOGGER.log(record);
520:            }
521:
522:            /**
523:             * Returns {@code true} if the backing store can be disposed now. This method is invoked
524:             * automatically after the amount of time specified by {@link #setTimeout} if the factory
525:             * were not used during that time.
526:             *
527:             * @param backingStore The backing store in process of being disposed.
528:             */
529:            protected boolean canDisposeBackingStore(
530:                    final AbstractAuthorityFactory backingStore) {
531:                if (backingStore instanceof  DirectEpsgFactory) {
532:                    return ((DirectEpsgFactory) backingStore).canDispose();
533:                }
534:                return super .canDisposeBackingStore(backingStore);
535:            }
536:
537:            /**
538:             * Ensures that the database connection will be closed on JVM exit. This code will be executed
539:             * even if the JVM is terminated because of an exception or with [Ctrl-C]. Note: we create this
540:             * shutdown hook only if this factory is registered as a service because it will prevent this
541:             * instance to be garbage collected until it is deregistered.
542:             */
543:            private final class ShutdownHook extends Thread {
544:                public ShutdownHook() {
545:                    super (DirectEpsgFactory.SHUTDOWN_THREAD);
546:                }
547:
548:                public void run() {
549:                    synchronized (ThreadedEpsgFactory.this ) {
550:                        try {
551:                            dispose();
552:                        } catch (Throwable exception) {
553:                            // Too late for logging, since the JVM is
554:                            // in process of shutting down. Ignore...
555:                        }
556:                    }
557:                }
558:            }
559:
560:            /**
561:             * Called when this factory is added to the given {@code category} of the given
562:             * {@code registry}. The object may already be registered under another category.
563:             */
564:            public synchronized void onRegistration(
565:                    final ServiceRegistry registry, final Class category) {
566:                super .onRegistration(registry, category);
567:                if (shutdown == null) {
568:                    shutdown = new ShutdownHook();
569:                    Runtime.getRuntime().addShutdownHook(shutdown);
570:                }
571:            }
572:
573:            /**
574:             * Called when this factory is removed from the given {@code category} of the given
575:             * {@code registry}.  The object may still be registered under another category.
576:             */
577:            public synchronized void onDeregistration(
578:                    final ServiceRegistry registry, final Class category) {
579:                if (shutdown != null) {
580:                    if (registry.getServiceProviderByClass(getClass()) == null) {
581:                        // Remove the shutdown hook only if this instance is not
582:                        // anymore registered as a service under any category.
583:                        Runtime.getRuntime().removeShutdownHook(shutdown);
584:                        shutdown = null;
585:                    }
586:                }
587:                super .onDeregistration(registry, category);
588:            }
589:
590:            /**
591:             * Constructs an object from the EPSG database and print its WKT (Well Know Text) to
592:             * the {@linkplain System#out standard output stream}.
593:             *
594:             * @deprecated Replaced in a more generic way by {@link org.geotools.referencing.CRS#main}
595:             *             with a {@code "-authority=EPSG"} optional argument.
596:             */
597:            public static void main(String[] args) {
598:                args = (String[]) org.geotools.resources.XArray.insert(args, 0,
599:                        1);
600:                args[0] = "-authority=EPSG";
601:                org.geotools.referencing.CRS.main(args);
602:            }
603:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.