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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005:         *    (C) 2004, 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;
018:
019:        // J2SE direct dependencies
020:        import java.io.IOException;
021:        import java.io.Writer;
022:        import java.util.Set;
023:        import java.util.Locale;
024:        import java.util.Iterator;
025:        import java.util.Collections;
026:        import java.util.LinkedHashSet;
027:        import javax.imageio.spi.ServiceRegistry;
028:        import javax.imageio.spi.RegisterableService;
029:
030:        // OpenGIS dependencies
031:        import org.opengis.metadata.citation.Citation;
032:        import org.opengis.referencing.Factory;
033:        import org.opengis.referencing.AuthorityFactory;
034:        import org.opengis.referencing.crs.CRSFactory;
035:        import org.opengis.referencing.crs.CRSAuthorityFactory;
036:        import org.opengis.referencing.cs.CSFactory;
037:        import org.opengis.referencing.cs.CSAuthorityFactory;
038:        import org.opengis.referencing.datum.DatumFactory;
039:        import org.opengis.referencing.datum.DatumAuthorityFactory;
040:        import org.opengis.referencing.operation.CoordinateOperationFactory;
041:        import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
042:        import org.opengis.referencing.operation.MathTransformFactory;
043:
044:        // Geotools dependencies
045:        import org.geotools.factory.Hints;
046:        import org.geotools.factory.GeoTools;
047:        import org.geotools.factory.FactoryFinder;
048:        import org.geotools.factory.FactoryCreator;
049:        import org.geotools.factory.FactoryRegistry;
050:        import org.geotools.factory.FactoryRegistryException;
051:        import org.geotools.metadata.iso.citation.Citations;
052:        import org.geotools.resources.Arguments;
053:        import org.geotools.resources.LazySet;
054:
055:        /**
056:         * Defines static methods used to access the application's default {@linkplain Factory
057:         * factory} implementation.
058:         *
059:         * <P>To declare a factory implementation, a services subdirectory is placed within the
060:         * {@code META-INF} directory that is present in every JAR file. This directory
061:         * contains a file for each factory interface that has one or more implementation classes
062:         * present in the JAR file. For example, if the JAR file contained a class named
063:         * {@code com.mycompany.DatumFactoryImpl} which implements the {@link DatumFactory}
064:         * interface, the JAR file would contain a file named:</P>
065:         *
066:         * <blockquote><pre>META-INF/services/org.opengis.referencing.datum.DatumFactory</pre></blockquote>
067:         *
068:         * <P>containing the line:</P>
069:         *
070:         * <blockquote><pre>com.mycompany.DatumFactoryImpl</pre></blockquote>
071:         *
072:         * <P>If the factory classes implements {@link RegisterableService}, it will be notified upon
073:         * registration and deregistration. Note that the factory classes should be lightweight and quick
074:         * to load. Implementations of these interfaces should avoid complex dependencies on other classes
075:         * and on native code. The usual pattern for more complex services is to register a lightweight
076:         * proxy for the heavyweight service.</P>
077:         *
078:         * <H2>Note on factory ordering</H2>
079:         * <P>This class is thread-safe. However, calls to any {@link #setAuthorityOrdering} or
080:         * {@link #setVendorOrdering} methods have a system-wide effect. If two threads or two
081:         * applications need a different ordering, they shall manage their own instance of
082:         * {@link FactoryRegistry}. This {@code FactoryFinder} class is simply a convenience
083:         * wrapper around a {@code FactoryRegistry} instance.</P>
084:         *
085:         * @since 2.4
086:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java $
087:         * @version $Id: ReferencingFactoryFinder.java 29058 2008-02-03 17:47:07Z desruisseaux $
088:         * @author Martin Desruisseaux
089:         */
090:        public class ReferencingFactoryFinder extends FactoryFinder {
091:            /**
092:             * The service registry for this manager.
093:             * Will be initialized only when first needed.
094:             */
095:            private static FactoryRegistry registry;
096:
097:            /**
098:             * The authority names. Will be created only when first needed.
099:             */
100:            private static Set/*<String>*/authorityNames;
101:
102:            /**
103:             * Do not allows any instantiation of this class.
104:             */
105:            ReferencingFactoryFinder() {
106:                // singleton
107:            }
108:
109:            /**
110:             * Returns the service registry. The registry will be created the first
111:             * time this method is invoked.
112:             */
113:            private static FactoryRegistry getServiceRegistry() {
114:                assert Thread.holdsLock(ReferencingFactoryFinder.class);
115:                if (registry == null) {
116:                    registry = new FactoryCreator(new Class[] {
117:                            DatumFactory.class, CSFactory.class,
118:                            CRSFactory.class, DatumAuthorityFactory.class,
119:                            CSAuthorityFactory.class,
120:                            CRSAuthorityFactory.class,
121:                            MathTransformFactory.class,
122:                            CoordinateOperationFactory.class,
123:                            CoordinateOperationAuthorityFactory.class });
124:                }
125:                return registry;
126:            }
127:
128:            /**
129:             * Returns the names of all currently registered authorities.
130:             */
131:            public static synchronized Set/*<String>*/getAuthorityNames() {
132:                /*
133:                 * IMPORTANT: Return the same Set instance (unmodifiable) as long as there is no change
134:                 * in the list of registered factories, and create a new instance in case of changes.
135:                 * 'add/removeAuthorityFactory(...)' and 'scanForPlugins()' methods reset 'authorityNames'
136:                 * to null, which will cause the creation of a new Set instance. Some implementations like
137:                 * AllAuthoritiesFactory rely on this behavior as a way to be notified of registration
138:                 * changes for clearing their cache.
139:                 */
140:                if (authorityNames == null) {
141:                    authorityNames = new LinkedHashSet();
142:                    final Hints hints = EMPTY_HINTS;
143:                    loop: for (int i = 0;; i++) {
144:                        final Set/*<AuthorityFactory>*/factories;
145:                        switch (i) {
146:                        case 0:
147:                            factories = getCRSAuthorityFactories(hints);
148:                            break;
149:                        case 1:
150:                            factories = getCSAuthorityFactories(hints);
151:                            break;
152:                        case 2:
153:                            factories = getDatumAuthorityFactories(hints);
154:                            break;
155:                        case 3:
156:                            factories = getCoordinateOperationAuthorityFactories(hints);
157:                            break;
158:                        default:
159:                            break loop;
160:                        }
161:                        for (final Iterator it = factories.iterator(); it
162:                                .hasNext();) {
163:                            final Citation authority = ((AuthorityFactory) it
164:                                    .next()).getAuthority();
165:                            authorityNames.addAll(authority.getIdentifiers());
166:                        }
167:                    }
168:                    authorityNames = Collections
169:                            .unmodifiableSet(authorityNames);
170:                }
171:                return authorityNames;
172:            }
173:
174:            /**
175:             * Returns all providers of the specified category.
176:             *
177:             * @param  category The factory category.
178:             * @param  hints An optional map of hints, or {@code null} if none.
179:             * @return Set of available factory implementations.
180:             */
181:            private static synchronized Set/*<T>*/getFactories(
182:                    final Class/*<T extends Factory>*/type, Hints hints) {
183:                hints = mergeSystemHints(hints);
184:                return new LazySet(getServiceRegistry().getServiceProviders(
185:                        type, null, hints));
186:            }
187:
188:            /**
189:             * Returns a provider of the specified category.
190:             *
191:             * @param  category The factory category.
192:             * @param  hints An optional map of hints, or {@code null} if none.
193:             * @param  key The hint key to use for searching an implementation.
194:             * @return The first factory that matches the supplied hints.
195:             * @throws FactoryRegistryException if no implementation was found or can be created for the
196:             *         specified interface.
197:             */
198:            private static synchronized Factory /*T*/getFactory(
199:                    final Class/*<T extends Factory>*/type, Hints hints,
200:                    final Hints.Key key) throws FactoryRegistryException {
201:                hints = mergeSystemHints(hints);
202:                return (Factory) getServiceRegistry().getServiceProvider(type,
203:                        null, hints, key);
204:            }
205:
206:            /**
207:             * Returns the first implementation of a factory matching the specified hints. If no
208:             * implementation matches, a new one is created if possible or an exception is thrown
209:             * otherwise. If more than one implementation is registered and an
210:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
211:             * implementation is returned. Otherwise an arbitrary one is selected.
212:             *
213:             * @param  category  The authority factory type.
214:             * @param  authority The desired authority (e.g. "EPSG").
215:             * @param  hints     An optional map of hints, or {@code null} if none.
216:             * @param  key       The hint key to use for searching an implementation.
217:             * @return The first authority factory that matches the supplied hints.
218:             * @throws FactoryRegistryException if no implementation was found or can be created for the
219:             *         specfied interface.
220:             */
221:            private static synchronized AuthorityFactory /*T*/getAuthorityFactory(
222:                    final Class/*<T extends AuthorityFactory>*/type,
223:                    final String authority, Hints hints, final Hints.Key key)
224:                    throws FactoryRegistryException {
225:                hints = mergeSystemHints(hints);
226:                return (AuthorityFactory) getServiceRegistry()
227:                        .getServiceProvider(type,
228:                                new AuthorityFilter(authority), hints, key);
229:            }
230:
231:            /**
232:             * Returns the first implementation of {@link DatumFactory} matching the specified hints.
233:             * If no implementation matches, a new one is created if possible or an exception is thrown
234:             * otherwise. If more than one implementation is registered and an
235:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
236:             * implementation is returned. Otherwise an arbitrary one is selected.
237:             *
238:             * @param  hints An optional map of hints, or {@code null} if none.
239:             * @return The first datum factory that matches the supplied hints.
240:             * @throws FactoryRegistryException if no implementation was found or can be created for the
241:             *         {@link DatumFactory} interface.
242:             */
243:            public static DatumFactory getDatumFactory(final Hints hints)
244:                    throws FactoryRegistryException {
245:                return (DatumFactory) getFactory(DatumFactory.class, hints,
246:                        Hints.DATUM_FACTORY);
247:            }
248:
249:            /**
250:             * Returns a set of all available implementations for the {@link DatumFactory} interface.
251:             *
252:             * @param  hints An optional map of hints, or {@code null} if none.
253:             * @return Set of available datum factory implementations.
254:             */
255:            public static Set getDatumFactories(final Hints hints) {
256:                return getFactories(DatumFactory.class, hints);
257:            }
258:
259:            /**
260:             * Returns the first implementation of {@link CSFactory} matching the specified hints.
261:             * If no implementation matches, a new one is created if possible or an exception is thrown
262:             * otherwise. If more than one implementation is registered and an
263:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
264:             * implementation is returned. Otherwise an arbitrary one is selected.
265:             *
266:             * @param  hints An optional map of hints, or {@code null} if none.
267:             * @return The first coordinate system factory that matches the supplied hints.
268:             * @throws FactoryRegistryException if no implementation was found or can be created for the
269:             *         {@link CSFactory} interface.
270:             */
271:            public static CSFactory getCSFactory(final Hints hints)
272:                    throws FactoryRegistryException {
273:                return (CSFactory) getFactory(CSFactory.class, hints,
274:                        Hints.CS_FACTORY);
275:            }
276:
277:            /**
278:             * Returns a set of all available implementations for the {@link CSFactory} interface.
279:             *
280:             * @param  hints An optional map of hints, or {@code null} if none.
281:             * @return Set of available coordinate system factory implementations.
282:             */
283:            public static Set getCSFactories(final Hints hints) {
284:                return getFactories(CSFactory.class, hints);
285:            }
286:
287:            /**
288:             * Returns the first implementation of {@link CRSFactory} matching the specified hints.
289:             * If no implementation matches, a new one is created if possible or an exception is thrown
290:             * otherwise. If more than one implementation is registered and an
291:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
292:             * implementation is returned. Otherwise an arbitrary one is selected.
293:             *
294:             * @param  hints An optional map of hints, or {@code null} if none.
295:             * @return The first coordinate reference system factory that matches the supplied hints.
296:             * @throws FactoryRegistryException if no implementation was found or can be created for the
297:             *         {@link CRSFactory} interface.
298:             */
299:            public static CRSFactory getCRSFactory(final Hints hints)
300:                    throws FactoryRegistryException {
301:                return (CRSFactory) getFactory(CRSFactory.class, hints,
302:                        Hints.CRS_FACTORY);
303:            }
304:
305:            /**
306:             * Returns a set of all available implementations for the {@link CRSFactory} interface.
307:             *
308:             * @param  hints An optional map of hints, or {@code null} if none.
309:             * @return Set of available coordinate reference system factory implementations.
310:             */
311:            public static Set getCRSFactories(final Hints hints) {
312:                return getFactories(CRSFactory.class, hints);
313:            }
314:
315:            /**
316:             * Returns the first implementation of {@link CoordinateOperationFactory} matching the specified
317:             * hints. If no implementation matches, a new one is created if possible or an exception is
318:             * thrown otherwise. If more than one implementation is registered and an
319:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
320:             * implementation is returned. Otherwise an arbitrary one is selected.
321:             * <p>
322:             * Hints that may be understood includes
323:             * {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM_FACTORY},
324:             * {@link Hints#DATUM_SHIFT_METHOD     DATUM_SHIFT_METHOD},
325:             * {@link Hints#LENIENT_DATUM_SHIFT    LENIENT_DATUM_SHIFT} and
326:             * {@link Hints#VERSION                VERSION}.
327:             *
328:             * @param  hints An optional map of hints, or {@code null} if none.
329:             * @return The first coordinate operation factory that matches the supplied hints.
330:             * @throws FactoryRegistryException if no implementation was found or can be created for the
331:             *         {@link CoordinateOperationFactory} interface.
332:             */
333:            public static CoordinateOperationFactory getCoordinateOperationFactory(
334:                    final Hints hints) throws FactoryRegistryException {
335:                return (CoordinateOperationFactory) getFactory(
336:                        CoordinateOperationFactory.class, hints,
337:                        Hints.COORDINATE_OPERATION_FACTORY);
338:            }
339:
340:            /**
341:             * Returns a set of all available implementations for the
342:             * {@link CoordinateOperationFactory} interface.
343:             *
344:             * @param  hints An optional map of hints, or {@code null} if none.
345:             * @return Set of available coordinate operation factory implementations.
346:             */
347:            public static Set getCoordinateOperationFactories(final Hints hints) {
348:                return getFactories(CoordinateOperationFactory.class, hints);
349:            }
350:
351:            /**
352:             * Returns the first implementation of {@link DatumAuthorityFactory} matching the specified
353:             * hints. If no implementation matches, a new one is created if possible or an exception is
354:             * thrown otherwise. If more than one implementation is registered and an
355:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
356:             * implementation is returned. Otherwise an arbitrary one is selected.
357:             *
358:             * @param  authority The desired authority (e.g. "EPSG").
359:             * @param  hints An optional map of hints, or {@code null} if none.
360:             * @return The first datum authority factory that matches the supplied hints.
361:             * @throws FactoryRegistryException if no implementation was found or can be created for the
362:             *         {@link DatumAuthorityFactory} interface.
363:             */
364:            public static DatumAuthorityFactory getDatumAuthorityFactory(
365:                    final String authority, final Hints hints)
366:                    throws FactoryRegistryException {
367:                return (DatumAuthorityFactory) getAuthorityFactory(
368:                        DatumAuthorityFactory.class, authority, hints,
369:                        Hints.DATUM_AUTHORITY_FACTORY);
370:            }
371:
372:            /**
373:             * Returns a set of all available implementations for the {@link DatumAuthorityFactory}
374:             * interface.
375:             *
376:             * @param  hints An optional map of hints, or {@code null} if none.
377:             * @return Set of available datum authority factory implementations.
378:             */
379:            public static Set getDatumAuthorityFactories(final Hints hints) {
380:                return getFactories(DatumAuthorityFactory.class, hints);
381:            }
382:
383:            /**
384:             * Returns the first implementation of {@link CSAuthorityFactory} matching the specified
385:             * hints. If no implementation matches, a new one is created if possible or an exception is
386:             * thrown otherwise. If more than one implementation is registered and an
387:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
388:             * implementation is returned. Otherwise an arbitrary one is selected.
389:             * <p>
390:             * Hints that may be understood includes
391:             * {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER FORCE_LONGITUDE_FIRST_AXIS_ORDER},
392:             * {@link Hints#FORCE_STANDARD_AXIS_UNITS        FORCE_STANDARD_AXIS_UNITS} and
393:             * {@link Hints#FORCE_STANDARD_AXIS_DIRECTIONS   FORCE_STANDARD_AXIS_DIRECTIONS} and
394:             * {@link Hints#VERSION                          VERSION}.
395:             *
396:             * @param  authority The desired authority (e.g. "EPSG").
397:             * @param  hints An optional map of hints, or {@code null} if none.
398:             * @return The first coordinate system authority factory that matches the supplied hints.
399:             * @throws FactoryRegistryException if no implementation was found or can be created for the
400:             *         {@link CSAuthorityFactory} interface.
401:             */
402:            public static CSAuthorityFactory getCSAuthorityFactory(
403:                    final String authority, final Hints hints)
404:                    throws FactoryRegistryException {
405:                return (CSAuthorityFactory) getAuthorityFactory(
406:                        CSAuthorityFactory.class, authority, hints,
407:                        Hints.CS_AUTHORITY_FACTORY);
408:            }
409:
410:            /**
411:             * Returns a set of all available implementations for the {@link CSAuthorityFactory} interface.
412:             *
413:             * @param  hints An optional map of hints, or {@code null} if none.
414:             * @return Set of available coordinate system authority factory implementations.
415:             */
416:            public static Set getCSAuthorityFactories(final Hints hints) {
417:                return getFactories(CSAuthorityFactory.class, hints);
418:            }
419:
420:            /**
421:             * Returns the first implementation of {@link CRSAuthorityFactory} matching the specified
422:             * hints. If no implementation matches, a new one is created if possible or an exception is
423:             * thrown otherwise. If more than one implementation is registered and an
424:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
425:             * implementation is returned. Otherwise an arbitrary one is selected.
426:             * <p>
427:             * Hints that may be understood includes
428:             * {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER FORCE_LONGITUDE_FIRST_AXIS_ORDER},
429:             * {@link Hints#FORCE_STANDARD_AXIS_UNITS        FORCE_STANDARD_AXIS_UNITS},
430:             * {@link Hints#FORCE_STANDARD_AXIS_DIRECTIONS   FORCE_STANDARD_AXIS_DIRECTIONS} and
431:             * {@link Hints#VERSION                          VERSION}.
432:             * <p>
433:             * <b>TIP:</b> The EPSG official factory and the EPSG extensions (additional CRS provided by
434:             * ESRI and others) are two distinct factories. Call to {@code getCRSAuthorityFactory("EPSG",
435:             * null)} returns only one of those, usually the official EPSG factory. If the union of those
436:             * two factories is wanted, then a chain of fallbacks is wanted. Consider using something like:
437:             *
438:             * <blockquote><code>
439:             * {@linkplain org.geotools.referencing.factory.FallbackAuthorityFactory#create(Class,
440:             * java.util.Collection) FallbackAuthorityFactory.create}(CRSAuthorityFactory.class,
441:             * {@linkplain #getCRSAuthorityFactories getCRSAuthorityFactories}(hints));
442:             * </code></blockquote>
443:             *
444:             * @param  authority The desired authority (e.g. "EPSG").
445:             * @param  hints An optional map of hints, or {@code null} if none.
446:             * @return The first coordinate reference system authority factory that matches the supplied hints.
447:             * @throws FactoryRegistryException if no implementation was found or can be created for the
448:             *         {@link CRSAuthorityFactory} interface.
449:             */
450:            public static CRSAuthorityFactory getCRSAuthorityFactory(
451:                    final String authority, final Hints hints)
452:                    throws FactoryRegistryException {
453:                return (CRSAuthorityFactory) getAuthorityFactory(
454:                        CRSAuthorityFactory.class, authority, hints,
455:                        Hints.CRS_AUTHORITY_FACTORY);
456:            }
457:
458:            /**
459:             * Returns a set of all available implementations for the {@link CRSAuthorityFactory} interface.
460:             * This set can be used to list the available codes known to all authorities.
461:             * In the event that the same code is understood by more then one authority
462:             * you will need to assume both are close enough, or make use of this set directly
463:             * rather than use the {@link CRS#decode} convenience method.
464:             *
465:             * @param  hints An optional map of hints, or {@code null} if none.
466:             * @return Set of available coordinate reference system authority factory implementations.
467:             */
468:            public static Set getCRSAuthorityFactories(final Hints hints) {
469:                return getFactories(CRSAuthorityFactory.class, hints);
470:            }
471:
472:            /**
473:             * Returns the first implementation of {@link CoordinateOperationAuthorityFactory} matching
474:             * the specified hints. If no implementation matches, a new one is created if possible or an
475:             * exception is thrown otherwise. If more than one implementation is registered and an
476:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
477:             * implementation is returned. Otherwise an arbitrary one is selected.
478:             *
479:             * @param  authority The desired authority (e.g. "EPSG").
480:             * @param  hints An optional map of hints, or {@code null} if none.
481:             * @return The first coordinate operation authority factory that matches the supplied hints.
482:             * @throws FactoryRegistryException if no implementation was found or can be created for the
483:             *         {@link CoordinateOperationAuthorityFactory} interface.
484:             */
485:            public static CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(
486:                    final String authority, final Hints hints)
487:                    throws FactoryRegistryException {
488:                return (CoordinateOperationAuthorityFactory) getAuthorityFactory(
489:                        CoordinateOperationAuthorityFactory.class, authority,
490:                        hints, Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY);
491:            }
492:
493:            /**
494:             * Returns a set of all available implementations for the
495:             * {@link CoordinateOperationAuthorityFactory} interface.
496:             *
497:             * @param  hints An optional map of hints, or {@code null} if none.
498:             * @return Set of available coordinate operation authority factory implementations.
499:             */
500:            public static Set getCoordinateOperationAuthorityFactories(
501:                    final Hints hints) {
502:                return getFactories(CoordinateOperationAuthorityFactory.class,
503:                        hints);
504:            }
505:
506:            /**
507:             * Returns the first implementation of {@link MathTransformFactory} matching the specified
508:             * hints. If no implementation matches, a new one is created if possible or an exception is
509:             * thrown otherwise. If more than one implementation is registered and an
510:             * {@linkplain #setVendorOrdering ordering is set}, then the preferred
511:             * implementation is returned. Otherwise an arbitrary one is selected.
512:             *
513:             * @param  hints An optional map of hints, or {@code null} if none.
514:             * @return The first math transform factory that matches the supplied hints.
515:             * @throws FactoryRegistryException if no implementation was found or can be created for the
516:             *         {@link MathTransformFactory} interface.
517:             */
518:            public static MathTransformFactory getMathTransformFactory(
519:                    final Hints hints) throws FactoryRegistryException {
520:                return (MathTransformFactory) getFactory(
521:                        MathTransformFactory.class, hints,
522:                        Hints.MATH_TRANSFORM_FACTORY);
523:            }
524:
525:            /**
526:             * Returns a set of all available implementations for the
527:             * {@link MathTransformFactory} interface.
528:             *
529:             * @param  hints An optional map of hints, or {@code null} if none.
530:             * @return Set of available math transform factory implementations.
531:             */
532:            public static Set getMathTransformFactories(final Hints hints) {
533:                return getFactories(MathTransformFactory.class, hints);
534:            }
535:
536:            /**
537:             * Sets a pairwise ordering between two vendors. If one or both vendors are not
538:             * currently registered, or if the desired ordering is already set, nothing happens
539:             * and {@code false} is returned.
540:             * <p>
541:             * The example below said that an ESRI implementation (if available) is
542:             * preferred over the Geotools one:
543:             *
544:             * <blockquote><code>FactoryFinder.setVendorOrdering("ESRI", "Geotools");</code></blockquote>
545:             *
546:             * @param  vendor1 The preferred vendor.
547:             * @param  vendor2 The vendor to which {@code vendor1} is preferred.
548:             * @return {@code true} if the ordering was set for at least one category.
549:             */
550:            public static synchronized boolean setVendorOrdering(
551:                    final String vendor1, final String vendor2) {
552:                return getServiceRegistry().setOrdering(Factory.class, true,
553:                        new VendorFilter(vendor1), new VendorFilter(vendor2));
554:            }
555:
556:            /**
557:             * Unsets a pairwise ordering between two vendors. If one or both vendors are not
558:             * currently registered, or if the desired ordering is already unset, nothing happens
559:             * and {@code false} is returned.
560:             *
561:             * @param  vendor1 The preferred vendor.
562:             * @param  vendor2 The vendor to which {@code vendor1} is preferred.
563:             * @return {@code true} if the ordering was unset for at least one category.
564:             */
565:            public static synchronized boolean unsetVendorOrdering(
566:                    final String vendor1, final String vendor2) {
567:                return getServiceRegistry().setOrdering(Factory.class, false,
568:                        new VendorFilter(vendor1), new VendorFilter(vendor2));
569:            }
570:
571:            /**
572:             * A filter for factories provided by a given vendor.
573:             */
574:            private static final class VendorFilter implements 
575:                    ServiceRegistry.Filter {
576:                /** The vendor to filter. */
577:                private final String vendor;
578:
579:                /** Constructs a filter for the given vendor. */
580:                public VendorFilter(final String vendor) {
581:                    this .vendor = vendor;
582:                }
583:
584:                /** Returns {@code true} if the specified provider is built by the vendor. */
585:                public boolean filter(final Object provider) {
586:                    return Citations.titleMatches(((Factory) provider)
587:                            .getVendor(), vendor);
588:                }
589:            }
590:
591:            /**
592:             * Sets a pairwise ordering between two authorities. If one or both authorities are not
593:             * currently registered, or if the desired ordering is already set, nothing happens
594:             * and {@code false} is returned.
595:             * <p>
596:             * The example below said that EPSG {@linkplain AuthorityFactory authority factories}
597:             * are preferred over ESRI ones:
598:             *
599:             * <blockquote><code>FactoryFinder.setAuthorityOrdering("EPSG", "ESRI");</code></blockquote>
600:             *
601:             * @param  authority1 The preferred authority.
602:             * @param  authority2 The authority to which {@code authority1} is preferred.
603:             * @return {@code true} if the ordering was set for at least one category.
604:             */
605:            public static synchronized boolean setAuthorityOrdering(
606:                    final String authority1, final String authority2) {
607:                return getServiceRegistry().setOrdering(AuthorityFactory.class,
608:                        true, new AuthorityFilter(authority1),
609:                        new AuthorityFilter(authority2));
610:            }
611:
612:            /**
613:             * Unsets a pairwise ordering between two authorities. If one or both authorities are not
614:             * currently registered, or if the desired ordering is already unset, nothing happens
615:             * and {@code false} is returned.
616:             *
617:             * @param  authority1 The preferred authority.
618:             * @param  authority2 The vendor to which {@code authority1} is preferred.
619:             * @return {@code true} if the ordering was unset for at least one category.
620:             */
621:            public static synchronized boolean unsetAuthorityOrdering(
622:                    final String authority1, final String authority2) {
623:                return getServiceRegistry().setOrdering(AuthorityFactory.class,
624:                        false, new AuthorityFilter(authority1),
625:                        new AuthorityFilter(authority2));
626:            }
627:
628:            /**
629:             * A filter for factories provided for a given authority.
630:             */
631:            private static final class AuthorityFilter implements 
632:                    ServiceRegistry.Filter {
633:                /** The authority to filter. */
634:                private final String authority;
635:
636:                /** Constructs a filter for the given authority. */
637:                public AuthorityFilter(final String authority) {
638:                    this .authority = authority;
639:                }
640:
641:                /** Returns {@code true} if the specified provider is for the authority. */
642:                public boolean filter(final Object provider) {
643:                    if (authority == null) {
644:                        // If the user didn't specified an authority name, then the factory to use must
645:                        // be specified explicitly through a hint (e.g. Hints.CRS_AUTHORITY_FACTORY).
646:                        return false;
647:                    }
648:                    return Citations.identifierMatches(
649:                            ((AuthorityFactory) provider).getAuthority(),
650:                            authority);
651:                }
652:            }
653:
654:            /**
655:             * Programmatic management of authority factories.
656:             * Needed for user managed, not plug-in managed, authority factory.
657:             * Also useful for test cases.
658:             *
659:             * @param authority The authority factory to add.
660:             */
661:            public static synchronized void addAuthorityFactory(
662:                    final AuthorityFactory authority) {
663:                if (registry == null) {
664:                    scanForPlugins();
665:                }
666:                getServiceRegistry().registerServiceProvider(authority);
667:                authorityNames = null;
668:            }
669:
670:            /**
671:             * Programmatic management of authority factories.
672:             * Needed for user managed, not plug-in managed, authority factory.
673:             * Also useful for test cases.
674:             *
675:             * @param authority The authority factory to remove.
676:             */
677:            public static synchronized void removeAuthorityFactory(
678:                    final AuthorityFactory authority) {
679:                getServiceRegistry().deregisterServiceProvider(authority);
680:                authorityNames = null;
681:            }
682:
683:            /**
684:             * Returns {@code true} if the specified factory is registered. A factory may have been
685:             * registered by {@link #scanForPlugins()} if it was declared in a {@code META-INF/services}
686:             * file, or it may have been {@linkplain #addAuthorityFactory added programmatically}.
687:             *
688:             * @since 2.4
689:             */
690:            public static synchronized boolean isRegistered(
691:                    final Factory factory) {
692:                return factory.equals(getServiceRegistry()
693:                        .getServiceProviderByClass(factory.getClass()));
694:            }
695:
696:            /**
697:             * Scans for factory plug-ins on the application class path. This method is needed because the
698:             * application class path can theoretically change, or additional plug-ins may become available.
699:             * Rather than re-scanning the classpath on every invocation of the API, the class path is
700:             * scanned automatically only on the first invocation. Clients can call this method to prompt
701:             * a re-scan. Thus this method need only be invoked by sophisticated applications which
702:             * dynamically make new plug-ins available at runtime.
703:             */
704:            public static void scanForPlugins() {
705:                synchronized (ReferencingFactoryFinder.class) {
706:                    authorityNames = null;
707:                    if (registry != null) {
708:                        registry.scanForPlugins();
709:                    }
710:                }
711:                GeoTools.fireConfigurationChanged();
712:            }
713:
714:            /**
715:             * List all available factory implementations in a tabular format. For each factory interface,
716:             * the first implementation listed is the default one. This method provides a way to check the
717:             * state of a system, usually for debugging purpose.
718:             *
719:             * @param  out The output stream where to format the list.
720:             * @param  locale The locale for the list, or {@code null}.
721:             * @throws IOException if an error occurs while writting to {@code out}.
722:             */
723:            public static synchronized void listProviders(final Writer out,
724:                    final Locale locale) throws IOException {
725:                final FactoryRegistry registry = getServiceRegistry();
726:                new FactoryPrinter().list(registry, out, locale);
727:            }
728:
729:            /**
730:             * Dump to the standard output stream a list of available factory implementations.
731:             * This method can be invoked from the command line. It provides a mean to verify
732:             * if some implementations were found in the classpath. The syntax is:
733:             * <BR>
734:             * <BLOCKQUOTE><CODE>
735:             * java org.geotools.referencing.FactoryFinder <VAR>&lt;options&gt;</VAR>
736:             * </CODE></BLOCKQUOTE>
737:             *
738:             * <P>where options are:</P>
739:             *
740:             * <TABLE CELLPADDING='0' CELLSPACING='0'>
741:             *   <TR><TD NOWRAP><CODE>-encoding</CODE> <VAR>&lt;code&gt;</VAR></TD>
742:             *       <TD NOWRAP>&nbsp;Set the character encoding</TD></TR>
743:             *   <TR><TD NOWRAP><CODE>-locale</CODE> <VAR>&lt;language&gt;</VAR></TD>
744:             *       <TD NOWRAP>&nbsp;Set the language for the output (e.g. "fr" for French)</TD></TR>
745:             * </TABLE>
746:             *
747:             * <P><strong>Note for Windows users:</strong> If the output contains strange
748:             * symbols, try to supply an "{@code -encoding}" argument. Example:</P>
749:             *
750:             * <blockquote><code>
751:             * java org.geotools.referencing.FactoryFinder -encoding Cp850
752:             * </code></blockquote>
753:             *
754:             * <P>The codepage number (850 in the previous example) can be obtained from the DOS
755:             * commande line using the "{@code chcp}" command with no arguments.
756:             * This {@code -encoding} argument need to be supplied only once.</P>
757:             *
758:             * @param args Command line arguments.
759:             */
760:            public static void main(String[] args) {
761:                final Arguments arguments = new Arguments(args);
762:                args = arguments.getRemainingArguments(0);
763:                try {
764:                    listProviders(arguments.out, arguments.locale);
765:                } catch (Exception exception) {
766:                    exception.printStackTrace(arguments.err);
767:                }
768:            }
769:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.