8002212: adding read/writeObject to additional SerialXXX classes
Reviewed-by: naoto, forax
--- 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 <code>Array</code>
@@ -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 <code>SerialArray</code>
* object.
*/
--- 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 <code>SerialDatalink</code>
- * 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;
}
--- 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
* <code>SerialJavaObject</code> 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<RowSetWarning> chain;
+ Vector<RowSetWarning> 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<RowSetWarning> tmp = (Vector<RowSetWarning>)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;
+ }
}
--- 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 <code>SerialRef</code>
+ * 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 <code>SerialRef</code>
* object.
*/
static final long serialVersionUID = -4727123500609662274L;
--- 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
* <code>SerialStruct</code> object.
*/