281 lines · 11.3 KB · Java
RawDownload
/* * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */  package javax.print.attribute; import java.io.InvalidObjectException;import java.io.ObjectStreamException;import java.io.Serializable; /** * Class EnumSyntax is an abstract base class providing the common * implementation of all "type safe enumeration" objects. An enumeration class * (which extends class EnumSyntax) provides a group of enumeration values * (objects) that are singleton instances of the enumeration class; for example: * <PRE> *     public class Bach extends EnumSyntax { *         public static final Bach JOHANN_SEBASTIAN     = new Bach(0); *         public static final Bach WILHELM_FRIEDEMANN   = new Bach(1); *         public static final Bach CARL_PHILIP_EMMANUEL = new Bach(2); *         public static final Bach JOHANN_CHRISTIAN     = new Bach(3); *         public static final Bach P_D_Q                = new Bach(4); * *         private static final String[] stringTable = { *             "Johann Sebastian Bach", *              "Wilhelm Friedemann Bach", *              "Carl Philip Emmanuel Bach", *              "Johann Christian Bach", *              "P.D.Q. Bach" *         }; * *         protected String[] getStringTable() { *             return stringTable; *         } * *         private static final Bach[] enumValueTable = { *             JOHANN_SEBASTIAN, *              WILHELM_FRIEDEMANN, *              CARL_PHILIP_EMMANUEL, *              JOHANN_CHRISTIAN, *              P_D_Q *         }; * *         protected EnumSyntax[] getEnumValueTable() { *             return enumValueTable; *         } *     } * </PRE> * You can then write code that uses the <CODE>==</CODE> and <CODE>!=</CODE> * operators to test enumeration values; for example: * <PRE> *     Bach theComposer; *     . . . *     if (theComposer == Bach.JOHANN_SEBASTIAN) { *         System.out.println ("The greatest composer of all time!"); *     } * </PRE> * The <CODE>equals()</CODE> method for an enumeration class just does a test * for identical objects (<CODE>==</CODE>). * <P> * You can convert an enumeration value to a string by calling {@link * #toString() <CODE>toString()</CODE>}. The string is obtained from a table * supplied by the enumeration class. * <P> * Under the hood, an enumeration value is just an integer, a different integer * for each enumeration value within an enumeration class. You can get an * enumeration value's integer value by calling {@link #getValue() * <CODE>getValue()</CODE>}. An enumeration value's integer value is established * when it is constructed (see {@link #EnumSyntax(int) * <CODE>EnumSyntax(int)</CODE>}). Since the constructor is protected, the only * possible enumeration values are the singleton objects declared in the * enumeration class; additional enumeration values cannot be created at run * time. * <P> * You can define a subclass of an enumeration class that extends it with * additional enumeration values. The subclass's enumeration values' integer * values need not be distinct from the superclass's enumeration values' integer * values; the <CODE>==</CODE>, <CODE>!=</CODE>, <CODE>equals()</CODE>, and * <CODE>toString()</CODE> methods will still work properly even if the subclass * uses some of the same integer values as the superclass. However, the * application in which the enumeration class and subclass are used may need to * have distinct integer values in the superclass and subclass. * <P> * * @author  David Mendenhall * @author  Alan Kaminsky */public abstract class EnumSyntax implements Serializable, Cloneable {     private static final long serialVersionUID = -2739521845085831642L;     /**     * This enumeration value's integer value.     * @serial     */    private int value;     /**     * Construct a new enumeration value with the given integer value.     *     * @param  value  Integer value.     */    protected EnumSyntax(int value) {        this.value = value;    }     /**     * Returns this enumeration value's integer value.     * @return the value     */    public int getValue() {        return value;    }     /**     * Returns a clone of this enumeration value, which to preserve the     * semantics of enumeration values is the same object as this enumeration     * value.     */    public Object clone() {        return this;    }     /**     * Returns a hash code value for this enumeration value. The hash code is     * just this enumeration value's integer value.     */    public int hashCode() {        return value;    }     /**     * Returns a string value corresponding to this enumeration value.     */    public String toString() {         String[] theTable = getStringTable();        int theIndex = value - getOffset();        return            theTable != null && theIndex >= 0 && theIndex < theTable.length ?            theTable[theIndex] :            Integer.toString (value);    }     /**     * During object input, convert this deserialized enumeration instance to     * the proper enumeration value defined in the enumeration attribute class.     *     * @return  The enumeration singleton value stored at index     *          <I>i</I>-<I>L</I> in the enumeration value table returned by     *          {@link #getEnumValueTable() <CODE>getEnumValueTable()</CODE>},     *          where <I>i</I> is this enumeration value's integer value and     *          <I>L</I> is the value returned by {@link #getOffset()     *          <CODE>getOffset()</CODE>}.     *     * @throws ObjectStreamException if the stream can't be deserialised     * @throws  InvalidObjectException     *     Thrown if the enumeration value table is null, this enumeration     *     value's integer value does not correspond to an element in the     *     enumeration value table, or the corresponding element in the     *     enumeration value table is null. (Note: {@link     *     java.io.InvalidObjectException InvalidObjectException} is a subclass     *     of {@link java.io.ObjectStreamException ObjectStreamException}, which     *     <CODE>readResolve()</CODE> is declared to throw.)     */    protected Object readResolve() throws ObjectStreamException {         EnumSyntax[] theTable = getEnumValueTable();         if (theTable == null) {            throw new InvalidObjectException(                                "Null enumeration value table for class " +                                getClass());        }         int theOffset = getOffset();        int theIndex = value - theOffset;         if (0 > theIndex || theIndex >= theTable.length) {            throw new InvalidObjectException                ("Integer value = " +  value + " not in valid range " +                 theOffset + ".." + (theOffset + theTable.length - 1) +                 "for class " + getClass());        }         EnumSyntax result = theTable[theIndex];        if (result == null) {            throw new InvalidObjectException                ("No enumeration value for integer value = " +                 value + "for class " + getClass());        }        return result;    }     // Hidden operations to be implemented in a subclass.     /**     * Returns the string table for this enumeration value's enumeration class.     * The enumeration class's integer values are assumed to lie in the range     * <I>L</I>..<I>L</I>+<I>N</I>-1, where <I>L</I> is the value returned by     * {@link #getOffset() <CODE>getOffset()</CODE>} and <I>N</I> is the length     * of the string table. The element in the string table at index     * <I>i</I>-<I>L</I> is the value returned by {@link #toString()     * <CODE>toString()</CODE>} for the enumeration value whose integer value     * is <I>i</I>. If an integer within the above range is not used by any     * enumeration value, leave the corresponding table element null.     * <P>     * The default implementation returns null. If the enumeration class (a     * subclass of class EnumSyntax) does not override this method to return a     * non-null string table, and the subclass does not override the {@link     * #toString() <CODE>toString()</CODE>} method, the base class {@link     * #toString() <CODE>toString()</CODE>} method will return just a string     * representation of this enumeration value's integer value.     * @return the string table     */    protected String[] getStringTable() {        return null;    }     /**     * Returns the enumeration value table for this enumeration value's     * enumeration class. The enumeration class's integer values are assumed to     * lie in the range <I>L</I>..<I>L</I>+<I>N</I>-1, where <I>L</I> is the     * value returned by {@link #getOffset() <CODE>getOffset()</CODE>} and     * <I>N</I> is the length of the enumeration value table. The element in the     * enumeration value table at index <I>i</I>-<I>L</I> is the enumeration     * value object whose integer value is <I>i</I>; the {@link #readResolve()     * <CODE>readResolve()</CODE>} method needs this to preserve singleton     * semantics during deserialization of an enumeration instance. If an     * integer within the above range is not used by any enumeration value,     * leave the corresponding table element null.     * <P>     * The default implementation returns null. If the enumeration class (a     * subclass of class EnumSyntax) does not override this method to return     * a non-null enumeration value table, and the subclass does not override     * the {@link #readResolve() <CODE>readResolve()</CODE>} method, the base     * class {@link #readResolve() <CODE>readResolve()</CODE>} method will throw     * an exception whenever an enumeration instance is deserialized from an     * object input stream.     * @return the value table     */    protected EnumSyntax[] getEnumValueTable() {        return null;    }     /**     * Returns the lowest integer value used by this enumeration value's     * enumeration class.     * <P>     * The default implementation returns 0. If the enumeration class (a     * subclass of class EnumSyntax) uses integer values starting at other than     * 0, override this method in the subclass.     * @return the offset of the lowest enumeration value.     */    protected int getOffset() {        return 0;    } }