Source Code Cross Referenced for BufferedAuthorityFactory.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:         *    This package contains documentation from OpenGIS specifications.
0018:         *    OpenGIS consortium's work is fully acknowledged here.
0019:         */
0020:        package org.geotools.referencing.factory;
0021:
0022:        // J2SE dependencies and extensions
0023:        import java.lang.ref.Reference;
0024:        import java.lang.ref.WeakReference;
0025:        import java.util.Map;
0026:        import java.util.Set;
0027:        import java.util.Iterator;
0028:        import java.util.Collection;
0029:        import java.util.Collections;
0030:        import java.util.WeakHashMap;
0031:        import java.util.LinkedHashMap;
0032:        import java.util.logging.LogRecord;
0033:        import java.util.logging.Level;
0034:        import javax.units.Unit;
0035:
0036:        // OpenGIS dependencies
0037:        import org.opengis.metadata.extent.Extent;
0038:        import org.opengis.metadata.citation.Citation;
0039:        import org.opengis.parameter.ParameterDescriptor;
0040:        import org.opengis.referencing.AuthorityFactory;
0041:        import org.opengis.referencing.FactoryException;
0042:        import org.opengis.referencing.IdentifiedObject;
0043:        import org.opengis.referencing.cs.*;
0044:        import org.opengis.referencing.crs.*;
0045:        import org.opengis.referencing.datum.*;
0046:        import org.opengis.referencing.operation.*;
0047:        import org.opengis.util.InternationalString;
0048:
0049:        // Geotools dependencies
0050:        import org.geotools.factory.Hints;
0051:        import org.geotools.factory.BufferedFactory;
0052:        import org.geotools.resources.Utilities;
0053:        import org.geotools.resources.i18n.Errors;
0054:        import org.geotools.resources.i18n.ErrorKeys;
0055:        import org.geotools.resources.i18n.Logging;
0056:        import org.geotools.resources.i18n.LoggingKeys;
0057:
0058:        /**
0059:         * An authority factory that caches all objects created by an other factory. All
0060:         * {@code createFoo(String)} methods first looks if a previously created object
0061:         * exists for the given code. If such an object exists, it is returned. Otherwise,
0062:         * the object creation is delegated to the {@linkplain AbstractAuthorityFactory authority factory}
0063:         * specified at creation time, and the result is cached in this buffered factory. 
0064:         * <p>
0065:         * Objects are cached by strong references, up to the amount of objects specified at
0066:         * construction time. If a greater amount of objects are cached, the oldest ones will
0067:         * be retained through a {@linkplain WeakReference weak reference} instead of a strong
0068:         * one. This means that this buffered factory will continue to returns them as long as
0069:         * they are in use somewhere else in the Java virtual machine, but will be discarted
0070:         * (and recreated on the fly if needed) otherwise.
0071:         *
0072:         * @since 2.1
0073:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/BufferedAuthorityFactory.java $
0074:         * @version $Id: BufferedAuthorityFactory.java 26078 2007-06-28 15:00:59Z desruisseaux $
0075:         * @author Martin Desruisseaux
0076:         */
0077:        public class BufferedAuthorityFactory extends AbstractAuthorityFactory
0078:                implements  BufferedFactory {
0079:            /**
0080:             * The default value for {@link #maxStrongReferences}.
0081:             */
0082:            static final int DEFAULT_MAX = 20;
0083:
0084:            /**
0085:             * The underlying authority factory. This field may be {@code null} if this object was
0086:             * created by the {@linkplain #BufferedAuthorityFactory(AbstractAuthorityFactory,int)
0087:             * package protected constructor}. In this case, the subclass is responsible for creating
0088:             * the backing store when {@link DeferredAuthorityFactory#createBackingStore} is invoked.
0089:             *
0090:             * @see #getBackingStore
0091:             * @see DeferredAuthorityFactory#createBackingStore
0092:             */
0093:            AbstractAuthorityFactory backingStore;
0094:
0095:            /**
0096:             * The pool of cached objects.
0097:             */
0098:            private final LinkedHashMap pool = new LinkedHashMap(32, 0.75f,
0099:                    true);
0100:
0101:            /**
0102:             * The maximum number of objects to keep by strong reference. If a greater amount of
0103:             * objects are created, then the strong references for the oldest ones are replaced by
0104:             * weak references.
0105:             */
0106:            private final int maxStrongReferences;
0107:
0108:            /**
0109:             * The pool of objects identified by {@link #find}.
0110:             */
0111:            private final Map/*<IdentifiedObject,IdentifiedObject>*/findPool = new WeakHashMap();
0112:
0113:            /**
0114:             * Constructs an instance wrapping the specified factory with a default number
0115:             * of entries to keep by strong reference.
0116:             * <p>
0117:             * This constructor is protected because subclasses must declare which of the
0118:             * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory}, {@link CRSAuthorityFactory}
0119:             * and {@link CoordinateOperationAuthorityFactory} interfaces they choose to implement.
0120:             *
0121:             * @param factory The factory to cache. Can not be {@code null}.
0122:             */
0123:            protected BufferedAuthorityFactory(
0124:                    final AbstractAuthorityFactory factory) {
0125:                this (factory, DEFAULT_MAX);
0126:            }
0127:
0128:            /**
0129:             * Constructs an instance wrapping the specified factory. The {@code maxStrongReferences}
0130:             * argument specify the maximum number of objects to keep by strong reference. If a greater
0131:             * amount of objects are created, then the strong references for the oldest ones are replaced
0132:             * by weak references.
0133:             * <p>
0134:             * This constructor is protected because subclasses must declare which of the
0135:             * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory}, {@link CRSAuthorityFactory}
0136:             * and {@link CoordinateOperationAuthorityFactory} interfaces they choose to implement.
0137:             *
0138:             * @param factory The factory to cache. Can not be {@code null}.
0139:             * @param maxStrongReferences The maximum number of objects to keep by strong reference.
0140:             */
0141:            protected BufferedAuthorityFactory(
0142:                    AbstractAuthorityFactory factory,
0143:                    final int maxStrongReferences) {
0144:                super (factory.getPriority());
0145:                while (factory instanceof  BufferedAuthorityFactory) {
0146:                    factory = ((BufferedAuthorityFactory) factory).backingStore;
0147:                }
0148:                this .backingStore = factory;
0149:                this .maxStrongReferences = maxStrongReferences;
0150:                completeHints();
0151:            }
0152:
0153:            /**
0154:             * Constructs an instance without initial backing store. This constructor is for subclass
0155:             * constructors only. Subclasses are responsible for creating an appropriate backing store
0156:             * when the {@link DeferredAuthorityFactory#createBackingStore} method is invoked.
0157:             *
0158:             * @param priority The priority for this factory, as a number between
0159:             *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
0160:             *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
0161:             * @param maxStrongReferences The maximum number of objects to keep by strong reference.
0162:             *
0163:             * @see DeferredAuthorityFactory#createBackingStore
0164:             */
0165:            BufferedAuthorityFactory(final int priority,
0166:                    final int maxStrongReferences) {
0167:                super (priority);
0168:                this .maxStrongReferences = maxStrongReferences;
0169:                // completeHints() will be invoked by DeferredAuthorityFactory.getBackingStore()
0170:            }
0171:
0172:            /**
0173:             * Completes the set of hints according the value currently set in this object. This method
0174:             * is invoked by {@code BufferedAuthorityFactory} or by {@code DeferredAuthorityFactory} at
0175:             * backing store creation time.
0176:             * <p>
0177:             * The backing store is of course an important dependency. This method gives a chance
0178:             * to {@link org.geotools.factory.FactoryRegistry} to compare the user-requested hints
0179:             * (especially {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER}) against the backing store
0180:             * hints, by following the dependency declared there.
0181:             * <p>
0182:             * DON'T FORGET to set those hints to {@code null} when {@link DeferredAuthorityFactory}
0183:             * dispose the backing store.
0184:             */
0185:            final void completeHints() {
0186:                if (backingStore instanceof  DatumAuthorityFactory) {
0187:                    hints.put(Hints.DATUM_AUTHORITY_FACTORY, backingStore);
0188:                }
0189:                if (backingStore instanceof  CSAuthorityFactory) {
0190:                    hints.put(Hints.CS_AUTHORITY_FACTORY, backingStore);
0191:                }
0192:                if (backingStore instanceof  CRSAuthorityFactory) {
0193:                    hints.put(Hints.CRS_AUTHORITY_FACTORY, backingStore);
0194:                }
0195:                if (backingStore instanceof  CoordinateOperationAuthorityFactory) {
0196:                    hints.put(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
0197:                            backingStore);
0198:                }
0199:            }
0200:
0201:            /**
0202:             * Returns the direct dependencies. The returned list contains the backing store
0203:             * specified at construction time, or the exception if it can't be obtained.
0204:             */
0205:            //@Override
0206:            Collection/*<?>*/dependencies() {
0207:                Object factory;
0208:                try {
0209:                    factory = getBackingStore();
0210:                } catch (FactoryException e) {
0211:                    factory = e;
0212:                }
0213:                return Collections.singleton(factory);
0214:            }
0215:
0216:            /**
0217:             * Returns the backing store authority factory.
0218:             *
0219:             * @return The backing store to uses in {@code createXXX(...)} methods.
0220:             * @throws FactoryException if the creation of backing store failed.
0221:             */
0222:            AbstractAuthorityFactory getBackingStore() throws FactoryException {
0223:                if (backingStore == null) {
0224:                    throw new FactoryException(Errors
0225:                            .format(ErrorKeys.DISPOSED_FACTORY));
0226:                }
0227:                return backingStore;
0228:            }
0229:
0230:            /**
0231:             * Returns {@code true} if this factory is available. The default implementation returns
0232:             * {@code false} if no backing store were setup and
0233:             * {@link DeferredAuthorityFactory#createBackingStore} throws an exception.
0234:             */
0235:            synchronized boolean isAvailable() {
0236:                try {
0237:                    return getBackingStore().isAvailable();
0238:                } catch (FactoryNotFoundException exception) {
0239:                    /*
0240:                     * The factory is not available. This is error may be normal; it happens
0241:                     * for example if no gt2-epsg-hsql.jar (or similar JAR) are found in the
0242:                     * classpath, which is the case for example in GeoServer 1.3. Do not log
0243:                     * any stack trace,  since stack traces suggest more serious errors than
0244:                     * what we really have here.
0245:                     */
0246:                } catch (FactoryException exception) {
0247:                    /*
0248:                     * The factory creation failed for an other reason, which may be more
0249:                     * serious. Now it is time to log a warning with a stack trace.
0250:                     */
0251:                    final Citation citation = getAuthority();
0252:                    final Collection titles = citation.getAlternateTitles();
0253:                    InternationalString title = citation.getTitle();
0254:                    if (titles != null) {
0255:                        for (final Iterator it = titles.iterator(); it
0256:                                .hasNext();) {
0257:                            /*
0258:                             * Uses the longuest title instead of the main one. In Geotools
0259:                             * implementation, the alternate title may contains usefull informations
0260:                             * like the EPSG database version number and the database engine.
0261:                             */
0262:                            final InternationalString candidate = (InternationalString) it
0263:                                    .next();
0264:                            if (candidate.length() > title.length()) {
0265:                                title = candidate;
0266:                            }
0267:                        }
0268:                    }
0269:                    final LogRecord record = Logging
0270:                            .format(
0271:                                    Level.WARNING,
0272:                                    LoggingKeys.UNAVAILABLE_AUTHORITY_FACTORY_$1,
0273:                                    title);
0274:                    record.setSourceClassName(getClass().getName());
0275:                    record.setSourceMethodName("isAvailable");
0276:                    record.setThrown(exception);
0277:                    LOGGER.log(record);
0278:                }
0279:                return false;
0280:            }
0281:
0282:            /**
0283:             * If this factory is a wrapper for the specified factory that do not add any additional
0284:             * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
0285:             * for {@link FallbackAuthorityFactory} internal use only and should not be public. A
0286:             * cheap test without {@link #getBackingStore} invocation is suffisient for our needs.
0287:             */
0288:            //@Override
0289:            boolean sameAuthorityCodes(final AuthorityFactory factory) {
0290:                final AbstractAuthorityFactory backingStore = this .backingStore; // Protect from changes.
0291:                if (backingStore != null
0292:                        && backingStore.sameAuthorityCodes(factory)) {
0293:                    return true;
0294:                }
0295:                return super .sameAuthorityCodes(factory);
0296:            }
0297:
0298:            /**
0299:             * Returns the vendor responsible for creating the underlying factory implementation.
0300:             */
0301:            public synchronized Citation getVendor() {
0302:                return (backingStore != null) ? backingStore.getVendor()
0303:                        : super .getVendor();
0304:            }
0305:
0306:            /**
0307:             * Returns the organization or party responsible for definition and maintenance of the
0308:             * underlying database.
0309:             */
0310:            public synchronized Citation getAuthority() {
0311:                return (backingStore != null) ? backingStore.getAuthority()
0312:                        : null;
0313:            }
0314:
0315:            /**
0316:             * Returns a description of the underlying backing store, or {@code null} if unknow.
0317:             * This is for example the database software used for storing the data.
0318:             *
0319:             * @throws FactoryException if a failure occured while fetching the engine description.
0320:             */
0321:            public synchronized String getBackingStoreDescription()
0322:                    throws FactoryException {
0323:                return getBackingStore().getBackingStoreDescription();
0324:            }
0325:
0326:            /**
0327:             * Returns the set of authority codes of the given type. The {@code type}
0328:             * argument specify the base class.
0329:             *
0330:             * @param  type The spatial reference objects type.
0331:             * @return The set of authority codes for spatial reference objects of the given type.
0332:             *         If this factory doesn't contains any object of the given type, then this method
0333:             *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
0334:             * @throws FactoryException if access to the underlying database failed.
0335:             */
0336:            public synchronized Set getAuthorityCodes(final Class type)
0337:                    throws FactoryException {
0338:                return getBackingStore().getAuthorityCodes(type);
0339:            }
0340:
0341:            /**
0342:             * Gets a description of the object corresponding to a code.
0343:             *
0344:             * @param  code Value allocated by authority.
0345:             * @return A description of the object, or {@code null} if the object
0346:             *         corresponding to the specified {@code code} has no description.
0347:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
0348:             * @throws FactoryException if the query failed for some other reason.
0349:             */
0350:            public synchronized InternationalString getDescriptionText(
0351:                    final String code) throws FactoryException {
0352:                return getBackingStore().getDescriptionText(code);
0353:            }
0354:
0355:            /**
0356:             * Returns an arbitrary object from a code.
0357:             */
0358:            public synchronized IdentifiedObject createObject(final String code)
0359:                    throws FactoryException {
0360:                final IdentifiedObject object;
0361:                final String key = trimAuthority(code);
0362:                final Object cached = get(key);
0363:                if (cached instanceof  IdentifiedObject) {
0364:                    object = (IdentifiedObject) cached;
0365:                } else {
0366:                    object = getBackingStore().createObject(code);
0367:                }
0368:                put(key, object);
0369:                return object;
0370:            }
0371:
0372:            /**
0373:             * Returns an arbitrary datum from a code.
0374:             */
0375:            public synchronized Datum createDatum(final String code)
0376:                    throws FactoryException {
0377:                final Datum datum;
0378:                final String key = trimAuthority(code);
0379:                final Object cached = get(key);
0380:                if (cached instanceof  Datum) {
0381:                    datum = (Datum) cached;
0382:                } else {
0383:                    datum = getBackingStore().createDatum(code);
0384:                }
0385:                put(key, datum);
0386:                return datum;
0387:            }
0388:
0389:            /**
0390:             * Returns an engineering datum from a code.
0391:             */
0392:            public synchronized EngineeringDatum createEngineeringDatum(
0393:                    final String code) throws FactoryException {
0394:                final EngineeringDatum datum;
0395:                final String key = trimAuthority(code);
0396:                final Object cached = get(key);
0397:                if (cached instanceof  EngineeringDatum) {
0398:                    datum = (EngineeringDatum) cached;
0399:                } else {
0400:                    datum = getBackingStore().createEngineeringDatum(code);
0401:                }
0402:                put(key, datum);
0403:                return datum;
0404:            }
0405:
0406:            /**
0407:             * Returns an image datum from a code.
0408:             */
0409:            public synchronized ImageDatum createImageDatum(final String code)
0410:                    throws FactoryException {
0411:                final ImageDatum datum;
0412:                final String key = trimAuthority(code);
0413:                final Object cached = get(key);
0414:                if (cached instanceof  ImageDatum) {
0415:                    datum = (ImageDatum) cached;
0416:                } else {
0417:                    datum = getBackingStore().createImageDatum(code);
0418:                }
0419:                put(key, datum);
0420:                return datum;
0421:            }
0422:
0423:            /**
0424:             * Returns a vertical datum from a code.
0425:             */
0426:            public synchronized VerticalDatum createVerticalDatum(
0427:                    final String code) throws FactoryException {
0428:                final VerticalDatum datum;
0429:                final String key = trimAuthority(code);
0430:                final Object cached = get(key);
0431:                if (cached instanceof  VerticalDatum) {
0432:                    datum = (VerticalDatum) cached;
0433:                } else {
0434:                    datum = getBackingStore().createVerticalDatum(code);
0435:                }
0436:                put(key, datum);
0437:                return datum;
0438:            }
0439:
0440:            /**
0441:             * Returns a temporal datum from a code.
0442:             */
0443:            public synchronized TemporalDatum createTemporalDatum(
0444:                    final String code) throws FactoryException {
0445:                final TemporalDatum datum;
0446:                final String key = trimAuthority(code);
0447:                final Object cached = get(key);
0448:                if (cached instanceof  TemporalDatum) {
0449:                    datum = (TemporalDatum) cached;
0450:                } else {
0451:                    datum = getBackingStore().createTemporalDatum(code);
0452:                }
0453:                put(key, datum);
0454:                return datum;
0455:            }
0456:
0457:            /**
0458:             * Returns a geodetic datum from a code.
0459:             */
0460:            public synchronized GeodeticDatum createGeodeticDatum(
0461:                    final String code) throws FactoryException {
0462:                final GeodeticDatum datum;
0463:                final String key = trimAuthority(code);
0464:                final Object cached = get(key);
0465:                if (cached instanceof  GeodeticDatum) {
0466:                    datum = (GeodeticDatum) cached;
0467:                } else {
0468:                    datum = getBackingStore().createGeodeticDatum(code);
0469:                }
0470:                put(key, datum);
0471:                return datum;
0472:            }
0473:
0474:            /**
0475:             * Returns an ellipsoid from a code.
0476:             */
0477:            public synchronized Ellipsoid createEllipsoid(final String code)
0478:                    throws FactoryException {
0479:                final Ellipsoid ellipsoid;
0480:                final String key = trimAuthority(code);
0481:                final Object cached = get(key);
0482:                if (cached instanceof  Ellipsoid) {
0483:                    ellipsoid = (Ellipsoid) cached;
0484:                } else {
0485:                    ellipsoid = getBackingStore().createEllipsoid(code);
0486:                }
0487:                put(key, ellipsoid);
0488:                return ellipsoid;
0489:            }
0490:
0491:            /**
0492:             * Returns a prime meridian from a code.
0493:             */
0494:            public synchronized PrimeMeridian createPrimeMeridian(
0495:                    final String code) throws FactoryException {
0496:                final PrimeMeridian meridian;
0497:                final String key = trimAuthority(code);
0498:                final Object cached = get(key);
0499:                if (cached instanceof  PrimeMeridian) {
0500:                    meridian = (PrimeMeridian) cached;
0501:                } else {
0502:                    meridian = getBackingStore().createPrimeMeridian(code);
0503:                }
0504:                put(key, meridian);
0505:                return meridian;
0506:            }
0507:
0508:            /**
0509:             * Returns an extent (usually an area of validity) from a code.
0510:             */
0511:            public synchronized Extent createExtent(final String code)
0512:                    throws FactoryException {
0513:                final Extent extent;
0514:                final String key = trimAuthority(code);
0515:                final Object cached = get(key);
0516:                if (cached instanceof  Extent) {
0517:                    extent = (Extent) cached;
0518:                } else {
0519:                    extent = getBackingStore().createExtent(code);
0520:                }
0521:                put(key, extent);
0522:                return extent;
0523:            }
0524:
0525:            /**
0526:             * Returns an arbitrary coordinate system from a code.
0527:             */
0528:            public synchronized CoordinateSystem createCoordinateSystem(
0529:                    final String code) throws FactoryException {
0530:                final CoordinateSystem cs;
0531:                final String key = trimAuthority(code);
0532:                final Object cached = get(key);
0533:                if (cached instanceof  CoordinateSystem) {
0534:                    cs = (CoordinateSystem) cached;
0535:                } else {
0536:                    cs = getBackingStore().createCoordinateSystem(code);
0537:                }
0538:                put(key, cs);
0539:                return cs;
0540:            }
0541:
0542:            /**
0543:             * Returns a cartesian coordinate system from a code.
0544:             */
0545:            public synchronized CartesianCS createCartesianCS(final String code)
0546:                    throws FactoryException {
0547:                final CartesianCS cs;
0548:                final String key = trimAuthority(code);
0549:                final Object cached = get(key);
0550:                if (cached instanceof  CartesianCS) {
0551:                    cs = (CartesianCS) cached;
0552:                } else {
0553:                    cs = getBackingStore().createCartesianCS(code);
0554:                }
0555:                put(key, cs);
0556:                return cs;
0557:            }
0558:
0559:            /**
0560:             * Returns a polar coordinate system from a code.
0561:             */
0562:            public synchronized PolarCS createPolarCS(final String code)
0563:                    throws FactoryException {
0564:                final PolarCS cs;
0565:                final String key = trimAuthority(code);
0566:                final Object cached = get(key);
0567:                if (cached instanceof  PolarCS) {
0568:                    cs = (PolarCS) cached;
0569:                } else {
0570:                    cs = getBackingStore().createPolarCS(code);
0571:                }
0572:                put(key, cs);
0573:                return cs;
0574:            }
0575:
0576:            /**
0577:             * Returns a cylindrical coordinate system from a code.
0578:             */
0579:            public synchronized CylindricalCS createCylindricalCS(
0580:                    final String code) throws FactoryException {
0581:                final CylindricalCS cs;
0582:                final String key = trimAuthority(code);
0583:                final Object cached = get(key);
0584:                if (cached instanceof  CylindricalCS) {
0585:                    cs = (CylindricalCS) cached;
0586:                } else {
0587:                    cs = getBackingStore().createCylindricalCS(code);
0588:                }
0589:                put(key, cs);
0590:                return cs;
0591:            }
0592:
0593:            /**
0594:             * Returns a spherical coordinate system from a code.
0595:             */
0596:            public synchronized SphericalCS createSphericalCS(final String code)
0597:                    throws FactoryException {
0598:                final SphericalCS cs;
0599:                final String key = trimAuthority(code);
0600:                final Object cached = get(key);
0601:                if (cached instanceof  SphericalCS) {
0602:                    cs = (SphericalCS) cached;
0603:                } else {
0604:                    cs = getBackingStore().createSphericalCS(code);
0605:                }
0606:                put(key, cs);
0607:                return cs;
0608:            }
0609:
0610:            /**
0611:             * Returns an ellipsoidal coordinate system from a code.
0612:             */
0613:            public synchronized EllipsoidalCS createEllipsoidalCS(
0614:                    final String code) throws FactoryException {
0615:                final EllipsoidalCS cs;
0616:                final String key = trimAuthority(code);
0617:                final Object cached = get(key);
0618:                if (cached instanceof  EllipsoidalCS) {
0619:                    cs = (EllipsoidalCS) cached;
0620:                } else {
0621:                    cs = getBackingStore().createEllipsoidalCS(code);
0622:                }
0623:                put(key, cs);
0624:                return cs;
0625:            }
0626:
0627:            /**
0628:             * Returns a vertical coordinate system from a code.
0629:             */
0630:            public synchronized VerticalCS createVerticalCS(final String code)
0631:                    throws FactoryException {
0632:                final VerticalCS cs;
0633:                final String key = trimAuthority(code);
0634:                final Object cached = get(key);
0635:                if (cached instanceof  VerticalCS) {
0636:                    cs = (VerticalCS) cached;
0637:                } else {
0638:                    cs = getBackingStore().createVerticalCS(code);
0639:                }
0640:                put(key, cs);
0641:                return cs;
0642:            }
0643:
0644:            /**
0645:             * Returns a temporal coordinate system from a code.
0646:             */
0647:            public synchronized TimeCS createTimeCS(final String code)
0648:                    throws FactoryException {
0649:                final TimeCS cs;
0650:                final String key = trimAuthority(code);
0651:                final Object cached = get(key);
0652:                if (cached instanceof  TimeCS) {
0653:                    cs = (TimeCS) cached;
0654:                } else {
0655:                    cs = getBackingStore().createTimeCS(code);
0656:                }
0657:                put(key, cs);
0658:                return cs;
0659:            }
0660:
0661:            /**
0662:             * Returns a coordinate system axis from a code.
0663:             */
0664:            public synchronized CoordinateSystemAxis createCoordinateSystemAxis(
0665:                    final String code) throws FactoryException {
0666:                final CoordinateSystemAxis axis;
0667:                final String key = trimAuthority(code);
0668:                final Object cached = get(key);
0669:                if (cached instanceof  CoordinateSystemAxis) {
0670:                    axis = (CoordinateSystemAxis) cached;
0671:                } else {
0672:                    axis = getBackingStore().createCoordinateSystemAxis(code);
0673:                }
0674:                put(key, axis);
0675:                return axis;
0676:            }
0677:
0678:            /**
0679:             * Returns an unit from a code.
0680:             */
0681:            public synchronized Unit createUnit(final String code)
0682:                    throws FactoryException {
0683:                final Unit unit;
0684:                final String key = trimAuthority(code);
0685:                final Object cached = get(key);
0686:                if (cached instanceof  Unit) {
0687:                    unit = (Unit) cached;
0688:                } else {
0689:                    unit = getBackingStore().createUnit(code);
0690:                }
0691:                put(key, unit);
0692:                return unit;
0693:            }
0694:
0695:            /**
0696:             * Returns an arbitrary coordinate reference system from a code.
0697:             */
0698:            public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(
0699:                    final String code) throws FactoryException {
0700:                final CoordinateReferenceSystem crs;
0701:                final String key = trimAuthority(code);
0702:                final Object cached = get(key);
0703:                if (cached instanceof  CoordinateReferenceSystem) {
0704:                    crs = (CoordinateReferenceSystem) cached;
0705:                } else {
0706:                    crs = getBackingStore().createCoordinateReferenceSystem(
0707:                            code);
0708:                }
0709:                put(key, crs);
0710:                return crs;
0711:            }
0712:
0713:            /**
0714:             * Returns a 3D coordinate reference system from a code.
0715:             */
0716:            public synchronized CompoundCRS createCompoundCRS(final String code)
0717:                    throws FactoryException {
0718:                final CompoundCRS crs;
0719:                final String key = trimAuthority(code);
0720:                final Object cached = get(key);
0721:                if (cached instanceof  CompoundCRS) {
0722:                    crs = (CompoundCRS) cached;
0723:                } else {
0724:                    crs = getBackingStore().createCompoundCRS(code);
0725:                }
0726:                put(key, crs);
0727:                return crs;
0728:            }
0729:
0730:            /**
0731:             * Returns a derived coordinate reference system from a code.
0732:             */
0733:            public synchronized DerivedCRS createDerivedCRS(final String code)
0734:                    throws FactoryException {
0735:                final DerivedCRS crs;
0736:                final String key = trimAuthority(code);
0737:                final Object cached = get(key);
0738:                if (cached instanceof  DerivedCRS) {
0739:                    crs = (DerivedCRS) cached;
0740:                } else {
0741:                    crs = getBackingStore().createDerivedCRS(code);
0742:                }
0743:                put(key, crs);
0744:                return crs;
0745:            }
0746:
0747:            /**
0748:             * Returns an engineering coordinate reference system from a code.
0749:             */
0750:            public synchronized EngineeringCRS createEngineeringCRS(
0751:                    final String code) throws FactoryException {
0752:                final EngineeringCRS crs;
0753:                final String key = trimAuthority(code);
0754:                final Object cached = get(key);
0755:                if (cached instanceof  EngineeringCRS) {
0756:                    crs = (EngineeringCRS) cached;
0757:                } else {
0758:                    crs = getBackingStore().createEngineeringCRS(code);
0759:                }
0760:                put(key, crs);
0761:                return crs;
0762:            }
0763:
0764:            /**
0765:             * Returns a geographic coordinate reference system from a code.
0766:             */
0767:            public synchronized GeographicCRS createGeographicCRS(
0768:                    final String code) throws FactoryException {
0769:                final GeographicCRS crs;
0770:                final String key = trimAuthority(code);
0771:                final Object cached = get(key);
0772:                if (cached instanceof  GeographicCRS) {
0773:                    crs = (GeographicCRS) cached;
0774:                } else {
0775:                    crs = getBackingStore().createGeographicCRS(code);
0776:                }
0777:                put(key, crs);
0778:                return crs;
0779:            }
0780:
0781:            /**
0782:             * Returns a geocentric coordinate reference system from a code.
0783:             */
0784:            public synchronized GeocentricCRS createGeocentricCRS(
0785:                    final String code) throws FactoryException {
0786:                final GeocentricCRS crs;
0787:                final String key = trimAuthority(code);
0788:                final Object cached = get(key);
0789:                if (cached instanceof  GeocentricCRS) {
0790:                    crs = (GeocentricCRS) cached;
0791:                } else {
0792:                    crs = getBackingStore().createGeocentricCRS(code);
0793:                }
0794:                put(key, crs);
0795:                return crs;
0796:            }
0797:
0798:            /**
0799:             * Returns an image coordinate reference system from a code.
0800:             */
0801:            public synchronized ImageCRS createImageCRS(final String code)
0802:                    throws FactoryException {
0803:                final ImageCRS crs;
0804:                final String key = trimAuthority(code);
0805:                final Object cached = get(key);
0806:                if (cached instanceof  ImageCRS) {
0807:                    crs = (ImageCRS) cached;
0808:                } else {
0809:                    crs = getBackingStore().createImageCRS(code);
0810:                }
0811:                put(key, crs);
0812:                return crs;
0813:            }
0814:
0815:            /**
0816:             * Returns a projected coordinate reference system from a code.
0817:             */
0818:            public synchronized ProjectedCRS createProjectedCRS(
0819:                    final String code) throws FactoryException {
0820:                final ProjectedCRS crs;
0821:                final String key = trimAuthority(code);
0822:                final Object cached = get(key);
0823:                if (cached instanceof  ProjectedCRS) {
0824:                    crs = (ProjectedCRS) cached;
0825:                } else {
0826:                    crs = getBackingStore().createProjectedCRS(code);
0827:                }
0828:                put(key, crs);
0829:                return crs;
0830:            }
0831:
0832:            /**
0833:             * Returns a temporal coordinate reference system from a code.
0834:             */
0835:            public synchronized TemporalCRS createTemporalCRS(final String code)
0836:                    throws FactoryException {
0837:                final TemporalCRS crs;
0838:                final String key = trimAuthority(code);
0839:                final Object cached = get(key);
0840:                if (cached instanceof  TemporalCRS) {
0841:                    crs = (TemporalCRS) cached;
0842:                } else {
0843:                    crs = getBackingStore().createTemporalCRS(code);
0844:                }
0845:                put(key, crs);
0846:                return crs;
0847:            }
0848:
0849:            /**
0850:             * Returns a vertical coordinate reference system from a code.
0851:             */
0852:            public synchronized VerticalCRS createVerticalCRS(final String code)
0853:                    throws FactoryException {
0854:                final VerticalCRS crs;
0855:                final String key = trimAuthority(code);
0856:                final Object cached = get(key);
0857:                if (cached instanceof  VerticalCRS) {
0858:                    crs = (VerticalCRS) cached;
0859:                } else {
0860:                    crs = getBackingStore().createVerticalCRS(code);
0861:                }
0862:                put(key, crs);
0863:                return crs;
0864:            }
0865:
0866:            /**
0867:             * Returns a parameter descriptor from a code. 
0868:             *
0869:             * @since 2.2
0870:             */
0871:            public synchronized ParameterDescriptor createParameterDescriptor(
0872:                    final String code) throws FactoryException {
0873:                final ParameterDescriptor parameter;
0874:                final String key = trimAuthority(code);
0875:                final Object cached = get(key);
0876:                if (cached instanceof  ParameterDescriptor) {
0877:                    parameter = (ParameterDescriptor) cached;
0878:                } else {
0879:                    parameter = getBackingStore().createParameterDescriptor(
0880:                            code);
0881:                }
0882:                put(key, parameter);
0883:                return parameter;
0884:            }
0885:
0886:            /**
0887:             * Returns an operation method from a code. 
0888:             *
0889:             * @since 2.2
0890:             */
0891:            public synchronized OperationMethod createOperationMethod(
0892:                    final String code) throws FactoryException {
0893:                final OperationMethod method;
0894:                final String key = trimAuthority(code);
0895:                final Object cached = get(key);
0896:                if (cached instanceof  OperationMethod) {
0897:                    method = (OperationMethod) cached;
0898:                } else {
0899:                    method = getBackingStore().createOperationMethod(code);
0900:                }
0901:                put(key, method);
0902:                return method;
0903:            }
0904:
0905:            /**
0906:             * Returns an operation from a single operation code. 
0907:             *
0908:             * @since 2.2
0909:             */
0910:            public synchronized CoordinateOperation createCoordinateOperation(
0911:                    final String code) throws FactoryException {
0912:                final CoordinateOperation operation;
0913:                final String key = trimAuthority(code);
0914:                final Object cached = get(key);
0915:                if (cached instanceof  CoordinateOperation) {
0916:                    operation = (CoordinateOperation) cached;
0917:                } else {
0918:                    operation = getBackingStore().createCoordinateOperation(
0919:                            code);
0920:                }
0921:                put(key, operation);
0922:                return operation;
0923:            }
0924:
0925:            /**
0926:             * Returns an operation from coordinate reference system codes.
0927:             *
0928:             * @since 2.2
0929:             */
0930:            public synchronized Set/*<CoordinateOperation>*/createFromCoordinateReferenceSystemCodes(
0931:                    final String sourceCode, final String targetCode)
0932:                    throws FactoryException {
0933:                final Set/*<CoordinateOperation>*/operations;
0934:                final CodePair key = new CodePair(trimAuthority(sourceCode),
0935:                        trimAuthority(targetCode));
0936:                final Object cached = get(key);
0937:                if (cached instanceof  Set/*<CoordinateOperation>*/) {
0938:                    operations = (Set/*<CoordinateOperation>*/) cached;
0939:                } else {
0940:                    operations = Collections.unmodifiableSet(getBackingStore()
0941:                            .createFromCoordinateReferenceSystemCodes(
0942:                                    sourceCode, targetCode));
0943:                }
0944:                put(key, operations);
0945:                return operations;
0946:            }
0947:
0948:            /**
0949:             * A pair of codes for operations to cache with
0950:             * {@link #createFromCoordinateReferenceSystemCodes}.
0951:             */
0952:            private static final class CodePair {
0953:                private final String source, target;
0954:
0955:                public CodePair(final String source, final String target) {
0956:                    this .source = source;
0957:                    this .target = target;
0958:                }
0959:
0960:                public int hashCode() {
0961:                    int code = 0;
0962:                    if (source != null)
0963:                        code = source.hashCode();
0964:                    if (target != null)
0965:                        code += target.hashCode() * 37;
0966:                    return code;
0967:                }
0968:
0969:                public boolean equals(final Object other) {
0970:                    if (other instanceof  CodePair) {
0971:                        final CodePair that = (CodePair) other;
0972:                        return Utilities.equals(this .source, that.source)
0973:                                && Utilities.equals(this .target, that.target);
0974:                    }
0975:                    return false;
0976:                }
0977:
0978:                public String toString() {
0979:                    return source + " \u21E8 " + target;
0980:                }
0981:            }
0982:
0983:            /**
0984:             * Returns a finder which can be used for looking up unidentified objects.
0985:             * The default implementation delegates lookup to the underlying backing
0986:             * store and caches the result.
0987:             *
0988:             * @since 2.4
0989:             */
0990:            //@Override
0991:            public synchronized IdentifiedObjectFinder getIdentifiedObjectFinder(
0992:                    final Class/*<? extends IdentifiedObject>*/type)
0993:                    throws FactoryException {
0994:                return new Finder(getBackingStore().getIdentifiedObjectFinder(
0995:                        type));
0996:            }
0997:
0998:            /**
0999:             * An implementation of {@link IdentifiedObjectFinder} which delegates
1000:             * the work to the underlying backing store and caches the result.
1001:             * <p>
1002:             * <b>Implementation note:</b> we will create objects using directly the underlying backing
1003:             * store, not using the cache. This is because hundred of objects may be created during a
1004:             * scan while only one will be typically retained. We don't want to overload the cache with
1005:             * every false candidates that we encounter during the scan.
1006:             */
1007:            private final class Finder extends IdentifiedObjectFinder.Adapter {
1008:                /**
1009:                 * Creates a finder for the underlying backing store.
1010:                 */
1011:                Finder(final IdentifiedObjectFinder finder) {
1012:                    super (finder);
1013:                }
1014:
1015:                /**
1016:                 * Looks up an object from this authority factory which is equals, ignoring metadata,
1017:                 * to the specified object. The default implementation performs the same lookup than
1018:                 * the backing store and caches the result.
1019:                 */
1020:                //@Override
1021:                public IdentifiedObject find(final IdentifiedObject object)
1022:                        throws FactoryException {
1023:                    /*
1024:                     * Do not synchronize on 'BufferedAuthorityFactory.this'. This method may take a
1025:                     * while to execute and we don't want to block other threads. The synchronizations
1026:                     * in the 'create' methods and in the 'findPool' map should be suffisient.
1027:                     *
1028:                     * TODO: avoid to search for the same object twice. For now we consider that this
1029:                     *       is not a big deal if the same object is searched twice; it is "just" a
1030:                     *       waste of CPU.
1031:                     */
1032:                    IdentifiedObject candidate;
1033:                    synchronized (findPool) {
1034:                        candidate = (IdentifiedObject) findPool.get(object);
1035:                    }
1036:                    if (candidate == null) {
1037:                        // Must delegates to 'finder' (not to 'super') in order to take
1038:                        // advantage of the method overriden by AllAuthoritiesFactory.
1039:                        candidate = finder.find(object);
1040:                        if (candidate != null) {
1041:                            synchronized (findPool) {
1042:                                findPool.put(object, candidate);
1043:                            }
1044:                        }
1045:                    }
1046:                    return candidate;
1047:                }
1048:
1049:                /**
1050:                 * Returns the identifier for the specified object.
1051:                 */
1052:                //@Override
1053:                public String findIdentifier(final IdentifiedObject object)
1054:                        throws FactoryException {
1055:                    IdentifiedObject candidate;
1056:                    synchronized (findPool) {
1057:                        candidate = (IdentifiedObject) findPool.get(object);
1058:                    }
1059:                    if (candidate != null) {
1060:                        return getIdentifier(candidate);
1061:                    }
1062:                    // We don't rely on super-class implementation, because we want to
1063:                    // take advantage of the method overriden by AllAuthoritiesFactory.
1064:                    return finder.findIdentifier(object);
1065:                }
1066:            }
1067:
1068:            /**
1069:             * Releases resources immediately instead of waiting for the garbage collector.
1070:             */
1071:            public synchronized void dispose() throws FactoryException {
1072:                if (backingStore != null) {
1073:                    backingStore.dispose();
1074:                    backingStore = null;
1075:                }
1076:                pool.clear();
1077:                super .dispose();
1078:            }
1079:
1080:            /**
1081:             * Returns an object from the pool for the specified code. If the object was retained as a
1082:             * {@linkplain Reference weak reference}, the {@link Reference#get referent} is returned.
1083:             *
1084:             * @todo Consider logging a message here to the finer or finest level.
1085:             */
1086:            private Object get(final Object key) {
1087:                assert Thread.holdsLock(this );
1088:                Object object = pool.get(key);
1089:                if (object instanceof  Reference) {
1090:                    object = ((Reference) object).get();
1091:                }
1092:                return object;
1093:            }
1094:
1095:            /**
1096:             * Put an element in the pool. This method is invoked everytime a {@code createFoo(...)}
1097:             * method is invoked, even if an object was already in the pool for the given code, for
1098:             * the following reasons: 1) Replaces weak reference by strong reference (if applicable)
1099:             * and 2) Alters the linked hash set order, so that this object is declared as the last
1100:             * one used.
1101:             */
1102:            private void put(final Object key, final Object object) {
1103:                assert Thread.holdsLock(this );
1104:                pool.put(key, object);
1105:                int toReplace = pool.size() - maxStrongReferences;
1106:                if (toReplace > 0) {
1107:                    for (final Iterator it = pool.entrySet().iterator(); it
1108:                            .hasNext();) {
1109:                        final Map.Entry entry = (Map.Entry) it.next();
1110:                        final Object value = entry.getValue();
1111:                        if (value instanceof  Reference) {
1112:                            if (((Reference) value).get() == null) {
1113:                                it.remove();
1114:                            }
1115:                            continue;
1116:                        }
1117:                        entry.setValue(new WeakReference(value));
1118:                        if (--toReplace == 0) {
1119:                            break;
1120:                        }
1121:                    }
1122:                }
1123:            }
1124:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.