1 //
2 // The contents of this file are subject to the Mozilla Public
3 // License Version 1.1 (the "License"); you may not use this file
4 // except in compliance with the License. You may obtain a copy of
5 // the License at http://www.mozilla.org/MPL/
6 //
7 // Software distributed under the License is distributed on an "AS
8 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 // implied. See the License for the specific language governing
10 // rights and limitations under the License.
11 //
12 // The Original Code is eBus.
13 //
14 // The Initial Developer of the Original Code is Charles W. Rapp.
15 // Portions created by Charles W. Rapp are
16 // Copyright (C) 2001 - 2003 Charles W. Rapp.
17 // All Rights Reserved.
18 //
19 // Contributor(s):
20 //
21 // RCS ID
22 // $Id: Enum.java,v 1.2 2003/11/28 18:01:09 charlesr Exp $
23 //
24 // Change Log
25 // $Log: Enum.java,v $
26 // Revision 1.2 2003/11/28 18:01:09 charlesr
27 // Updated incorrect javadocs.
28 //
29 // Revision 1.1 2003/11/28 17:06:24 charlesr
30 // Changed _ordinal from int to Integer. This was done to allow
31 ///Enum objects to be stored in a map using their Integer
32 // _ordinal value. This allows for non-sequential ordinal values.
33 //
34 // Revision 1.0 2003/11/20 01:45:34 charlesr
35 // Initial revision
36 //
37
38 package net.sf.eBus.util;
39
40 import java.io.Serializable;
41
42 /**
43 * This is the base class for all enumerated classes. Subclasses
44 * are expected to create a <code>java.lang.Map</code> and an
45 * array to store the enumerated objects in the map using the
46 * object name as key and in the array using the object ordinal
47 * as the array index.
48 * <p>
49 * <b>Extending Enum</b>
50 * <p>
51 * Classes extending <code>Enum</code> should provide the
52 * following:
53 * <ul>
54 * <li>
55 * Have a <i>private</i> constructor which takes a least
56 * the enumerated object's name and ordinal as arguments.
57 * </li>
58 * <li>
59 * Store the enumerated objects in both an array and a
60 * <code>Map</code>. Use the ordinal as the array index and
61 * the name as the <code>Map</code>'s key. <b>Note:</b>
62 * because the ordinal is used as an array index, you should
63 * number the enumerated objects sequentially starting from
64 * <code>0</code>.
65 * </li>
66 * <li>
67 * Define each enumerated object as a public static final
68 * data member.
69 * </li>
70 * <li>
71 * Provide two methods to translate an ordinal or name into
72 * an enumerated object:
73 * <p>
74 * <pre>
75 public static MyEnum valueOf(int ordinal)
76 throws ArrayIndexOutOfBoundsException
77 {
78 return (_OrdinalMap.get(_ordinal));
79 }
80
81 public static MyEnum valueOf(String name)
82 {
83 return ((MyEnum) _NameMap.get(name));
84 }
85 * </li>
86 * </ul>
87 * <p>
88 * See {@link net.sf.eBus.util.logging.ReportFrequencyEnum} for
89 * an Enum example.
90 * <p>
91 * <b>Serializing an Enum</b>
92 * <p>
93 * Because all enumerated objects are statically instantiated
94 * and applications depending on == working for two separate
95 * references to the same enumeration object, serialization
96 * must reuse those existing enumeration objects and not create
97 * new ones. If you are extending <code>Enum</code> and need to
98 * serialize your enumeration objects, then do the following:
99 * <ul>
100 * <li>
101 * Have your enumeration class implement
102 * <code>java.io.Serliazable</code> interface.
103 * </li>
104 * <li>
105 * Make all member data transient. The <code>Enum</code>
106 * base class will serialize only the _ordinal.
107 * <li>
108 * This method translates the deserialized ordinal
109 * back into one of the existing references:
110 * <p>
111 * <pre>
112 private Object readResolve()
113 throws ObjectStreamException
114 {
115 MyEnum retval = (MyEnum) _ordinalMap.get(_ordinal);
116
117 if (retval == null)
118 {
119 throw (
120 new InvalidObjectException(
121 "invalid ordinal (" + _ordinal + ")"));
122 }
123
124 return (retval);
125 }
126 * </pre>
127 * </li>
128 * </ul>
129 *
130 * @author <a href="mailto:rapp@acm.org">Charles Rapp</a>
131 */
132
133 public abstract class Enum
134 implements Comparable,
135 Serializable
136 {
137 // Member methods.
138
139 /**
140 * Returns the enum name.
141 * @return the enum name.
142 */
143 public String toString()
144 {
145 return (_name);
146 }
147
148 /**
149 * Returns <code>true</code> if <code>obj</code> is equal to
150 * <code>this ClassTypeEnum</code> and <code>false</code>
151 * otherwise.
152 * @return <code>true</code> if:
153 * <ol>
154 * <li>
155 * <code>obj</code> is not <code>null</code>.
156 * </li>
157 * <li>
158 * <code>obj</code> is a <code>ClassTypeEnum</code>
159 * object.
160 * </li>
161 * <li>
162 * <code>obj</code>'s ordinal is equal to
163 * <code>this</code>
164 * object's ordinal.
165 * </li>
166 * </ol>
167 * Otherwise, <code>false</code> is returned.
168 */
169 public boolean equals(Object obj)
170 {
171 boolean retcode = false;
172
173 if (obj == this)
174 {
175 retcode = true;
176 }
177 else if (obj != null &&
178 obj.getClass().equals(getClass()) == true)
179 {
180 try
181 {
182 Enum enumObj = (Enum) obj;
183
184 retcode = enumObj._ordinal.equals(_ordinal);
185 }
186 catch (ClassCastException castex)
187 {
188 // The return code is already set to false.
189 }
190 }
191
192 return (retcode);
193 }
194
195 /**
196 * Returns a value less than, equal to or greater than
197 * 0 if <code>this Enum</code> is less than,
198 * equal to or greater than <code>obj</code>.
199 * @param obj another <code>Enum</code> object.
200 * @return < 0 if this <code>Enum</code>
201 * is less than <code>obj</code>; 0 if they are equal and
202 * > 0 if this object is less than <code>obj</code>.
203 * @exception ClassCastException
204 * if <code>obj</code> is a different class than
205 * <code>this</code> enumerated object.
206 */
207 public int compareTo(Object obj)
208 {
209 Class clazz = obj.getClass();
210
211 if (clazz.equals(getClass()) == false)
212 {
213 throw (
214 new ClassCastException());
215 }
216
217 return (_ordinal.compareTo(((Enum) obj)._ordinal));
218 }
219
220 /**
221 * Returns the ordinal value as the hash code.
222 * @return the ordinal value as the hash code.
223 */
224 public int hashCode()
225 {
226 return (_ordinal.hashCode());
227 }
228
229 /**
230 * Returns the enum's textual name.
231 * @return the enum's textual name.
232 */
233 public String getName()
234 {
235 return (_name);
236 }
237
238 /**
239 * Returns this enum's ordinal value.
240 * @return the enum's ordinal value.
241 */
242 public int getOrdinal()
243 {
244 return (_ordinal.intValue());
245 }
246
247 /**
248 * Sets the enumerated object's name and ordinal value.
249 * @param name the object's unique name.
250 * @param ordinal the object's unique integer index.
251 */
252 protected Enum(String name, int ordinal)
253 {
254 _name = name;
255 _ordinal = new Integer(ordinal);
256 }
257
258 // Member data.
259
260 /**
261 * The enumerated object's unique name.
262 */
263 protected transient final String _name;
264
265 /**
266 * The enumerated object's unique integer index.
267 * @serial include
268 */
269 protected final Integer _ordinal;
270 }