Source Code Cross Referenced for ClassChanger.java in  » GIS » GeoTools-2.4.1 » org » geotools » resources » 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.resources 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2001, 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; either
010:         *    version 2.1 of the License, or (at your option) any later version.
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:        package org.geotools.resources;
018:
019:        // Standard set of Java objects.
020:        import java.util.Date;
021:
022:        /**
023:         * A central place to register transformations between an arbitrary class and a
024:         * {@link Number}. For example, it is sometime convenient to consider {@link Date}
025:         * objects as if they were {@link Long} objects for computation purpose in generic
026:         * algorithms. Client can call the following method to convert an arbitrary object
027:         * to a {@link Number}:
028:         *
029:         * <blockquote><pre>
030:         * Object someArbitraryObject = new Date();
031:         * Number myObjectAsANumber = {@link ClassChanger#toNumber ClassChanger.toNumber}(someArbitraryObject);
032:         * </pre></blockquote>
033:         *
034:         * @since 2.0
035:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/resources/ClassChanger.java $
036:         * @version $Id: ClassChanger.java 26581 2007-08-17 18:04:30Z desruisseaux $
037:         * @author Martin Desruisseaux
038:         */
039:        public abstract class ClassChanger {
040:            /**
041:             * Wrapper classes sorted by their wide.
042:             */
043:            private static final Class[] CLASS_RANK = { Byte.class,
044:                    Short.class, Integer.class, Long.class, Float.class,
045:                    Double.class };
046:
047:            /**
048:             * Liste des classes d'objets pouvant être convertis en nombre. Cette liste
049:             * contiendra par défaut quelques instances de {@link ClassChanger} pour
050:             * quelques classes standards du Java, telle que {@link Date}. Toutefois,
051:             * d'autres objets pourront être ajoutés par la suite. Cette liste est
052:             * <u>ordonnée</u>. Les classe le plus hautes dans la hierarchie (les
053:             * classes parentes) doivent apparaître à la fin.
054:             */
055:            private static ClassChanger[] list = new ClassChanger[] { new ClassChanger(
056:                    Date.class, Long.class) {
057:                protected Number convert(final Comparable object) {
058:                    return new Long(((Date) object).getTime());
059:                }
060:
061:                protected Comparable inverseConvert(final Number value) {
062:                    return new Date(value.longValue());
063:                }
064:            } };
065:
066:            /**
067:             * Parent class for {@link #convert}'s input objects.
068:             */
069:            private final Class source;
070:
071:            /**
072:             * Parent class for {@link #convert}'s output objects.
073:             */
074:            private final Class target;
075:
076:            /**
077:             * Construct a new class changer.
078:             *
079:             * @param source Parent class for {@link #convert}'s input objects.
080:             * @param target Parent class for {@link #convert}'s output objects.
081:             */
082:            protected ClassChanger(final Class source, final Class target) {
083:                this .source = source;
084:                this .target = target;
085:                if (!Comparable.class.isAssignableFrom(source)) {
086:                    throw new IllegalArgumentException(String.valueOf(source));
087:                }
088:                if (!Number.class.isAssignableFrom(target)) {
089:                    throw new IllegalArgumentException(String.valueOf(target));
090:                }
091:            }
092:
093:            /**
094:             * Returns the numerical value for an object.
095:             *
096:             * @param  object Object to convert (may be null).
097:             * @return The object's numerical value.
098:             * @throws ClassCastException if {@code object} is not of the expected class.
099:             */
100:            protected abstract Number convert(final Comparable object)
101:                    throws ClassCastException;
102:
103:            /**
104:             * Returns an instance of the converted classe from a numerical value.
105:             *
106:             * @param  value The value to wrap.
107:             * @return An instance of the source classe.
108:             */
109:            protected abstract Comparable inverseConvert(final Number value);
110:
111:            /**
112:             * Returns a string representation for this class changer.
113:             */
114:            //@Override
115:            public String toString() {
116:                return "ClassChanger[" + source.getName()
117:                        + "\u00A0\u21E8\u00A0" + target.getName() + ']';
118:            }
119:
120:            /**
121:             * Registers a new transformation. All registered {@link ClassChanger} will
122:             * be taken in account by the {@link #toNumber} method. The example below
123:             * register a transformation for the {@link Date} class:
124:             *
125:             * <blockquote><pre>
126:             * &nbsp;ClassChanger.register(new ClassChanger(Date.class, Long.class) {
127:             * &nbsp;    protected Number convert(final Comparable o) {
128:             * &nbsp;        return new Long(((Date) o).getTime());
129:             * &nbsp;    }
130:             * &nbsp;
131:             * &nbsp;    protected Comparable inverseConvert(final Number number) {
132:             * &nbsp;        return new Date(number.longValue());
133:             * &nbsp;    }
134:             * &nbsp;});
135:             * </pre></blockquote>
136:             *
137:             * @param  converter The {@link ClassChanger} to add.
138:             * @throws IllegalStateException if an other {@link ClassChanger} was already
139:             *         registered for the same {@code source} class. This is usually
140:             *         not a concern since the registration usually take place during the
141:             *         class initialization ("static" constructor).
142:             */
143:            public static synchronized void register(
144:                    final ClassChanger converter) throws IllegalStateException {
145:                int i;
146:                for (i = 0; i < list.length; i++) {
147:                    if (list[i].source.isAssignableFrom(converter.source)) {
148:                        /*
149:                         * On a trouvé un convertisseur qui utilisait
150:                         * une classe parente. Le nouveau convertisseur
151:                         * devra s'insérer avant son parent. Mais on va
152:                         * d'abord s'assurer qu'il n'existait pas déjà
153:                         * un convertisseur pour cette classe.
154:                         */
155:                        for (int j = i; j < list.length; j++) {
156:                            if (list[j].source.equals(converter.source)) {
157:                                throw new IllegalStateException(list[j]
158:                                        .toString());
159:                            }
160:                        }
161:                        break;
162:                    }
163:                }
164:                list = (ClassChanger[]) XArray.insert(list, i, 1);
165:                list[i] = converter;
166:            }
167:
168:            /**
169:             * Returns the class changer for the specified classe.
170:             *
171:             * @param  source The class.
172:             * @return The class changer for the specified class.
173:             * @throws ClassNotFoundException if {@code source} is not a registered class.
174:             */
175:            private static synchronized ClassChanger getClassChanger(
176:                    final Class source) throws ClassNotFoundException {
177:                for (int i = 0; i < list.length; i++) {
178:                    if (list[i].source.isAssignableFrom(source)) {
179:                        return list[i];
180:                    }
181:                }
182:                throw new ClassNotFoundException(source.getName());
183:            }
184:
185:            /**
186:             * Returns the target class for the specified source class, if a suitable
187:             * transformation is known. The source class is a {@link Comparable} subclass
188:             * that will be specified as input to {@link #convert}. The target class is a
189:             * {@link Number} subclass that will be returned as output by {@link #convert}.
190:             * If no suitable mapping is found, then {@code source} is returned.
191:             */
192:            public static synchronized Class getTransformedClass(
193:                    final Class source) {
194:                if (source != null) {
195:                    for (int i = 0; i < list.length; i++) {
196:                        if (list[i].source.isAssignableFrom(source)) {
197:                            return list[i].target;
198:                        }
199:                    }
200:                }
201:                return source;
202:            }
203:
204:            /**
205:             * Returns the numeric value for the specified object. For example the code
206:             * <code>toNumber(new&nbsp;Date())</code> returns the {@link Date#getTime()}
207:             * value of the specified date object as a {@link Long}.
208:             *
209:             * @param  object Object to convert (may be null).
210:             * @return {@code null} if {@code object} was null; otherwise
211:             *         {@code object} if the supplied object is already an instance
212:             *         of {@link Number}; otherwise a new number with the numerical value.
213:             * @throws ClassNotFoundException if {@code object} is not an instance
214:             *         of a registered class.
215:             */
216:            public static Number toNumber(final Comparable object)
217:                    throws ClassNotFoundException {
218:                if (object != null) {
219:                    if (object instanceof  Number) {
220:                        return (Number) object;
221:                    }
222:                    return getClassChanger(object.getClass()).convert(object);
223:                }
224:                return null;
225:            }
226:
227:            /**
228:             * Wraps the specified number as an instance of the specified classe.
229:             * For example <code>toComparable(Date.class,&nbsp;new&nbsp;Long(time))</code>
230:             * is equivalent to <code>new&nbsp;Date(time)</code>. There is of course no
231:             * point to use this method if the destination class is know at compile time.
232:             * This method is useful for creating instance of classes choosen dynamically
233:             * at run time.
234:             *
235:             * @param  value  The numerical value (may be null).
236:             * @param  classe The desired classe for return value.
237:             * @throws ClassNotFoundException if {@code classe} is not a registered class.
238:             */
239:            public static Comparable toComparable(final Number value,
240:                    final Class classe) throws ClassNotFoundException {
241:                if (value != null) {
242:                    if (Number.class.isAssignableFrom(classe)) {
243:                        return (Comparable) value;
244:                    }
245:                    return getClassChanger(classe).inverseConvert(value);
246:                }
247:                return null;
248:            }
249:
250:            /**
251:             * Converts a wrapper class to a primitive class. For example this method converts
252:             * <code>{@linkplain Double}.class</code> to <code>Double.{@linkplain Double#TYPE TYPE}</code>.
253:             *
254:             * @param  c The wrapper class.
255:             * @return The primitive class.
256:             * @throws IllegalArgumentException if the specified class is not a wrapper for a primitive.
257:             */
258:            public static Class toPrimitive(final Class c)
259:                    throws IllegalArgumentException {
260:                if (Double.class.equals(c))
261:                    return Double.TYPE;
262:                if (Float.class.equals(c))
263:                    return Float.TYPE;
264:                if (Long.class.equals(c))
265:                    return Long.TYPE;
266:                if (Integer.class.equals(c))
267:                    return Integer.TYPE;
268:                if (Short.class.equals(c))
269:                    return Short.TYPE;
270:                if (Byte.class.equals(c))
271:                    return Byte.TYPE;
272:                if (Boolean.class.equals(c))
273:                    return Boolean.TYPE;
274:                if (Character.class.equals(c))
275:                    return Character.TYPE;
276:                throw new IllegalArgumentException(Utilities.getShortName(c));
277:            }
278:
279:            /**
280:             * Converts a primitive class to a wrapper class. For example this method converts
281:             * <code>Double.{@linkplain Double#TYPE TYPE}</code> to <code>{@linkplain Double}.class</code>.
282:             *
283:             * @param  c The primitive class.
284:             * @return The wrapper class.
285:             * @throws IllegalArgumentException if the specified class is not a primitive.
286:             */
287:            public static Class toWrapper(final Class c)
288:                    throws IllegalArgumentException {
289:                if (Double.TYPE.equals(c))
290:                    return Double.class;
291:                if (Float.TYPE.equals(c))
292:                    return Float.class;
293:                if (Long.TYPE.equals(c))
294:                    return Long.class;
295:                if (Integer.TYPE.equals(c))
296:                    return Integer.class;
297:                if (Short.TYPE.equals(c))
298:                    return Short.class;
299:                if (Byte.TYPE.equals(c))
300:                    return Byte.class;
301:                if (Boolean.TYPE.equals(c))
302:                    return Boolean.class;
303:                if (Character.TYPE.equals(c))
304:                    return Character.class;
305:                throw new IllegalArgumentException(Utilities.getShortName(c));
306:            }
307:
308:            /**
309:             * Casts the number to the specified class. The class must by one of {@link Byte},
310:             * {@link Short}, {@link Integer}, {@link Long}, {@link Float} or {@link Double}.
311:             *
312:             * @todo Use {@code valueOf} when we will be allowed to compile for J2SE 1.5.
313:             */
314:            public static Number cast(final Number n, final Class c) {
315:                if (n != null && !n.getClass().equals(c)) {
316:                    if (Byte.class.equals(c))
317:                        return new Byte(n.byteValue());
318:                    if (Short.class.equals(c))
319:                        return new Short(n.shortValue());
320:                    if (Integer.class.equals(c))
321:                        return new Integer(n.intValue());
322:                    if (Long.class.equals(c))
323:                        return new Long(n.longValue());
324:                    if (Float.class.equals(c))
325:                        return new Float(n.floatValue());
326:                    if (Double.class.equals(c))
327:                        return new Double(n.doubleValue());
328:                    throw new IllegalArgumentException(Utilities
329:                            .getShortName(c));
330:                }
331:                return n;
332:            }
333:
334:            /**
335:             * Returns the class of the widest type. Numbers {@code n1} and {@code n2}
336:             * must be instance of any of {@link Byte}, {@link Short}, {@link Integer}, {@link Long},
337:             * {@link Float} or {@link Double} types. At most one of the argument can be null.
338:             */
339:            public static Class getWidestClass(final Number n1, final Number n2) {
340:                return getWidestClass((n1 != null) ? n1.getClass() : null,
341:                        (n2 != null) ? n2.getClass() : null);
342:            }
343:
344:            /**
345:             * Returns the class of the widest type. Classes {@code c1} and {@code c2}
346:             * must be of any of {@link Byte}, {@link Short}, {@link Integer}, {@link Long},
347:             * {@link Float} or {@link Double} types. At most one of the argument can be null.
348:             */
349:            public static Class getWidestClass(final Class c1, final Class c2) {
350:                if (c1 == null)
351:                    return c2;
352:                if (c2 == null)
353:                    return c1;
354:                return CLASS_RANK[Math.max(getRank(c1), getRank(c2))];
355:            }
356:
357:            /**
358:             * Returns the class of the finest type. Classes {@code c1} and {@code c2}
359:             * must be of any of {@link Byte}, {@link Short}, {@link Integer}, {@link Long},
360:             * {@link Float} or {@link Double} types. At most one of the argument can be null.
361:             */
362:            public static Class getFinestClass(final Class c1, final Class c2) {
363:                if (c1 == null)
364:                    return c2;
365:                if (c2 == null)
366:                    return c1;
367:                return CLASS_RANK[Math.min(getRank(c1), getRank(c2))];
368:            }
369:
370:            /**
371:             * Returns the smallest class capable to hold the specified value.
372:             */
373:            public static Class getFinestClass(final double value) {
374:                final long lg = (long) value;
375:                if (value == lg) {
376:                    if (lg >= Byte.MIN_VALUE && lg <= Byte.MAX_VALUE)
377:                        return Byte.class;
378:                    if (lg >= Short.MIN_VALUE && lg <= Short.MAX_VALUE)
379:                        return Short.class;
380:                    if (lg >= Integer.MIN_VALUE && lg <= Integer.MAX_VALUE)
381:                        return Integer.class;
382:                    if (lg >= Short.MIN_VALUE && lg <= Long.MAX_VALUE)
383:                        return Long.class;
384:                }
385:                final float fv = (float) value;
386:                if (value == (double) fv) {
387:                    return Float.class;
388:                }
389:                return Double.class;
390:            }
391:
392:            /**
393:             * Returns the rank (in the {@link #CLASS_RANK} array) of the specified class.
394:             */
395:            private static int getRank(final Class c) {
396:                for (int i = 0; i < CLASS_RANK.length; i++) {
397:                    if (CLASS_RANK[i].isAssignableFrom(c)) {
398:                        return i;
399:                    }
400:                }
401:                throw new IllegalArgumentException(Utilities.getShortName(c));
402:            }
403:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.