alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SerialJavaObject.java)

This example Java source code file (SerialJavaObject.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

callersensitive, cannot, class, classnotfoundexception, field, internalerror, ioexception, located, object, reflection, securitymanager, serialexception, serializable, serialjavaobject, util, vector

The SerialJavaObject.java Java example source code

/*
 * Copyright (c) 2003, 2013, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.sql.rowset.serial;

import java.io.*;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Vector;
import javax.sql.rowset.RowSetWarning;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;

/**
 * A serializable mapping in the Java programming language of an SQL
 * <code>JAVA_OBJECT value. Assuming the Java object
 * implements the <code>Serializable interface, this class simply wraps the
 * serialization process.
 * <P>
 * If however, the serialization is not possible because
 * the Java object is not immediately serializable, this class will
 * attempt to serialize all non-static members to permit the object
 * state to be serialized.
 * Static or transient fields cannot be serialized; an attempt to serialize
 * them will result in a <code>SerialException object being thrown.
 *
 * <h3> Thread safety 
 *
 * A SerialJavaObject is not safe for use by multiple concurrent threads.  If a
 * SerialJavaObject is to be used by more than one thread then access to the
 * SerialJavaObject should be controlled by appropriate synchronization.
 *
 * @author Jonathan Bruce
 */
public class SerialJavaObject implements Serializable, Cloneable {

    /**
     * Placeholder for object to be serialized.
     */
    private Object obj;


   /**
    * Placeholder for all fields in the <code>JavaObject being serialized.
    */
    private transient Field[] fields;

    /**
     * Constructor for <code>SerialJavaObject helper class.
     * <p>
     *
     * @param obj the Java <code>Object to be serialized
     * @throws SerialException if the object is found not to be serializable
     */
    public SerialJavaObject(Object obj) throws SerialException {

        // if any static fields are found, an exception
        // should be thrown


        // get Class. Object instance should always be available
        Class<?> c = obj.getClass();

        // determine if object implements Serializable i/f
        if (!(obj instanceof java.io.Serializable)) {
            setWarning(new RowSetWarning("Warning, the object passed to the constructor does not implement Serializable"));
        }

        // can only determine public fields (obviously). If
        // any of these are static, this should invalidate
        // the action of attempting to persist these fields
        // in a serialized form
        fields = c.getFields();

        if (hasStaticFields(fields)) {
            throw new SerialException("Located static fields in " +
                "object instance. Cannot serialize");
        }

        this.obj = obj;
    }

    /**
     * Returns an <code>Object that is a copy of this SerialJavaObject
     * object.
     *
     * @return a copy of this <code>SerialJavaObject object as an
     *         <code>Object in the Java programming language
     * @throws SerialException if the instance is corrupt
     */
    public Object getObject() throws SerialException {
        return this.obj;
    }

    /**
     * Returns an array of <code>Field objects that contains each
     * field of the object that this helper class is serializing.
     *
     * @return an array of <code>Field objects
     * @throws SerialException if an error is encountered accessing
     * the serialized object
     * @throws  SecurityException  If a security manager, <i>s, is present
     * and the caller's class loader is not the same as or an
     * ancestor of the class loader for the class of the
     * {@linkplain #getObject object} being serialized
     * and invocation of {@link SecurityManager#checkPackageAccess
     * s.checkPackageAccess()} denies access to the package
     * of that class.
     * @see Class#getFields
     */
    @CallerSensitive
    public Field[] getFields() throws SerialException {
        if (fields != null) {
            Class<?> c = this.obj.getClass();
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                /*
                 * Check if the caller is allowed to access the specified class's package.
                 * If access is denied, throw a SecurityException.
                 */
                Class<?> caller = sun.reflect.Reflection.getCallerClass();
                if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
                                                        c.getClassLoader())) {
                    ReflectUtil.checkPackageAccess(c);
                }
            }
            return c.getFields();
        } else {
            throw new SerialException("SerialJavaObject does not contain" +
                " a serialized object instance");
        }
    }

    /**
     * The identifier that assists in the serialization of this
     * <code>SerialJavaObject object.
     */
    static final long serialVersionUID = -1465795139032831023L;

    /**
     * A container for the warnings issued on this <code>SerialJavaObject
     * object. When there are multiple warnings, each warning is chained to the
     * previous warning.
     */
    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 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)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;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java SerialJavaObject.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.