001 /*
002 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.sql.rowset.serial;
027
028 import java.sql.*;
029 import java.io.*;
030 import java.util.Map;
031 import java.lang.reflect.*;
032 import javax.sql.rowset.RowSetWarning;
033
034 /**
035 * A serializable mapping in the Java programming language of an SQL
036 * <code>JAVA_OBJECT</code> value. Assuming the Java object
037 * implements the <code>Serializable</code> interface, this class simply wraps the
038 * serialization process.
039 * <P>
040 * If however, the serialization is not possible because
041 * the Java object is not immediately serializable, this class will
042 * attempt to serialize all non-static members to permit the object
043 * state to be serialized.
044 * Static or transient fields cannot be serialized; an attempt to serialize
045 * them will result in a <code>SerialException</code> object being thrown.
046 *
047 * @version 0.1
048 * @author Jonathan Bruce
049 */
050 public class SerialJavaObject implements Serializable, Cloneable {
051
052 /**
053 * Placeholder for object to be serialized.
054 */
055 private Object obj;
056
057 /**
058 * Placeholder for all fields in the <code>JavaObject</code> being serialized.
059 */
060 private transient Field[] fields;
061
062 /**
063 * Constructor for <code>SerialJavaObject</code> helper class.
064 * <p>
065 *
066 * @param obj the Java <code>Object</code> to be serialized
067 * @throws SerialException if the object is found
068 * to be unserializable
069 */
070 public SerialJavaObject(Object obj) throws SerialException {
071
072 // if any static fields are found, an exception
073 // should be thrown
074
075 // get Class. Object instance should always be available
076 Class c = obj.getClass();
077
078 // determine if object implements Serializable i/f
079 boolean serializableImpl = false;
080 Class[] theIf = c.getInterfaces();
081 for (int i = 0; i < theIf.length; i++) {
082 String ifName = theIf[i].getName();
083 if (ifName == "java.io.Serializable") {
084 serializableImpl = true;
085 }
086 }
087
088 // can only determine public fields (obviously). If
089 // any of these are static, this should invalidate
090 // the action of attempting to persist these fields
091 // in a serialized form
092
093 boolean anyStaticFields = false;
094 fields = c.getFields();
095 //fields = new Object[field.length];
096
097 for (int i = 0; i < fields.length; i++) {
098 if (fields[i].getModifiers() == Modifier.STATIC) {
099 anyStaticFields = true;
100 }
101 //fields[i] = field[i].get(obj);
102 }
103 try {
104 if (!(serializableImpl)) {
105 throw new RowSetWarning("Test");
106 }
107 } catch (RowSetWarning w) {
108 setWarning(w);
109 }
110
111 if (anyStaticFields) {
112 throw new SerialException("Located static fields in "
113 + "object instance. Cannot serialize");
114 }
115
116 this .obj = obj;
117 }
118
119 /**
120 * Returns an <code>Object</code> that is a copy of this <code>SerialJavaObject</code>
121 * object.
122 *
123 * @return a copy of this <code>SerialJavaObject</code> object as an
124 * <code>Object</code> in the Java programming language
125 * @throws SerialException if the instance is corrupt
126 */
127 public Object getObject() throws SerialException {
128 return this .obj;
129 }
130
131 /**
132 * Returns an array of <code>Field</code> objects that contains each
133 * field of the object that this helper class is serializing.
134 *
135 * @return an array of <code>Field</code> objects
136 * @throws SerialException if an error is encountered accessing
137 * the serialized object
138 */
139 public Field[] getFields() throws SerialException {
140 if (fields != null) {
141 Class c = this .obj.getClass();
142 //the following has to be commented before mustang integration
143 //return c.getFields();
144 //the following has to be uncommented before mustang integration
145 return sun.reflect.misc.FieldUtil.getFields(c);
146 } else {
147 throw new SerialException(
148 "SerialJavaObject does not contain"
149 + " a serialized object instance");
150 }
151 }
152
153 /**
154 * The identifier that assists in the serialization of this
155 * <code>SerialJavaObject</code> object.
156 */
157 static final long serialVersionUID = -1465795139032831023L;
158
159 /**
160 * A container for the warnings issued on this <code>SerialJavaObject</code>
161 * object. When there are multiple warnings, each warning is chained to the
162 * previous warning.
163 */
164 java.util.Vector chain;
165
166 /**
167 * Registers the given warning.
168 */
169 private void setWarning(RowSetWarning e) {
170 if (chain == null) {
171 chain = new java.util.Vector();
172 }
173 chain.add(e);
174 }
175 }
|