Source Code Cross Referenced for FactoryUsingWKT.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-2007, 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.PrintWriter;
022:        import java.util.Set;
023:        import java.util.Map;
024:        import java.util.TreeSet;
025:        import java.util.TreeMap;
026:        import java.util.Iterator;
027:        import java.util.Locale;
028:        import java.util.Collection;
029:        import java.util.logging.Level;
030:        import java.net.MalformedURLException;
031:        import java.net.URL;
032:
033:        // OpenGIS dependencies
034:        import org.opengis.metadata.citation.Citation;
035:        import org.opengis.referencing.IdentifiedObject;
036:        import org.opengis.referencing.FactoryException;
037:        import org.opengis.referencing.crs.CRSAuthorityFactory;
038:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
039:
040:        // Geotools dependencies
041:        import org.geotools.factory.GeoTools;
042:        import org.geotools.factory.Hints;
043:        import org.geotools.referencing.ReferencingFactoryFinder;
044:        import org.geotools.referencing.factory.AbstractAuthorityFactory;
045:        import org.geotools.referencing.factory.DeferredAuthorityFactory;
046:        import org.geotools.referencing.factory.FactoryNotFoundException;
047:        import org.geotools.referencing.factory.PropertyAuthorityFactory;
048:        import org.geotools.referencing.factory.ReferencingFactoryContainer;
049:        import org.geotools.metadata.iso.citation.Citations;
050:        import org.geotools.metadata.iso.citation.CitationImpl;
051:        import org.geotools.io.TableWriter;
052:        import org.geotools.io.IndentedLineWriter;
053:        import org.geotools.resources.Arguments;
054:        import org.geotools.resources.i18n.Errors;
055:        import org.geotools.resources.i18n.ErrorKeys;
056:        import org.geotools.resources.i18n.Logging;
057:        import org.geotools.resources.i18n.LoggingKeys;
058:        import org.geotools.resources.i18n.Vocabulary;
059:        import org.geotools.resources.i18n.VocabularyKeys;
060:
061:        /**
062:         * Authority factory for {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}
063:         * beyong the one defined in the EPSG database. This factory is used as a fallback when a
064:         * requested code is not found in the EPSG database, or when there is no connection at all
065:         * to the EPSG database. The additional CRS are defined as <cite>Well Known Text</cite> in
066:         * a property file located by default in the {@code org.geotools.referencing.factory.epsg}
067:         * package, and whose name should be {@value #FILENAME}. If no property file is found, the
068:         * factory won't be activated. The property file can also be located in a custom directory;
069:         * See {@link #getDefinitionsURL()} for more details.
070:         * <p>
071:         * This factory can also be used to provide custom extensions or overrides to a main EPSG factory.
072:         * In order to provide a custom extension file, override the {@link #getDefinitionsURL()} method.
073:         * In order to make the factory be an override, change the default priority by using the 
074:         * two arguments constructor (this factory defaults to {@link ThreadedEpsgFactory#PRIORITY} - 10,
075:         * so it's used as an extension).
076:         *
077:         * @since 2.1
078:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingWKT.java $
079:         * @version $Id: FactoryUsingWKT.java 27848 2007-11-12 13:10:32Z desruisseaux $
080:         * @author Martin Desruisseaux
081:         * @author Jody Garnett
082:         * @author Rueben Schulz
083:         * @author Andrea Aime
084:         */
085:        public class FactoryUsingWKT extends DeferredAuthorityFactory implements 
086:                CRSAuthorityFactory {
087:            /**
088:             * The {@linkplain System#getProperty(String) system property} key for setting the directory
089:             * where to search for the {@value #FILENAME} file.
090:             *
091:             * @since 2.4
092:             * @deprecated Moved to {@link GeoTools#CRS_AUTHORITY_EXTRA_DIRECTORY}.
093:             */
094:            public static final String CRS_DIRECTORY_KEY = GeoTools.CRS_AUTHORITY_EXTRA_DIRECTORY;
095:
096:            /**
097:             * The authority. Will be created only when first needed.
098:             *
099:             * @see #getAuthority
100:             */
101:            private Citation authority;
102:
103:            /**
104:             * The default filename to read. The default {@code FactoryUsingWKT} implementation will
105:             * search for the first occurence of this file in the following places:
106:             * <p>
107:             * <ul>
108:             *   <li>In the directory specified by the {@value GeoTools#CRS_DIRECTORY_KEY} system
109:             *       property.</li>
110:             *   <li>In every {@code org/geotools/referencing/factory/espg} directories found on the
111:             *       classpath.</li>
112:             * </ul>
113:             * <p>
114:             * The filename part before the extension ({@code "epsg"}) denotes the authority namespace
115:             * where to register the content of this file. The user-directory given by the system property
116:             * may contains other property files for other authorities, like {@code "esri.properties"},
117:             * but those additional authorities are not handled by the default {@code FactoryUsingWKT}
118:             * class.
119:             *
120:             * @see #getDefinitionsURL
121:             */
122:            public static final String FILENAME = "epsg.properties";
123:
124:            /**
125:             * The factories to be given to the backing store.
126:             */
127:            private final ReferencingFactoryContainer factories;
128:
129:            /**
130:             * Default priority for this factory.
131:             *
132:             * @since 2.4
133:             * @deprecated We will try to replace the priority mechanism by a better
134:             *             one in a future Geotools version.
135:             */
136:            protected static final int DEFAULT_PRIORITY = ThreadedEpsgFactory.PRIORITY - 10;
137:
138:            /**
139:             * Directory scanned for extra definitions.
140:             */
141:            private final File directory;
142:
143:            /**
144:             * Constructs an authority factory using the default set of factories.
145:             */
146:            public FactoryUsingWKT() {
147:                this (null);
148:            }
149:
150:            /**
151:             * Constructs an authority factory using a set of factories created from the specified hints.
152:             * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
153:             * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
154:             * {@code FACTORY} hints.
155:             */
156:            public FactoryUsingWKT(final Hints userHints) {
157:                this (userHints, DEFAULT_PRIORITY);
158:            }
159:
160:            /**
161:             * Constructs an authority factory using the specified hints and priority.
162:             */
163:            protected FactoryUsingWKT(final Hints userHints, final int priority) {
164:                super (userHints, priority);
165:                factories = ReferencingFactoryContainer.instance(userHints);
166:                Object hint = null;
167:                if (userHints != null) {
168:                    hint = userHints.get(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY);
169:                }
170:                if (hint instanceof  File) {
171:                    directory = (File) hint;
172:                } else if (hint instanceof  String) {
173:                    directory = new File((String) hint);
174:                } else {
175:                    directory = null;
176:                }
177:                hints.put(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY, directory);
178:                // Disposes the cached property file after at least 15 minutes of inactivity.
179:                setTimeout(15 * 60 * 1000L);
180:            }
181:
182:            /**
183:             * Returns the authority. The default implementation returns the first citation returned
184:             * by {@link #getAuthorities()}, with the addition of identifiers from all additional
185:             * authorities returned by the above method.
186:             *
187:             * @see #getAuthorities
188:             */
189:            //@Override
190:            public Citation getAuthority() {
191:                // No need to synchronize; this is not a big deal if we create this object twice.
192:                if (authority == null) {
193:                    final Citation[] authorities = getAuthorities();
194:                    switch (authorities.length) {
195:                    case 0:
196:                        authority = Citations.EPSG;
197:                        break;
198:                    case 1:
199:                        authority = authorities[0];
200:                        break;
201:                    default: {
202:                        final CitationImpl c = new CitationImpl(authorities[0]);
203:                        final Collection types = c.getIdentifierTypes();
204:                        final Collection identifiers = c.getIdentifiers();
205:                        for (int i = 1; i < authorities.length; i++) {
206:                            types.add("Authority name");
207:                            identifiers.add(Citations
208:                                    .getIdentifier(authorities[i]));
209:                        }
210:                        c.freeze();
211:                        authority = c;
212:                        break;
213:                    }
214:                    }
215:                }
216:                return authority;
217:            }
218:
219:            /**
220:             * Returns the set of authorities to use as {@linkplain CoordinateReferenceSystem#getIdentifiers
221:             * identifiers} for the CRS to be created. This set is given to the
222:             * {@linkplain PropertyAuthorityFactory#PropertyAuthorityFactory(ReferencingFactoryContainer,
223:             * Citation[], URL) properties-backed factory constructor}.
224:             * <p>
225:             * The default implementation returns a singleton containing only {@linkplain Citations#EPSG
226:             * EPSG}. Subclasses should override this method in order to enumerate all relevant authorities,
227:             * with {@linkplain Citations#EPSG EPSG} in last position. For example {@link EsriExtension}
228:             * returns {{@linkplain Citations#ESRI ESRI}, {@linkplain Citations#EPSG EPSG}}.
229:             *
230:             * @since 2.4
231:             */
232:            protected Citation[] getAuthorities() {
233:                return new Citation[] { Citations.EPSG };
234:            }
235:
236:            /**
237:             * Returns the URL to the property file that contains CRS definitions.
238:             * The default implementation performs the following search path:
239:             * <ul>
240:             *   <li>If a value is set for the {@value #CRS_DIRECTORY_KEY} system property key,
241:             *       then the {@value #FILENAME} file will be searched in this directory.</li>
242:             *   <li>If no value is set for the above-cited system property, or if no {@value #FILENAME}
243:             *       file was found in that directory, then the first {@value #FILENAME} file found in
244:             *       any {@code org/geotools/referencing/factory/epsg} directory on the classpath will
245:             *       be used.</li>
246:             *   <li>If no file was found on the classpath neither, then this factory will be disabled.</li>
247:             * </ul>
248:             *
249:             * @return The URL, or {@code null} if none.
250:             */
251:            protected URL getDefinitionsURL() {
252:                try {
253:                    if (directory != null) {
254:                        final File file = new File(directory, FILENAME);
255:                        if (file.isFile()) {
256:                            return file.toURI().toURL();
257:                        }
258:                    }
259:                } catch (SecurityException exception) {
260:                    org.geotools.util.logging.Logging.unexpectedException(
261:                            LOGGER, exception);
262:                } catch (MalformedURLException exception) {
263:                    org.geotools.util.logging.Logging.unexpectedException(
264:                            LOGGER, exception);
265:                }
266:                return FactoryUsingWKT.class.getResource(FILENAME);
267:            }
268:
269:            /**
270:             * Creates the backing store authority factory.
271:             *
272:             * @return The backing store to uses in {@code createXXX(...)} methods.
273:             * @throws FactoryNotFoundException if the no {@code epsg.properties} file has been found.
274:             * @throws FactoryException if the constructor failed to find or read the file.
275:             *         This exception usually has an {@link IOException} as its cause.
276:             */
277:            protected AbstractAuthorityFactory createBackingStore()
278:                    throws FactoryException {
279:                try {
280:                    URL url = getDefinitionsURL();
281:                    if (url == null) {
282:                        throw new FactoryNotFoundException(Errors.format(
283:                                ErrorKeys.FILE_DOES_NOT_EXIST_$1, FILENAME));
284:                    }
285:                    final Iterator ids = getAuthority().getIdentifiers()
286:                            .iterator();
287:                    final String authority = ids.hasNext() ? (String) ids
288:                            .next() : "EPSG";
289:                    LOGGER.log(Logging.format(Level.CONFIG,
290:                            LoggingKeys.USING_FILE_AS_FACTORY_$2,
291:                            url.getPath(), authority));
292:                    return new PropertyAuthorityFactory(factories,
293:                            getAuthorities(), url);
294:                } catch (IOException exception) {
295:                    throw new FactoryException(Errors.format(
296:                            ErrorKeys.CANT_READ_$1, FILENAME), exception);
297:                }
298:            }
299:
300:            /**
301:             * Returns a factory of the given type.
302:             */
303:            private static final AbstractAuthorityFactory /*T*/getFactory(
304:                    final Class/*<T extends AbstractAuthorityFactory>*/type) {
305:                // TODO: use type.cast(...) when we will be allowed to compile for J2SE 1.5.
306:                return (AbstractAuthorityFactory) ReferencingFactoryFinder
307:                        .getCRSAuthorityFactory("EPSG", new Hints(
308:                                Hints.CRS_AUTHORITY_FACTORY, type));
309:            }
310:
311:            /**
312:             * Prints a list of codes that duplicate the ones provided by {@link ThreadedEpsgFactory}.
313:             * This is used for implementation of {@linkplain #main main method} in order to check
314:             * the content of the {@value #FILENAME} file (or whatever property file used as backing
315:             * store for this factory) from the command line.
316:             *
317:             * @param  out The writer where to print the report.
318:             * @return The set of duplicated codes.
319:             * @throws FactoryException if an error occured.
320:             *
321:             * @since 2.4
322:             */
323:            protected Set reportDuplicatedCodes(final PrintWriter out)
324:                    throws FactoryException {
325:                final AbstractAuthorityFactory sqlFactory = getFactory(ThreadedEpsgFactory.class);
326:                final Vocabulary resources = Vocabulary.getResources(null);
327:                out.println(resources.getLabel(VocabularyKeys.COMPARE_WITH));
328:                try {
329:                    final IndentedLineWriter w = new IndentedLineWriter(out);
330:                    w.setIndentation(4);
331:                    w.write(sqlFactory.getBackingStoreDescription());
332:                    w.flush();
333:                } catch (IOException e) {
334:                    // Should never happen, since we are writting to a PrintWriter.
335:                    throw new AssertionError(e);
336:                }
337:                out.println();
338:                final Set wktCodes = this 
339:                        .getAuthorityCodes(IdentifiedObject.class);
340:                final Set sqlCodes = sqlFactory
341:                        .getAuthorityCodes(IdentifiedObject.class);
342:                final Set duplicated = new TreeSet();
343:                for (final Iterator it = wktCodes.iterator(); it.hasNext();) {
344:                    final String code = ((String) it.next()).trim();
345:                    if (sqlCodes.contains(code)) {
346:                        duplicated.add(code);
347:                        /*
348:                         * Note: we don't use wktCodes.retainsAll(sqlCode) because the Set implementations
349:                         *       are usually not the standard ones, but rather some implementations backed
350:                         *       by a connection to the resources of the underlying factory. We also close
351:                         *       the connection after this loop for the same reason.  In addition, we take
352:                         *       this opportunity for sorting the codes.
353:                         */
354:                    }
355:                }
356:                if (duplicated.isEmpty()) {
357:                    out.println(resources
358:                            .getString(VocabularyKeys.NO_DUPLICATION_FOUND));
359:                } else {
360:                    for (final Iterator it = duplicated.iterator(); it
361:                            .hasNext();) {
362:                        final String code = (String) it.next();
363:                        out.print(resources
364:                                .getLabel(VocabularyKeys.DUPLICATED_VALUE));
365:                        out.println(code);
366:                    }
367:                }
368:                return duplicated;
369:            }
370:
371:            /**
372:             * Prints a list of CRS that can't be instantiated. This is used for implementation of
373:             * {@linkplain #main main method} in order to check the content of the {@value #FILENAME}
374:             * file (or whatever property file used as backing store for this factory) from the command
375:             * line.
376:             *
377:             * @param  out The writer where to print the report.
378:             * @return The set of codes that can't be instantiated.
379:             * @throws FactoryException if an error occured while
380:             *         {@linkplain #getAuthorityCodes fetching authority codes}.
381:             *
382:             * @since 2.4
383:             */
384:            protected Set reportInstantiationFailures(final PrintWriter out)
385:                    throws FactoryException {
386:                final Set codes = getAuthorityCodes(CoordinateReferenceSystem.class);
387:                final Map failures = new TreeMap();
388:                for (final Iterator it = codes.iterator(); it.hasNext();) {
389:                    final String code = (String) it.next();
390:                    try {
391:                        createCoordinateReferenceSystem(code);
392:                    } catch (FactoryException exception) {
393:                        failures.put(code, exception.getLocalizedMessage());
394:                    }
395:                }
396:                if (!failures.isEmpty()) {
397:                    final TableWriter writer = new TableWriter(out, " ");
398:                    for (final Iterator it = failures.entrySet().iterator(); it
399:                            .hasNext();) {
400:                        final Map.Entry entry = (Map.Entry) it.next();
401:                        writer.write((String) entry.getKey());
402:                        writer.write(':');
403:                        writer.nextColumn();
404:                        writer.write((String) entry.getValue());
405:                        writer.nextLine();
406:                    }
407:                    try {
408:                        writer.flush();
409:                    } catch (IOException e) {
410:                        // Should not happen, since we are writting to a PrintWriter
411:                        throw new AssertionError(e);
412:                    }
413:                }
414:                return failures.keySet();
415:            }
416:
417:            /**
418:             * Prints a list of codes that duplicate the ones provided in the {@link ThreadedEpsgFactory}.
419:             * The factory tested is the one registered in {@link ReferencingFactoryFinder}. By default,
420:             * this is this {@code FactoryUsingWKT} class backed by the {@value #FILENAME} property file.
421:             * This method can be invoked from the command line in order to check the content of the
422:             * property file. Valid arguments are:
423:             * <p>
424:             * <table>
425:             *   <tr><td>{@code -test}</td><td>Try to instantiate all CRS and reports any failure
426:             *       to do so.</td></tr>
427:             *   <tr><td>{@code -duplicated}</td><td>List all codes from the WKT factory that are
428:             *       duplicating a code from the SQL factory.</td></tr>
429:             * </table>
430:             *
431:             * @param  args Command line arguments.
432:             * @throws FactoryException if an error occured.
433:             *
434:             * @since 2.4
435:             */
436:            public static void main(final String[] args)
437:                    throws FactoryException {
438:                main(args, FactoryUsingWKT.class);
439:            }
440:
441:            /**
442:             * Implementation of the {@link #main} method, shared by subclasses.
443:             */
444:            static void main(String[] args,
445:                    final Class/*<? extends FactoryUsingWKT>*/type)
446:                    throws FactoryException {
447:                final Arguments arguments = new Arguments(args);
448:                Locale.setDefault(arguments.locale);
449:                final boolean duplicated = arguments.getFlag("-duplicated");
450:                final boolean instantiate = arguments.getFlag("-test");
451:                args = arguments.getRemainingArguments(0);
452:                // TODO: remove the cast when we will be allowed to compile for J2SE 1.5.
453:                final FactoryUsingWKT factory = (FactoryUsingWKT) getFactory(type);
454:                if (duplicated) {
455:                    factory.reportDuplicatedCodes(arguments.out);
456:                }
457:                if (instantiate) {
458:                    factory.reportInstantiationFailures(arguments.out);
459:                }
460:                factory.dispose();
461:            }
462:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.