Source Code Cross Referenced for IdentifiedObjectFinder.java in  » GIS » GeoTools-2.4.1 » org » geotools » referencing » factory » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.referencing.factory 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2007, GeoTools Project Managment Committee (PMC)
005:         *   
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         *
016:         *    This package contains documentation from OpenGIS specifications.
017:         *    OpenGIS consortium's work is fully acknowledged here.
018:         */
019:        package org.geotools.referencing.factory;
020:
021:        // J2SE dependencies
022:        import java.util.Set;
023:        import java.util.Iterator;
024:
025:        // OpenGIS dependencies
026:        import org.opengis.util.GenericName;
027:        import org.opengis.metadata.Identifier;
028:        import org.opengis.metadata.citation.Citation;
029:        import org.opengis.referencing.IdentifiedObject;
030:        import org.opengis.referencing.AuthorityFactory;
031:        import org.opengis.referencing.FactoryException;
032:        import org.opengis.referencing.ReferenceIdentifier;
033:        import org.opengis.referencing.NoSuchAuthorityCodeException;
034:
035:        // Geotools dependencies
036:        import org.geotools.referencing.CRS;
037:        import org.geotools.referencing.AbstractIdentifiedObject;
038:        import org.geotools.metadata.iso.citation.Citations;
039:        import org.geotools.util.logging.Logging;
040:
041:        /**
042:         * Looks up an object from an {@linkplain AuthorityFactory authority factory} which is
043:         * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the specified
044:         * object. The main purpose of this class is to get a fully {@linkplain IdentifiedObject
045:         * identified object} from an incomplete one, for example from an object without
046:         * {@linkplain IdentifiedObject#getIdentifiers identifiers} or "{@code AUTHORITY[...]}"
047:         * element in <cite>Well Known Text</cite> terminology.
048:         *
049:         * @since 2.4
050:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/IdentifiedObjectFinder.java $
051:         * @version $Id: IdentifiedObjectFinder.java 27862 2007-11-12 19:51:19Z desruisseaux $
052:         * @author Martin Desruisseaux
053:         */
054:        public class IdentifiedObjectFinder {
055:            /**
056:             * The proxy for object creation.
057:             */
058:            final AuthorityFactoryProxy proxy;
059:
060:            /**
061:             * {@code true} for performing full scans, or {@code false} otherwise.
062:             */
063:            private boolean fullScan = true;
064:
065:            /**
066:             * Creates a finder using the same proxy than the specified finder.
067:             */
068:            IdentifiedObjectFinder(final IdentifiedObjectFinder finder) {
069:                this .proxy = finder.proxy;
070:            }
071:
072:            /**
073:             * Creates a finder using the specified factory. This constructor is
074:             * protected because instances of this class should not be created directly.
075:             * Use {@link AbstractAuthorityFactory#getIdentifiedObjectFinder} instead.
076:             *
077:             * @param factory The factory to scan for the identified objects.
078:             * @param type    The type of objects to lookup.
079:             */
080:            protected IdentifiedObjectFinder(final AuthorityFactory factory,
081:                    final Class/*<? extends IdentifiedObject>*/type) {
082:                proxy = AuthorityFactoryProxy.getInstance(factory, type);
083:            }
084:
085:            /*
086:             * Do NOT provide the following method:
087:             *
088:             *     public AuthorityFactory getAuthorityFactory() {
089:             *         return proxy.getAuthorityFactory();
090:             *     }
091:             *
092:             * because the returned factory may not be the one the user would expect. Some of our
093:             * AbstractAuthorityFactory implementations create proxy to the underlying backing
094:             * store rather than to the factory on which 'getIdentifiedObjectFinder()' was invoked.
095:             */
096:
097:            /**
098:             * If {@code true}, an exhaustive full scan against all registered objects
099:             * will be performed (may be slow). Otherwise only a fast lookup based on
100:             * embedded identifiers and names will be performed. The default value is
101:             * {@code true}.
102:             */
103:            public boolean isFullScanAllowed() {
104:                return fullScan;
105:            }
106:
107:            /**
108:             * Set whatever an exhaustive scan against all registered objects is allowed.
109:             * The default value is {@code true}.
110:             */
111:            public void setFullScanAllowed(final boolean fullScan) {
112:                this .fullScan = fullScan;
113:            }
114:
115:            /**
116:             * Lookups an object which is
117:             * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
118:             * specified object. The default implementation tries to instantiate some
119:             * {@linkplain IdentifiedObject identified objects} from the authority factory
120:             * specified at construction time, in the following order:
121:             * <p>
122:             * <ul>
123:             *   <li>If the specified object contains {@linkplain IdentifiedObject#getIdentifiers
124:             *       identifiers} associated to the same authority than the factory, then those
125:             *       identifiers are used for {@linkplain AuthorityFactory#createObject creating
126:             *       objects} to be tested.</li>
127:             *   <li>If the authority factory can create objects from their {@linkplain
128:             *       IdentifiedObject#getName name} in addition of identifiers, then the name and
129:             *       {@linkplain IdentifiedObject#getAlias aliases} are used for creating objects
130:             *       to be tested.</li>
131:             *   <li>If {@linkplain #isFullScanAllowed full scan is allowed}, then full
132:             *       {@linkplain #getCodeCandidates set of authority codes} are used for
133:             *       creating objects to be tested.</li>
134:             * </ul>
135:             * <p>
136:             * The first of the above created objects which is equals to the specified object in the
137:             * the sense of {@link CRS#equalsIgnoreMetadata equalsIgnoreMetadata} is returned.
138:             *
139:             * @param  object The object looked up.
140:             * @return The identified object, or {@code null} if not found.
141:             * @throws FactoryException if an error occured while creating an object.
142:             */
143:            public IdentifiedObject find(final IdentifiedObject object)
144:                    throws FactoryException {
145:                /*
146:                 * First check if one of the identifiers can be used to spot directly an
147:                 * identified object (and check it's actually equal to one in the factory).
148:                 */
149:                IdentifiedObject candidate = createFromIdentifiers(object);
150:                if (candidate != null) {
151:                    return candidate;
152:                }
153:                /*
154:                 * We are unable to find the object from its identifiers. Try a quick name lookup.
155:                 * Some implementations like the one backed by the EPSG database are capable to find
156:                 * an object from its name.
157:                 */
158:                candidate = createFromNames(object);
159:                if (candidate != null) {
160:                    return candidate;
161:                }
162:                /*
163:                 * Here we exhausted the quick paths. Bail out if the user does not want a full scan.
164:                 */
165:                return fullScan ? createFromCodes(object) : null;
166:            }
167:
168:            /**
169:             * Returns the identifier of the specified object, or {@code null} if none. The default
170:             * implementation invokes <code>{@linkplain #find find}(object)</code> and extracts the
171:             * code from the returned {@linkplain IdentifiedObject identified object}.
172:             */
173:            public String findIdentifier(final IdentifiedObject object)
174:                    throws FactoryException {
175:                final IdentifiedObject candidate = find(object);
176:                return (candidate != null) ? getIdentifier(candidate) : null;
177:            }
178:
179:            /**
180:             * Returns the identifier for the specified object.
181:             */
182:            final String getIdentifier(final IdentifiedObject object) {
183:                Citation authority = proxy.getAuthorityFactory().getAuthority();
184:                if (ReferencingFactory.ALL.equals(authority)) {
185:                    /*
186:                     * "All" is a pseudo-authority declared by AllAuthoritiesFactory. This is not a real
187:                     * authority, so we will not find any identifier if we search for this authority. We
188:                     * will rather pickup the first identifier, regardless its authority.
189:                     */
190:                    authority = null;
191:                }
192:                ReferenceIdentifier identifier = AbstractIdentifiedObject
193:                        .getIdentifier(object, authority);
194:                if (identifier == null) {
195:                    identifier = object.getName();
196:                    // Should never be null past this point, since 'name' is a mandatory attribute.
197:                }
198:                final String codespace = identifier.getCodeSpace();
199:                final String code = identifier.getCode();
200:                if (codespace != null) {
201:                    return codespace
202:                            + org.geotools.util.GenericName.DEFAULT_SEPARATOR
203:                            + code;
204:                } else {
205:                    return code;
206:                }
207:            }
208:
209:            /**
210:             * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
211:             * specified object using only the {@linkplain IdentifiedObject#getIdentifiers identifiers}.
212:             * If no such object is found, returns {@code null}.
213:             * <p>
214:             * This method may be used in order to get a fully identified object from a partially
215:             * identified one.
216:             * 
217:             * @param object The object looked up.
218:             * @return The identified object, or {@code null} if not found.
219:             * @see #createFromCodes
220:             * @see #createFromNames
221:             * @throws FactoryException if an error occured while creating an object.
222:             */
223:            final IdentifiedObject createFromIdentifiers(
224:                    final IdentifiedObject object) throws FactoryException {
225:                final Citation authority = proxy.getAuthorityFactory()
226:                        .getAuthority();
227:                final boolean isAll = ReferencingFactory.ALL.equals(authority);
228:                for (final Iterator it = object.getIdentifiers().iterator(); it
229:                        .hasNext();) {
230:                    final Identifier id = (Identifier) it.next();
231:                    if (!isAll
232:                            && !Citations.identifierMatches(authority, id
233:                                    .getAuthority())) {
234:                        // The identifier is not for this authority. Looks the other ones.
235:                        continue;
236:                    }
237:                    IdentifiedObject candidate;
238:                    try {
239:                        candidate = proxy.create(id.getCode());
240:                    } catch (NoSuchAuthorityCodeException e) {
241:                        // The identifier was not recognized. No problem, let's go on.
242:                        continue;
243:                    }
244:                    candidate = deriveEquivalent(candidate, object);
245:                    if (candidate != null) {
246:                        return candidate;
247:                    }
248:                }
249:                return null;
250:            }
251:
252:            /**
253:             * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to
254:             * the specified object using only the {@linkplain IdentifiedObject#getName name} and
255:             * {@linkplain IdentifiedObject#getAlias aliases}. If no such object is found, returns
256:             * {@code null}.
257:             * <p>
258:             * This method may be used with some {@linkplain AuthorityFactory authority factory}
259:             * implementations like the one backed by the EPSG database, which are capable to find
260:             * an object from its name when the identifier is unknown.
261:             * 
262:             * @param object The object looked up.
263:             * @return The identified object, or {@code null} if not found.
264:             * @see #createFromCodes
265:             * @see #createFromIdentifiers
266:             * @throws FactoryException if an error occured while creating an object.
267:             */
268:            final IdentifiedObject createFromNames(final IdentifiedObject object)
269:                    throws FactoryException {
270:                IdentifiedObject candidate;
271:                try {
272:                    candidate = proxy.create(object.getName().getCode());
273:                    candidate = deriveEquivalent(candidate, object);
274:                    if (candidate != null) {
275:                        return candidate;
276:                    }
277:                } catch (FactoryException e) {
278:                    /*
279:                     * The identifier was not recognized. No problem, let's go on.
280:                     * Note: we catch a more generic exception than NoSuchAuthorityCodeException
281:                     *       because this attempt may fail for various reasons (character string
282:                     *       not supported by the underlying database for primary key, duplicated
283:                     *       name found, etc.).
284:                     */
285:                }
286:                for (final Iterator it = object.getAlias().iterator(); it
287:                        .hasNext();) {
288:                    final GenericName id = (GenericName) it.next();
289:                    try {
290:                        candidate = proxy.create(id.toString());
291:                    } catch (FactoryException e) {
292:                        // The name was not recognized. No problem, let's go on.
293:                        continue;
294:                    }
295:                    candidate = deriveEquivalent(candidate, object);
296:                    if (candidate != null) {
297:                        return candidate;
298:                    }
299:                }
300:                return null;
301:            }
302:
303:            /**
304:             * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
305:             * specified object. This method scans the {@linkplain #getAuthorityCodes authority codes},
306:             * create the objects and returns the first one which is equals to the specified object in
307:             * the sense of {@link CRS#equalsIgnoreMetadata equalsIgnoreMetadata}.
308:             * <p>
309:             * This method may be used in order to get a fully {@linkplain IdentifiedObject identified
310:             * object} from an object without {@linkplain IdentifiedObject#getIdentifiers identifiers}.
311:             * <p>
312:             * Scaning the whole set of authority codes may be slow. Users should try
313:             * <code>{@linkplain #createFromIdentifiers createFromIdentifiers}(object)</code> and/or
314:             * <code>{@linkplain #createFromNames createFromNames}(object)</code> before to fallback
315:             * on this method.
316:             *
317:             * @param  object The object looked up.
318:             * @return The identified object, or {@code null} if not found.
319:             * @throws FactoryException if an error occured while scanning through authority codes.
320:             *
321:             * @see #createFromIdentifiers
322:             * @see #createFromNames
323:             */
324:            final IdentifiedObject createFromCodes(final IdentifiedObject object)
325:                    throws FactoryException {
326:                final Set/*<String>*/codes = getCodeCandidates(object);
327:                for (final Iterator it = codes.iterator(); it.hasNext();) {
328:                    final String code = (String) it.next();
329:                    IdentifiedObject candidate;
330:                    try {
331:                        candidate = proxy.create(code);
332:                    } catch (FactoryException e) {
333:                        // Some object cannot be created properly.
334:                        continue;
335:                    }
336:                    candidate = deriveEquivalent(candidate, object);
337:                    if (candidate != null) {
338:                        return candidate;
339:                    }
340:                }
341:                return null;
342:            }
343:
344:            /**
345:             * Returns a set of authority codes that <strong>may</strong> identify the same object than
346:             * the specified one. The returned set must contains the code of every objects that are
347:             * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the specified one.
348:             * However the set is not required to contains only the codes of those objects; it may
349:             * conservatively contains the code for more objects if an exact search is too expensive.
350:             * <p>
351:             * This method is invoked by the default {@link #find find} method implementation. The caller
352:             * may iterates through every returned codes, instantiate the objects and compare them with
353:             * the specified one in order to determine which codes are really applicable.
354:             * <p>
355:             * The default implementation returns the same set than
356:             * <code>{@linkplain AuthorityFactory#getAuthorityCodes getAuthorityCodes}(type)</code>
357:             * where {@code type} is the interface specified at construction type. Subclasses should
358:             * override this method in order to return a smaller set, if they can.
359:             *
360:             * @param  object The object looked up.
361:             * @return A set of code candidates.
362:             * @throws FactoryException if an error occured while fetching the set of code candidates.
363:             */
364:            protected Set/*<String>*/getCodeCandidates(
365:                    final IdentifiedObject object) throws FactoryException {
366:                return proxy.getAuthorityCodes();
367:            }
368:
369:            /*
370:             * Do NOT define the following method in IdentifiedObjectFinder's API:
371:             *
372:             *     protected IdentifiedObject create(String code) throws FactoryException {
373:             *         return proxy.create(code);
374:             *     }
375:             *
376:             * We may be tempted to put such method in order to allow BufferedAuthorityFactory to
377:             * override it with caching service,  but it conflicts with AuthorityFactoryAdapter's
378:             * work. The later (or to be more accurate, OrderedAxisAuthorityFactory) expects axis
379:             * in (latitude,longitude) order first, in order to test this CRS before to switch to
380:             * (longitude,latitude) order and test again. If the BufferedAuthorityFactory's cache
381:             * is in the way, we get directly (longitude,latitude) order and miss an opportunity
382:             * to identify the user's CRS.
383:             *
384:             * We should invoke directly AuthorityFactoryProxy.create(String) instead.
385:             */
386:
387:            /**
388:             * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
389:             * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
390:             * model. Otherwise returns {@code null}.
391:             * <p>
392:             * This method is overriden by factories that may test many flavors of
393:             * {@code candidate}, for example {@link TransformedAuthorityFactory}.
394:             *
395:             * @param  candidate An object created by the factory specified at construction time.
396:             * @return {@code candidate}, or an object derived from {@code candidate} (for example with axis
397:             *         order forced to (<var>longitude</var>, <var>latitude</var>), or {@code null} if none
398:             *         of the above is {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the
399:             *         specified model.
400:             *
401:             * @throws FactoryException if an error occured while creating a derived object.
402:             */
403:            protected IdentifiedObject deriveEquivalent(
404:                    final IdentifiedObject candidate,
405:                    final IdentifiedObject model) throws FactoryException {
406:                return CRS.equalsIgnoreMetadata(candidate, model) ? candidate
407:                        : null;
408:            }
409:
410:            /**
411:             * Returns a string representation of this finder, for debugging purpose only.
412:             */
413:            //@Override
414:            public String toString() {
415:                return proxy.toString(IdentifiedObjectFinder.class);
416:            }
417:
418:            /**
419:             * A finder which delegate part of its work to an other finder. This adapter forwards
420:             * some method calls to the underlying finder. This class should not be public, because
421:             * not all method are overriden. The choice is tuned for {@link BufferedAuthorityFactory}
422:             * and {@link AuthorityFactoryAdapter} needs and may not be appropriate in the general case.
423:             *
424:             * @author Martin Desruisseaux
425:             */
426:            static class Adapter extends IdentifiedObjectFinder {
427:                /**
428:                 * The finder on which to delegate the work.
429:                 */
430:                protected final IdentifiedObjectFinder finder;
431:
432:                /**
433:                 * Creates an adapter for the specified finder.
434:                 */
435:                protected Adapter(final IdentifiedObjectFinder finder) {
436:                    super (finder);
437:                    this .finder = finder;
438:                }
439:
440:                /**
441:                 * Set whatever an exhaustive scan against all registered objects is allowed.
442:                 */
443:                //@Override
444:                public void setFullScanAllowed(final boolean fullScan) {
445:                    finder.setFullScanAllowed(fullScan);
446:                    super .setFullScanAllowed(fullScan);
447:                }
448:
449:                /**
450:                 * Returns a set of authority codes that <strong>may</strong> identify the same object
451:                 * than the specified one. The default implementation delegates to the backing finder.
452:                 */
453:                //@Override
454:                protected Set/*<String>*/getCodeCandidates(
455:                        final IdentifiedObject object) throws FactoryException {
456:                    return finder.getCodeCandidates(object);
457:                }
458:
459:                /**
460:                 * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
461:                 * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
462:                 * model. The default implementation delegates to the backing finder.
463:                 */
464:                //@Override
465:                protected IdentifiedObject deriveEquivalent(
466:                        final IdentifiedObject candidate,
467:                        final IdentifiedObject model) throws FactoryException {
468:                    return finder.deriveEquivalent(candidate, model);
469:                }
470:            }
471:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.