Source Code Cross Referenced for AuthorityFactoryAdapter.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) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2005-2006, GeoTools Project Managment Committee (PMC)
0005:         *    (C) 2005, Institut de Recherche pour le Développement
0006:         *   
0007:         *    This library is free software; you can redistribute it and/or
0008:         *    modify it under the terms of the GNU Lesser General Public
0009:         *    License as published by the Free Software Foundation;
0010:         *    version 2.1 of the License.
0011:         *
0012:         *    This library is distributed in the hope that it will be useful,
0013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015:         *    Lesser General Public License for more details.
0016:         */
0017:        package org.geotools.referencing.factory;
0018:
0019:        // J2SE dependencies
0020:        import java.util.Set;
0021:        import java.util.Map;
0022:        import java.util.List;
0023:        import java.util.ArrayList;
0024:        import java.util.Collection;
0025:        import java.util.Collections;
0026:        import java.util.logging.Level;
0027:        import java.util.logging.LogRecord;
0028:        import javax.units.Unit;
0029:
0030:        // OpenGIS dependencies
0031:        import org.opengis.metadata.extent.Extent;
0032:        import org.opengis.metadata.citation.Citation;
0033:        import org.opengis.referencing.NoSuchAuthorityCodeException;
0034:        import org.opengis.util.InternationalString;
0035:        import org.opengis.parameter.ParameterDescriptor;
0036:        import org.opengis.referencing.IdentifiedObject;
0037:        import org.opengis.referencing.AuthorityFactory;
0038:        import org.opengis.referencing.FactoryException;
0039:        import org.opengis.referencing.cs.*;
0040:        import org.opengis.referencing.crs.*;
0041:        import org.opengis.referencing.datum.*;
0042:        import org.opengis.referencing.operation.*;
0043:
0044:        // Geotools dependencies
0045:        import org.geotools.factory.Hints;
0046:        import org.geotools.factory.Factory;
0047:        import org.geotools.factory.AbstractFactory;
0048:        import org.geotools.factory.OptionalFactory;
0049:        import org.geotools.factory.FactoryRegistryException;
0050:        import org.geotools.metadata.iso.citation.Citations;
0051:        import org.geotools.referencing.CRS;
0052:        import org.geotools.referencing.ReferencingFactoryFinder;
0053:        import org.geotools.resources.i18n.Logging;
0054:        import org.geotools.resources.i18n.LoggingKeys;
0055:        import org.geotools.resources.i18n.ErrorKeys;
0056:        import org.geotools.resources.i18n.Errors;
0057:        import org.geotools.resources.Utilities;
0058:
0059:        /**
0060:         * An authority factory which delegates {@linkplain CoordinateReferenceSystem CRS},
0061:         * {@linkplain CoordinateSystem CS} or {@linkplain Datum datum} objects creation to
0062:         * some other factory implementations.
0063:         * <p>
0064:         * All constructors are protected because this class must be subclassed in order to determine
0065:         * which of the {@link DatumAuthorityFactory}, {@link CSAuthorityFactory} and
0066:         * {@link CRSAuthorityFactory} interfaces to implement.
0067:         *
0068:         * @since 2.2
0069:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AuthorityFactoryAdapter.java $
0070:         * @version $Id: AuthorityFactoryAdapter.java 26212 2007-07-12 02:34:18Z jgarnett $
0071:         * @author Martin Desruisseaux
0072:         */
0073:        public class AuthorityFactoryAdapter extends AbstractAuthorityFactory
0074:                implements  OptionalFactory {
0075:            /**
0076:             * List of hint keys related to authority factories.
0077:             */
0078:            private static final Hints.Key[] TYPES = new Hints.Key[] {
0079:                    Hints.CRS_AUTHORITY_FACTORY, Hints.CS_AUTHORITY_FACTORY,
0080:                    Hints.DATUM_AUTHORITY_FACTORY,
0081:                    Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY };
0082:
0083:            /**
0084:             * The underlying {@linkplain Datum datum} authority factory,
0085:             * or {@code null} if none.
0086:             *
0087:             * @deprecated Use {@link #getDatumAuthorityFactory} instead.
0088:             *             This field will become private in Geotools 2.5.
0089:             */
0090:            protected final DatumAuthorityFactory datumFactory;
0091:
0092:            /**
0093:             * The underlying {@linkplain CoordinateSystem coordinate system} authority factory,
0094:             * or {@code null} if none.
0095:             *
0096:             * @deprecated Use {@link #getCSAuthorityFactory} instead.
0097:             *             This field will become private in Geotools 2.5.
0098:             */
0099:            protected final CSAuthorityFactory csFactory;
0100:
0101:            /**
0102:             * The underlying {@linkplain CoordinateReferenceSystem coordinate reference system}
0103:             * authority factory, or {@code null} if none.
0104:             *
0105:             * @deprecated Use {@link #getCRSAuthorityFactory} instead.
0106:             *             This field will become private in Geotools 2.5.
0107:             */
0108:            protected final CRSAuthorityFactory crsFactory;
0109:
0110:            /**
0111:             * The underlying {@linkplain CoordinateOperation coordinate operation} authority factory,
0112:             * or {@code null} if none.
0113:             *
0114:             * @deprecated Use {@link #getCoordinateOperationAuthorityFactory} instead.
0115:             *             This field will become private in Geotools 2.5.
0116:             */
0117:            protected final CoordinateOperationAuthorityFactory operationFactory;
0118:
0119:            /**
0120:             * A set of low-level factories to be used if none were found in {@link #datumFactory},
0121:             * {@link #csFactory}, {@link #crsFactory} or {@link #operationFactory}. Will be created
0122:             * only when first needed.
0123:             *
0124:             * @see #getFactoryContainer
0125:             */
0126:            private transient ReferencingFactoryContainer factories;
0127:
0128:            /**
0129:             * Creates a wrapper around no factory. This constructor should never be used except by
0130:             * subclasses overriding the <code>get</code><var>Foo</var><code>AuthorityFactory</code>
0131:             * methods.
0132:             *
0133:             * @param priority The priority for this factory, as a number between
0134:             *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
0135:             *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
0136:             */
0137:            AuthorityFactoryAdapter(final int priority) {
0138:                super (priority);
0139:                datumFactory = null;
0140:                csFactory = null;
0141:                crsFactory = null;
0142:                operationFactory = null;
0143:            }
0144:
0145:            /**
0146:             * Creates a wrapper around the specified factory. The {@link #priority priority} field
0147:             * will be set to the same value than the specified factory. Subclasses should override
0148:             * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
0149:             * priority for this instance.
0150:             *
0151:             * @param factory The factory to wrap.
0152:             */
0153:            protected AuthorityFactoryAdapter(final AuthorityFactory factory) {
0154:                this (factory, null);
0155:            }
0156:
0157:            /**
0158:             * For {@link FallbackAuthorityFactory} constructor only.
0159:             */
0160:            AuthorityFactoryAdapter(final AuthorityFactory factory,
0161:                    final AuthorityFactory fallback) {
0162:                this (
0163:                        (factory instanceof  CRSAuthorityFactory) ? (CRSAuthorityFactory) factory
0164:                                : (fallback instanceof  CRSAuthorityFactory) ? (CRSAuthorityFactory) fallback
0165:                                        : null,
0166:                        (factory instanceof  CSAuthorityFactory) ? (CSAuthorityFactory) factory
0167:                                : (fallback instanceof  CSAuthorityFactory) ? (CSAuthorityFactory) fallback
0168:                                        : null,
0169:                        (factory instanceof  DatumAuthorityFactory) ? (DatumAuthorityFactory) factory
0170:                                : (fallback instanceof  DatumAuthorityFactory) ? (DatumAuthorityFactory) fallback
0171:                                        : null,
0172:                        (factory instanceof  CoordinateOperationAuthorityFactory) ? (CoordinateOperationAuthorityFactory) factory
0173:                                : (fallback instanceof  CoordinateOperationAuthorityFactory) ? (CoordinateOperationAuthorityFactory) fallback
0174:                                        : null);
0175:            }
0176:
0177:            /**
0178:             * Creates a wrapper around the specified factories. The {@link #priority priority} field will
0179:             * be set to the highest priority found in the specified factories. Subclasses should override
0180:             * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
0181:             * priority for this instance.
0182:             *
0183:             * @param crsFactory   The {@linkplain CoordinateReferenceSystem coordinate reference system}
0184:             *                     authority factory, or {@code null}.
0185:             * @param csFactory    The {@linkplain CoordinateSystem coordinate system} authority factory,
0186:             *                     or {@code null}.
0187:             * @param datumFactory The {@linkplain Datum datum} authority factory, or {@code null}.
0188:             * @param opFactory    The {@linkplain CoordinateOperation coordinate operation} authority
0189:             *                     factory, or {@code null}.
0190:             */
0191:            protected AuthorityFactoryAdapter(
0192:                    final CRSAuthorityFactory crsFactory,
0193:                    final CSAuthorityFactory csFactory,
0194:                    final DatumAuthorityFactory datumFactory,
0195:                    final CoordinateOperationAuthorityFactory opFactory) {
0196:                super (Math.max(getPriority(datumFactory), Math.max(
0197:                        getPriority(csFactory), Math
0198:                                .max(getPriority(crsFactory),
0199:                                        getPriority(opFactory)))));
0200:
0201:                if (this  instanceof  CRSAuthorityFactory) {
0202:                    ensureNonNull("crsFactory", crsFactory);
0203:                }
0204:                if (this  instanceof  CSAuthorityFactory) {
0205:                    ensureNonNull("csFactory", csFactory);
0206:                }
0207:                if (this  instanceof  DatumAuthorityFactory) {
0208:                    ensureNonNull("datumFactory", datumFactory);
0209:                }
0210:                if (this  instanceof  CoordinateOperationAuthorityFactory) {
0211:                    ensureNonNull("opFactory", opFactory);
0212:                }
0213:                store(Hints.DATUM_AUTHORITY_FACTORY,
0214:                        this .datumFactory = datumFactory);
0215:                store(Hints.CS_AUTHORITY_FACTORY, this .csFactory = csFactory);
0216:                store(Hints.CRS_AUTHORITY_FACTORY, this .crsFactory = crsFactory);
0217:                store(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
0218:                        this .operationFactory = opFactory);
0219:            }
0220:
0221:            /**
0222:             * Returns the priority of the specified factory, or {@link #NORMAL_PRIORITY} if unknown.
0223:             */
0224:            private static int getPriority(final AuthorityFactory factory) {
0225:                return (factory instanceof  AbstractFactory) ? ((AbstractFactory) factory)
0226:                        .getPriority()
0227:                        : NORMAL_PRIORITY;
0228:            }
0229:
0230:            /**
0231:             * Adds the specified factory to the set of hints, if non null.
0232:             */
0233:            private void store(final Hints.Key key,
0234:                    final AuthorityFactory factory) {
0235:                if (factory != null) {
0236:                    if (hints.put(key, factory) != null) {
0237:                        // Should never happen since 'hints' should be initially empty.
0238:                        throw new AssertionError(key);
0239:                    }
0240:                }
0241:            }
0242:
0243:            /**
0244:             * Creates a wrappers around the default factories for the specified authority.
0245:             * The factories are fetched using {@link ReferencingFactoryFinder}.
0246:             *
0247:             * @param authority The authority to wraps (example: {@code "EPSG"}). If {@code null},
0248:             *                  then all authority factories must be explicitly specified in the
0249:             *                  set of hints.
0250:             * @param userHints An optional set of hints, or {@code null} if none.
0251:             * @throws FactoryRegistryException if at least one factory can not be obtained.
0252:             *
0253:             * @since 2.4
0254:             */
0255:            protected AuthorityFactoryAdapter(final String authority,
0256:                    final Hints userHints) throws FactoryRegistryException {
0257:                this (
0258:                        ReferencingFactoryFinder.getCRSAuthorityFactory(
0259:                                authority, trim(userHints,
0260:                                        Hints.CRS_AUTHORITY_FACTORY)),
0261:                        ReferencingFactoryFinder.getCSAuthorityFactory(
0262:                                authority, trim(userHints,
0263:                                        Hints.CS_AUTHORITY_FACTORY)),
0264:                        ReferencingFactoryFinder.getDatumAuthorityFactory(
0265:                                authority, trim(userHints,
0266:                                        Hints.DATUM_AUTHORITY_FACTORY)),
0267:                        ReferencingFactoryFinder
0268:                                .getCoordinateOperationAuthorityFactory(
0269:                                        authority,
0270:                                        trim(
0271:                                                userHints,
0272:                                                Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY)));
0273:            }
0274:
0275:            /**
0276:             * Removes every {@code *_AUTHORITY_FACTORY} hints except the specified one. The removal,
0277:             * if needed, is performed in a copy of the supplied hints in order to keep user's map
0278:             * unmodified.
0279:             * <p>
0280:             * This removal is performed because {@code *_AUTHORITY_FACTORY} hints are typically supplied
0281:             * to the above constructor in order to initialize the {@link #crsFactory}, {@link #csFactory},
0282:             * <cite>etc.</cite> fields. But because the same map of hints is used for every call to {@code
0283:             * ReferencingFactoryFinder.getFooAuthorityFactory(...)}, if we don't perform this removal, then
0284:             * the {@code CRS_AUTHORITY_FACTORY} hint is taken in account for fetching other factories like
0285:             * {@link CSAuthorityFactory}. We may think that it is not a problem since CS authority factory
0286:             * should not care about {@code CRS_AUTHORITY_FACTORY} hint. But... our EPSG authority factory
0287:             * implements both {@link CRSAuthorityFactory} and {@link CSAuthorityFactory} interfaces, so
0288:             * our {@link CSAuthorityFactory} implementation do have CRS-related hints.
0289:             * <p>
0290:             * Conclusion: if we do not remove those hints, it typically leads to failure to find
0291:             * a CS authority factory using this specific CRS authority factory. We may argue that
0292:             * this is a Geotools design problem. Maybe... this is not a trivial issue. So we are
0293:             * better to not document that in public API for now.
0294:             *
0295:             * @param  userHints The user hints to trim. This map will never be modified.
0296:             * @param  keep  The hint to <strong>not</strong> remove.
0297:             * @return A copy of {@code userHints} without the authority hints, or {@code userHints}
0298:             *         if no change were required.
0299:             */
0300:            private static Hints trim(final Hints userHints,
0301:                    final Hints.Key keep) {
0302:                Hints reduced = userHints;
0303:                if (userHints != null) {
0304:                    for (int i = 0; i < TYPES.length; i++) {
0305:                        final Hints.Key key = TYPES[i];
0306:                        if (!keep.equals(key)) {
0307:                            if (reduced == userHints) {
0308:                                if (!userHints.containsKey(key)) {
0309:                                    continue;
0310:                                }
0311:                                // Copies the map only if we need to modify it.
0312:                                reduced = new Hints(userHints);
0313:                            }
0314:                            reduced.remove(key);
0315:                        }
0316:                    }
0317:                }
0318:                return reduced;
0319:            }
0320:
0321:            /**
0322:             * Returns the {@linkplain #hints hints} extented will all hints specified in dependencies.
0323:             */
0324:            private Hints hints() {
0325:                final Hints extended = new Hints(hints);
0326:                addAll(operationFactory, extended);
0327:                addAll(datumFactory, extended);
0328:                addAll(csFactory, extended);
0329:                addAll(crsFactory, extended);
0330:                extended.putAll(hints); // Gives precedence to the hints from this class.
0331:                return extended;
0332:            }
0333:
0334:            /**
0335:             * Adds all hints from the specified factory into the specified set of hints.
0336:             */
0337:            private static void addAll(final AuthorityFactory factory,
0338:                    final Hints hints) {
0339:                if (factory instanceof  Factory) {
0340:                    hints.putAll(((Factory) factory).getImplementationHints());
0341:                }
0342:            }
0343:
0344:            /**
0345:             * Returns the direct dependencies. The returned list contains the backing store specified
0346:             * at construction time, or the exception if the backing store can't be obtained.
0347:             */
0348:            //@Override
0349:            Collection/*<?>*/dependencies() {
0350:                final List/*<?>*/dep = new ArrayList(4);
0351:                Object factory;
0352:                try {
0353:                    factory = getAuthorityFactory(null);
0354:                } catch (FactoryException e) {
0355:                    factory = e;
0356:                }
0357:                dep.add(factory);
0358:                return dep;
0359:            }
0360:
0361:            /**
0362:             * If this factory is a wrapper for the specified factory that do not add any additional
0363:             * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
0364:             * for {@link FallbackAuthorityFactory} internal use only and should not be public. We
0365:             * expect only a simple check, so we don't invoke the {@code getFooAuthorityFactory(...)}
0366:             * methods.
0367:             */
0368:            //@Override
0369:            boolean sameAuthorityCodes(final AuthorityFactory factory) {
0370:                if (!isCodeMethodOverriden()) {
0371:                    /*
0372:                     * Tests wrapped factories only if the 'toBackingFactoryCode(String)' method is not
0373:                     * overwritten, otherwise we can't assume that the authority codes are the same. The
0374:                     * impact on the main subclasses are usually as below:
0375:                     *
0376:                     *     URN_AuthorityFactory           - excluded
0377:                     *     HTTP_AuthorityFactory          - excluded
0378:                     *     OrderedAxisAuthorityFactory    - make the test below
0379:                     *     FallbackAuthorityFactory       - make the test below
0380:                     *
0381:                     * Note: in the particular case of FallbackAuthorityFactory, we test the
0382:                     *       primary factory only, not the fallback. This behavior matches the
0383:                     *       FallbackAuthorityFactory.create(boolean,int,Iterator) need, which
0384:                     *       will process this case in a special way.
0385:                     */
0386:                    if (sameAuthorityCodes(crsFactory, factory)
0387:                            && sameAuthorityCodes(csFactory, factory)
0388:                            && sameAuthorityCodes(datumFactory, factory)
0389:                            && sameAuthorityCodes(operationFactory, factory)) {
0390:                        return true;
0391:                    }
0392:                }
0393:                return super .sameAuthorityCodes(factory);
0394:            }
0395:
0396:            /**
0397:             * Helper methods for {@link #sameAuthorityCodes(AuthorityFactory)} and
0398:             * {@link FallbackAuthorityFactory#create(boolean,int,Iterator)} implementations. If there is no
0399:             * backing store, returns {@code true} in order to take in account only the backing stores that
0400:             * are assigned. This behavior match the need of the above-cited implementations.
0401:             */
0402:            static boolean sameAuthorityCodes(
0403:                    final AuthorityFactory backingStore,
0404:                    final AuthorityFactory factory) {
0405:                if (backingStore instanceof  AbstractAuthorityFactory) {
0406:                    if (((AbstractAuthorityFactory) backingStore)
0407:                            .sameAuthorityCodes(factory)) {
0408:                        return true;
0409:                    }
0410:                }
0411:                return (factory == backingStore) || (backingStore == null);
0412:            }
0413:
0414:            /**
0415:             * Returns {@code true} if this factory is ready for use. This default implementation
0416:             * checks the availability of CRS, CS, datum and operation authority factories specified
0417:             * at construction time.
0418:             */
0419:            public boolean isAvailable() {
0420:                return isAvailable(crsFactory) && isAvailable(csFactory)
0421:                        && isAvailable(datumFactory)
0422:                        && isAvailable(operationFactory);
0423:            }
0424:
0425:            /**
0426:             * Checks the availability of the specified factory.
0427:             */
0428:            private static boolean isAvailable(final AuthorityFactory factory) {
0429:                return !(factory instanceof  OptionalFactory)
0430:                        || ((OptionalFactory) factory).isAvailable();
0431:            }
0432:
0433:            /**
0434:             * Replaces the specified unit, if applicable.
0435:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0436:             */
0437:            Unit replace(Unit units) throws FactoryException {
0438:                return units;
0439:            }
0440:
0441:            /**
0442:             * Replaces (if needed) the specified axis by a new one.
0443:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0444:             */
0445:            CoordinateSystemAxis replace(CoordinateSystemAxis axis)
0446:                    throws FactoryException {
0447:                return axis;
0448:            }
0449:
0450:            /**
0451:             * Replaces (if needed) the specified coordinate system by a new one.
0452:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0453:             */
0454:            CoordinateSystem replace(CoordinateSystem cs)
0455:                    throws FactoryException {
0456:                return cs;
0457:            }
0458:
0459:            /**
0460:             * Replaces (if needed) the specified datum by a new one.
0461:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0462:             */
0463:            Datum replace(Datum datum) throws FactoryException {
0464:                return datum;
0465:            }
0466:
0467:            /**
0468:             * Replaces (if needed) the specified coordinate reference system.
0469:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0470:             */
0471:            CoordinateReferenceSystem replace(CoordinateReferenceSystem crs)
0472:                    throws FactoryException {
0473:                return crs;
0474:            }
0475:
0476:            /**
0477:             * Replaces (if needed) the specified coordinate operation.
0478:             * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0479:             */
0480:            CoordinateOperation replace(CoordinateOperation operation)
0481:                    throws FactoryException {
0482:                return operation;
0483:            }
0484:
0485:            /**
0486:             * Delegates the work to an appropriate {@code replace} method for the given object.
0487:             */
0488:            private IdentifiedObject replaceObject(final IdentifiedObject object)
0489:                    throws FactoryException {
0490:                if (object instanceof  CoordinateReferenceSystem) {
0491:                    return replace((CoordinateReferenceSystem) object);
0492:                }
0493:                if (object instanceof  CoordinateSystem) {
0494:                    return replace((CoordinateSystem) object);
0495:                }
0496:                if (object instanceof  CoordinateSystemAxis) {
0497:                    return replace((CoordinateSystemAxis) object);
0498:                }
0499:                if (object instanceof  Datum) {
0500:                    return replace((Datum) object);
0501:                }
0502:                if (object instanceof  CoordinateOperation) {
0503:                    return replace((CoordinateOperation) object);
0504:                }
0505:                return object;
0506:            }
0507:
0508:            /**
0509:             * Returns one of the underlying factories as an instance of the GeoTools implementation. If
0510:             * there is none of them, then returns {@code null} or throws an exception if {@code caller}
0511:             * is not null.
0512:             */
0513:            private AbstractAuthorityFactory getGeotoolsFactory(
0514:                    final String caller, final String code)
0515:                    throws FactoryException {
0516:                final AuthorityFactory candidate = getAuthorityFactory(code);
0517:                if (candidate instanceof  AbstractAuthorityFactory) {
0518:                    return (AbstractAuthorityFactory) candidate;
0519:                }
0520:                if (caller == null) {
0521:                    return null;
0522:                }
0523:                throw new FactoryException(Errors.format(
0524:                        ErrorKeys.GEOTOOLS_EXTENSION_REQUIRED_$1, caller));
0525:            }
0526:
0527:            /**
0528:             * Returns a description of the underlying backing store, or {@code null} if unknow.
0529:             *
0530:             * @throws FactoryException if a failure occured while fetching the engine description.
0531:             */
0532:            public String getBackingStoreDescription() throws FactoryException {
0533:                final AbstractAuthorityFactory factory = getGeotoolsFactory(
0534:                        null, null);
0535:                return (factory != null) ? factory.getBackingStoreDescription()
0536:                        : null;
0537:            }
0538:
0539:            /**
0540:             * Returns the vendor responsible for creating this factory implementation.
0541:             */
0542:            public Citation getVendor() {
0543:                return getAuthorityFactory().getVendor();
0544:            }
0545:
0546:            /**
0547:             * Returns the organization or party responsible for definition and maintenance of the
0548:             * database.
0549:             */
0550:            public Citation getAuthority() {
0551:                return getAuthorityFactory().getAuthority();
0552:            }
0553:
0554:            /**
0555:             * Returns the set of authority code for the specified type.
0556:             * 
0557:             * @todo We should returns the union of authority codes from all underlying factories.
0558:             */
0559:            public Set/*<String>*/getAuthorityCodes(final Class type)
0560:                    throws FactoryException {
0561:                return getAuthorityFactory(null).getAuthorityCodes(type);
0562:            }
0563:
0564:            /**
0565:             * Returns a description for the object identified by the specified code.
0566:             */
0567:            public InternationalString getDescriptionText(final String code)
0568:                    throws FactoryException {
0569:                return getAuthorityFactory(code).getDescriptionText(
0570:                        toBackingFactoryCode(code));
0571:            }
0572:
0573:            /**
0574:             * Returns an arbitrary object from a code.
0575:             *
0576:             * @see #createCoordinateReferenceSystem
0577:             * @see #createDatum
0578:             * @see #createEllipsoid
0579:             * @see #createUnit
0580:             */
0581:            public IdentifiedObject createObject(final String code)
0582:                    throws FactoryException {
0583:                return replaceObject(getAuthorityFactory(code).createObject(
0584:                        toBackingFactoryCode(code)));
0585:            }
0586:
0587:            /**
0588:             * Returns an arbitrary {@linkplain Datum datum} from a code.
0589:             *
0590:             * @see #createGeodeticDatum
0591:             * @see #createVerticalDatum
0592:             * @see #createTemporalDatum
0593:             */
0594:            public Datum createDatum(final String code) throws FactoryException {
0595:                return replace(getDatumAuthorityFactory(code).createDatum(
0596:                        toBackingFactoryCode(code)));
0597:            }
0598:
0599:            /**
0600:             * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
0601:             *
0602:             * @see #createEngineeringCRS
0603:             */
0604:            public EngineeringDatum createEngineeringDatum(final String code)
0605:                    throws FactoryException {
0606:                return (EngineeringDatum) replace(getDatumAuthorityFactory(code)
0607:                        .createEngineeringDatum(toBackingFactoryCode(code)));
0608:            }
0609:
0610:            /**
0611:             * Creates a {@linkplain ImageDatum image datum} from a code.
0612:             *
0613:             * @see #createImageCRS
0614:             */
0615:            public ImageDatum createImageDatum(final String code)
0616:                    throws FactoryException {
0617:                return (ImageDatum) replace(getDatumAuthorityFactory(code)
0618:                        .createImageDatum(toBackingFactoryCode(code)));
0619:            }
0620:
0621:            /**
0622:             * Creates a {@linkplain VerticalDatum vertical datum} from a code.
0623:             *
0624:             * @see #createVerticalCRS
0625:             */
0626:            public VerticalDatum createVerticalDatum(final String code)
0627:                    throws FactoryException {
0628:                return (VerticalDatum) replace(getDatumAuthorityFactory(code)
0629:                        .createVerticalDatum(toBackingFactoryCode(code)));
0630:            }
0631:
0632:            /**
0633:             * Creates a {@linkplain TemporalDatum temporal datum} from a code.
0634:             *
0635:             * @see #createTemporalCRS
0636:             */
0637:            public TemporalDatum createTemporalDatum(final String code)
0638:                    throws FactoryException {
0639:                return (TemporalDatum) replace(getDatumAuthorityFactory(code)
0640:                        .createTemporalDatum(toBackingFactoryCode(code)));
0641:            }
0642:
0643:            /**
0644:             * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
0645:             *
0646:             * @see #createEllipsoid
0647:             * @see #createPrimeMeridian
0648:             * @see #createGeographicCRS
0649:             * @see #createProjectedCRS
0650:             */
0651:            public GeodeticDatum createGeodeticDatum(final String code)
0652:                    throws FactoryException {
0653:                return (GeodeticDatum) replace(getDatumAuthorityFactory(code)
0654:                        .createGeodeticDatum(toBackingFactoryCode(code)));
0655:            }
0656:
0657:            /**
0658:             * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
0659:             *
0660:             * @see #createGeodeticDatum
0661:             */
0662:            public Ellipsoid createEllipsoid(final String code)
0663:                    throws FactoryException {
0664:                return getDatumAuthorityFactory(code).createEllipsoid(
0665:                        toBackingFactoryCode(code));
0666:            }
0667:
0668:            /**
0669:             * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
0670:             *
0671:             * @see #createGeodeticDatum
0672:             */
0673:            public PrimeMeridian createPrimeMeridian(final String code)
0674:                    throws FactoryException {
0675:                return getDatumAuthorityFactory(code).createPrimeMeridian(
0676:                        toBackingFactoryCode(code));
0677:            }
0678:
0679:            /**
0680:             * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
0681:             */
0682:            public Extent createExtent(final String code)
0683:                    throws FactoryException {
0684:                return getGeotoolsFactory("createExtent", code).createExtent(
0685:                        toBackingFactoryCode(code));
0686:            }
0687:
0688:            /**
0689:             * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
0690:             */
0691:            public CoordinateSystem createCoordinateSystem(final String code)
0692:                    throws FactoryException {
0693:                return replace(getCSAuthorityFactory(code)
0694:                        .createCoordinateSystem(toBackingFactoryCode(code)));
0695:            }
0696:
0697:            /**
0698:             * Creates a cartesian coordinate system from a code.
0699:             */
0700:            public CartesianCS createCartesianCS(final String code)
0701:                    throws FactoryException {
0702:                return (CartesianCS) replace(getCSAuthorityFactory(code)
0703:                        .createCartesianCS(toBackingFactoryCode(code)));
0704:            }
0705:
0706:            /**
0707:             * Creates a polar coordinate system from a code.
0708:             */
0709:            public PolarCS createPolarCS(final String code)
0710:                    throws FactoryException {
0711:                return (PolarCS) replace(getCSAuthorityFactory(code)
0712:                        .createPolarCS(toBackingFactoryCode(code)));
0713:            }
0714:
0715:            /**
0716:             * Creates a cylindrical coordinate system from a code.
0717:             */
0718:            public CylindricalCS createCylindricalCS(final String code)
0719:                    throws FactoryException {
0720:                return (CylindricalCS) replace(getCSAuthorityFactory(code)
0721:                        .createCylindricalCS(toBackingFactoryCode(code)));
0722:            }
0723:
0724:            /**
0725:             * Creates a spherical coordinate system from a code.
0726:             */
0727:            public SphericalCS createSphericalCS(final String code)
0728:                    throws FactoryException {
0729:                return (SphericalCS) replace(getCSAuthorityFactory(code)
0730:                        .createSphericalCS(toBackingFactoryCode(code)));
0731:            }
0732:
0733:            /**
0734:             * Creates an ellipsoidal coordinate system from a code.
0735:             */
0736:            public EllipsoidalCS createEllipsoidalCS(final String code)
0737:                    throws FactoryException {
0738:                return (EllipsoidalCS) replace(getCSAuthorityFactory(code)
0739:                        .createEllipsoidalCS(toBackingFactoryCode(code)));
0740:            }
0741:
0742:            /**
0743:             * Creates a vertical coordinate system from a code.
0744:             */
0745:            public VerticalCS createVerticalCS(final String code)
0746:                    throws FactoryException {
0747:                return (VerticalCS) replace(getCSAuthorityFactory(code)
0748:                        .createVerticalCS(toBackingFactoryCode(code)));
0749:            }
0750:
0751:            /**
0752:             * Creates a temporal coordinate system from a code.
0753:             */
0754:            public TimeCS createTimeCS(final String code)
0755:                    throws FactoryException {
0756:                return (TimeCS) replace(getCSAuthorityFactory(code)
0757:                        .createTimeCS(toBackingFactoryCode(code)));
0758:            }
0759:
0760:            /**
0761:             * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
0762:             */
0763:            public CoordinateSystemAxis createCoordinateSystemAxis(
0764:                    final String code) throws FactoryException {
0765:                return replace(getCSAuthorityFactory(code)
0766:                        .createCoordinateSystemAxis(toBackingFactoryCode(code)));
0767:            }
0768:
0769:            /**
0770:             * Returns an {@linkplain Unit unit} from a code.
0771:             */
0772:            public Unit createUnit(final String code) throws FactoryException {
0773:                return replace(getCSAuthorityFactory(code).createUnit(
0774:                        toBackingFactoryCode(code)));
0775:            }
0776:
0777:            /**
0778:             * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
0779:             * from a code.
0780:             *
0781:             * @see #createGeographicCRS
0782:             * @see #createProjectedCRS
0783:             * @see #createVerticalCRS
0784:             * @see #createTemporalCRS
0785:             * @see #createCompoundCRS
0786:             */
0787:            public CoordinateReferenceSystem createCoordinateReferenceSystem(
0788:                    final String code) throws FactoryException {
0789:                return replace(getCRSAuthorityFactory(code)
0790:                        .createCoordinateReferenceSystem(
0791:                                toBackingFactoryCode(code)));
0792:            }
0793:
0794:            /**
0795:             * Creates a 3D coordinate reference system from a code.
0796:             */
0797:            public CompoundCRS createCompoundCRS(final String code)
0798:                    throws FactoryException {
0799:                return (CompoundCRS) replace(getCRSAuthorityFactory(code)
0800:                        .createCompoundCRS(toBackingFactoryCode(code)));
0801:            }
0802:
0803:            /**
0804:             * Creates a derived coordinate reference system from a code.
0805:             */
0806:            public DerivedCRS createDerivedCRS(final String code)
0807:                    throws FactoryException {
0808:                return (DerivedCRS) replace(getCRSAuthorityFactory(code)
0809:                        .createDerivedCRS(toBackingFactoryCode(code)));
0810:            }
0811:
0812:            /**
0813:             * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
0814:             */
0815:            public EngineeringCRS createEngineeringCRS(final String code)
0816:                    throws FactoryException {
0817:                return (EngineeringCRS) replace(getCRSAuthorityFactory(code)
0818:                        .createEngineeringCRS(toBackingFactoryCode(code)));
0819:            }
0820:
0821:            /**
0822:             * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
0823:             */
0824:            public GeographicCRS createGeographicCRS(final String code)
0825:                    throws FactoryException {
0826:                return (GeographicCRS) replace(getCRSAuthorityFactory(code)
0827:                        .createGeographicCRS(toBackingFactoryCode(code)));
0828:            }
0829:
0830:            /**
0831:             * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
0832:             */
0833:            public GeocentricCRS createGeocentricCRS(final String code)
0834:                    throws FactoryException {
0835:                return (GeocentricCRS) replace(getCRSAuthorityFactory(code)
0836:                        .createGeocentricCRS(toBackingFactoryCode(code)));
0837:            }
0838:
0839:            /**
0840:             * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
0841:             */
0842:            public ImageCRS createImageCRS(final String code)
0843:                    throws FactoryException {
0844:                return (ImageCRS) replace(getCRSAuthorityFactory(code)
0845:                        .createImageCRS(toBackingFactoryCode(code)));
0846:            }
0847:
0848:            /**
0849:             * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
0850:             */
0851:            public ProjectedCRS createProjectedCRS(final String code)
0852:                    throws FactoryException {
0853:                return (ProjectedCRS) replace(getCRSAuthorityFactory(code)
0854:                        .createProjectedCRS(toBackingFactoryCode(code)));
0855:            }
0856:
0857:            /**
0858:             * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
0859:             */
0860:            public TemporalCRS createTemporalCRS(final String code)
0861:                    throws FactoryException {
0862:                return (TemporalCRS) replace(getCRSAuthorityFactory(code)
0863:                        .createTemporalCRS(toBackingFactoryCode(code)));
0864:            }
0865:
0866:            /**
0867:             * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
0868:             */
0869:            public VerticalCRS createVerticalCRS(final String code)
0870:                    throws FactoryException {
0871:                return (VerticalCRS) replace(getCRSAuthorityFactory(code)
0872:                        .createVerticalCRS(toBackingFactoryCode(code)));
0873:            }
0874:
0875:            /**
0876:             * Creates a parameter descriptor from a code.
0877:             */
0878:            public ParameterDescriptor createParameterDescriptor(
0879:                    final String code) throws FactoryException {
0880:                return getGeotoolsFactory("createParameterDescriptor", code)
0881:                        .createParameterDescriptor(toBackingFactoryCode(code));
0882:            }
0883:
0884:            /**
0885:             * Creates an operation method from a code.
0886:             */
0887:            public OperationMethod createOperationMethod(final String code)
0888:                    throws FactoryException {
0889:                return getGeotoolsFactory("createOperationMethod", code)
0890:                        .createOperationMethod(toBackingFactoryCode(code));
0891:            }
0892:
0893:            /**
0894:             * Creates an operation from a single operation code.
0895:             */
0896:            public CoordinateOperation createCoordinateOperation(
0897:                    final String code) throws FactoryException {
0898:                return replace(getCoordinateOperationAuthorityFactory(code)
0899:                        .createCoordinateOperation(toBackingFactoryCode(code)));
0900:            }
0901:
0902:            /**
0903:             * Creates an operation from coordinate reference system codes.
0904:             */
0905:            public Set/*<CoordinateOperation>*/createFromCoordinateReferenceSystemCodes(
0906:                    final String sourceCode, final String targetCode)
0907:                    throws FactoryException {
0908:                final CoordinateOperationAuthorityFactory factory, check;
0909:                factory = getCoordinateOperationAuthorityFactory(sourceCode);
0910:                check = getCoordinateOperationAuthorityFactory(targetCode);
0911:                if (factory != check) {
0912:                    /*
0913:                     * No coordinate operation because of mismatched factories. This is not
0914:                     * illegal - the result is an empty set - but it is worth to notify the
0915:                     * user since this case has some chances to be an user error.
0916:                     */
0917:                    final LogRecord record = Logging
0918:                            .format(
0919:                                    Level.WARNING,
0920:                                    LoggingKeys.MISMATCHED_COORDINATE_OPERATION_FACTORIES_$2,
0921:                                    sourceCode, targetCode);
0922:                    record
0923:                            .setSourceMethodName("createFromCoordinateReferenceSystemCodes");
0924:                    record.setSourceClassName(AuthorityFactoryAdapter.class
0925:                            .getName());
0926:                    LOGGER.log(record);
0927:                    return Collections.EMPTY_SET;
0928:                }
0929:                return factory.createFromCoordinateReferenceSystemCodes(
0930:                        toBackingFactoryCode(sourceCode),
0931:                        toBackingFactoryCode(targetCode));
0932:            }
0933:
0934:            /**
0935:             * Returns a finder which can be used for looking up unidentified objects.
0936:             * The default implementation delegates the lookups to the underlying factory.
0937:             *
0938:             * @since 2.4
0939:             */
0940:            //@Override
0941:            public IdentifiedObjectFinder getIdentifiedObjectFinder(
0942:                    final Class/*<? extends IdentifiedObject>*/type)
0943:                    throws FactoryException {
0944:                return new Finder(type);
0945:            }
0946:
0947:            /**
0948:             * A {@link IdentifiedObjectFinder} which tests
0949:             * {@linkplain AuthorityFactoryAdapter#replaceObject modified objects}
0950:             * in addition of original object.
0951:             */
0952:            class Finder extends IdentifiedObjectFinder.Adapter {
0953:                /**
0954:                 * Creates a finder for the underlying backing store.
0955:                 */
0956:                protected Finder(
0957:                        final Class/*<? extends IdentifiedObject>*/type)
0958:                        throws FactoryException {
0959:                    super (getGeotoolsFactory("getIdentifiedObjectFinder", null)
0960:                            .getIdentifiedObjectFinder(type));
0961:                }
0962:
0963:                /**
0964:                 * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
0965:                 * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
0966:                 * model. Otherwise returns {@code null}.
0967:                 *
0968:                 * @throws FactoryException if an error occured while creating a derived object.
0969:                 */
0970:                //@Override
0971:                protected IdentifiedObject deriveEquivalent(
0972:                        final IdentifiedObject candidate,
0973:                        final IdentifiedObject model) throws FactoryException {
0974:                    final IdentifiedObject modified = replaceObject(candidate);
0975:                    if (modified != candidate) {
0976:                        if (CRS.equalsIgnoreMetadata(modified, model)) {
0977:                            return modified;
0978:                        }
0979:                    }
0980:                    return super .deriveEquivalent(candidate, model);
0981:                }
0982:            }
0983:
0984:            /**
0985:             * Creates an exception for a missing factory. We actually returns an instance of
0986:             * {@link NoSuchAuthorityCodeException} because this kind of exception is treated
0987:             * especially by {@link FallbackAuthorityFactory}.
0988:             */
0989:            private FactoryException missingFactory(final Class category,
0990:                    final String code) {
0991:                return new NoSuchAuthorityCodeException(Errors.format(
0992:                        ErrorKeys.FACTORY_NOT_FOUND_$1, Utilities
0993:                                .getShortName(category)), Citations
0994:                        .getIdentifier(getAuthority()), trimAuthority(code));
0995:            }
0996:
0997:            /**
0998:             * For internal use by {@link #getAuthority} and {@link #getVendor} only. Its only purpose
0999:             * is to catch the {@link FactoryException} for methods that don't allow it. The protected
1000:             * method should be used instead when this exception is allowed.
1001:             */
1002:            private AuthorityFactory getAuthorityFactory() {
1003:                try {
1004:                    return getAuthorityFactory(null);
1005:                } catch (FactoryException cause) {
1006:                    IllegalStateException e = new IllegalStateException(Errors
1007:                            .format(ErrorKeys.UNDEFINED_PROPERTY));
1008:                    e.initCause(cause); // TODO: inline when we will be allowed to compile for J2SE 1.5.
1009:                    throw e;
1010:                }
1011:            }
1012:
1013:            /**
1014:             * Returns an authority factory of the specified type. This method delegates to:
1015:             * <ul>
1016:             *   <li>{@link #getCRSAuthorityFactory} if {@code type} is
1017:             *       {@code CRSAuthorityFactory.class};</li>
1018:             *   <li>{@link #getCSAuthorityFactory} if {@code type} is
1019:             *       {@code CSAuthorityFactory.class};</li>
1020:             *   <li>{@link #getDatumAuthorityFactory} if {@code type} is
1021:             *       {@code DatumAuthorityFactory.class};</li>
1022:             *   <li>{@link #CoordinateOperationAuthorityFactory} if {@code type} is
1023:             *       {@code CoordinateOperationAuthorityFactory.class};</li>
1024:             * </ul>
1025:             *
1026:             * @throws IllegalArgumentException if the specified {@code type} is invalid.
1027:             * @throws FactoryException if no suitable factory were found.
1028:             */
1029:            AuthorityFactory getAuthorityFactory(
1030:                    final Class/*<T extends AuthorityFactory>*/type,
1031:                    final String code) throws FactoryException {
1032:                if (CRSAuthorityFactory.class.equals(type)) {
1033:                    return getCRSAuthorityFactory(code);
1034:                }
1035:                if (CSAuthorityFactory.class.equals(type)) {
1036:                    return getCSAuthorityFactory(code);
1037:                }
1038:                if (DatumAuthorityFactory.class.equals(type)) {
1039:                    return getDatumAuthorityFactory(code);
1040:                }
1041:                if (CoordinateOperationAuthorityFactory.class.equals(type)) {
1042:                    return getCoordinateOperationAuthorityFactory(code);
1043:                }
1044:                throw new IllegalArgumentException(Errors.format(
1045:                        ErrorKeys.ILLEGAL_ARGUMENT_$2, "type", type));
1046:            }
1047:
1048:            /**
1049:             * Returns a generic object factory to use for the specified code. The default implementation
1050:             * returns one of the factory specified at construction time. Subclasses can override
1051:             * this method in order to select a different factory implementation depending on the
1052:             * code value.
1053:             * <p>
1054:             * <strong>Note:</strong> The value of the {@code code} argument given to this
1055:             * method may be {@code null} when a factory is needed for some global task,
1056:             * like {@link #getAuthorityCodes} method execution.
1057:             *
1058:             * @param  code The authority code given to this class. Note that the code to be given
1059:             *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1060:             * @return A factory for the specified authority code (never {@code null}).
1061:             * @throws FactoryException if no suitable factory were found.
1062:             *
1063:             * @since 2.4
1064:             */
1065:            protected AuthorityFactory getAuthorityFactory(final String code)
1066:                    throws FactoryException {
1067:                if (crsFactory != null)
1068:                    return crsFactory;
1069:                if (csFactory != null)
1070:                    return csFactory;
1071:                if (datumFactory != null)
1072:                    return datumFactory;
1073:                if (operationFactory != null)
1074:                    return operationFactory;
1075:                throw missingFactory(AuthorityFactory.class, code);
1076:            }
1077:
1078:            /**
1079:             * Returns the datum factory to use for the specified code. The default implementation
1080:             * always returns the factory specified at construction time. Subclasses can override
1081:             * this method in order to select a different factory implementation depending on the
1082:             * code value.
1083:             *
1084:             * @param  code The authority code given to this class. Note that the code to be given
1085:             *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1086:             * @return A factory for the specified authority code (never {@code null}).
1087:             * @throws FactoryException if no datum factory were specified at construction time.
1088:             *
1089:             * @since 2.4
1090:             */
1091:            protected DatumAuthorityFactory getDatumAuthorityFactory(
1092:                    final String code) throws FactoryException {
1093:                if (datumFactory == null) {
1094:                    throw missingFactory(DatumAuthorityFactory.class, code);
1095:                }
1096:                return datumFactory;
1097:            }
1098:
1099:            /**
1100:             * Returns the coordinate system factory to use for the specified code. The default
1101:             * implementation always returns the factory specified at construction time. Subclasses
1102:             * can override this method in order to select a different factory implementation
1103:             * depending on the code value.
1104:             *
1105:             * @param  code The authority code given to this class. Note that the code to be given
1106:             *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1107:             * @return A factory for the specified authority code (never {@code null}).
1108:             * @throws FactoryException if no coordinate system factory were specified at construction time.
1109:             *
1110:             * @since 2.4
1111:             */
1112:            protected CSAuthorityFactory getCSAuthorityFactory(final String code)
1113:                    throws FactoryException {
1114:                if (csFactory == null) {
1115:                    throw missingFactory(CSAuthorityFactory.class, code);
1116:                }
1117:                return csFactory;
1118:            }
1119:
1120:            /**
1121:             * Returns the coordinate reference system factory to use for the specified code. The default
1122:             * implementation always returns the factory specified at construction time. Subclasses can
1123:             * override this method in order to select a different factory implementation depending on
1124:             * the code value.
1125:             *
1126:             * @param  code The authority code given to this class. Note that the code to be given
1127:             *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1128:             * @return A factory for the specified authority code (never {@code null}).
1129:             * @throws FactoryException if no coordinate reference system factory were specified
1130:             *         at construction time.
1131:             *
1132:             * @since 2.4
1133:             */
1134:            protected CRSAuthorityFactory getCRSAuthorityFactory(
1135:                    final String code) throws FactoryException {
1136:                if (crsFactory == null) {
1137:                    throw missingFactory(CRSAuthorityFactory.class, code);
1138:                }
1139:                return crsFactory;
1140:            }
1141:
1142:            /**
1143:             * Returns the coordinate operation factory to use for the specified code. The default
1144:             * implementation always returns the factory specified at construction time. Subclasses can
1145:             * override this method in order to select a different factory implementation depending on
1146:             * the code value.
1147:             *
1148:             * @param  code The authority code given to this class. Note that the code to be given
1149:             *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1150:             * @return A factory for the specified authority code (never {@code null}).
1151:             * @throws FactoryException if no coordinate operation factory were specified
1152:             *         at construction time.
1153:             *
1154:             * @since 2.4
1155:             */
1156:            protected CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(
1157:                    final String code) throws FactoryException {
1158:                if (operationFactory == null) {
1159:                    throw missingFactory(
1160:                            CoordinateOperationAuthorityFactory.class, code);
1161:                }
1162:                return operationFactory;
1163:            }
1164:
1165:            /**
1166:             * Returns a coordinate operation factory for this adapter. This method will try to fetch
1167:             * this information from the coordinate operation authority factory, or will returns the
1168:             * default one if no explicit factory were found.
1169:             */
1170:            final CoordinateOperationFactory getCoordinateOperationFactory()
1171:                    throws FactoryException {
1172:                if (operationFactory instanceof  Factory) {
1173:                    final Factory factory = (Factory) operationFactory;
1174:                    final Map hints = factory.getImplementationHints();
1175:                    final Object candidate = hints
1176:                            .get(Hints.COORDINATE_OPERATION_FACTORY);
1177:                    if (candidate instanceof  CoordinateOperationFactory) {
1178:                        return (CoordinateOperationFactory) candidate;
1179:                    }
1180:                }
1181:                return ReferencingFactoryFinder
1182:                        .getCoordinateOperationFactory(hints());
1183:            }
1184:
1185:            /**
1186:             * Suggests a low-level factory group. If {@code crs} is {@code true}, then this method will
1187:             * try to fetch the factory group from the CRS authority factory. Otherwise it will try to
1188:             * fetch the factory group from the CS authority factory. This is used by subclasses like
1189:             * {@link TransformedAuthorityFactory} that need low-level access to factories. Do not change
1190:             * this method into a public one; we would need a better API before to do such thing.
1191:             */
1192:            final ReferencingFactoryContainer getFactoryContainer(
1193:                    final boolean crs) {
1194:                final AuthorityFactory factory;
1195:                if (crs) {
1196:                    factory = crsFactory;
1197:                } else {
1198:                    factory = csFactory;
1199:                }
1200:                if (factory instanceof  DirectAuthorityFactory) {
1201:                    return ((DirectAuthorityFactory) factory).factories;
1202:                }
1203:                // No predefined factory group. Create one.
1204:                if (factories == null) {
1205:                    factories = ReferencingFactoryContainer.instance(hints());
1206:                }
1207:                return factories;
1208:            }
1209:
1210:            /**
1211:             * Returns the code to be given to the wrapped factories. This method is automatically
1212:             * invoked by all {@code create} methods before to forward the code to the
1213:             * {@linkplain #getCRSAuthorityFactory CRS}, {@linkplain #getCSAuthorityFactory CS},
1214:             * {@linkplain #getDatumAuthorityFactory datum} or {@linkplain #operationFactory operation}
1215:             * factory. The default implementation returns the {@code code} unchanged.
1216:             *
1217:             * @param  code The code given to this factory.
1218:             * @return The code to give to the underlying factories.
1219:             * @throws FactoryException if the code can't be converted.
1220:             *
1221:             * @since 2.4
1222:             */
1223:            protected String toBackingFactoryCode(final String code)
1224:                    throws FactoryException {
1225:                return code;
1226:            }
1227:
1228:            /**
1229:             * Returns {@code true} if the {@link #toBackingFactoryCode} method is overriden.
1230:             */
1231:            final boolean isCodeMethodOverriden() {
1232:                final Class[] arguments = new Class[] { String.class };
1233:                for (Class type = getClass(); !AuthorityFactoryAdapter.class
1234:                        .equals(type); type = type.getSuperclass()) {
1235:                    try {
1236:                        type.getDeclaredMethod("toBackingFactoryCode",
1237:                                arguments);
1238:                    } catch (NoSuchMethodException e) {
1239:                        // The method is not overriden in this class.
1240:                        // Checks in the super-class.
1241:                        continue;
1242:                    } catch (SecurityException e) {
1243:                        // We are not allowed to get this information.
1244:                        // Conservatively assumes that the method is overriden.
1245:                    }
1246:                    return true;
1247:                }
1248:                return false;
1249:            }
1250:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.