1 /* 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.sql.rowset.serial; 27 28 import java.sql.*; 29 import java.io.*; 30 import java.util.*; 31 32 /** 33 * A serialized mapping of a <code>Ref</code> object, which is the mapping in the 34 * Java programming language of an SQL <code>REF</code> value. 35 * <p> 36 * The <code>SerialRef</code> class provides a constructor for 37 * creating a <code>SerialRef</code> instance from a <code>Ref</code> 38 * object and provides methods for getting and setting the <code>Ref</code> object. 39 */ 40 public class SerialRef implements Ref, Serializable, Cloneable { 41 42 /** 43 * String containing the base type name. 44 * @serial 45 */ 46 private String baseTypeName; 47 48 /** 49 * This will store the type <code>Ref</code> as an <code>Object</code>. 50 */ 51 private Object object; 52 53 /** 54 * Private copy of the Ref reference. 55 */ 56 private Ref reference; 57 58 /** 59 * Constructs a <code>SerialRef</code> object from the given <code>Ref</code> 60 * object. 61 * 62 * @param ref a Ref object; cannot be <code>null</code> 63 * @throws SQLException if a database access occurs; if <code>ref</code> 64 * is <code>null</code>; or if the <code>Ref</code> object returns a 65 * <code>null</code> value base type name. 66 * @throws SerialException if an error occurs serializing the <code>Ref</code> 67 * object 68 */ 69 public SerialRef(Ref ref) throws SerialException, SQLException { 70 if (ref == null) { 71 throw new SQLException("Cannot instantiate a SerialRef object " + 72 "with a null Ref object"); 73 } 74 reference = ref; 75 object = ref; 76 if (ref.getBaseTypeName() == null) { 77 throw new SQLException("Cannot instantiate a SerialRef object " + 78 "that returns a null base type name"); 79 } else { 80 baseTypeName = ref.getBaseTypeName(); 81 } 82 } 83 84 /** 85 * Returns a string describing the base type name of the <code>Ref</code>. 86 * 87 * @return a string of the base type name of the Ref 88 * @throws SerialException in no Ref object has been set 89 */ 90 public String getBaseTypeName() throws SerialException { 91 return baseTypeName; 92 } 93 94 /** 95 * Returns an <code>Object</code> representing the SQL structured type 96 * to which this <code>SerialRef</code> object refers. The attributes 97 * of the structured type are mapped according to the given type map. 98 * 99 * @param map a <code>java.util.Map</code> object containing zero or 100 * more entries, with each entry consisting of 1) a <code>String</code> 101 * giving the fully qualified name of a UDT and 2) the 102 * <code>Class</code> object for the <code>SQLData</code> implementation 103 * that defines how the UDT is to be mapped 104 * @return an object instance resolved from the Ref reference and mapped 105 * according to the supplied type map 106 * @throws SerialException if an error is encountered in the reference 107 * resolution 108 */ 109 public Object getObject(java.util.Map<String,Class<?>> map) 110 throws SerialException 111 { 112 map = new Hashtable<String, Class<?>>(map); 113 if (object != null) { 114 return map.get(object); 115 } else { 116 throw new SerialException("The object is not set"); 117 } 118 } 119 120 /** 121 * Returns an <code>Object</code> representing the SQL structured type 122 * to which this <code>SerialRef</code> object refers. 123 * 124 * @return an object instance resolved from the Ref reference 125 * @throws SerialException if an error is encountered in the reference 126 * resolution 127 */ 128 public Object getObject() throws SerialException { 129 130 if (reference != null) { 131 try { 132 return reference.getObject(); 133 } catch (SQLException e) { 134 throw new SerialException("SQLException: " + e.getMessage()); 135 } 136 } 137 138 if (object != null) { 139 return object; 140 } 141 142 143 throw new SerialException("The object is not set"); 144 145 } 146 147 /** 148 * Sets the SQL structured type that this <code>SerialRef</code> object 149 * references to the given <code>Object</code> object. 150 * 151 * @param obj an <code>Object</code> representing the SQL structured type 152 * to be referenced 153 * @throws SerialException if an error is encountered generating the 154 * the structured type referenced by this <code>SerialRef</code> object 155 */ 156 public void setObject(Object obj) throws SerialException { 157 try { 158 reference.setObject(obj); 159 } catch (SQLException e) { 160 throw new SerialException("SQLException: " + e.getMessage()); 161 } 162 object = obj; 163 } 164 165 /** 166 * Compares this SerialRef to the specified object. The result is {@code 167 * true} if and only if the argument is not {@code null} and is a {@code 168 * SerialRef} object that represents the same object as this 169 * object. 170 * 171 * @param obj The object to compare this {@code SerialRef} against 172 * 173 * @return {@code true} if the given object represents a {@code SerialRef} 174 * equivalent to this SerialRef, {@code false} otherwise 175 * 176 */ 177 public boolean equals(Object obj) { 178 if (this == obj) { 179 return true; 180 } 181 if(obj instanceof SerialRef) { 182 SerialRef ref = (SerialRef)obj; 183 if(baseTypeName.equals(ref.baseTypeName)) { 184 return object.equals(ref.object); 185 } 186 } 187 return false; 188 } 189 190 /** 191 * Returns a hash code for this {@code SerialRef}. 192 * @return a hash code value for this object. 193 */ 194 public int hashCode() { 195 return (31 + object.hashCode()) * 31 + baseTypeName.hashCode(); 196 } 197 198 /** 199 * Returns a clone of this {@code SerialRef}. . 200 * The underlying {@code Ref} object will be set to null. 201 * 202 * @return a clone of this SerialRef 203 */ 204 public Object clone() { 205 try { 206 SerialRef ref = (SerialRef) super.clone(); 207 ref.reference = null; 208 return ref; 209 } catch (CloneNotSupportedException ex) { 210 // this shouldn't happen, since we are Cloneable 211 throw new InternalError(); 212 } 213 214 } 215 216 /** 217 * readObject is called to restore the state of the SerialRef from 218 * a stream. 219 */ 220 private void readObject(ObjectInputStream s) 221 throws IOException, ClassNotFoundException { 222 ObjectInputStream.GetField fields = s.readFields(); 223 object = fields.get("object", null); 224 baseTypeName = (String) fields.get("baseTypeName", null); 225 reference = (Ref) fields.get("reference", null); 226 } 227 228 /** 229 * writeObject is called to save the state of the SerialRef 230 * to a stream. 231 */ 232 private void writeObject(ObjectOutputStream s) 233 throws IOException, ClassNotFoundException { 234 235 ObjectOutputStream.PutField fields = s.putFields(); 236 fields.put("baseTypeName", baseTypeName); 237 fields.put("object", object); 238 // Note: this check to see if it is an instance of Serializable 239 // is for backwards compatibiity 240 fields.put("reference", reference instanceof Serializable ? reference : null); 241 s.writeFields(); 242 } 243 244 /** 245 * The identifier that assists in the serialization of this <code>SerialRef</code> 246 * object. 247 */ 248 static final long serialVersionUID = -4727123500609662274L; 249 250 251 }