Source Code Cross Referenced for ManyAuthoritiesFactory.java in  » GIS » GeoTools-2.4.1 » org » geotools » referencing » factory » 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 
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:         *    (C) 2005, 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;
018:
019:        // J2SE dependencies
020:        import java.util.*;
021:        import javax.units.Unit;
022:
023:        // OpenGIS dependencies
024:        import org.opengis.referencing.*;
025:        import org.opengis.referencing.cs.*;
026:        import org.opengis.referencing.crs.*;
027:        import org.opengis.referencing.datum.*;
028:        import org.opengis.referencing.operation.*;
029:        import org.opengis.util.InternationalString;
030:        import org.opengis.metadata.citation.Citation;
031:
032:        // Geotools dependencies
033:        import org.geotools.factory.Hints;
034:        import org.geotools.factory.Factory;
035:        import org.geotools.factory.FactoryRegistryException;
036:        import org.geotools.metadata.iso.citation.Citations;
037:        import org.geotools.util.GenericName;
038:        import org.geotools.resources.i18n.ErrorKeys;
039:        import org.geotools.resources.i18n.Errors;
040:        import org.geotools.resources.i18n.Vocabulary;
041:        import org.geotools.resources.i18n.VocabularyKeys;
042:
043:        /**
044:         * An authority factory that delegates the object creation to an other factory determined from the
045:         * authority name in the code. This factory requires that every codes given to a {@code createFoo}
046:         * method are prefixed by the authority name, for example {@code "EPSG:4326"}. This is different
047:         * from using a factory from a known authority, in which case the authority part was optional (for
048:         * example when using the {@linkplain org.geotools.referencing.factory.epsg EPSG authority factory},
049:         * the {@code "EPSG:"} part in {@code "EPSG:4326"} is optional).
050:         * <p>
051:         * This class parses the authority name and delegates the work the corresponding factory. For
052:         * example if any {@code createFoo(...)} method in this class is invoked with a code starting
053:         * by {@code "EPSG:"}, then this class delegates the object creation to one of the authority
054:         * factories provided to the constructor.
055:         * <p>
056:         * This class is not registered in {@link ReferencingFactoryFinder}, because it is not a real
057:         * authority factory. There is not a single authority name associated to this factory, but rather
058:         * a set of names determined from all available authority factories.
059:         *
060:         * @since 2.4
061:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ManyAuthoritiesFactory.java $
062:         * @version $Id: ManyAuthoritiesFactory.java 29058 2008-02-03 17:47:07Z desruisseaux $
063:         * @author Martin Desruisseaux
064:         */
065:        public class ManyAuthoritiesFactory extends AuthorityFactoryAdapter
066:                implements  CRSAuthorityFactory, CSAuthorityFactory,
067:                DatumAuthorityFactory, CoordinateOperationAuthorityFactory {
068:            /**
069:             * The types to be recognized for the {@code factories} argument in
070:             * constructors. Must be consistent with the types expected by the
071:             * {@link AllAuthoritiesFactory#fromFactoryRegistry(String, Class)} method.
072:             */
073:            private static final Class[] FACTORY_TYPES = new Class[] {
074:                    CRSAuthorityFactory.class, DatumAuthorityFactory.class,
075:                    CSAuthorityFactory.class,
076:                    CoordinateOperationAuthorityFactory.class };
077:
078:            /**
079:             * The types created by {@link #FACTORY_TYPES}. For each type {@code OBJECT_TYPES[i]},
080:             * the factory to be used must be {@code FACTORY_TYPES[i]}.
081:             */
082:            private static final Class[] OBJECT_TYPES = new Class[] {
083:                    CoordinateReferenceSystem.class, Datum.class,
084:                    CoordinateSystem.class, CoordinateOperation.class };
085:
086:            /**
087:             * The set of user-specified factories, or {@code null} if none.
088:             * This field should be modified by {@link #setFactories} only.
089:             */
090:            private Collection/*<AuthorityFactory>*/factories;
091:
092:            /**
093:             * The separator between the authority name and the code.
094:             *
095:             * @deprecated Remove this field after we removed the deprecated constructor.
096:             */
097:            private final char separator;
098:
099:            /**
100:             * Guard against infinite recursivity in {@link #getAuthorityCodes}.
101:             */
102:            private final ThreadLocal/*<Boolean>*/inProgress = new ThreadLocal();
103:
104:            /**
105:             * Creates a new factory using the specified hints.
106:             *
107:             * @param userHints An optional set of hints, or {@code null} if none.
108:             *
109:             * @deprecated Use {@link #ManyAuthoritiesFactory(Collection)}.
110:             */
111:            public ManyAuthoritiesFactory(final Hints userHints) {
112:                this (userHints, null);
113:            }
114:
115:            /**
116:             * Creates a new factory using the specified set of user factories. Any call to a
117:             * {@code createFoo(code)} method will scan the supplied factories in their iteration
118:             * order. The first factory implementing the appropriate interface and having the expected
119:             * {@linkplain AuthorityFactory#getAuthority authority name} will be used.
120:             * <p>
121:             * If the {@code factories} collection contains more than one factory for the same authority
122:             * and interface, then all additional factories will be {@linkplain FallbackAuthorityFactory
123:             * fallbacks}, to be tried in iteration order only if the first acceptable factory failed to
124:             * create the requested object.
125:             *
126:             * @param factories A set of user-specified factories to try before to delegate
127:             *        to {@link GeometryFactoryFinder}.
128:             */
129:            public ManyAuthoritiesFactory(
130:                    final Collection/*<? extends AuthorityFactory>*/factories) {
131:                this (null, factories, (char) 0);
132:            }
133:
134:            /**
135:             * Creates a new factory using the specified hints and a set of user factories.
136:             *
137:             * @param userHints An optional set of hints, or {@code null} if none.
138:             * @param factories A set of user-specified factories to try before to delegate
139:             *        to {@link ReferencingFactoryFinder}.
140:             *
141:             * @deprecated Use {@link #ManyAuthoritiesFactory(Collection)}.
142:             */
143:            public ManyAuthoritiesFactory(final Hints userHints,
144:                    final Collection/*<? extends AuthorityFactory>*/factories) {
145:                this (userHints, factories, (char) 0);
146:            }
147:
148:            /**
149:             * Creates a new factory using the specified hints, user factories and name
150:             * separator.
151:             *
152:             * @deprecated Override the {@link #getSeparator} method instead.
153:             */
154:            ManyAuthoritiesFactory(final Hints userHints,
155:                    final Collection/*<? extends AuthorityFactory>*/factories,
156:                    final char separator) {
157:                super (NORMAL_PRIORITY);
158:                this .separator = separator;
159:                if (factories != null && !factories.isEmpty()) {
160:                    for (final Iterator it = factories.iterator(); it.hasNext();) {
161:                        final Object factory = it.next();
162:                        if (factory instanceof  Factory) {
163:                            hints.putAll(((Factory) factory)
164:                                    .getImplementationHints());
165:                        }
166:                    }
167:                    this .factories = createFallbacks(factories);
168:                }
169:            }
170:
171:            /**
172:             * Returns the factories. This method should not be public since it returns directly the
173:             * internal instance. This method is to be overriden by {@link AllAuthoritiesFactory} only.
174:             */
175:            Collection/*<AuthorityFactory>*/getFactories() {
176:                return factories;
177:            }
178:
179:            /**
180:             * Sets the factories. This method is invoked by the {@link AllAuthoritiesFactory} subclass
181:             * only. No one else should invoke this method, since factories should be immutable.
182:             */
183:            final void setFactories(
184:                    final Collection/*<AuthorityFactory>*/factories) {
185:                assert Thread.holdsLock(this );
186:                this .factories = createFallbacks(factories);
187:            }
188:
189:            /**
190:             * If more than one factory is found for the same authority and interface,
191:             * then wraps them as a chain of {@link FallbackAuthorityFactory}.
192:             */
193:            private static Collection/*<AuthorityFactory>*/createFallbacks(
194:                    final Collection/*<? extends AuthorityFactory>*/factories) {
195:                /*
196:                 * 'authorities' Will contains the set of all authorities found without duplicate values
197:                 * in the sense of Citations.identifierMatches(...). 'factoriesByAuthority' will contains
198:                 * the collection of factories for each authority.
199:                 */
200:                int authorityCount = 0;
201:                final Citation[] authorities = new Citation[factories.size()];
202:                final List[] factoriesByAuthority = new List[authorities.length];
203:                for (final Iterator it = factories.iterator(); it.hasNext();) {
204:                    final AuthorityFactory factory = (AuthorityFactory) it
205:                            .next();
206:                    /*
207:                     * Check if the authority has already been meet previously. If the authority is found
208:                     * then 'authorityIndex' is set to its index. Otherwise the new authority is added to
209:                     * the 'authorities' list.
210:                     */
211:                    Citation authority = factory.getAuthority();
212:                    int authorityIndex;
213:                    for (authorityIndex = 0; authorityIndex < authorityCount; authorityIndex++) {
214:                        final Citation candidate = authorities[authorityIndex];
215:                        if (Citations.identifierMatches(candidate, authority)) {
216:                            authority = candidate;
217:                            break;
218:                        }
219:                    }
220:                    final List/*<AuthorityFactory>*/list;
221:                    if (authorityIndex == authorityCount) {
222:                        authorities[authorityCount++] = authority;
223:                        factoriesByAuthority[authorityIndex] = list = new ArrayList(
224:                                4);
225:                    } else {
226:                        list = factoriesByAuthority[authorityIndex];
227:                    }
228:                    if (!list.contains(factory)) {
229:                        list.add(factory);
230:                    }
231:                }
232:                /*
233:                 * For each authority, chains the factories into a FallbackAuthorityFactory object.
234:                 */
235:                final ArrayList/*<AuthorityFactory>*/result = new ArrayList();
236:                final List/*<AuthorityFactory>*/buffer = new ArrayList(4);
237:                for (int i = 0; i < authorityCount; i++) {
238:                    final Collection list = factoriesByAuthority[i];
239:                    while (!list.isEmpty()) {
240:                        AuthorityFactory primary = null;
241:                        boolean needOtherChains = false;
242:                        for (final Iterator it = list.iterator(); it.hasNext();) {
243:                            final AuthorityFactory fallback = (AuthorityFactory) it
244:                                    .next();
245:                            if (primary == null) {
246:                                primary = fallback;
247:                            } else if (!FallbackAuthorityFactory.chainable(
248:                                    primary, fallback)) {
249:                                needOtherChains = true;
250:                                continue;
251:                            }
252:                            buffer.add(fallback);
253:                            if (!needOtherChains) {
254:                                it.remove();
255:                            }
256:                        }
257:                        result.add(FallbackAuthorityFactory.create(buffer));
258:                        buffer.clear();
259:                    }
260:                }
261:                result.trimToSize();
262:                return result;
263:            }
264:
265:            /**
266:             * If this factory is a wrapper for the specified factory that do not add any additional
267:             * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
268:             * for {@link FallbackAuthorityFactory} internal use only.
269:             */
270:            //@Override
271:            boolean sameAuthorityCodes(final AuthorityFactory factory) {
272:                // We don't want to inherit AuthorityFactoryAdapter implementation here.
273:                return factory == this ;
274:            }
275:
276:            /**
277:             * Returns the character separator for the specified code. The default implementation returns
278:             * the {@linkplain GenericName#DEFAULT_SEPARATOR default name separator} {@code ':'}, except
279:             * if the code looks like a URL (e.g. {@code "http://www.opengis.net/"}), in which case this
280:             * method returns {@code '/'}.
281:             * <p>
282:             * In the current implementation, "looks like a URL" means that the first
283:             * non-{@linkplain Character#isLetterOrDigit(char) aplhanumeric} characters
284:             * are {@code "://"}. But this heuristic rule may change in future implementations.
285:             */
286:            protected char getSeparator(String code) {
287:                if (separator != 0) {
288:                    // Remove this block after we removed the deprecated separator field.
289:                    return separator;
290:                }
291:                code = code.trim();
292:                final int length = code.length();
293:                for (int i = 0; i < length; i++) {
294:                    if (!Character.isLetterOrDigit(code.charAt(i))) {
295:                        if (code.regionMatches(i, "://", 0, 3)) {
296:                            return '/';
297:                        }
298:                        break;
299:                    }
300:                }
301:                return GenericName.DEFAULT_SEPARATOR;
302:            }
303:
304:            /**
305:             * Returns {@code true} if the specified code can be splitted in a (<cite>authority</cite>,
306:             * <cite>code</cite>) pair at the specified index. The default implementation returns
307:             * {@code true} if the first non-whitespace character on the left and right side are
308:             * valid Java identifiers.
309:             * <p>
310:             * The purpose of this method is to avoid considering the {@code "//"} part in
311:             * {@code "http://www.opengis.net/gml/srs/epsg.xml"} as separators. In case of
312:             * failure to parse the code, this restriction will produce and error message
313:             * like "<cite>Unknown <code>http://www.opengis.net</code> authority</cite>"
314:             * instead of "<cite>Unknown <code>http:</code> authority</cite>".
315:             * <p>
316:             * We may consider to turn this method into a protected one if the users need to override it.
317:             */
318:            private static boolean canSeparateAt(final String code,
319:                    final int index) {
320:                char c;
321:                int i = index;
322:                do {
323:                    if (--i < 0) {
324:                        return false;
325:                    }
326:                    c = code.charAt(i);
327:                } while (Character.isWhitespace(c));
328:                if (!Character.isJavaIdentifierPart(c)) {
329:                    return false;
330:                }
331:                final int length = code.length();
332:                i = index;
333:                do {
334:                    if (++i >= length) {
335:                        return false;
336:                    }
337:                    c = code.charAt(i);
338:                } while (Character.isWhitespace(c));
339:                return Character.isJavaIdentifierPart(c);
340:            }
341:
342:            /**
343:             * Returns the vendor responsible for creating this factory implementation.
344:             * The default implementation returns {@linkplain Citations#GEOTOOLS Geotools}.
345:             */
346:            public Citation getVendor() {
347:                return Citations.GEOTOOLS;
348:            }
349:
350:            /**
351:             * Returns the organization or party responsible for definition and maintenance of the
352:             * database. The default implementation returns a citation with title "All".
353:             */
354:            public Citation getAuthority() {
355:                return ALL;
356:            }
357:
358:            /**
359:             * Returns the authority names of every factories given at construction time.
360:             */
361:            public Set/*<String>*/getAuthorityNames() {
362:                final Set names = new HashSet();
363:                final Collection/*<AuthorityFactory>*/factories = getFactories();
364:                if (factories != null) {
365:                    for (final Iterator it = factories.iterator(); it.hasNext();) {
366:                        final AuthorityFactory factory = (AuthorityFactory) it
367:                                .next();
368:                        names.addAll(factory.getAuthority().getIdentifiers());
369:                    }
370:                }
371:                return names;
372:            }
373:
374:            /**
375:             * Returns a description of the underlying backing store, or {@code null} if unknow.
376:             *
377:             * @throws FactoryException if a failure occured while fetching the engine description.
378:             */
379:            public String getBackingStoreDescription() throws FactoryException {
380:                // We have no authority code, so we can't pick a particular factory.
381:                return null;
382:            }
383:
384:            /**
385:             * Returns the direct dependencies. Current implementation returns the internal structure
386:             * because we know that this package will not modifies it. But if the method become public,
387:             * we will need to returns a unmodifiable view.
388:             */
389:            //@Override
390:            Collection/*<?>*/dependencies() {
391:                return getFactories();
392:            }
393:
394:            /**
395:             * Returns {@code true} if the specified factory should be excluded from the search.
396:             * We exclude adapters around {@link AllAuthoritiesFactory}. This code actually aims
397:             * to exclude {@link URN_AuthorityFactory} and similar adapters around all factories,
398:             * since it leads to duplicated search and innacurate identifier to be returned by
399:             * {@link #findIdentifier}.
400:             */
401:            private static boolean exclude(final AuthorityFactory factory) {
402:                if (ManyAuthoritiesFactory.class.isInstance(factory)) {
403:                    return true;
404:                }
405:                if (factory instanceof  AuthorityFactoryAdapter) {
406:                    final AuthorityFactoryAdapter adapter = (AuthorityFactoryAdapter) factory;
407:                    return exclude(adapter.crsFactory)
408:                            || exclude(adapter.csFactory)
409:                            || exclude(adapter.datumFactory)
410:                            || exclude(adapter.operationFactory);
411:                }
412:                return false;
413:            }
414:
415:            /**
416:             * Same as {@link #fromFactoryRegistry(String, Class)}, but returns every factories
417:             * that fit the given type. The factories are added to the specified set.
418:             */
419:            final void fromFactoryRegistry(final String authority,
420:                    final Class/*<? extends AuthorityFactory>*/type,
421:                    final Set/*<AuthorityFactory>*/addTo) {
422:                for (int i = 0; i < OBJECT_TYPES.length; i++) {
423:                    if (OBJECT_TYPES[i].isAssignableFrom(type)) {
424:                        final AuthorityFactory factory;
425:                        try {
426:                            factory = fromFactoryRegistry(authority,
427:                                    FACTORY_TYPES[i]);
428:                        } catch (FactoryRegistryException e) {
429:                            // No factory for the given authority. It may be normal.
430:                            continue;
431:                        }
432:                        if (!exclude(factory)) {
433:                            addTo.add(factory);
434:                        }
435:                    }
436:                }
437:            }
438:
439:            /**
440:             * Returns a factory for the specified authority, or {@code null} if none.
441:             * To be overriden by {@link AllAuthoritiesFactory} in order to search among
442:             * factories registered on a system-wide basis.
443:             *
444:             * @param  authority The authority to query.
445:             * @param  type The interface to be implemented.
446:             * @return The factory.
447:             * @throws FactoryRegistryException if there is no factory registered for the supplied
448:             *         authority and hints.
449:             */
450:            AuthorityFactory fromFactoryRegistry(final String authority,
451:                    final Class/*<? extends AuthorityFactory>*/type)
452:                    throws FactoryRegistryException {
453:                return null;
454:            }
455:
456:            /**
457:             * Searchs for a factory of the given type. This method first search in user-supplied
458:             * factories. If no user factory is found, then this method request for a factory using
459:             * {@link ReferencingFactoryFinder}. The authority name is inferred from the specified code.
460:             *
461:             * @param  type The interface to be implemented.
462:             * @param  code The code of the object to create.
463:             * @return The factory.
464:             * @throws NoSuchAuthorityCodeException if no suitable factory were found.
465:             */
466:            //@Override
467:            final AuthorityFactory getAuthorityFactory(
468:                    final Class/*<T extends AuthorityFactory>*/type,
469:                    final String code) throws NoSuchAuthorityCodeException {
470:                ensureNonNull("code", code);
471:                String authority = null;
472:                FactoryRegistryException cause = null;
473:                final Collection/*<AuthorityFactory>*/factories = getFactories();
474:                final char separator = getSeparator(code);
475:                for (int split = code.lastIndexOf(separator); split >= 0; split = code
476:                        .lastIndexOf(separator, split - 1)) {
477:                    if (!canSeparateAt(code, split)) {
478:                        continue;
479:                    }
480:                    /*
481:                     * Try all possible authority names, begining with the most specific ones.
482:                     * For example if the code is "urn:ogc:def:crs:EPSG:6.8:4326", then we will
483:                     * try "urn:ogc:def:crs:EPSG:6.8" first, "urn:ogc:def:crs:EPSG" next, etc.
484:                     * until a suitable factory is found (searching into user-supplied factories
485:                     * first).
486:                     */
487:                    authority = code.substring(0, split).trim();
488:                    if (factories != null) {
489:                        for (final Iterator it = factories.iterator(); it
490:                                .hasNext();) {
491:                            final AuthorityFactory factory = (AuthorityFactory) it
492:                                    .next();
493:                            if (type.isAssignableFrom(factory.getClass())) {
494:                                if (Citations.identifierMatches(factory
495:                                        .getAuthority(), authority)) {
496:                                    return factory;
497:                                }
498:                            }
499:                        }
500:                    }
501:                    /*
502:                     * No suitable user-supplied factory. Now query FactoryFinder.
503:                     */
504:                    final AuthorityFactory factory;
505:                    try {
506:                        factory = fromFactoryRegistry(authority, type);
507:                    } catch (FactoryRegistryException exception) {
508:                        cause = exception;
509:                        continue;
510:                    }
511:                    if (factory != null) {
512:                        return /*type.cast*/(factory);
513:                        // TODO: uncomment when we will be allowed to compile for J2SE 1.5.
514:                    }
515:                }
516:                /*
517:                 * No factory found. Creates an error message from the most global authority name
518:                 * (for example "urn" if the code was "urn:ogc:def:crs:EPSG:6.8:4326") and the
519:                 * corresponding cause. Both the authority and cause may be null if the code didn't
520:                 * had any authority part.
521:                 */
522:                throw noSuchAuthority(code, authority, cause);
523:            }
524:
525:            /**
526:             * Formats the exception to be throw when the user asked for a code from an unknown authority.
527:             *
528:             * @param  code      The code with an unknown authority.
529:             * @param  authority The authority, or {@code null} if none.
530:             * @param  cause     The cause for the exception to be formatted, or {@code null} if none.
531:             * @return The formatted exception to be throw.
532:             */
533:            private NoSuchAuthorityCodeException noSuchAuthority(
534:                    final String code, String authority,
535:                    final FactoryRegistryException cause) {
536:                final String message;
537:                if (authority == null) {
538:                    authority = Vocabulary.format(VocabularyKeys.UNKNOW);
539:                    message = Errors.format(ErrorKeys.MISSING_AUTHORITY_$1,
540:                            code);
541:                } else {
542:                    message = Errors.format(ErrorKeys.UNKNOW_AUTHORITY_$1,
543:                            authority);
544:                }
545:                final NoSuchAuthorityCodeException exception;
546:                exception = new NoSuchAuthorityCodeException(message,
547:                        authority, code);
548:                exception.initCause(cause);
549:                return exception;
550:            }
551:
552:            /**
553:             * Returns a generic object authority factory for the specified {@code "AUTHORITY:NUMBER"}
554:             * code.
555:             *
556:             * @param  code The code to parse.
557:             * @return The authority factory.
558:             * @throws NoSuchAuthorityCodeException if no authority name has been found.
559:             */
560:            //@Override
561:            protected AuthorityFactory getAuthorityFactory(final String code)
562:                    throws NoSuchAuthorityCodeException {
563:                return getAuthorityFactory(AuthorityFactory.class, code);
564:            }
565:
566:            /**
567:             * Returns the datum authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
568:             *
569:             * @param  code The code to parse.
570:             * @return The authority factory.
571:             * @throws NoSuchAuthorityCodeException if no authority name has been found.
572:             */
573:            //@Override
574:            protected DatumAuthorityFactory getDatumAuthorityFactory(
575:                    final String code) throws NoSuchAuthorityCodeException {
576:                return (DatumAuthorityFactory) // TODO: remove cast with J2SE 1.5.
577:                getAuthorityFactory(DatumAuthorityFactory.class, code);
578:            }
579:
580:            /**
581:             * Returns the CS authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
582:             *
583:             * @param  code The code to parse.
584:             * @return The authority factory.
585:             * @throws NoSuchAuthorityCodeException if no authority name has been found.
586:             */
587:            //@Override
588:            protected CSAuthorityFactory getCSAuthorityFactory(final String code)
589:                    throws NoSuchAuthorityCodeException {
590:                return (CSAuthorityFactory) // TODO: remove cast with J2SE 1.5.
591:                getAuthorityFactory(CSAuthorityFactory.class, code);
592:            }
593:
594:            /**
595:             * Returns the CRS authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
596:             *
597:             * @param  code The code to parse.
598:             * @return The authority factory.
599:             * @throws NoSuchAuthorityCodeException if no authority name has been found.
600:             */
601:            //@Override
602:            protected CRSAuthorityFactory getCRSAuthorityFactory(
603:                    final String code) throws NoSuchAuthorityCodeException {
604:                return (CRSAuthorityFactory) // TODO: remove cast with J2SE 1.5.
605:                getAuthorityFactory(CRSAuthorityFactory.class, code);
606:            }
607:
608:            /**
609:             * Returns the operation authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
610:             *
611:             * @param  code The code to parse.
612:             * @return The authority factory.
613:             * @throws NoSuchAuthorityCodeException if no authority name has been found.
614:             */
615:            //@Override
616:            protected CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(
617:                    final String code) throws NoSuchAuthorityCodeException {
618:                return (CoordinateOperationAuthorityFactory) // TODO: remove cast with J2SE 1.5.
619:                getAuthorityFactory(CoordinateOperationAuthorityFactory.class,
620:                        code);
621:            }
622:
623:            /**
624:             * Returns the set of authority codes of the given type.
625:             *
626:             * @param  type The spatial reference objects type (may be {@code IdentifiedObject.class}).
627:             * @return The set of authority codes for spatial reference objects of the given type.
628:             *         If this factory doesn't contains any object of the given type, then this method
629:             *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
630:             * @throws FactoryException if access to the underlying database failed.
631:             */
632:            public Set/*<String>*/getAuthorityCodes(final Class type)
633:                    throws FactoryException {
634:                if (Boolean.TRUE.equals(inProgress.get())) {
635:                    /*
636:                     * 'getAuthorityCodes' is invoking itself (indirectly). Returns an empty set in order
637:                     * to avoid infinite recursivity. Note that the end result (the output of the caller)
638:                     * will usually not be empty.
639:                     */
640:                    return Collections.EMPTY_SET;
641:                }
642:                final Set/*<String>*/codes = new LinkedHashSet();
643:                final Set/*<AuthorityFactory>*/done = new HashSet();
644:                done.add(this ); // Safety for avoiding recursive calls.
645:                inProgress.set(Boolean.TRUE);
646:                try {
647:                    for (final Iterator it = getAuthorityNames().iterator(); it
648:                            .hasNext();) {
649:                        final String authority = ((String) it.next()).trim();
650:                        final char separator = getSeparator(authority);
651:                        /*
652:                         * Prepares a buffer with the "AUTHORITY:" part in "AUTHORITY:NUMBER".
653:                         * We will reuse this buffer in order to prefix the authority name in
654:                         * front of every codes.
655:                         */
656:                        final StringBuffer code = new StringBuffer(authority);
657:                        int codeBase = code.length();
658:                        if (codeBase != 0
659:                                && code.charAt(codeBase - 1) != separator) {
660:                            code.append(separator);
661:                            codeBase = code.length();
662:                        }
663:                        code.append("all");
664:                        final String dummyCode = code.toString();
665:                        /*
666:                         * Now scan over all factories. We will process a factory only if this particular
667:                         * factory has not already been done in a previous iteration (some implementation
668:                         * apply to more than one factory).
669:                         */
670:                        scanForType: for (int i = 0; i < FACTORY_TYPES.length; i++) {
671:                            if (!OBJECT_TYPES[i].isAssignableFrom(type)) {
672:                                continue;
673:                            }
674:                            final Class factoryType = FACTORY_TYPES[i];
675:                            final AuthorityFactory factory;
676:                            try {
677:                                factory = getAuthorityFactory(factoryType,
678:                                        dummyCode);
679:                            } catch (NoSuchAuthorityCodeException e) {
680:                                continue;
681:                            }
682:                            if (!done.add(factory)) {
683:                                continue;
684:                            }
685:                            AuthorityFactory wrapped = factory;
686:                            while (wrapped instanceof  AuthorityFactoryAdapter) {
687:                                final AuthorityFactoryAdapter adapter = (AuthorityFactoryAdapter) wrapped;
688:                                try {
689:                                    wrapped = adapter.getAuthorityFactory(
690:                                            factoryType, dummyCode);
691:                                } catch (NoSuchAuthorityCodeException exception) {
692:                                    /*
693:                                     * The factory doesn't understand our dummy code. It happen with
694:                                     * URN_AuthorityFactory, which expect the type ("CRS", etc.) in the URN.
695:                                     */
696:                                    continue scanForType;
697:                                }
698:                                if (!done.add(wrapped)) {
699:                                    /*
700:                                     * Avoid the factories that are wrapper around an other factory already
701:                                     * done. If we don't do that, we will duplicate the whole set of EPSG
702:                                     * identifiers (more than 3000 codes) for OrderedAuthorityFactory,
703:                                     * HTTP_AuthorityFactory, URN_AuthorityFactory, etc.
704:                                     */
705:                                    continue scanForType;
706:                                }
707:                            }
708:                            for (final Iterator it2 = factory
709:                                    .getAuthorityCodes(type).iterator(); it2
710:                                    .hasNext();) {
711:                                String candidate = ((String) it2.next()).trim();
712:                                if (candidate.length() < codeBase
713:                                        || Character.isLetterOrDigit(candidate
714:                                                .charAt(codeBase - 1))
715:                                        || !authority
716:                                                .equalsIgnoreCase(candidate
717:                                                        .substring(0,
718:                                                                codeBase - 1))) {
719:                                    // Prepend the authority code if it was not already presents.
720:                                    code.setLength(codeBase);
721:                                    code.append(candidate);
722:                                    candidate = code.toString();
723:                                }
724:                                codes.add(candidate);
725:                            }
726:                        }
727:                    }
728:                } finally {
729:                    inProgress.set(Boolean.FALSE);
730:                    // TODO: use inProgress.remove() when we will be allowed to compile for J2SE 1.5.
731:                }
732:                return codes;
733:            }
734:
735:            /**
736:             * Gets a description of the object corresponding to a code.
737:             *
738:             * @param  code Value allocated by authority.
739:             * @return A description of the object, or {@code null} if the object
740:             *         corresponding to the specified {@code code} has no description.
741:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
742:             * @throws FactoryException if the query failed for some other reason.
743:             */
744:            public InternationalString getDescriptionText(final String code)
745:                    throws FactoryException {
746:                final Set/*<AuthorityFactory>*/done = new HashSet();
747:                done.add(this ); // Safety for avoiding recursive calls.
748:                FactoryException failure = null;
749:                for (int type = 0; type < FACTORY_TYPES.length; type++) {
750:                    /*
751:                     * Try all factories, starting with the CRS factory because it is the only one most
752:                     * users care about. If the CRS factory doesn't know about the specified object, then
753:                     * we will try the other factories (datum, CS, ...) before to rethrow the exception.
754:                     */
755:                    final AuthorityFactory factory;
756:                    try {
757:                        factory = getAuthorityFactory(FACTORY_TYPES[type], code);
758:                    } catch (NoSuchAuthorityCodeException exception) {
759:                        if (failure == null) {
760:                            failure = exception;
761:                        }
762:                        continue;
763:                    }
764:                    if (done.add(factory))
765:                        try {
766:                            return factory.getDescriptionText(code);
767:                        } catch (FactoryException exception) {
768:                            /*
769:                             * Failed to creates an object using the current factory.  We will retain only the
770:                             * first exception and discart all other ones, except if the first exceptions were
771:                             * due to unknown authority (we will prefer exception due to unknown code instead).
772:                             * The first exception is usually thrown by the CRS factory, which is the only
773:                             * factory most users care about.
774:                             */
775:                            if (failure == null
776:                                    || failure.getCause() instanceof  FactoryRegistryException) {
777:                                failure = exception;
778:                            }
779:                        }
780:                }
781:                if (failure == null) {
782:                    failure = noSuchAuthorityCode(IdentifiedObject.class, code);
783:                }
784:                throw failure;
785:            }
786:
787:            /**
788:             * Returns an arbitrary object from a code.
789:             *
790:             * @see #createCoordinateReferenceSystem
791:             * @see #createDatum
792:             * @see #createEllipsoid
793:             * @see #createUnit
794:             */
795:            public IdentifiedObject createObject(final String code)
796:                    throws FactoryException {
797:                final Set/*<AuthorityFactory>*/done = new HashSet();
798:                done.add(this ); // Safety for avoiding recursive calls.
799:                FactoryException failure = null;
800:                for (int type = 0; type < FACTORY_TYPES.length; type++) {
801:                    /*
802:                     * Try all factories, starting with the CRS factory because it is the only one most
803:                     * users care about. If the CRS factory doesn't know about the specified object, then
804:                     * we will try the other factories (datum, CS, ...) before to rethrow the exception.
805:                     */
806:                    final AuthorityFactory factory;
807:                    try {
808:                        factory = getAuthorityFactory(FACTORY_TYPES[type], code);
809:                    } catch (NoSuchAuthorityCodeException exception) {
810:                        if (failure == null) {
811:                            failure = exception;
812:                        }
813:                        continue;
814:                    }
815:                    if (done.add(factory))
816:                        try {
817:                            return factory.createObject(code);
818:                        } catch (FactoryException exception) {
819:                            /*
820:                             * Failed to creates an object using the current factory.  We will retain only the
821:                             * first exception and discart all other ones, except if the first exceptions were
822:                             * due to unknown authority (we will prefer exception due to unknown code instead).
823:                             * The first exception is usually thrown by the CRS factory, which is the only
824:                             * factory most users care about.
825:                             */
826:                            if (failure == null
827:                                    || failure.getCause() instanceof  FactoryRegistryException) {
828:                                failure = exception;
829:                            }
830:                        }
831:                }
832:                if (failure == null) {
833:                    failure = noSuchAuthorityCode(IdentifiedObject.class, code);
834:                }
835:                throw failure;
836:            }
837:
838:            /**
839:             * Returns a finder which can be used for looking up unidentified objects.
840:             * The default implementation delegates the lookups to the underlying factories.
841:             */
842:            //@Override
843:            public IdentifiedObjectFinder getIdentifiedObjectFinder(
844:                    final Class/*<? extends IdentifiedObject>*/type)
845:                    throws FactoryException {
846:                return new Finder(this , type);
847:            }
848:
849:            /**
850:             * A {@link IdentifiedObjectFinder} which tests every factories.
851:             */
852:            static class Finder extends IdentifiedObjectFinder {
853:                /**
854:                 * Creates a finder for the specified type.
855:                 */
856:                protected Finder(final ManyAuthoritiesFactory factory,
857:                        final Class/*<? extends IdentifiedObject>*/type) {
858:                    super (factory, type);
859:                }
860:
861:                /**
862:                 * Returns the user-supplied factories.
863:                 */
864:                final Collection getFactories() {
865:                    return ((ManyAuthoritiesFactory) proxy
866:                            .getAuthorityFactory()).getFactories();
867:                }
868:
869:                /**
870:                 * Returns the next finder in the specified set of factories, or {@code null} if none.
871:                 */
872:                final IdentifiedObjectFinder next(
873:                        final Iterator/*<AuthorityFactory>*/it)
874:                        throws FactoryException {
875:                    while (it.hasNext()) {
876:                        final AuthorityFactory factory = (AuthorityFactory) it
877:                                .next();
878:                        if (exclude(factory)) {
879:                            continue;
880:                        }
881:                        if (factory instanceof  AbstractAuthorityFactory) {
882:                            final IdentifiedObjectFinder finder = ((AbstractAuthorityFactory) factory)
883:                                    .getIdentifiedObjectFinder(proxy.getType());
884:                            if (finder != null) {
885:                                finder.setFullScanAllowed(isFullScanAllowed());
886:                                return finder;
887:                            }
888:                        }
889:                    }
890:                    return null;
891:                }
892:
893:                /**
894:                 * Lookups for the specified object.
895:                 */
896:                //@Override
897:                public IdentifiedObject find(final IdentifiedObject object)
898:                        throws FactoryException {
899:                    /*
900:                     * Try to create from the identifier before to scan over every factories,
901:                     * because the identifier may contains the authority name, in which case
902:                     * we can pickup directly the right factory instead of trying them all.
903:                     */
904:                    IdentifiedObject candidate = createFromIdentifiers(object);
905:                    if (candidate != null) {
906:                        return candidate;
907:                    }
908:                    final Collection factories = getFactories();
909:                    if (factories != null) {
910:                        IdentifiedObjectFinder finder;
911:                        final Iterator it = factories.iterator();
912:                        while ((finder = next(it)) != null) {
913:                            candidate = finder.find(object);
914:                            if (candidate != null) {
915:                                break;
916:                            }
917:                        }
918:                    }
919:                    return candidate;
920:                }
921:
922:                /**
923:                 * Returns the identifier of the specified object, or {@code null} if none.
924:                 */
925:                //@Override
926:                public String findIdentifier(final IdentifiedObject object)
927:                        throws FactoryException {
928:                    /*
929:                     * Try to create from the identifier for the same reason than find(IdentifiedObject).
930:                     * Note that we returns directly the primary name; we don't try to locate a name for
931:                     * a given authority since the "All" authority do not really exists.
932:                     */
933:                    IdentifiedObject candidate = createFromIdentifiers(object);
934:                    if (candidate != null) {
935:                        return candidate.getName().toString();
936:                    }
937:                    final Collection factories = getFactories();
938:                    if (factories != null) {
939:                        IdentifiedObjectFinder finder;
940:                        final Iterator it = factories.iterator();
941:                        while ((finder = next(it)) != null) {
942:                            final String id = finder.findIdentifier(object);
943:                            if (id != null) {
944:                                return id;
945:                            }
946:                        }
947:                    }
948:                    return null;
949:                }
950:            }
951:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.