Source Code Cross Referenced for Enum.java in  » Library » Apache-common-lang » org » apache » commons » lang » enums » 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 » Library » Apache common lang » org.apache.commons.lang.enums 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.commons.lang.enums;
018:
019:        import java.io.Serializable;
020:        import java.lang.reflect.InvocationTargetException;
021:        import java.lang.reflect.Method;
022:        import java.util.ArrayList;
023:        import java.util.Collections;
024:        import java.util.HashMap;
025:        import java.util.WeakHashMap;
026:        import java.util.Iterator;
027:        import java.util.List;
028:        import java.util.Map;
029:
030:        import org.apache.commons.lang.ClassUtils;
031:        import org.apache.commons.lang.StringUtils;
032:
033:        /**
034:         * <p>Abstract superclass for type-safe enums.</p>
035:         *
036:         * <p>One feature of the C programming language lacking in Java is enumerations. The
037:         * C implementation based on ints was poor and open to abuse. The original Java
038:         * recommendation and most of the JDK also uses int constants. It has been recognised
039:         * however that a more robust type-safe class-based solution can be designed. This
040:         * class follows the basic Java type-safe enumeration pattern.</p>
041:         *
042:         * <p><em>NOTE:</em> Due to the way in which Java ClassLoaders work, comparing
043:         * Enum objects should always be done using <code>equals()</code>, not <code>==</code>.
044:         * The equals() method will try == first so in most cases the effect is the same.</p>
045:         * 
046:         * <p>Of course, if you actually want (or don't mind) Enums in different class
047:         * loaders being non-equal, then you can use <code>==</code>.</p>
048:         * 
049:         * <h4>Simple Enums</h4>
050:         *
051:         * <p>To use this class, it must be subclassed. For example:</p>
052:         *
053:         * <pre>
054:         * public final class ColorEnum extends Enum {
055:         *   public static final ColorEnum RED = new ColorEnum("Red");
056:         *   public static final ColorEnum GREEN = new ColorEnum("Green");
057:         *   public static final ColorEnum BLUE = new ColorEnum("Blue");
058:         *
059:         *   private ColorEnum(String color) {
060:         *     super(color);
061:         *   }
062:         * 
063:         *   public static ColorEnum getEnum(String color) {
064:         *     return (ColorEnum) getEnum(ColorEnum.class, color);
065:         *   }
066:         * 
067:         *   public static Map getEnumMap() {
068:         *     return getEnumMap(ColorEnum.class);
069:         *   }
070:         * 
071:         *   public static List getEnumList() {
072:         *     return getEnumList(ColorEnum.class);
073:         *   }
074:         * 
075:         *   public static Iterator iterator() {
076:         *     return iterator(ColorEnum.class);
077:         *   }
078:         * }
079:         * </pre>
080:         *
081:         * <p>As shown, each enum has a name. This can be accessed using <code>getName</code>.</p>
082:         *
083:         * <p>The <code>getEnum</code> and <code>iterator</code> methods are recommended.
084:         * Unfortunately, Java restrictions require these to be coded as shown in each subclass.
085:         * An alternative choice is to use the {@link EnumUtils} class.</p>
086:         * 
087:         * <h4>Subclassed Enums</h4>
088:         * <p>A hierarchy of Enum classes can be built. In this case, the superclass is
089:         * unaffected by the addition of subclasses (as per normal Java). The subclasses
090:         * may add additional Enum constants <em>of the type of the superclass</em>. The
091:         * query methods on the subclass will return all of the Enum constants from the
092:         * superclass and subclass.</p>
093:         *
094:         * <pre>
095:         * public final class ExtraColorEnum extends ColorEnum {
096:         *   // NOTE: Color enum declared above is final, change that to get this
097:         *   // example to compile.
098:         *   public static final ColorEnum YELLOW = new ExtraColorEnum("Yellow");
099:         *
100:         *   private ExtraColorEnum(String color) {
101:         *     super(color);
102:         *   }
103:         * 
104:         *   public static ColorEnum getEnum(String color) {
105:         *     return (ColorEnum) getEnum(ExtraColorEnum.class, color);
106:         *   }
107:         * 
108:         *   public static Map getEnumMap() {
109:         *     return getEnumMap(ExtraColorEnum.class);
110:         *   }
111:         * 
112:         *   public static List getEnumList() {
113:         *     return getEnumList(ExtraColorEnum.class);
114:         *   }
115:         * 
116:         *   public static Iterator iterator() {
117:         *     return iterator(ExtraColorEnum.class);
118:         *   }
119:         * }
120:         * </pre>
121:         *
122:         * <p>This example will return RED, GREEN, BLUE, YELLOW from the List and iterator
123:         * methods in that order. The RED, GREEN and BLUE instances will be the same (==) 
124:         * as those from the superclass ColorEnum. Note that YELLOW is declared as a
125:         * ColorEnum and not an ExtraColorEnum.</p>
126:         * 
127:         * <h4>Functional Enums</h4>
128:         *
129:         * <p>The enums can have functionality by defining subclasses and
130:         * overriding the <code>getEnumClass()</code> method:</p>
131:         * 
132:         * <pre>
133:         *   public static final OperationEnum PLUS = new PlusOperation();
134:         *   private static final class PlusOperation extends OperationEnum {
135:         *     private PlusOperation() {
136:         *       super("Plus");
137:         *     }
138:         *     public int eval(int a, int b) {
139:         *       return a + b;
140:         *     }
141:         *   }
142:         *   public static final OperationEnum MINUS = new MinusOperation();
143:         *   private static final class MinusOperation extends OperationEnum {
144:         *     private MinusOperation() {
145:         *       super("Minus");
146:         *     }
147:         *     public int eval(int a, int b) {
148:         *       return a - b;
149:         *     }
150:         *   }
151:         *
152:         *   private OperationEnum(String color) {
153:         *     super(color);
154:         *   }
155:         * 
156:         *   public final Class getEnumClass() {     // NOTE: new method!
157:         *     return OperationEnum.class;
158:         *   }
159:         *
160:         *   public abstract double eval(double a, double b);
161:         * 
162:         *   public static OperationEnum getEnum(String name) {
163:         *     return (OperationEnum) getEnum(OperationEnum.class, name);
164:         *   }
165:         * 
166:         *   public static Map getEnumMap() {
167:         *     return getEnumMap(OperationEnum.class);
168:         *   }
169:         * 
170:         *   public static List getEnumList() {
171:         *     return getEnumList(OperationEnum.class);
172:         *   }
173:         * 
174:         *   public static Iterator iterator() {
175:         *     return iterator(OperationEnum.class);
176:         *   }
177:         * }
178:         * </pre>
179:         * <p>The code above will work on JDK 1.2. If JDK1.3 and later is used,
180:         * the subclasses may be defined as anonymous.</p>
181:         * 
182:         * <h4>Nested class Enums</h4>
183:         *
184:         * <p>Care must be taken with class loading when defining a static nested class
185:         * for enums. The static nested class can be loaded without the surrounding outer
186:         * class being loaded. This can result in an empty list/map/iterator being returned.
187:         * One solution is to define a static block that references the outer class where
188:         * the constants are defined. For example:</p>
189:         *
190:         * <pre>
191:         * public final class Outer {
192:         *   public static final BWEnum BLACK = new BWEnum("Black");
193:         *   public static final BWEnum WHITE = new BWEnum("White");
194:         *
195:         *   // static nested enum class
196:         *   public static final class BWEnum extends Enum {
197:         * 
198:         *     static {
199:         *       // explicitly reference BWEnum class to force constants to load
200:         *       Object obj = Outer.BLACK;
201:         *     }
202:         * 
203:         *     // ... other methods omitted
204:         *   }
205:         * }
206:         * </pre>
207:         * 
208:         * <p>Although the above solves the problem, it is not recommended. The best solution
209:         * is to define the constants in the enum class, and hold references in the outer class:
210:         *
211:         * <pre>
212:         * public final class Outer {
213:         *   public static final BWEnum BLACK = BWEnum.BLACK;
214:         *   public static final BWEnum WHITE = BWEnum.WHITE;
215:         *
216:         *   // static nested enum class
217:         *   public static final class BWEnum extends Enum {
218:         *     // only define constants in enum classes - private if desired
219:         *     private static final BWEnum BLACK = new BWEnum("Black");
220:         *     private static final BWEnum WHITE = new BWEnum("White");
221:         * 
222:         *     // ... other methods omitted
223:         *   }
224:         * }
225:         * </pre>
226:         * 
227:         * <p>For more details, see the 'Nested' test cases.
228:         *
229:         * <h4>Lang Enums and Java 5.0 Enums</h4>
230:         *
231:         * <p>Enums were added to Java in Java 5.0. The main differences between Lang's 
232:         * implementation and the new official JDK implementation are: </p>
233:         * <ul>
234:         * <li>The standard Enum is a not just a superclass, but is a type baked into the 
235:         * language. </li>
236:         * <li>The standard Enum does not support extension, so the standard methods that 
237:         * are provided in the Lang enum are not available. </li>
238:         * <li>Lang mandates a String name, whereas the standard Enum uses the class 
239:         * name as its name. getName() changes to name(). </li>
240:         * </ul>
241:         *
242:         * <p>Generally people should use the standard Enum. Migrating from the Lang 
243:         * enum to the standard Enum is not as easy as it might be due to the lack of 
244:         * class inheritence in standard Enums. This means that it's not possible 
245:         * to provide a 'super-enum' which could provide the same utility methods 
246:         * that the Lang enum does. The following utility class is a Java 5.0 
247:         * version of our EnumUtils class and provides those utility methods. </p>
248:         *
249:         * <pre>
250:         * import java.util.*;
251:         * 
252:         * public class EnumUtils {
253:         * 
254:         *   public static Enum getEnum(Class enumClass, String token) {
255:         *     return Enum.valueOf(enumClass, token);
256:         *   }
257:         * 
258:         *   public static Map getEnumMap(Class enumClass) {
259:         *     HashMap map = new HashMap();
260:         *     Iterator itr = EnumUtils.iterator(enumClass);
261:         *     while(itr.hasNext()) {
262:         *       Enum enm = (Enum) itr.next();
263:         *       map.put( enm.name(), enm );
264:         *     }
265:         *     return map;
266:         *   }
267:         * 
268:         *   public static List getEnumList(Class enumClass) {
269:         *     return new ArrayList( EnumSet.allOf(enumClass) );
270:         *   }
271:         * 
272:         *   public static Iterator iterator(Class enumClass) {
273:         *     return EnumUtils.getEnumList(enumClass).iterator();
274:         *   }
275:         * }
276:         * </pre>
277:         * 
278:         * @author Apache Avalon project
279:         * @author Stephen Colebourne
280:         * @author Chris Webb
281:         * @author Mike Bowler
282:         * @author Matthias Eichel
283:         * @since 2.1 (class existed in enum package from v1.0)
284:         * @version $Id: Enum.java 466285 2006-10-20 22:36:21Z bayard $
285:         */
286:        public abstract class Enum implements  Comparable, Serializable {
287:
288:            /**
289:             * Required for serialization support.
290:             * 
291:             * @see java.io.Serializable
292:             */
293:            private static final long serialVersionUID = -487045951170455942L;
294:
295:            // After discussion, the default size for HashMaps is used, as the
296:            // sizing algorithm changes across the JDK versions
297:            /**
298:             * An empty <code>Map</code>, as JDK1.2 didn't have an empty map.
299:             */
300:            private static final Map EMPTY_MAP = Collections
301:                    .unmodifiableMap(new HashMap(0));
302:
303:            /**
304:             * <code>Map</code>, key of class name, value of <code>Entry</code>.
305:             */
306:            private static final Map cEnumClasses = new WeakHashMap();
307:
308:            /**
309:             * The string representation of the Enum.
310:             */
311:            private final String iName;
312:
313:            /**
314:             * The hashcode representation of the Enum.
315:             */
316:            private transient final int iHashCode;
317:
318:            /**
319:             * The toString representation of the Enum.
320:             * @since 2.0
321:             */
322:            protected transient String iToString = null;
323:
324:            /**
325:             * <p>Enable the iterator to retain the source code order.</p>
326:             */
327:            private static class Entry {
328:                /**
329:                 * Map of Enum name to Enum.
330:                 */
331:                final Map map = new HashMap();
332:                /**
333:                 * Map of Enum name to Enum.
334:                 */
335:                final Map unmodifiableMap = Collections.unmodifiableMap(map);
336:                /**
337:                 * List of Enums in source code order.
338:                 */
339:                final List list = new ArrayList(25);
340:                /**
341:                 * Map of Enum name to Enum.
342:                 */
343:                final List unmodifiableList = Collections
344:                        .unmodifiableList(list);
345:
346:                /**
347:                 * <p>Restrictive constructor.</p>
348:                 */
349:                protected Entry() {
350:                    super ();
351:                }
352:            }
353:
354:            /**
355:             * <p>Constructor to add a new named item to the enumeration.</p>
356:             *
357:             * @param name  the name of the enum object,
358:             *  must not be empty or <code>null</code>
359:             * @throws IllegalArgumentException if the name is <code>null</code>
360:             *  or an empty string
361:             * @throws IllegalArgumentException if the getEnumClass() method returns
362:             *  a null or invalid Class
363:             */
364:            protected Enum(String name) {
365:                super ();
366:                init(name);
367:                iName = name;
368:                iHashCode = 7 + getEnumClass().hashCode() + 3 * name.hashCode();
369:                // cannot create toString here as subclasses may want to include other data
370:            }
371:
372:            /**
373:             * Initializes the enumeration.
374:             * 
375:             * @param name  the enum name
376:             * @throws IllegalArgumentException if the name is null or empty or duplicate
377:             * @throws IllegalArgumentException if the enumClass is null or invalid
378:             */
379:            private void init(String name) {
380:                if (StringUtils.isEmpty(name)) {
381:                    throw new IllegalArgumentException(
382:                            "The Enum name must not be empty or null");
383:                }
384:
385:                Class enumClass = getEnumClass();
386:                if (enumClass == null) {
387:                    throw new IllegalArgumentException(
388:                            "getEnumClass() must not be null");
389:                }
390:                Class cls = getClass();
391:                boolean ok = false;
392:                while (cls != null && cls != Enum.class
393:                        && cls != ValuedEnum.class) {
394:                    if (cls == enumClass) {
395:                        ok = true;
396:                        break;
397:                    }
398:                    cls = cls.getSuperclass();
399:                }
400:                if (ok == false) {
401:                    throw new IllegalArgumentException(
402:                            "getEnumClass() must return a superclass of this class");
403:                }
404:
405:                // create entry
406:                Entry entry = (Entry) cEnumClasses.get(enumClass);
407:                if (entry == null) {
408:                    entry = createEntry(enumClass);
409:                    cEnumClasses.put(enumClass, entry);
410:                }
411:                if (entry.map.containsKey(name)) {
412:                    throw new IllegalArgumentException(
413:                            "The Enum name must be unique, '" + name
414:                                    + "' has already been added");
415:                }
416:                entry.map.put(name, this );
417:                entry.list.add(this );
418:            }
419:
420:            /**
421:             * <p>Handle the deserialization of the class to ensure that multiple
422:             * copies are not wastefully created, or illegal enum types created.</p>
423:             *
424:             * @return the resolved object
425:             */
426:            protected Object readResolve() {
427:                Entry entry = (Entry) cEnumClasses.get(getEnumClass());
428:                if (entry == null) {
429:                    return null;
430:                }
431:                return entry.map.get(getName());
432:            }
433:
434:            //--------------------------------------------------------------------------------
435:
436:            /**
437:             * <p>Gets an <code>Enum</code> object by class and name.</p>
438:             * 
439:             * @param enumClass  the class of the Enum to get, must not
440:             *  be <code>null</code>
441:             * @param name  the name of the <code>Enum</code> to get,
442:             *  may be <code>null</code>
443:             * @return the enum object, or <code>null</code> if the enum does not exist
444:             * @throws IllegalArgumentException if the enum class
445:             *  is <code>null</code>
446:             */
447:            protected static Enum getEnum(Class enumClass, String name) {
448:                Entry entry = getEntry(enumClass);
449:                if (entry == null) {
450:                    return null;
451:                }
452:                return (Enum) entry.map.get(name);
453:            }
454:
455:            /**
456:             * <p>Gets the <code>Map</code> of <code>Enum</code> objects by
457:             * name using the <code>Enum</code> class.</p>
458:             *
459:             * <p>If the requested class has no enum objects an empty
460:             * <code>Map</code> is returned.</p>
461:             * 
462:             * @param enumClass  the class of the <code>Enum</code> to get,
463:             *  must not be <code>null</code>
464:             * @return the enum object Map
465:             * @throws IllegalArgumentException if the enum class is <code>null</code>
466:             * @throws IllegalArgumentException if the enum class is not a subclass of Enum
467:             */
468:            protected static Map getEnumMap(Class enumClass) {
469:                Entry entry = getEntry(enumClass);
470:                if (entry == null) {
471:                    return EMPTY_MAP;
472:                }
473:                return entry.unmodifiableMap;
474:            }
475:
476:            /**
477:             * <p>Gets the <code>List</code> of <code>Enum</code> objects using the
478:             * <code>Enum</code> class.</p>
479:             *
480:             * <p>The list is in the order that the objects were created (source code order).
481:             * If the requested class has no enum objects an empty <code>List</code> is
482:             * returned.</p>
483:             * 
484:             * @param enumClass  the class of the <code>Enum</code> to get,
485:             *  must not be <code>null</code>
486:             * @return the enum object Map
487:             * @throws IllegalArgumentException if the enum class is <code>null</code>
488:             * @throws IllegalArgumentException if the enum class is not a subclass of Enum
489:             */
490:            protected static List getEnumList(Class enumClass) {
491:                Entry entry = getEntry(enumClass);
492:                if (entry == null) {
493:                    return Collections.EMPTY_LIST;
494:                }
495:                return entry.unmodifiableList;
496:            }
497:
498:            /**
499:             * <p>Gets an <code>Iterator</code> over the <code>Enum</code> objects in
500:             * an <code>Enum</code> class.</p>
501:             *
502:             * <p>The <code>Iterator</code> is in the order that the objects were
503:             * created (source code order). If the requested class has no enum
504:             * objects an empty <code>Iterator</code> is returned.</p>
505:             * 
506:             * @param enumClass  the class of the <code>Enum</code> to get,
507:             *  must not be <code>null</code>
508:             * @return an iterator of the Enum objects
509:             * @throws IllegalArgumentException if the enum class is <code>null</code>
510:             * @throws IllegalArgumentException if the enum class is not a subclass of Enum
511:             */
512:            protected static Iterator iterator(Class enumClass) {
513:                return Enum.getEnumList(enumClass).iterator();
514:            }
515:
516:            //-----------------------------------------------------------------------
517:            /**
518:             * <p>Gets an <code>Entry</code> from the map of Enums.</p>
519:             * 
520:             * @param enumClass  the class of the <code>Enum</code> to get
521:             * @return the enum entry
522:             */
523:            private static Entry getEntry(Class enumClass) {
524:                if (enumClass == null) {
525:                    throw new IllegalArgumentException(
526:                            "The Enum Class must not be null");
527:                }
528:                if (Enum.class.isAssignableFrom(enumClass) == false) {
529:                    throw new IllegalArgumentException(
530:                            "The Class must be a subclass of Enum");
531:                }
532:                Entry entry = (Entry) cEnumClasses.get(enumClass);
533:                return entry;
534:            }
535:
536:            /**
537:             * <p>Creates an <code>Entry</code> for storing the Enums.</p>
538:             *
539:             * <p>This accounts for subclassed Enums.</p>
540:             * 
541:             * @param enumClass  the class of the <code>Enum</code> to get
542:             * @return the enum entry
543:             */
544:            private static Entry createEntry(Class enumClass) {
545:                Entry entry = new Entry();
546:                Class cls = enumClass.getSuperclass();
547:                while (cls != null && cls != Enum.class
548:                        && cls != ValuedEnum.class) {
549:                    Entry loopEntry = (Entry) cEnumClasses.get(cls);
550:                    if (loopEntry != null) {
551:                        entry.list.addAll(loopEntry.list);
552:                        entry.map.putAll(loopEntry.map);
553:                        break; // stop here, as this will already have had superclasses added
554:                    }
555:                    cls = cls.getSuperclass();
556:                }
557:                return entry;
558:            }
559:
560:            //-----------------------------------------------------------------------
561:            /**
562:             * <p>Retrieve the name of this Enum item, set in the constructor.</p>
563:             * 
564:             * @return the <code>String</code> name of this Enum item
565:             */
566:            public final String getName() {
567:                return iName;
568:            }
569:
570:            /**
571:             * <p>Retrieves the Class of this Enum item, set in the constructor.</p>
572:             * 
573:             * <p>This is normally the same as <code>getClass()</code>, but for
574:             * advanced Enums may be different. If overridden, it must return a
575:             * constant value.</p>
576:             * 
577:             * @return the <code>Class</code> of the enum
578:             * @since 2.0
579:             */
580:            public Class getEnumClass() {
581:                return getClass();
582:            }
583:
584:            /**
585:             * <p>Tests for equality.</p>
586:             *
587:             * <p>Two Enum objects are considered equal
588:             * if they have the same class names and the same names.
589:             * Identity is tested for first, so this method usually runs fast.</p>
590:             * 
591:             * <p>If the parameter is in a different class loader than this instance,
592:             * reflection is used to compare the names.</p>
593:             *
594:             * @param other  the other object to compare for equality
595:             * @return <code>true</code> if the Enums are equal
596:             */
597:            public final boolean equals(Object other) {
598:                if (other == this ) {
599:                    return true;
600:                } else if (other == null) {
601:                    return false;
602:                } else if (other.getClass() == this .getClass()) {
603:                    // Ok to do a class cast to Enum here since the test above
604:                    // guarantee both
605:                    // classes are in the same class loader.
606:                    return iName.equals(((Enum) other).iName);
607:                } else {
608:                    // This and other are in different class loaders, we must check indirectly
609:                    if (other.getClass().getName().equals(
610:                            this .getClass().getName()) == false) {
611:                        return false;
612:                    }
613:                    return iName.equals(getNameInOtherClassLoader(other));
614:                }
615:            }
616:
617:            /**
618:             * <p>Returns a suitable hashCode for the enumeration.</p>
619:             *
620:             * @return a hashcode based on the name
621:             */
622:            public final int hashCode() {
623:                return iHashCode;
624:            }
625:
626:            /**
627:             * <p>Tests for order.</p>
628:             *
629:             * <p>The default ordering is alphabetic by name, but this
630:             * can be overridden by subclasses.</p>
631:             * 
632:             * <p>If the parameter is in a different class loader than this instance,
633:             * reflection is used to compare the names.</p>
634:             *
635:             * @see java.lang.Comparable#compareTo(Object)
636:             * @param other  the other object to compare to
637:             * @return -ve if this is less than the other object, +ve if greater
638:             *  than, <code>0</code> of equal
639:             * @throws ClassCastException if other is not an Enum
640:             * @throws NullPointerException if other is <code>null</code>
641:             */
642:            public int compareTo(Object other) {
643:                if (other == this ) {
644:                    return 0;
645:                }
646:                if (other.getClass() != this .getClass()) {
647:                    if (other.getClass().getName().equals(
648:                            this .getClass().getName())) {
649:                        return iName
650:                                .compareTo(getNameInOtherClassLoader(other));
651:                    }
652:                    throw new ClassCastException("Different enum class '"
653:                            + ClassUtils.getShortClassName(other.getClass())
654:                            + "'");
655:                }
656:                return iName.compareTo(((Enum) other).iName);
657:            }
658:
659:            /**
660:             * <p>Use reflection to return an objects class name.</p>
661:             *
662:             * @param other The object to determine the class name for
663:             * @return The class name
664:             */
665:            private String getNameInOtherClassLoader(Object other) {
666:                try {
667:                    Method mth = other.getClass().getMethod("getName", null);
668:                    String name = (String) mth.invoke(other, null);
669:                    return name;
670:                } catch (NoSuchMethodException e) {
671:                    // ignore - should never happen
672:                } catch (IllegalAccessException e) {
673:                    // ignore - should never happen
674:                } catch (InvocationTargetException e) {
675:                    // ignore - should never happen
676:                }
677:                throw new IllegalStateException("This should not happen");
678:            }
679:
680:            /**
681:             * <p>Human readable description of this Enum item.</p>
682:             * 
683:             * @return String in the form <code>type[name]</code>, for example:
684:             * <code>Color[Red]</code>. Note that the package name is stripped from
685:             * the type name.
686:             */
687:            public String toString() {
688:                if (iToString == null) {
689:                    String shortName = ClassUtils
690:                            .getShortClassName(getEnumClass());
691:                    iToString = shortName + "[" + getName() + "]";
692:                }
693:                return iToString;
694:            }
695:
696:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.