KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > print > attribute > EnumSyntax


1 /*
2  * @(#)EnumSyntax.java 1.5 04/01/07
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8
9 package javax.print.attribute;
10
11 import java.io.InvalidObjectException JavaDoc;
12 import java.io.ObjectStreamException JavaDoc;
13 import java.io.Serializable JavaDoc;
14
15 /**
16  * Class EnumSyntax is an abstract base class providing the common
17  * implementation of all "type safe enumeration" objects. An enumeration class
18  * (which extends class EnumSyntax) provides a group of enumeration values
19  * (objects) that are singleton instances of the enumeration class; for example:
20  * <PRE>
21  * public class Bach extends EnumSyntax {
22  * public static final Bach JOHANN_SEBASTIAN = new Bach(0);
23  * public static final Bach WILHELM_FRIEDEMANN = new Bach(1);
24  * public static final Bach CARL_PHILIP_EMMANUEL = new Bach(2);
25  * public static final Bach JOHANN_CHRISTIAN = new Bach(3);
26  * public static final Bach P_D_Q = new Bach(4);
27  *
28  * private static final String[] stringTable = {
29  * "Johann Sebastian Bach",
30  * "Wilhelm Friedemann Bach",
31  * "Carl Philip Emmanuel Bach",
32  * "Johann Christian Bach",
33  * "P.D.Q. Bach"
34  * };
35  *
36  * protected String[] getStringTable() {
37  * return stringTable;
38  * }
39  *
40  * private static final Bach[] enumValueTable = {
41  * JOHANN_SEBASTIAN,
42  * WILHELM_FRIEDEMANN,
43  * CARL_PHILIP_EMMANUEL,
44  * JOHANN_CHRISTIAN,
45  * P_D_Q
46  * };
47  *
48  * protected EnumSyntax[] getEnumValueTable() {
49  * return enumValueTable;
50  * }
51  * }
52  * </PRE>
53  * You can then write code that uses the <CODE>==</CODE> and <CODE>!=</CODE>
54  * operators to test enumeration values; for example:
55  * <PRE>
56  * Bach theComposer;
57  * . . .
58  * if (theComposer == Bach.JOHANN_SEBASTIAN) {
59  * System.out.println ("The greatest composer of all time!");
60  * }
61  * </PRE>
62  * The <CODE>equals()</CODE> method for an enumeration class just does a test
63  * for identical objects (<CODE>==</CODE>).
64  * <P>
65  * You can convert an enumeration value to a string by calling {@link
66  * #toString() <CODE>toString()</CODE>}. The string is obtained from a table
67  * supplied by the enumeration class.
68  * <P>
69  * Under the hood, an enumeration value is just an integer, a different integer
70  * for each enumeration value within an enumeration class. You can get an
71  * enumeration value's integer value by calling {@link #getValue()
72  * <CODE>getValue()</CODE>}. An enumeration value's integer value is established
73  * when it is constructed (see {@link #EnumSyntax(int)
74  * <CODE>EnumSyntax(int)</CODE>}). Since the constructor is protected, the only
75  * possible enumeration values are the singleton objects declared in the
76  * enumeration class; additional enumeration values cannot be created at run
77  * time.
78  * <P>
79  * You can define a subclass of an enumeration class that extends it with
80  * additional enumeration values. The subclass's enumeration values' integer
81  * values need not be distinct from the superclass's enumeration values' integer
82  * values; the <CODE>==</CODE>, <CODE>!=</CODE>, <CODE>equals()</CODE>, and
83  * <CODE>toString()</CODE> methods will still work properly even if the subclass
84  * uses some of the same integer values as the superclass. However, the
85  * application in which the enumeration class and subclass are used may need to
86  * have distinct integer values in the superclass and subclass.
87  * <P>
88  *
89  * @author David Mendenhall
90  * @author Alan Kaminsky
91  */

