Source Code Cross Referenced for PropertyAuthorityFactory.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) 2004-2006, 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:        package org.geotools.referencing.factory;
017:
018:        // J2SE dependencies
019:        import java.io.InputStream;
020:        import java.io.IOException;
021:        import java.net.URL;
022:        import java.text.ParseException;
023:        import java.util.Collections;
024:        import java.util.Iterator;
025:        import java.util.Map;
026:        import java.util.HashMap;
027:        import java.util.Properties;
028:        import java.util.Set;
029:
030:        // OpenGIS dependencies
031:        import org.opengis.metadata.citation.Citation;
032:        import org.opengis.referencing.FactoryException;
033:        import org.opengis.referencing.IdentifiedObject;
034:        import org.opengis.referencing.NoSuchAuthorityCodeException;
035:        import org.opengis.referencing.cs.CSAuthorityFactory;
036:        import org.opengis.referencing.crs.CRSAuthorityFactory;
037:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
038:        import org.opengis.referencing.datum.DatumAuthorityFactory;
039:        import org.opengis.util.InternationalString;
040:        import org.opengis.util.GenericName;
041:
042:        // Geotools dependencies
043:        import org.geotools.factory.Hints;
044:        import org.geotools.referencing.wkt.Symbols;
045:        import org.geotools.referencing.NamedIdentifier;
046:        import org.geotools.metadata.iso.citation.Citations;
047:        import org.geotools.util.DerivedSet;
048:        import org.geotools.util.NameFactory;
049:        import org.geotools.util.SimpleInternationalString;
050:        import org.geotools.resources.i18n.Errors;
051:        import org.geotools.resources.i18n.ErrorKeys;
052:
053:        /**
054:         * Default implementation for a coordinate reference system authority factory
055:         * backed by a property file. This gives some of the benificts of using the
056:         * {@linkplain org.geotools.referencing.factory.epsg.DirectEpsgFactory EPSG database backed
057:         * authority factory} (for example), in a portable property file.
058:         * <p>
059:         * This factory doesn't cache any result. Any call to a {@code createFoo} method will trig a new
060:         * WKT parsing. For caching, this factory should be wrapped in some buffered factory like
061:         * {@link BufferedAuthorityFactory}.
062:         *
063:         * @since 2.1
064:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyAuthorityFactory.java $
065:         * @version $Id: PropertyAuthorityFactory.java 29104 2008-02-06 16:00:14Z aaime $
066:         * @author Jody Garnett
067:         * @author Rueben Schulz
068:         * @author Martin Desruisseaux
069:         */
070:        public class PropertyAuthorityFactory extends DirectAuthorityFactory
071:                implements  CRSAuthorityFactory, CSAuthorityFactory,
072:                DatumAuthorityFactory {
073:            /**
074:             * The authority for this factory.
075:             */
076:            private final Citation authority;
077:
078:            /**
079:             * Same as {@link #authority}, but may contains more than one elements in some particular
080:             * cases.
081:             */
082:            private final Citation[] authorities;
083:
084:            /**
085:             * The properties object for our properties file. Keys are the authority
086:             * code for a coordinate reference system and the associated value is a 
087:             * WKT string for the CRS.
088:             * <p>
089:             * It is technically possible to add or remove elements after they have been
090:             * loaded by the constructor. However if such modification are made, then we
091:             * should update {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER} accordingly.
092:             * It may be an issue since hints are supposed to be immutable after factory
093:             * construction. For now, this class to not allow addition of elements.
094:             */
095:            private final Properties definitions = new Properties();
096:
097:            /**
098:             * An unmodifiable view of the authority keys. This view is always up to date
099:             * even if entries are added or removed in the {@linkplain #definitions} map.
100:             */
101:            private final Set codes = Collections.unmodifiableSet(definitions
102:                    .keySet());
103:
104:            /**
105:             * Views of {@link #codes} for different types. Views will be constructed only when first
106:             * needed. View are always up to date even if entries are added or removed in the
107:             * {@linkplain #definitions} map.
108:             */
109:            private transient Map filteredCodes;
110:
111:            /**
112:             * A WKT parser.
113:             */
114:            private transient Parser parser;
115:
116:            /**
117:             * Creates a factory for the specified authority from the specified file.
118:             *
119:             * @param  factories   The underlying factories used for objects creation.
120:             * @param  authority   The organization or party responsible for definition and maintenance of
121:             *                     the database.
122:             * @param  definitions URL to the definition file.
123:             * @throws IOException if the definitions can't be read.
124:             */
125:            public PropertyAuthorityFactory(
126:                    final ReferencingFactoryContainer factories,
127:                    final Citation authority, final URL definitions)
128:                    throws IOException {
129:                this (factories, new Citation[] { authority }, definitions);
130:            }
131:
132:            /**
133:             * Creates a factory for the specified authorities from the specified file. More than
134:             * one authority may be specified when the CRS to create should have more than one
135:             * {@linkplain CoordinateReferenceSystem#getIdentifiers identifier}, each with the same
136:             * code but different namespace. For example a
137:             * {@linkplain org.geotools.referencing.factory.epsg.EsriExtension factory for CRS defined
138:             * by ESRI} uses the {@code "ESRI"} namespace, but also the {@code "EPSG"} namespace
139:             * because those CRS are used as extension of the EPSG database. Concequently, the same
140:             * CRS can be identified as {@code "ESRI:53001"} and {@code "EPSG:53001"}, where
141:             * {@code "53001"} is a unused code in the official EPSG database.
142:             *
143:             * @param  factories   The underlying factories used for objects creation.
144:             * @param  authorities The organizations or party responsible for definition
145:             *                     and maintenance of the database.
146:             * @param  definitions URL to the definition file.
147:             * @throws IOException if the definitions can't be read.
148:             *
149:             * @since 2.4
150:             */
151:            public PropertyAuthorityFactory(
152:                    final ReferencingFactoryContainer factories,
153:                    final Citation[] authorities, final URL definitions)
154:                    throws IOException {
155:                super (factories, MINIMUM_PRIORITY + 10);
156:                // The following hints have no effect on this class behaviour,
157:                // but tell to the user what this factory do about axis order.
158:                hints.put(Hints.FORCE_STANDARD_AXIS_DIRECTIONS, Boolean.FALSE);
159:                hints.put(Hints.FORCE_STANDARD_AXIS_UNITS, Boolean.FALSE);
160:                ensureNonNull("authorities", authorities);
161:                if (authorities.length == 0) {
162:                    throw new IllegalArgumentException(Errors
163:                            .format(ErrorKeys.EMPTY_ARRAY));
164:                }
165:                this .authorities = (Citation[]) authorities.clone();
166:                authority = authorities[0];
167:                ensureNonNull("authority", authority);
168:                final InputStream in = definitions.openStream();
169:                this .definitions.load(in);
170:                in.close();
171:                /*
172:                 * If the WKT do not contains any AXIS[...] element, then every CRS will be created with
173:                 * the default (longitude,latitude) axis order. In such case this factory is insensitive
174:                 * to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint (i.e. every CRS to be created by this
175:                 * instance are invariant under the above-cited hint value) and we can remove it from
176:                 * the hint map. Removing this hint allow the CRS.decode(..., true) convenience method
177:                 * to find this factory (GEOT-1175).
178:                 */
179:                final Symbols s = Symbols.DEFAULT;
180:                for (final Iterator it = this .definitions.values().iterator(); it
181:                        .hasNext();) {
182:                    final String wkt = (String) it.next();
183:                    if (s.containsAxis(wkt)) {
184:                        LOGGER
185:                                .warning("Axis elements found in a wkt definition, the force longitude "
186:                                        + "first axis order hint might not be respected:\n"
187:                                        + wkt);
188:                    }
189:                }
190:            }
191:
192:            /**
193:             * Returns the organization or party responsible for definition and maintenance of the
194:             * database.
195:             */
196:            public Citation getAuthority() {
197:                return authority;
198:            }
199:
200:            /**  
201:             * Returns the set of authority codes of the given type. The type  
202:             * argument specify the base class. For example if this factory is 
203:             * an instance of CRSAuthorityFactory, then:
204:             * <p>
205:             * <ul>
206:             *  <li>{@code CoordinateReferenceSystem.class} asks for all authority codes accepted by
207:             *      {@link #createGeographicCRS createGeographicCRS},
208:             *      {@link #createProjectedCRS  createProjectedCRS},
209:             *      {@link #createVerticalCRS   createVerticalCRS},
210:             *      {@link #createTemporalCRS   createTemporalCRS}
211:             *      and their friends.</li>
212:             *  <li>{@code ProjectedCRS.class} asks only for authority codes accepted by
213:             *      {@link #createProjectedCRS createProjectedCRS}.</li>
214:             * </ul>
215:             *
216:             * The default implementaiton filters the set of codes based on the
217:             * {@code "PROJCS"} and {@code "GEOGCS"} at the start of the WKT strings.
218:             *
219:             * @param  type The spatial reference objects type (may be {@code Object.class}).
220:             * @return The set of authority codes for spatial reference objects of the given type.
221:             *         If this factory doesn't contains any object of the given type, then this method
222:             *         returns an empty set.
223:             * @throws FactoryException if access to the underlying database failed.
224:             */
225:            public Set getAuthorityCodes(final Class type)
226:                    throws FactoryException {
227:                if (type == null
228:                        || type.isAssignableFrom(IdentifiedObject.class)) {
229:                    return codes;
230:                }
231:                if (filteredCodes == null) {
232:                    filteredCodes = new HashMap();
233:                }
234:                synchronized (filteredCodes) {
235:                    Set filtered = (Set) filteredCodes.get(type);
236:                    if (filtered == null) {
237:                        filtered = new Codes(definitions, type);
238:                        filteredCodes.put(type, filtered);
239:                    }
240:                    return filtered;
241:                }
242:            }
243:
244:            /**
245:             * The set of codes for a specific type of CRS. This set filter the codes set in the
246:             * enclosing {@link PropertyAuthorityFactory} in order to keep only the codes for the
247:             * specified type. Filtering is performed on the fly. Consequently, this set is cheap
248:             * if the user just want to check for the existence of a particular code.
249:             */
250:            private static final class Codes extends DerivedSet/*<String, String>*/{
251:                /**
252:                 * The spatial reference objects type (may be {@code Object.class}).
253:                 */
254:                private final Class/*<? extends IdentifiedType>*/type;
255:
256:                /**
257:                 * The reference to {@link PropertyAuthorityFactory#definitions}.
258:                 */
259:                private final Map/*<String,String>*/definitions;
260:
261:                /**
262:                 * Constructs a set of codes for the specified type.
263:                 */
264:                public Codes(final Map/*<String,String>*/definitions,
265:                        final Class/*<? extends IdentifiedType>*/type) {
266:                    super (definitions.keySet());
267:                    this .definitions = definitions;
268:                    this .type = type;
269:                }
270:
271:                /**
272:                 * Returns the code if the associated key is of the expected type, or {@code null}
273:                 * otherwise.
274:                 */
275:                protected/*String*/Object baseToDerived(
276:                        final/*String*/Object element) {
277:                    final String key = (String) element;
278:                    final String wkt = (String) definitions.get(key);
279:                    final int length = wkt.length();
280:                    int i = 0;
281:                    while (i < length
282:                            && Character.isJavaIdentifierPart(wkt.charAt(i)))
283:                        i++;
284:                    Class candidate = Parser.getClassOf(wkt.substring(0, i));
285:                    if (candidate == null) {
286:                        candidate = IdentifiedObject.class;
287:                    }
288:                    return type.isAssignableFrom(candidate) ? key : null;
289:                }
290:
291:                /**
292:                 * Transforms a value in this set to a value in the base set.
293:                 */
294:                protected/*String*/Object derivedToBase(
295:                        final/*String*/Object element) {
296:                    return element;
297:                }
298:            }
299:
300:            /**
301:             * Returns the Well Know Text from a code.
302:             *
303:             * @param  code Value allocated by authority.
304:             * @return The Well Know Text (WKT) for the specified code.
305:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
306:             */
307:            public String getWKT(final String code)
308:                    throws NoSuchAuthorityCodeException {
309:                ensureNonNull("code", code);
310:                final String wkt = definitions.getProperty(trimAuthority(code));
311:                if (wkt == null) {
312:                    throw noSuchAuthorityCode(IdentifiedObject.class, code);
313:                }
314:                return wkt.trim();
315:            }
316:
317:            /**
318:             * Gets a description of the object corresponding to a code.
319:             *
320:             * @param  code Value allocated by authority.
321:             * @return A description of the object, or {@code null} if the object
322:             *         corresponding to the specified {@code code} has no description.
323:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
324:             * @throws FactoryException if the query failed for some other reason.
325:             */
326:            public InternationalString getDescriptionText(final String code)
327:                    throws NoSuchAuthorityCodeException, FactoryException {
328:                final String wkt = getWKT(code);
329:                int start = wkt.indexOf('"');
330:                if (start >= 0) {
331:                    final int end = wkt.indexOf('"', ++start);
332:                    if (end >= 0) {
333:                        return new SimpleInternationalString(wkt.substring(
334:                                start, end).trim());
335:                    }
336:                }
337:                return null;
338:            }
339:
340:            /**
341:             * Returns the parser.
342:             */
343:            private Parser getParser() {
344:                if (parser == null) {
345:                    parser = new Parser();
346:                }
347:                return parser;
348:            }
349:
350:            /**
351:             * Returns an arbitrary object from a code. If the object type is know at compile time, it is
352:             * recommended to invoke the most precise method instead of this one.
353:             *
354:             * @param  code Value allocated by authority.
355:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
356:             * @throws FactoryException if the object creation failed for some other reason.
357:             */
358:            public IdentifiedObject createObject(final String code)
359:                    throws NoSuchAuthorityCodeException, FactoryException {
360:                final String wkt = getWKT(code);
361:                final Parser parser = getParser();
362:                try {
363:                    synchronized (parser) {
364:                        parser.code = code;
365:                        return (IdentifiedObject) parser.parseObject(wkt);
366:                    }
367:                } catch (ParseException exception) {
368:                    throw new FactoryException(exception);
369:                }
370:            }
371:
372:            /**
373:             * Returns a coordinate reference system from a code. If the object type is know at compile
374:             * time, it is recommended to invoke the most precise method instead of this one.
375:             *
376:             * @param  code Value allocated by authority.
377:             * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
378:             * @throws FactoryException if the object creation failed for some other reason.
379:             */
380:            public CoordinateReferenceSystem createCoordinateReferenceSystem(
381:                    final String code) throws NoSuchAuthorityCodeException,
382:                    FactoryException {
383:                final String wkt = getWKT(code);
384:                final Parser parser = getParser();
385:                try {
386:                    synchronized (parser) {
387:                        parser.code = code;
388:                        // parseCoordinateReferenceSystem provides a slightly faster path than parseObject.
389:                        return (CoordinateReferenceSystem) parser
390:                                .parseCoordinateReferenceSystem(wkt);
391:                    }
392:                } catch (ParseException exception) {
393:                    throw new FactoryException(exception);
394:                }
395:            }
396:
397:            /**
398:             * Trims the authority scope, if present. If more than one authority were given at
399:             * {@linkplain #PropertyAuthorityFactory(ReferencingFactoryContainer, Citation[], URL)
400:             * construction time}, then any of them may appears as the scope in the supplied code.
401:             *
402:             * @param  code The code to trim.
403:             * @return The code without the authority scope.
404:             */
405:            //@Override
406:            protected String trimAuthority(String code) {
407:                code = code.trim();
408:                final GenericName name = NameFactory.create(code);
409:                final GenericName scope = name.getScope();
410:                if (scope == null) {
411:                    return code;
412:                }
413:                final String candidate = scope.toString();
414:                for (int i = 0; i < authorities.length; i++) {
415:                    if (Citations.identifierMatches(authorities[i], candidate)) {
416:                        return name.asLocalName().toString().trim();
417:                    }
418:                }
419:                return code;
420:            }
421:
422:            /**
423:             * The WKT parser for this authority factory. This parser add automatically the authority
424:             * code if it was not explicitly specified in the WKT.
425:             */
426:            private final class Parser extends
427:                    org.geotools.referencing.wkt.Parser {
428:                /**
429:                 * The authority code for the WKT to be parsed.
430:                 */
431:                String code;
432:
433:                /**
434:                 * Creates the parser.
435:                 */
436:                public Parser() {
437:                    super (Symbols.DEFAULT, factories);
438:                }
439:
440:                /**
441:                 * Add the authority code to the specified properties, if not already present.
442:                 */
443:                // @Override
444:                protected Map alterProperties(Map properties) {
445:                    Object candidate = properties
446:                            .get(IdentifiedObject.IDENTIFIERS_KEY);
447:                    if (candidate == null && code != null) {
448:                        properties = new HashMap(properties);
449:                        code = trimAuthority(code);
450:                        final Object identifiers;
451:                        if (authorities.length <= 1) {
452:                            identifiers = new NamedIdentifier(authority, code);
453:                        } else {
454:                            final NamedIdentifier[] ids = new NamedIdentifier[authorities.length];
455:                            for (int i = 0; i < ids.length; i++) {
456:                                ids[i] = new NamedIdentifier(authorities[i],
457:                                        code);
458:                            }
459:                            identifiers = ids;
460:                        }
461:                        properties.put(IdentifiedObject.IDENTIFIERS_KEY,
462:                                identifiers);
463:                    }
464:                    return super.alterProperties(properties);
465:                }
466:            }
467:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.