# HG changeset patch # User lancea # Date 1352231962 18000 # Node ID d879c92507ec9bab2d28f78a0e12b53786709268 # Parent db08012d1d6f8c0843967a5ce5f185145dff208e 8002212: adding read/writeObject to additional SerialXXX classes Reviewed-by: naoto, forax diff -r db08012d1d6f -r d879c92507ec jdk/src/share/classes/javax/sql/rowset/serial/SerialArray.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialArray.java Mon Nov 05 12:51:14 2012 -0500 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialArray.java Tue Nov 06 14:59:22 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -29,7 +29,7 @@ import java.io.*; import java.util.Map; import java.net.URL; - +import java.util.Arrays; /** * A serialized version of an Array @@ -525,6 +525,97 @@ } /** + * Compares this SerialArray to the specified object. The result is {@code + * true} if and only if the argument is not {@code null} and is a {@code + * SerialArray} object whose elements are identical to this object's elements + * + * @param obj The object to compare this {@code SerialArray} against + * + * @return {@code true} if the given object represents a {@code SerialArray} + * equivalent to this SerialArray, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof SerialArray) { + SerialArray sa = (SerialArray)obj; + return baseType == sa.baseType && + baseTypeName.equals(sa.baseTypeName) && + Arrays.equals(elements, sa.elements); + } + return false; + } + + /** + * Returns a hash code for this SerialArray. The hash code for a + * {@code SerialArray} object is computed using the hash codes + * of the elements of the {@code SerialArray} object + * + * @return a hash code value for this object. + */ + public int hashCode() { + return (((31 + Arrays.hashCode(elements)) * 31 + len) * 31 + + baseType) * 31 + baseTypeName.hashCode(); + } + + /** + * Returns a clone of this {@code SerialArray}. The copy will contain a + * reference to a clone of the underlying objects array, not a reference + * to the original underlying object array of this {@code SerialArray} object. + * + * @return a clone of this SerialArray + */ + public Object clone() { + try { + SerialArray sa = (SerialArray) super.clone(); + sa.elements = Arrays.copyOf(elements, len); + return sa; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + + } + + /** + * readObject is called to restore the state of the {@code SerialArray} from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + + ObjectInputStream.GetField fields = s.readFields(); + Object[] tmp = (Object[])fields.get("elements", null); + if (tmp == null) + throw new InvalidObjectException("elements is null and should not be!"); + elements = tmp.clone(); + len = fields.get("len", 0); + if(elements.length != len) + throw new InvalidObjectException("elements is not the expected size"); + + baseType = fields.get("baseType", 0); + baseTypeName = (String)fields.get("baseTypeName", null); + } + + /** + * writeObject is called to save the state of the {@code SerialArray} + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException { + + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("elements", elements); + fields.put("len", len); + fields.put("baseType", baseType); + fields.put("baseTypeName", baseTypeName); + s.writeFields(); + } + + /** * The identifier that assists in the serialization of this SerialArray * object. */ diff -r db08012d1d6f -r d879c92507ec jdk/src/share/classes/javax/sql/rowset/serial/SerialDatalink.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialDatalink.java Mon Nov 05 12:51:14 2012 -0500 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialDatalink.java Tue Nov 06 14:59:22 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -100,10 +100,64 @@ return aURL; } + /** + * Compares this {@code SerialDatalink} to the specified object. + * The result is {@code true} if and only if the argument is not + * {@code null} and is a {@code SerialDatalink} object whose URL is + * identical to this object's URL + * + * @param obj The object to compare this {@code SerialDatalink} against + * + * @return {@code true} if the given object represents a {@code SerialDatalink} + * equivalent to this SerialDatalink, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SerialDatalink) { + SerialDatalink sdl = (SerialDatalink) obj; + return url.equals(sdl.url); + } + return false; + } /** - * The identifier that assists in the serialization of this SerialDatalink - * object. + * Returns a hash code for this {@code SerialDatalink}. The hash code for a + * {@code SerialDatalink} object is taken as the hash code of + * the {@code URL} it stores + * + * @return a hash code value for this object. + */ + public int hashCode() { + return 31 + url.hashCode(); + } + + /** + * Returns a clone of this {@code SerialDatalink}. + * + * @return a clone of this SerialDatalink + */ + public Object clone() { + try { + SerialDatalink sdl = (SerialDatalink) super.clone(); + return sdl; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + + /** + * readObject and writeObject are called to restore the state + * of the {@code SerialDatalink} + * from a stream. Note: we leverage the default Serialized form + */ + + /** + * The identifier that assists in the serialization of this + * {@code SerialDatalink} object. */ static final long serialVersionUID = 2826907821828733626L; } diff -r db08012d1d6f -r d879c92507ec jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java Mon Nov 05 12:51:14 2012 -0500 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialJavaObject.java Tue Nov 06 14:59:22 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -27,6 +27,8 @@ import java.io.*; import java.lang.reflect.*; +import java.util.Arrays; +import java.util.Vector; import javax.sql.rowset.RowSetWarning; /** @@ -49,7 +51,7 @@ /** * Placeholder for object to be serialized. */ - private final Object obj; + private Object obj; /** @@ -82,18 +84,9 @@ // any of these are static, this should invalidate // the action of attempting to persist these fields // in a serialized form - - boolean anyStaticFields = false; fields = c.getFields(); - for (int i = 0; i < fields.length; i++ ) { - if ( fields[i].getModifiers() == Modifier.STATIC ) { - anyStaticFields = true; - } - } - - - if (anyStaticFields) { + if (hasStaticFields(fields)) { throw new SerialException("Located static fields in " + "object instance. Cannot serialize"); } @@ -132,7 +125,7 @@ } /** - * The identifier that assists in the serialization of this + * The identifier that assists in the serialization of this * SerialJavaObject object. */ static final long serialVersionUID = -1465795139032831023L; @@ -142,15 +135,117 @@ * object. When there are multiple warnings, each warning is chained to the * previous warning. */ - java.util.Vector chain; + Vector chain; + + /** + * Compares this SerialJavaObject to the specified object. + * The result is {@code true} if and only if the argument + * is not {@code null} and is a {@code SerialJavaObject} + * object that is identical to this object + * + * @param o The object to compare this {@code SerialJavaObject} against + * + * @return {@code true} if the given object represents a {@code SerialJavaObject} + * equivalent to this SerialJavaObject, {@code false} otherwise + * + */ + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o instanceof SerialJavaObject) { + SerialJavaObject sjo = (SerialJavaObject) o; + return obj.equals(sjo.obj); + } + return false; + } + + /** + * Returns a hash code for this SerialJavaObject. The hash code for a + * {@code SerialJavaObject} object is taken as the hash code of + * the {@code Object} it stores + * + * @return a hash code value for this object. + */ + public int hashCode() { + return 31 + obj.hashCode(); + } + + /** + * Returns a clone of this {@code SerialJavaObject}. + * + * @return a clone of this SerialJavaObject + */ + + public Object clone() { + try { + SerialJavaObject sjo = (SerialJavaObject) super.clone(); + sjo.fields = Arrays.copyOf(fields, fields.length); + if (chain != null) + sjo.chain = new Vector<>(chain); + return sjo; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } /** * Registers the given warning. */ private void setWarning(RowSetWarning e) { if (chain == null) { - chain = new java.util.Vector<>(); + chain = new Vector<>(); } chain.add(e); } + + /** + * readObject is called to restore the state of the {@code SerialJavaObject} + * from a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + + ObjectInputStream.GetField fields1 = s.readFields(); + @SuppressWarnings("unchecked") + Vector tmp = (Vector)fields1.get("chain", null); + if (tmp != null) + chain = new Vector<>(tmp); + + obj = fields1.get("obj", null); + if (obj != null) { + fields = obj.getClass().getFields(); + if(hasStaticFields(fields)) + throw new IOException("Located static fields in " + + "object instance. Cannot serialize"); + } else { + throw new IOException("Object cannot be null!"); + } + + } + + /** + * writeObject is called to save the state of the {@code SerialJavaObject} + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException { + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("obj", obj); + fields.put("chain", chain); + s.writeFields(); + } + + /* + * Check to see if there are any Static Fields in this object + */ + private static boolean hasStaticFields(Field[] fields) { + for (Field field : fields) { + if ( field.getModifiers() == Modifier.STATIC) { + return true; + } + } + return false; + } } diff -r db08012d1d6f -r d879c92507ec jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java Mon Nov 05 12:51:14 2012 -0500 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java Tue Nov 06 14:59:22 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -163,7 +163,85 @@ } /** - * The identifier that assists in the serialization of this SerialRef + * Compares this SerialRef to the specified object. The result is {@code + * true} if and only if the argument is not {@code null} and is a {@code + * SerialRef} object that represents the same object as this + * object. + * + * @param obj The object to compare this {@code SerialRef} against + * + * @return {@code true} if the given object represents a {@code SerialRef} + * equivalent to this SerialRef, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if(obj instanceof SerialRef) { + SerialRef ref = (SerialRef)obj; + return baseTypeName.equals(ref.baseTypeName) && + object.equals(ref.object); + } + return false; + } + + /** + * Returns a hash code for this {@code SerialRef}. + * @return a hash code value for this object. + */ + public int hashCode() { + return (31 + object.hashCode()) * 31 + baseTypeName.hashCode(); + } + + /** + * Returns a clone of this {@code SerialRef}. . + * The underlying {@code Ref} object will be set to null. + * + * @return a clone of this SerialRef + */ + public Object clone() { + try { + SerialRef ref = (SerialRef) super.clone(); + ref.reference = null; + return ref; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + + } + + /** + * readObject is called to restore the state of the SerialRef from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = s.readFields(); + object = fields.get("object", null); + baseTypeName = (String) fields.get("baseTypeName", null); + reference = (Ref) fields.get("reference", null); + } + + /** + * writeObject is called to save the state of the SerialRef + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException { + + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("baseTypeName", baseTypeName); + fields.put("object", object); + // Note: this check to see if it is an instance of Serializable + // is for backwards compatibiity + fields.put("reference", reference instanceof Serializable ? reference : null); + s.writeFields(); + } + + /** + * The identifier that assists in the serialization of this SerialRef * object. */ static final long serialVersionUID = -4727123500609662274L; diff -r db08012d1d6f -r d879c92507ec jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Mon Nov 05 12:51:14 2012 -0500 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Tue Nov 06 14:59:22 2012 -0500 @@ -250,6 +250,88 @@ } /** + * Compares this SerialStruct to the specified object. The result is + * {@code true} if and only if the argument is not {@code null} and is a + * {@code SerialStruct} object whose attributes are identical to this + * object's attributes + * + * @param obj The object to compare this {@code SerialStruct} against + * + * @return {@code true} if the given object represents a {@code SerialStruct} + * equivalent to this SerialStruct, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SerialStruct) { + SerialStruct ss = (SerialStruct)obj; + return SQLTypeName.equals(ss.SQLTypeName) && + Arrays.equals(attribs, ss.attribs); + } + return false; + } + + /** + * Returns a hash code for this {@code SerialStruct}. The hash code for a + * {@code SerialStruct} object is computed using the hash codes + * of the attributes of the {@code SerialStruct} object and its + * {@code SQLTypeName} + * + * @return a hash code value for this object. + */ + public int hashCode() { + return ((31 + Arrays.hashCode(attribs)) * 31) * 31 + + SQLTypeName.hashCode(); + } + + /** + * Returns a clone of this {@code SerialStruct}. The copy will contain a + * reference to a clone of the underlying attribs array, not a reference + * to the original underlying attribs array of this {@code SerialStruct} object. + * + * @return a clone of this SerialStruct + */ + public Object clone() { + try { + SerialStruct ss = (SerialStruct) super.clone(); + ss.attribs = Arrays.copyOf(attribs, attribs.length); + return ss; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + + } + + /** + * readObject is called to restore the state of the {@code SerialStruct} from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + + ObjectInputStream.GetField fields = s.readFields(); + Object[] tmp = (Object[])fields.get("attribs", null); + attribs = tmp == null ? null : tmp.clone(); + SQLTypeName = (String)fields.get("SQLTypeName", null); + } + + /** + * writeObject is called to save the state of the {@code SerialStruct} + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException { + + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("attribs", attribs); + fields.put("SQLTypeName", SQLTypeName); + s.writeFields(); + } + + /** * The identifier that assists in the serialization of this * SerialStruct object. */