Path: blob/master/src/java.desktop/share/classes/javax/print/attribute/EnumSyntax.java
41159 views
/*1* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.print.attribute;2627import java.io.InvalidObjectException;28import java.io.ObjectStreamException;29import java.io.Serial;30import java.io.Serializable;3132/**33* Class {@code EnumSyntax} is an abstract base class providing the common34* implementation of all "type safe enumeration" objects. An enumeration class35* (which extends class {@code EnumSyntax}) provides a group of enumeration36* values (objects) that are singleton instances of the enumeration class; for37* example:38*39* <pre>40* public class Bach extends EnumSyntax {41* public static final Bach JOHANN_SEBASTIAN = new Bach(0);42* public static final Bach WILHELM_FRIEDEMANN = new Bach(1);43* public static final Bach CARL_PHILIP_EMMANUEL = new Bach(2);44* public static final Bach JOHANN_CHRISTIAN = new Bach(3);45* public static final Bach P_D_Q = new Bach(4);46*47* private static final String[] stringTable = {48* "Johann Sebastian Bach",49* "Wilhelm Friedemann Bach",50* "Carl Philip Emmanuel Bach",51* "Johann Christian Bach",52* "P.D.Q. Bach"53* };54*55* protected String[] getStringTable() {56* return stringTable;57* }58*59* private static final Bach[] enumValueTable = {60* JOHANN_SEBASTIAN,61* WILHELM_FRIEDEMANN,62* CARL_PHILIP_EMMANUEL,63* JOHANN_CHRISTIAN,64* P_D_Q65* };66*67* protected EnumSyntax[] getEnumValueTable() {68* return enumValueTable;69* }70* }71* </pre>72* You can then write code that uses the {@code ==} and {@code !=} operators to73* test enumeration values; for example:74* <pre>75* Bach theComposer;76* . . .77* if (theComposer == Bach.JOHANN_SEBASTIAN) {78* System.out.println ("The greatest composer of all time!");79* }80* </pre>81* The {@code equals()} method for an enumeration class just does a test for82* identical objects ({@code ==}).83* <p>84* You can convert an enumeration value to a string by calling85* {@link #toString() toString()}. The string is obtained from a table supplied86* by the enumeration class.87* <p>88* Under the hood, an enumeration value is just an integer, a different integer89* for each enumeration value within an enumeration class. You can get an90* enumeration value's integer value by calling {@link #getValue() getValue()}.91* An enumeration value's integer value is established when it is constructed92* (see {@link #EnumSyntax(int) EnumSyntax(int)}). Since the constructor is93* protected, the only possible enumeration values are the singleton objects94* declared in the enumeration class; additional enumeration values cannot be95* created at run time.96* <p>97* You can define a subclass of an enumeration class that extends it with98* additional enumeration values. The subclass's enumeration values' integer99* values need not be distinct from the superclass's enumeration values' integer100* values; the {@code ==}, {@code !=}, {@code equals()}, and {@code toString()}101* methods will still work properly even if the subclass uses some of the same102* integer values as the superclass. However, the application in which the103* enumeration class and subclass are used may need to have distinct integer104* values in the superclass and subclass.105*106* @author David Mendenhall107* @author Alan Kaminsky108*/109public abstract class EnumSyntax implements Serializable, Cloneable {110111/**112* Use serialVersionUID from JDK 1.4 for interoperability.113*/114@Serial115private static final long serialVersionUID = -2739521845085831642L;116117/**118* This enumeration value's integer value.119*120* @serial121*/122private int value;123124/**125* Construct a new enumeration value with the given integer value.126*127* @param value Integer value128*/129protected EnumSyntax(int value) {130this.value = value;131}132133/**134* Returns this enumeration value's integer value.135*136* @return the value137*/138public int getValue() {139return value;140}141142/**143* Returns a clone of this enumeration value, which to preserve the144* semantics of enumeration values is the same object as this enumeration145* value.146*/147public Object clone() {148return this;149}150151/**152* Returns a hash code value for this enumeration value. The hash code is153* just this enumeration value's integer value.154*/155public int hashCode() {156return value;157}158159/**160* Returns a string value corresponding to this enumeration value.161*/162public String toString() {163164String[] theTable = getStringTable();165int theIndex = value - getOffset();166return167theTable != null && theIndex >= 0 && theIndex < theTable.length ?168theTable[theIndex] :169Integer.toString (value);170}171172/**173* During object input, convert this deserialized enumeration instance to174* the proper enumeration value defined in the enumeration attribute class.175*176* @return The enumeration singleton value stored at index <i>i</i>-<i>L</i>177* in the enumeration value table returned by178* {@link #getEnumValueTable() getEnumValueTable()}, where <i>i</i>179* is this enumeration value's integer value and <i>L</i> is the180* value returned by {@link #getOffset() getOffset()}181* @throws ObjectStreamException if the stream can't be deserialised182* @throws InvalidObjectException if the enumeration value table is183* {@code null}, this enumeration value's integer value does not184* correspond to an element in the enumeration value table, or the185* corresponding element in the enumeration value table is186* {@code null}. (Note:187* {@link InvalidObjectException InvalidObjectException} is a188* subclass of {@link ObjectStreamException ObjectStreamException},189* which {@code readResolve()} is declared to throw.)190*/191@Serial192protected Object readResolve() throws ObjectStreamException {193194EnumSyntax[] theTable = getEnumValueTable();195196if (theTable == null) {197throw new InvalidObjectException(198"Null enumeration value table for class " +199getClass());200}201202int theOffset = getOffset();203int theIndex = value - theOffset;204205if (0 > theIndex || theIndex >= theTable.length) {206throw new InvalidObjectException207("Integer value = " + value + " not in valid range " +208theOffset + ".." + (theOffset + theTable.length - 1) +209"for class " + getClass());210}211212EnumSyntax result = theTable[theIndex];213if (result == null) {214throw new InvalidObjectException215("No enumeration value for integer value = " +216value + "for class " + getClass());217}218return result;219}220221// Hidden operations to be implemented in a subclass.222223/**224* Returns the string table for this enumeration value's enumeration class.225* The enumeration class's integer values are assumed to lie in the range226* <i>L</i>..<i>L</i>+<i>N</i>-1, where <i>L</i> is the value returned by227* {@link #getOffset() getOffset()} and <i>N</i> is the length of the string228* table. The element in the string table at index <i>i</i>-<i>L</i> is the229* value returned by {@link #toString() toString()} for the enumeration230* value whose integer value is <i>i</i>. If an integer within the above231* range is not used by any enumeration value, leave the corresponding table232* element {@code null}.233* <p>234* The default implementation returns {@code null}. If the enumeration class235* (a subclass of class {@code EnumSyntax}) does not override this method to236* return a {@code non-null} string table, and the subclass does not237* override the {@link #toString() toString()} method, the base class238* {@link #toString() toString()} method will return just a string239* representation of this enumeration value's integer value.240*241* @return the string table242*/243protected String[] getStringTable() {244return null;245}246247/**248* Returns the enumeration value table for this enumeration value's249* enumeration class. The enumeration class's integer values are assumed to250* lie in the range <i>L</i>..<i>L</i>+<i>N</i>-1, where <i>L</i> is the251* value returned by {@link #getOffset() getOffset()} and <i>N</i> is the252* length of the enumeration value table. The element in the enumeration253* value table at index <i>i</i>-<i>L</i> is the enumeration value object254* whose integer value is <i>i</i>; the {@link #readResolve() readResolve()}255* method needs this to preserve singleton semantics during deserialization256* of an enumeration instance. If an integer within the above range is not257* used by any enumeration value, leave the corresponding table element258* {@code null}.259* <p>260* The default implementation returns {@code null}. If the enumeration class261* (a subclass of class EnumSyntax) does not override this method to return262* a {@code non-null} enumeration value table, and the subclass does not263* override the {@link #readResolve() readResolve()} method, the base class264* {@link #readResolve() readResolve()} method will throw an exception265* whenever an enumeration instance is deserialized from an object input266* stream.267*268* @return the value table269*/270protected EnumSyntax[] getEnumValueTable() {271return null;272}273274/**275* Returns the lowest integer value used by this enumeration value's276* enumeration class.277* <p>278* The default implementation returns 0. If the enumeration class (a279* subclass of class {@code EnumSyntax}) uses integer values starting at280* other than 0, override this method in the subclass.281*282* @return the offset of the lowest enumeration value283*/284protected int getOffset() {285return 0;286}287}288289290