Source Code Cross Referenced for NamedIdentifier.java in  » GIS » GeoTools-2.4.1 » org » geotools » referencing » 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 
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:         *    (C) 2004, Institut de Recherche pour le Développement
006:         *   
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation;
010:         *    version 2.1 of the License.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         *
017:         *    This package contains documentation from OpenGIS specifications.
018:         *    OpenGIS consortium's work is fully acknowledged here.
019:         */
020:        package org.geotools.referencing;
021:
022:        // J2SE dependencies
023:        import java.io.Serializable;
024:        import java.util.Collection;
025:        import java.util.HashMap;
026:        import java.util.Iterator;
027:        import java.util.List;
028:        import java.util.Locale;
029:        import java.util.Map;
030:        import java.util.logging.Level;
031:
032:        // OpenGIS dependencies
033:        import org.opengis.metadata.citation.Citation;
034:        import org.opengis.parameter.InvalidParameterValueException;
035:        import org.opengis.referencing.ReferenceIdentifier;
036:        import org.opengis.util.GenericName;
037:        import org.opengis.util.InternationalString;
038:        import org.opengis.util.LocalName;
039:        import org.opengis.util.NameSpace;
040:        import org.opengis.util.ScopedName;
041:
042:        // Geotools dependencies
043:        import org.geotools.resources.Utilities;
044:        import org.geotools.resources.i18n.Errors;
045:        import org.geotools.resources.i18n.ErrorKeys;
046:        import org.geotools.resources.i18n.Logging;
047:        import org.geotools.resources.i18n.LoggingKeys;
048:        import org.geotools.metadata.iso.citation.Citations;
049:        import org.geotools.util.GrowableInternationalString;
050:        import org.geotools.util.WeakValueHashMap;
051:
052:        /**
053:         * An identification of a CRS object. The main interface implemented by this class is
054:         * {@link ReferenceIdentifier}. However, this class also implements {@link GenericName}
055:         * in order to make it possible to reuse the same identifiers in the list of
056:         * {@linkplain AbstractIdentifiedObject#getAlias aliases}. Casting an alias's
057:         * {@linkplain GenericName generic name} to an {@linkplain ReferenceIdentifier identifier}
058:         * gives access to more informations, like the URL of the authority.
059:         * <P>
060:         * The {@linkplain GenericName generic name} will be infered from
061:         * {@linkplain ReferenceIdentifier identifier} attributes. More specifically, a
062:         * {@linkplain ScopedName scoped name} will be constructed using the shortest authority's
063:         * {@linkplain Citation#getAlternateTitles alternate titles} (or the
064:         * {@linkplain Citation#getTitle main title} if there is no alternate titles) as the
065:         * {@linkplain ScopedName#getScope scope}, and the {@linkplain #getCode code} as the
066:         * {@linkplain ScopedName#asLocalName head}. This heuristic rule seems raisonable
067:         * since, according ISO 19115, the {@linkplain Citation#getAlternateTitles alternate
068:         * titles} often contains abreviation (for example "DCW" as an alternative title for
069:         * "<cite>Digital Chart of the World</cite>").
070:         *
071:         * @since 2.1
072:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/NamedIdentifier.java $
073:         * @version $Id: NamedIdentifier.java 27862 2007-11-12 19:51:19Z desruisseaux $
074:         * @author Martin Desruisseaux
075:         */
076:        public class NamedIdentifier implements  ReferenceIdentifier,
077:                GenericName, Serializable {
078:            /**
079:             * Serial number for interoperability with different versions.
080:             */
081:            private static final long serialVersionUID = 8474731565582774497L;
082:
083:            /**
084:             * @todo Replace by static import once we are allowed to compile for J2SE 1.5.
085:             */
086:            private static final String REMARKS_KEY = org.opengis.referencing.IdentifiedObject.REMARKS_KEY;
087:
088:            /**
089:             * A pool of {@link LocalName} values for given {@link InternationalString}.
090:             * Will be constructed only when first needed.
091:             */
092:            private static Map SCOPES;
093:
094:            /**
095:             * Identifier code or name, optionally from a controlled list or pattern
096:             * defined by a code space.
097:             */
098:            private final String code;
099:
100:            /**
101:             * Name or identifier of the person or organization responsible for namespace.
102:             */
103:            private final String codespace;
104:
105:            /**
106:             * Organization or party responsible for definition and maintenance of the
107:             * code space or code.
108:             */
109:            private final Citation authority;
110:
111:            /**
112:             * Identifier of the version of the associated code space or code, as specified
113:             * by the code space or code authority. This version is included only when the
114:             * {@linkplain #getCode code} uses versions. When appropriate, the edition is
115:             * identified by the effective date, coded using ISO 8601 date format.
116:             */
117:            private final String version;
118:
119:            /**
120:             * Comments on or information about this identifier, or {@code null} if none.
121:             */
122:            private final InternationalString remarks;
123:
124:            /**
125:             * The name of this identifier as a generic name. If {@code null}, will
126:             * be constructed only when first needed. This field is serialized (instead
127:             * of being recreated after deserialization) because it may be a user-supplied
128:             * value.
129:             */
130:            private GenericName name;
131:
132:            /**
133:             * Constructs an identifier from a set of properties. Keys are strings from the table below.
134:             * Key are case-insensitive, and leading and trailing spaces are ignored. The map given in
135:             * argument shall contains at least a <code>"code"</code> property. Other properties listed
136:             * in the table below are optional.
137:             * <p>
138:             * <table border='1'>
139:             *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
140:             *     <th nowrap>Property name</th>
141:             *     <th nowrap>Value type</th>
142:             *     <th nowrap>Value given to</th>
143:             *   </tr>
144:             *   <tr>
145:             *     <td nowrap>&nbsp;{@link #CODE_KEY "code"}&nbsp;</td>
146:             *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
147:             *     <td nowrap>&nbsp;{@link #getCode}</td>
148:             *   </tr>
149:             *   <tr>
150:             *     <td nowrap>&nbsp;{@link #CODESPACE_KEY "code"}&nbsp;</td>
151:             *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
152:             *     <td nowrap>&nbsp;{@link #getCodeSpace}</td>
153:             *   </tr>
154:             *   <tr>
155:             *     <td nowrap>&nbsp;{@link #AUTHORITY_KEY "authority"}&nbsp;</td>
156:             *     <td nowrap>&nbsp;{@link String} or {@link Citation}&nbsp;</td>
157:             *     <td nowrap>&nbsp;{@link #getAuthority}</td>
158:             *   </tr>
159:             *   <tr>
160:             *     <td nowrap>&nbsp;{@link #VERSION_KEY "version"}&nbsp;</td>
161:             *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
162:             *     <td nowrap>&nbsp;{@link #getVersion}</td>
163:             *   </tr>
164:             *   <tr>
165:             *     <td nowrap>&nbsp;{@link #REMARKS_KEY "remarks"}&nbsp;</td>
166:             *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
167:             *     <td nowrap>&nbsp;{@link #getRemarks}</td>
168:             *   </tr>
169:             * </table>
170:             *
171:             * <P><code>"remarks"</code> is a localizable attributes which may have a language and country
172:             * code suffix. For example the <code>"remarks_fr"</code> property stands for remarks in
173:             * {@linkplain Locale#FRENCH French} and the <code>"remarks_fr_CA"</code> property stands
174:             * for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}.</P>
175:             *
176:             * @throws InvalidParameterValueException if a property has an invalid value.
177:             * @throws IllegalArgumentException if a property is invalid for some other reason.
178:             */
179:            public NamedIdentifier(final Map properties)
180:                    throws IllegalArgumentException {
181:                this (properties, true);
182:            }
183:
184:            /**
185:             * Constructs an identifier from an authority and code informations. This is a convenience
186:             * constructor for commonly-used parameters. If more control are wanted (for example adding
187:             * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
188:             *
189:             * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
190:             * @param code      The code. The {@linkplain Locale#US English name} is used
191:             *                  for the code, and the international string is used for the
192:             *                  {@linkplain GenericName generic name}.
193:             */
194:            public NamedIdentifier(final Citation authority,
195:                    final InternationalString code) {
196:                this (authority, code.toString(Locale.US));
197:                name = getName(authority, code);
198:            }
199:
200:            /**
201:             * Constructs an identifier from an authority and code informations. This is a convenience
202:             * constructor for commonly-used parameters. If more control are wanted (for example adding
203:             * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
204:             *
205:             * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
206:             * @param code      The code. This parameter is mandatory.
207:             */
208:            public NamedIdentifier(final Citation authority, final String code) {
209:                this (authority, code, null);
210:            }
211:
212:            /**
213:             * Constructs an identifier from an authority and code informations. This is a convenience
214:             * constructor for commonly-used parameters. If more control are wanted (for example adding
215:             * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
216:             *
217:             * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
218:             * @param code      The code. This parameter is mandatory.
219:             * @param version   The version, or {@code null} if none.
220:             */
221:            public NamedIdentifier(final Citation authority, final String code,
222:                    final String version) {
223:                this (toMap(authority, code, version));
224:            }
225:
226:            /**
227:             * Work around for RFE #4093999 in Sun's bug database
228:             * ("Relax constraint on placement of this()/super() call in constructors").
229:             */
230:            private static Map toMap(final Citation authority,
231:                    final String code, final String version) {
232:                final Map properties = new HashMap(4);
233:                if (authority != null)
234:                    properties.put(AUTHORITY_KEY, authority);
235:                if (code != null)
236:                    properties.put(CODE_KEY, code);
237:                if (version != null)
238:                    properties.put(VERSION_KEY, version);
239:                return properties;
240:            }
241:
242:            /**
243:             * Implementation of the constructor. The remarks in the {@code properties} will be
244:             * parsed only if the {@code standalone} argument is set to {@code true}, i.e.
245:             * this identifier is being constructed as a standalone object. If {@code false}, then
246:             * this identifier is assumed to be constructed from inside the {@link AbstractIdentifiedObject}
247:             * constructor.
248:             *
249:             * @param properties The properties to parse, as described in the public constructor.
250:             * @param standalone {@code true} for parsing "remarks" as well.
251:             *
252:             * @throws InvalidParameterValueException if a property has an invalid value.
253:             * @throws IllegalArgumentException if a property is invalid for some other reason.
254:             */
255:            NamedIdentifier(final Map properties, final boolean standalone)
256:                    throws IllegalArgumentException {
257:                ensureNonNull("properties", properties);
258:                Object code = null;
259:                Object codespace = null;
260:                Object version = null;
261:                Object authority = null;
262:                Object remarks = null;
263:                GrowableInternationalString growable = null;
264:                /*
265:                 * Iterate through each map entry. This have two purposes:
266:                 *
267:                 *   1) Ignore case (a call to properties.get("foo") can't do that)
268:                 *   2) Find localized remarks.
269:                 *
270:                 * This algorithm is sub-optimal if the map contains a lot of entries of no interest to
271:                 * this identifier. Hopefully, most users will fill a map only with usefull entries.
272:                 */
273:                String key = null;
274:                Object value = null;
275:                for (final Iterator it = properties.entrySet().iterator(); it
276:                        .hasNext();) {
277:                    final Map.Entry entry = (Map.Entry) it.next();
278:                    key = ((String) entry.getKey()).trim().toLowerCase();
279:                    value = entry.getValue();
280:                    /*
281:                     * Note: String.hashCode() is part of J2SE specification,
282:                     *       so it should not change across implementations.
283:                     */
284:                    switch (key.hashCode()) {
285:                    case 3373707: {
286:                        if (!standalone && key.equals("name")) {
287:                            code = value;
288:                            continue;
289:                        }
290:                        break;
291:                    }
292:                    case 3059181: {
293:                        if (key.equals(CODE_KEY)) {
294:                            code = value;
295:                            continue;
296:                        }
297:                        break;
298:                    }
299:                    case -1108676807: {
300:                        if (key.equals(CODESPACE_KEY)) {
301:                            codespace = value;
302:                            continue;
303:                        }
304:                        break;
305:
306:                    }
307:                    case 351608024: {
308:                        if (key.equals(VERSION_KEY)) {
309:                            version = value;
310:                            continue;
311:                        }
312:                        break;
313:                    }
314:                    case 1475610435: {
315:                        if (key.equals(AUTHORITY_KEY)) {
316:                            if (value instanceof  String) {
317:                                value = Citations.fromName(value.toString());
318:                            }
319:                            authority = value;
320:                            continue;
321:                        }
322:                        break;
323:                    }
324:                    case 1091415283: {
325:                        if (standalone && key.equals(REMARKS_KEY)) {
326:                            if (value instanceof  InternationalString) {
327:                                remarks = value;
328:                                continue;
329:                            }
330:                        }
331:                        break;
332:                    }
333:                    }
334:                    /*
335:                     * Search for additional locales (e.g. "remarks_fr").
336:                     */
337:                    if (standalone && value instanceof  String) {
338:                        if (growable == null) {
339:                            if (remarks instanceof  GrowableInternationalString) {
340:                                growable = (GrowableInternationalString) remarks;
341:                            } else {
342:                                growable = new GrowableInternationalString();
343:                            }
344:                        }
345:                        growable.add(REMARKS_KEY, key, value.toString());
346:                    }
347:                }
348:                /*
349:                 * Get the localized remarks, if it was not yet set. If a user specified remarks
350:                 * both as InternationalString and as String for some locales (which is a weird
351:                 * usage...), then current implementation discart the later with a warning.
352:                 */
353:                if (growable != null && !growable.getLocales().isEmpty()) {
354:                    if (remarks == null) {
355:                        remarks = growable;
356:                    } else {
357:                        org.geotools.util.logging.Logging.getLogger(
358:                                "org.geotools.referencing").log(
359:                                Logging.format(Level.WARNING,
360:                                        LoggingKeys.LOCALES_DISCARTED));
361:                    }
362:                }
363:                /*
364:                 * Completes the code space if it was not explicitly set. We take the first
365:                 * identifier if there is any, otherwise we take the shortest title.
366:                 */
367:                if (codespace == null && authority instanceof  Citation) {
368:                    codespace = getCodeSpace((Citation) authority);
369:                }
370:                /*
371:                 * Stores the definitive reference to the attributes. Note that casts are performed only
372:                 * there (not before). This is a wanted feature, since we want to catch ClassCastExceptions
373:                 * are rethrown them as more informative exceptions.
374:                 */
375:                try {
376:                    key = CODE_KEY;
377:                    this .code = (String) (value = code);
378:                    key = VERSION_KEY;
379:                    this .version = (String) (value = version);
380:                    key = CODESPACE_KEY;
381:                    this .codespace = (String) (value = codespace);
382:                    key = AUTHORITY_KEY;
383:                    this .authority = (Citation) (value = authority);
384:                    key = REMARKS_KEY;
385:                    this .remarks = (InternationalString) (value = remarks);
386:                } catch (ClassCastException exception) {
387:                    InvalidParameterValueException e = new InvalidParameterValueException(
388:                            Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, key,
389:                                    value), key, value);
390:                    e.initCause(exception);
391:                    throw e;
392:                }
393:                ensureNonNull(CODE_KEY, code);
394:            }
395:
396:            /**
397:             * Makes sure an argument is non-null. This is method duplicate
398:             * {@link AbstractIdentifiedObject#ensureNonNull(String, Object)}
399:             * except for the more accurate stack trace. It is duplicated
400:             * there in order to avoid a dependency to {@link AbstractIdentifiedObject}.
401:             *
402:             * @param  name   Argument name.
403:             * @param  object User argument.
404:             * @throws InvalidParameterValueException if {@code object} is null.
405:             */
406:            private static void ensureNonNull(final String name,
407:                    final Object object) throws IllegalArgumentException {
408:                if (object == null) {
409:                    throw new InvalidParameterValueException(Errors.format(
410:                            ErrorKeys.NULL_ARGUMENT_$1, name), name, object);
411:                }
412:            }
413:
414:            /**
415:             * Identifier code or name, optionally from a controlled list or pattern.
416:             *
417:             * @return The code.
418:             */
419:            public String getCode() {
420:                return code;
421:            }
422:
423:            /**
424:             * Name or identifier of the person or organization responsible for namespace.
425:             * 
426:             * @return The codespace, or {@code null} if not available.
427:             */
428:            public String getCodeSpace() {
429:                return codespace;
430:            }
431:
432:            /**
433:             * Organization or party responsible for definition and maintenance of the
434:             * {@linkplain #getCode code}.
435:             *
436:             * @return The authority, or {@code null} if not available.
437:             */
438:            public Citation getAuthority() {
439:                return authority;
440:            }
441:
442:            /**
443:             * Identifier of the version of the associated code space or code, as specified by the
444:             * code authority. This version is included only when the {@linkplain #getCode code}
445:             * uses versions. When appropriate, the edition is identified by the effective date,
446:             * coded using ISO 8601 date format.
447:             *
448:             * @return The version, or {@code null} if not available.
449:             */
450:            public String getVersion() {
451:                return version;
452:            }
453:
454:            /**
455:             * Comments on or information about this identifier, or {@code null} if none.
456:             */
457:            public InternationalString getRemarks() {
458:                return remarks;
459:            }
460:
461:            /**
462:             * Returns the generic name of this identifier. The name will be constructed
463:             * automatically the first time it will be needed. The name's scope is infered
464:             * from the shortest alternative title (if any). This heuristic rule seems raisonable
465:             * since, according ISO 19115, the {@linkplain Citation#getAlternateTitles alternate
466:             * titles} often contains abreviation (for example "DCW" as an alternative title for
467:             * "Digital Chart of the World"). If no alternative title is found or if the main title
468:             * is yet shorter, then it is used.
469:             */
470:            private GenericName getName() {
471:                // No need to synchronize; this is not a big deal if the name is created twice.
472:                if (name == null) {
473:                    name = getName(authority, code);
474:                }
475:                return name;
476:            }
477:
478:            /**
479:             * Constructs a generic name from the specified authority and code.
480:             */
481:            private GenericName getName(final Citation authority,
482:                    final CharSequence code) {
483:                if (authority == null) {
484:                    return new org.geotools.util.LocalName(code);
485:                }
486:                final CharSequence title;
487:                if (codespace != null) {
488:                    title = codespace;
489:                } else {
490:                    title = getShortestTitle(authority);
491:                }
492:                GenericName scope;
493:                synchronized (NamedIdentifier.class) {
494:                    if (SCOPES == null) {
495:                        SCOPES = new WeakValueHashMap();
496:                    }
497:                    scope = (GenericName) SCOPES.get(title);
498:                    if (scope == null) {
499:                        scope = new org.geotools.util.LocalName(title);
500:                        SCOPES.put(title, scope);
501:                    }
502:                }
503:                return new org.geotools.util.ScopedName(scope, code);
504:            }
505:
506:            /**
507:             * Returns the shortest title inferred from the specified authority.
508:             */
509:            private static InternationalString getShortestTitle(
510:                    final Citation authority) {
511:                InternationalString title = authority.getTitle();
512:                int length = title.length();
513:                final Collection alt = authority.getAlternateTitles();
514:                if (alt != null) {
515:                    for (final Iterator it = alt.iterator(); it.hasNext();) {
516:                        final InternationalString candidate = (InternationalString) it
517:                                .next();
518:                        final int candidateLength = candidate.length();
519:                        if (candidateLength > 0 && candidateLength < length) {
520:                            title = candidate;
521:                            length = candidateLength;
522:                        }
523:                    }
524:                }
525:                return title;
526:            }
527:
528:            /**
529:             * Tries to get a codespace from the specified authority. This method scan first
530:             * through the identifier, then through the titles if no suitable identifier were found.
531:             */
532:            private static String getCodeSpace(final Citation authority) {
533:                final Collection identifiers = authority.getIdentifiers();
534:                if (identifiers != null) {
535:                    for (final Iterator it = identifiers.iterator(); it
536:                            .hasNext();) {
537:                        final String identifier = (String) it.next();
538:                        if (isValidCodeSpace(identifier)) {
539:                            return identifier;
540:                        }
541:                    }
542:                }
543:                final String title = getShortestTitle(authority).toString(
544:                        Locale.US);
545:                if (isValidCodeSpace(title)) {
546:                    return title;
547:                }
548:                return null;
549:            }
550:
551:            /**
552:             * Returns {@code true} if the specified string looks like a valid code space.
553:             * This method, together with {@link #getShortestTitle}, uses somewhat heuristic
554:             * rules that may change in future Geotools versions.
555:             */
556:            private static boolean isValidCodeSpace(final String codespace) {
557:                if (codespace == null) {
558:                    return false;
559:                }
560:                for (int i = codespace.length(); --i >= 0;) {
561:                    if (!Character.isJavaIdentifierPart(codespace.charAt(i))) {
562:                        return false;
563:                    }
564:                }
565:                return true;
566:            }
567:
568:            /**
569:             * Returns the last element in the sequence of {@linkplain #getParsedNames parsed names}.
570:             *
571:             * @since 2.3
572:             */
573:            public LocalName name() {
574:                return getName().name();
575:            }
576:
577:            /**
578:             * Returns a view of this object as a local name. The local name returned by this method
579:             * will have the same {@linkplain LocalName#getScope scope} than this generic name.
580:             * 
581:             * @deprecated Replaced by {@link #name()}.
582:             */
583:            public LocalName asLocalName() {
584:                return getName().asLocalName();
585:            }
586:
587:            /**
588:             * Returns the scope (name space) in which this name is local.
589:             *
590:             * @since 2.3
591:             */
592:            public NameSpace scope() {
593:                return getName().scope();
594:            }
595:
596:            /**
597:             * Returns the scope (name space) of this generic name. If this name has no scope
598:             * (e.g. is the root), then this method returns {@code null}.
599:             * 
600:             * @deprecated Replaced by {@link #scope()}.
601:             */
602:            public GenericName getScope() {
603:                return getName().getScope();
604:            }
605:
606:            /**
607:             * Returns the depth of this name within the namespace hierarchy.
608:             *
609:             * @since 2.3
610:             */
611:            public int depth() {
612:                return getName().depth();
613:            }
614:
615:            /**
616:             * Returns the sequence of {@linkplain LocalName local names} making this generic name.
617:             * Each element in this list is like a directory name in a file path name.
618:             * The length of this sequence is the generic name depth.
619:             */
620:            public List getParsedNames() {
621:                return getName().getParsedNames();
622:            }
623:
624:            /**
625:             * Returns this name expanded with the specified scope. One may represent this operation
626:             * as a concatenation of the specified {@code name} with {@code this}.
627:             *
628:             * @since 2.3
629:             */
630:            public ScopedName push(final GenericName scope) {
631:                return getName().push(scope);
632:            }
633:
634:            /**
635:             * Returns a view of this name as a fully-qualified name.
636:             *
637:             * @since 2.3
638:             */
639:            public GenericName toFullyQualifiedName() {
640:                return getName().toFullyQualifiedName();
641:            }
642:
643:            /**
644:             * Returns a view of this object as a scoped name,
645:             * or {@code null} if this name has no scope.
646:             * 
647:             * @deprecated Replaced by {@link #toFullyQualifiedName()}.
648:             */
649:            public ScopedName asScopedName() {
650:                return getName().asScopedName();
651:            }
652:
653:            /**
654:             * Returns a local-dependent string representation of this generic name. This string
655:             * is similar to the one returned by {@link #toString} except that each element has
656:             * been localized in the {@linkplain InternationalString#toString(Locale) specified locale}.
657:             * If no international string is available, then this method returns an implementation mapping
658:             * to {@link #toString} for all locales.
659:             */
660:            public InternationalString toInternationalString() {
661:                return getName().toInternationalString();
662:            }
663:
664:            /**
665:             * Returns a string representation of this generic name. This string representation
666:             * is local-independant. It contains all elements listed by {@link #getParsedNames}
667:             * separated by an arbitrary character (usually {@code :} or {@code /}).
668:             */
669:            public String toString() {
670:                return getName().toString();
671:            }
672:
673:            /**
674:             * Compares this name with the specified object for order. Returns a negative integer,
675:             * zero, or a positive integer as this name lexicographically precedes, is equals to,
676:             * or follows the specified object.
677:             */
678:            public int compareTo(final Object object) {
679:                return getName().compareTo(object);
680:            }
681:
682:            /**
683:             * Compares this identifier with the specified object for equality.
684:             */
685:            public boolean equals(final Object object) {
686:                if (object != null && object.getClass().equals(getClass())) {
687:                    final NamedIdentifier that = (NamedIdentifier) object;
688:                    return Utilities.equals(this .code, that.code)
689:                            && Utilities.equals(this .codespace, that.codespace)
690:                            && Utilities.equals(this .version, that.version)
691:                            && Utilities.equals(this .authority, that.authority)
692:                            && Utilities.equals(this .remarks, that.remarks);
693:                }
694:                return false;
695:            }
696:
697:            /**
698:             * Returns a hash code value for this identifier.
699:             */
700:            public int hashCode() {
701:                int hash = (int) serialVersionUID;
702:                if (code != null) {
703:                    hash ^= code.hashCode();
704:                }
705:                if (version != null) {
706:                    hash = hash * 37 + version.hashCode();
707:                }
708:                return hash;
709:            }
710:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.