TypeSafeEnum.java revision 0
286N/A/*
286N/A * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
286N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
286N/A *
286N/A * This code is free software; you can redistribute it and/or modify it
286N/A * under the terms of the GNU General Public License version 2 only, as
286N/A * published by the Free Software Foundation.
286N/A *
286N/A * This code is distributed in the hope that it will be useful, but WITHOUT
286N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
286N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
286N/A * version 2 for more details (a copy is included in the LICENSE file that
286N/A * accompanied this code).
286N/A *
286N/A * You should have received a copy of the GNU General Public License version
286N/A * 2 along with this work; if not, write to the Free Software Foundation,
286N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
286N/A *
286N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
286N/A * CA 95054 USA or visit www.sun.com if you need additional information or
286N/A * have any questions.
286N/A */
286N/A
286N/A/* @test
524N/A * @bug 4140729
286N/A * @summary Verify that writeReplace & readResolve are called by serialization.
286N/A * readResolve is used to maintain the invariant that the enums
286N/A * of TypeSafeEnum are singletons.
286N/A */
286N/Aimport java.io.*;
286N/A
286N/Apublic class TypeSafeEnum implements Serializable, ObjectInputValidation {
286N/A private static int numWriteObject = 0;
286N/A private static int numReadObject = 0;
286N/A
286N/A
286N/A private String value;
286N/A private TypeSafeEnum(String value) {
286N/A this.value = value;
286N/A }
286N/A
286N/A final public static TypeSafeEnum FIRST = new TypeSafeEnum("First");
286N/A final public static TypeSafeEnum SECOND = new TypeSafeEnum("Second");
286N/A final public static TypeSafeEnum THIRD = new TypeSafeEnum("Third");
286N/A static int numReadResolve = 0;
286N/A static int numWriteReplace = 0;
286N/A static boolean verbose = false;
286N/A
286N/A
286N/A private Object writeReplace() throws IOException {
286N/A numWriteReplace++;
286N/A if (verbose) {
286N/A System.out.println("TypeSafeEnum.writeReplace() " +
286N/A this.toString());
286N/A }
286N/A return this;
286N/A }
286N/A
286N/A private Object readResolve() throws IOException {
286N/A numReadResolve++;
286N/A if (verbose) {
286N/A System.out.println("readResolve called on " + this.toString());
286N/A }
286N/A if (value.equals(FIRST.value)) {
286N/A return FIRST;
286N/A } else if (value.equals(SECOND.value)) {
286N/A return SECOND;
524N/A } else if (value.equals(THIRD.value)) {
286N/A return THIRD;
286N/A } else {
286N/A //unknown type safe enum
286N/A return this;
286N/A }
286N/A }
286N/A
286N/A private void readObject(ObjectInputStream in)
286N/A throws IOException, ClassNotFoundException
286N/A {
286N/A numReadObject++;
286N/A in.defaultReadObject();
286N/A if (verbose) {
286N/A System.out.println("TypeSafeEnum.readObject() " + this.toString());
286N/A }
286N/A if (value == null) {
286N/A in.registerValidation(this, 0);
286N/A }
286N/A }
286N/A
286N/A public void validateObject() throws InvalidObjectException {
286N/A // only top level case has null for value, validate.
286N/A if (numWriteObject != 4) {
286N/A throw new Error("Expected 4 calls to writeObject, only " +
286N/A numWriteObject + " made");
286N/A }
286N/A if (numReadObject != 4) {
286N/A throw new Error("Expected 4 calls to readObject, only " +
286N/A numReadObject + " made");
286N/A }
286N/A if (numWriteReplace != 4) {
286N/A throw new Error("Expected 4 calls to writeReplace, only " +
286N/A numWriteReplace + " made");
286N/A }
286N/A if (numReadResolve != 4) {
286N/A throw new Error("Expected 4 calls to readResolve, only " +
286N/A numReadResolve + " made");
286N/A }
286N/A }
286N/A
286N/A private void writeObject(ObjectOutputStream out) throws IOException
286N/A {
286N/A numWriteObject++;
286N/A out.defaultWriteObject();
286N/A if (verbose) {
286N/A System.out.println("TypeSafeEnum.writeObject() " +
286N/A this.toString());
286N/A }
286N/A }
286N/A
286N/A public String toString() {
286N/A return super.toString() + " value=" + value;
286N/A }
286N/A
286N/A public static void main(String args[])
286N/A throws IOException, ClassNotFoundException
286N/A {
286N/A if (args.length > 0 && args[0].equals("-verbose"))
286N/A verbose = true;
286N/A
286N/A TypeSafeEnum[] writeArray = new TypeSafeEnum[7];
286N/A writeArray[0] = FIRST;
286N/A writeArray[1] = SECOND;
286N/A writeArray[2] = THIRD;
286N/A writeArray[3] = FIRST;
286N/A writeArray[4] = SECOND;
286N/A writeArray[5] = THIRD;
286N/A writeArray[6] = new TypeSafeEnum("Third");
286N/A
286N/A ByteArrayOutputStream baos = new ByteArrayOutputStream();
286N/A ObjectOutputStream os = new ObjectOutputStream(baos);
286N/A os.writeObject(writeArray);
286N/A os.close();
286N/A
286N/A TypeSafeEnum[] readArray;
286N/A ObjectInputStream in =
286N/A new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
286N/A readArray = (TypeSafeEnum[])in.readObject();
286N/A in.close();
286N/A
286N/A for (int i= 0; i < writeArray.length - 1 ; i++) {
if (writeArray[i] != readArray[i]) {
throw new Error("Serializa/deserialize did not preserve " +
"singleton for " +
readArray[i].toString() +
" and " + writeArray[i].toString());
}
}
}
};