92 public abstract class EnumSyntax implements Serializable JavaDoc, Cloneable JavaDoc {
93
94     private static final long serialVersionUID = -2739521845085831642L;
95
96     /**
97      * This enumeration value's integer value.
98      * @serial
99      */

100     private int value;
101
102     /**
103      * Construct a new enumeration value with the given integer value.
104      *
105      * @param value Integer value.
106      */

107     protected EnumSyntax(int value) {
108     this.value = value;
109     }
110
111     /**
112      * Returns this enumeration value's integer value.
113      * @return the value
114      */

115     public int getValue() {
116     return value;
117     }
118
119     /**
120      * Returns a clone of this enumeration value, which to preserve the
121      * semantics of enumeration values is the same object as this enumeration
122      * value.
123      */

124     public Object JavaDoc clone() {
125     return this;
126     }
127
128     /**
129      * Returns a hash code value for this enumeration value. The hash code is
130      * just this enumeration value's integer value.
131      */

132     public int hashCode() {
133     return value;
134     }
135
136     /**
137      * Returns a string value corresponding to this enumeration value.
138      */

139     public String JavaDoc toString() {
140
141     String JavaDoc[] theTable = getStringTable();
142     int theIndex = value - getOffset();
143     return
144         theTable != null && theIndex >= 0 && theIndex < theTable.length ?
145         theTable[theIndex] :
146         Integer.toString (value);
147     }
148         
149     /**
150      * During object input, convert this deserialized enumeration instance to
151      * the proper enumeration value defined in the enumeration attribute class.
152      *
153      * @return The enumeration singleton value stored at index
154      * <I>i</I>-<I>L</I> in the enumeration value table returned by
155      * {@link #getEnumValueTable() <CODE>getEnumValueTable()</CODE>},
156      * where <I>i</I> is this enumeration value's integer value and
157      * <I>L</I> is the value returned by {@link #getOffset()
158      * <CODE>getOffset()</CODE>}.
159      *
160      * @throws ObjectStreamException if the stream can't be deserialised
161      * @throws InvalidObjectException
162      * Thrown if the enumeration value table is null, this enumeration
163      * value's integer value does not correspond to an element in the
164      * enumeration value table, or the corresponding element in the
165      * enumeration value table is null. (Note: {@link
166      * java.io.InvalidObjectException InvalidObjectException} is a subclass
167      * of {@link java.io.ObjectStreamException ObjectStreamException}, which
168      * <CODE>readResolve()</CODE> is declared to throw.)
169      */

170     protected Object JavaDoc readResolve() throws ObjectStreamException JavaDoc {
171
172     EnumSyntax JavaDoc[] theTable = getEnumValueTable();
173
174     if (theTable == null) {
175         throw new InvalidObjectException JavaDoc(
176                 "Null enumeration value table for class " +
177                 getClass());
178     }
179
180     int theOffset = getOffset();
181     int theIndex = value - theOffset;
182
183     if (0 > theIndex || theIndex >= theTable.length) {
184         throw new InvalidObjectException JavaDoc
185         ("Integer value = " + value + " not in valid range " +
186          theOffset + ".." + (theOffset + theTable.length - 1) +
187          "for class " + getClass());
188     }
189
190     EnumSyntax JavaDoc result = theTable[theIndex];
191     if (result == null) {
192         throw new InvalidObjectException JavaDoc
193         ("No enumeration value for integer value = " +
194          value + "for class " + getClass());
195     }
196     return result;
197     }
198
199     // Hidden operations to be implemented in a subclass.
200

201     /**
202      * Returns the string table for this enumeration value's enumeration class.
203      * The enumeration class's integer values are assumed to lie in the range
204      * <I>L</I>..<I>L</I>+<I>N</I>-1, where <I>L</I> is the value returned by
205      * {@link #getOffset() <CODE>getOffset()</CODE>} and <I>N</I> is the length
206      * of the string table. The element in the string table at index
207      * <I>i</I>-<I>L</I> is the value returned by {@link #toString()
208      * <CODE>toString()</CODE>} for the enumeration value whose integer value
209      * is <I>i</I>. If an integer within the above range is not used by any
210      * enumeration value, leave the corresponding table element null.
211      * <P>
212      * The default implementation returns null. If the enumeration class (a
213      * subclass of class EnumSyntax) does not override this method to return a
214      * non-null string table, and the subclass does not override the {@link
215      * #toString() <CODE>toString()</CODE>} method, the base class {@link
216      * #toString() <CODE>toString()</CODE>} method will return just a string
217      * representation of this enumeration value's integer value.
218      * @return the string table
219      */

220     protected String JavaDoc[] getStringTable() {
221     return null;
222     }
223
224     /**
225      * Returns the enumeration value table for this enumeration value's
226      * enumeration class. The enumeration class's integer values are assumed to
227      * lie in the range <I>L</I>..<I>L</I>+<I>N</I>-1, where <I>L</I> is the
228      * value returned by {@link #getOffset() <CODE>getOffset()</CODE>} and
229      * <I>N</I> is the length of the enumeration value table. The element in the
230      * enumeration value table at index <I>i</I>-<I>L</I> is the enumeration
231      * value object whose integer value is <I>i</I>; the {@link #readResolve()
232      * <CODE>readResolve()</CODE>} method needs this to preserve singleton
233      * semantics during deserialization of an enumeration instance. If an
234      * integer within the above range is not used by any enumeration value,
235      * leave the corresponding table element null.
236      * <P>
237      * The default implementation returns null. If the enumeration class (a
238      * subclass of class EnumSyntax) does not override this method to return
239      * a non-null enumeration value table, and the subclass does not override
240      * the {@link #readResolve() <CODE>readResolve()</CODE>} method, the base
241      * class {@link #readResolve() <CODE>readResolve()</CODE>} method will throw
242      * an exception whenever an enumeration instance is deserialized from an
243      * object input stream.
244      * @return the value table
245      */

246     protected EnumSyntax JavaDoc[] getEnumValueTable() {
247     return null;
248     }
249
250     /**
251      * Returns the lowest integer value used by this enumeration value's
252      * enumeration class.
253      * <P>
254      * The default implementation returns 0. If the enumeration class (a
255      * subclass of class EnumSyntax) uses integer values starting at other than
256      * 0, override this method in the subclass.
257      * @return the offset of the lowest enumeration value.
258      */

259     protected int getOffset() {
260     return 0;
261     }
262     
263 }
264
Popular Tags