From 9cfc35f3657951c4d9cc93e4f1c27ecb4618ea08 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Thu, 1 Nov 2012 17:35:17 -0400 Subject: [PATCH] 8001536: Added readObject,writeObject,clone, equals, hashcode to SerialXLob Reviewed-by: alanb, forax --- .../javax/sql/rowset/serial/SerialBlob.java | 94 +++++++++++++++++- .../javax/sql/rowset/serial/SerialClob.java | 96 ++++++++++++++++++- 2 files changed, 186 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SerialBlob.java b/jdk/src/share/classes/javax/sql/rowset/serial/SerialBlob.java index bae2d9355eb..7b3c3634a96 100644 --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialBlob.java +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialBlob.java @@ -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 @@ -28,6 +28,7 @@ package javax.sql.rowset.serial; import java.sql.*; import java.io.*; import java.lang.reflect.*; +import java.util.Arrays; /** @@ -448,6 +449,97 @@ public class SerialBlob implements Blob, Serializable, Cloneable { public void free() throws SQLException { throw new java.lang.UnsupportedOperationException("Not supported"); } + + /** + * Compares this SerialBlob to the specified object. The result is {@code + * true} if and only if the argument is not {@code null} and is a {@code + * SerialBlob} object that represents the same sequence of bytes as this + * object. + * + * @param obj The object to compare this {@code SerialBlob} against + * + * @return {@code true} if the given object represents a {@code SerialBlob} + * equivalent to this SerialBlob, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SerialBlob) { + SerialBlob sb = (SerialBlob)obj; + if (this.len == sb.len) { + return Arrays.equals(buf, sb.buf); + } + } + return false; + } + + /** + * Returns a hash code for this {@code SerialBlob}. + * @return a hash code value for this object. + */ + public int hashCode() { + return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen; + } + + /** + * Returns a clone of this {@code SerialBlob}. The copy will contain a + * reference to a clone of the internal byte array, not a reference + * to the original internal byte array of this {@code SerialBlob} object. + * The underlying {@code Blob} object will be set to null. + * + * @return a clone of this SerialBlob + */ + public Object clone() { + try { + SerialBlob sb = (SerialBlob) super.clone(); + sb.buf = Arrays.copyOf(buf, (int)len); + sb.blob = null; + return sb; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + + } + + /** + * readObject is called to restore the state of the SerialBlob from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + + ObjectInputStream.GetField fields = s.readFields(); + byte[] tmp = (byte[])fields.get("buf", null); + if (tmp == null) + throw new InvalidObjectException("buf is null and should not be!"); + buf = tmp.clone(); + len = fields.get("len", 0L); + if (buf.length != len) + throw new InvalidObjectException("buf is not the expected size"); + origLen = fields.get("origLen", 0L); + blob = (Blob) fields.get("blob", null); + } + + /** + * writeObject is called to save the state of the SerialBlob + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException { + + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("buf", buf); + fields.put("len", len); + fields.put("origLen", origLen); + // Note: this check to see if it is an instance of Serializable + // is for backwards compatibiity + fields.put("blob", blob instanceof Serializable ? blob : null); + s.writeFields(); + } + /** * The identifier that assists in the serialization of this SerialBlob * object. diff --git a/jdk/src/share/classes/javax/sql/rowset/serial/SerialClob.java b/jdk/src/share/classes/javax/sql/rowset/serial/SerialClob.java index 97e8995081f..84bed0909f7 100644 --- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialClob.java +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialClob.java @@ -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,7 @@ package javax.sql.rowset.serial; import java.sql.*; import java.io.*; +import java.util.Arrays; /** * A serialized mapping in the Java programming language of an SQL @@ -60,7 +61,7 @@ public class SerialClob implements Clob, Serializable, Cloneable { * Internal Clob representation if SerialClob is initialized with a * Clob. Null if SerialClob is initialized with a char[]. */ - private final Clob clob; + private Clob clob; /** * The length in characters of this SerialClob object's @@ -76,7 +77,7 @@ public class SerialClob implements Clob, Serializable, Cloneable { * * @serial */ - private final long origLen; + private long origLen; /** * Constructs a SerialClob object that is a serialized version of @@ -514,6 +515,95 @@ public class SerialClob implements Clob, Serializable, Cloneable { throw new java.lang.UnsupportedOperationException("Not supported"); } + /** + * Compares this SerialClob to the specified object. The result is {@code + * true} if and only if the argument is not {@code null} and is a {@code + * SerialClob} object that represents the same sequence of characters as this + * object. + * + * @param obj The object to compare this {@code SerialClob} against + * + * @return {@code true} if the given object represents a {@code SerialClob} + * equivalent to this SerialClob, {@code false} otherwise + * + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SerialClob) { + SerialClob sc = (SerialClob)obj; + if (this.len == sc.len) { + return Arrays.equals(buf, sc.buf); + } + } + return false; + } + + /** + * Returns a hash code for this {@code SerialClob}. + * @return a hash code value for this object. + */ + public int hashCode() { + return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen; + } + + /** + * Returns a clone of this {@code SerialClob}. The copy will contain a + * reference to a clone of the internal character array, not a reference + * to the original internal character array of this {@code SerialClob} object. + * The underlying {@code Clob} object will be set to null. + * + * @return a clone of this SerialClob + */ + public Object clone() { + try { + SerialClob sc = (SerialClob) super.clone(); + sc.buf = Arrays.copyOf(buf, (int)len); + sc.clob = null; + return sc; + } catch (CloneNotSupportedException ex) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + + /** + * readObject is called to restore the state of the SerialClob from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + + ObjectInputStream.GetField fields = s.readFields(); + char[] tmp = (char[])fields.get("buf", null); + if (tmp == null) + throw new InvalidObjectException("buf is null and should not be!"); + buf = tmp.clone(); + len = fields.get("len", 0L); + if (buf.length != len) + throw new InvalidObjectException("buf is not the expected size"); + origLen = fields.get("origLen", 0L); + clob = (Clob) fields.get("clob", null); + } + + /** + * writeObject is called to save the state of the SerialClob + * to a stream. + */ + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException { + + ObjectOutputStream.PutField fields = s.putFields(); + fields.put("buf", buf); + fields.put("len", len); + fields.put("origLen", origLen); + // Note: this check to see if it is an instance of Serializable + // is for backwards compatibiity + fields.put("clob", clob instanceof Serializable ? clob : null); + s.writeFields(); + } + /** * The identifier that assists in the serialization of this SerialClob * object.