All Downloads are FREE. Search and download functionalities are using the official Maven repository.

clime.messadmin.providers.serializable.MaybeSerializableProvider Maven / Gradle / Ivy

Go to download

Notification system and Session administration for J2EE Web Applications

There is a newer version: 4.1.1
Show newest version
/**
 * 
 */
package clime.messadmin.providers.serializable;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import clime.messadmin.providers.spi.SerializableProvider;
import clime.messadmin.utils.IdentityHashMap;

/**
 * Determines if an object is serializable by lookup if it implementes java.io.Serializable.
 * While this implementation is quick, it may not be accurate:
 *   a return value of true does not waranty that such an object is really serializable.
 *   a return value of false is a 100% warranty that the object is not serializable.
 * This implementation recurses into Collections and Arrays.
 * @author Cédrik LIME
 */
public class MaybeSerializableProvider implements SerializableProvider {

	/**
	 * 
	 */
	public MaybeSerializableProvider() {
		super();
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isSerializable(Object obj) {
		return isMaybeSerializable(obj);
	}

	/**
	 * {@inheritDoc}
	 */
	public int getPriority() {
		return 10;
	}

	/**
	 * Determines if an object is serializable by lookup if it implementes java.io.Serializable.
	 * While this implementation is quick, it may not be accurate:
	 *   a return value of true does not waranty that such an object is really serializable. Use {@link #isSerializable(Object)} for certainty.
	 *   a return value of false is a 100% warranty that the object is not serializable.
	 * This implementation recurses into Collections and Arrays.
	 * @param o
	 * @return true if o is Serializable, false if not
	 */
	private static boolean isMaybeSerializable(Object o) {
		if (o == null) {
			return true;
		}
		if (! (o instanceof Serializable)) {
			return false;
		}
		IdentityHashMap visitedObjects = new IdentityHashMap();
		return isMaybeSerializable(o, visitedObjects);
	}

	/**
	 * Implementation note: we need to track a list of visited objects in order to
	 * avoid graph cycle problems.
	 * @see #isMaybeSerializable(Object)
	 * @param o
	 * @param visitedObjects
	 * @return true if o is Serializable, false if not
	 */
	private static boolean isMaybeSerializable(Object o, IdentityHashMap visitedObjects) {
		if (o == null) {
			return true;
		}
		if (! (o instanceof Serializable)) {
			return false;
		}
		if (visitedObjects.containsKey(o)) {
			return true;
		}
		visitedObjects.put(o, o);
		// Collection: each member of the collection must be Serializable
		if (o instanceof Collection) {
			try {
				Iterator iter = ((Collection) o).iterator();
				while (iter.hasNext()) {
					Object oo = iter.next();
					if (! isMaybeSerializable(oo, visitedObjects)) {
						return false;
					}
				}
			} catch (RuntimeException rte) {
				//e.g. Hibernate Lazy Exception
				return false;
			}
		}
		// Map: each entry (key and value) of the map must be Serializable
		if (o instanceof Map) {
			try {
				Iterator iter = ((Map) o).entrySet().iterator();
				while (iter.hasNext()) {
					Map.Entry entry = (Map.Entry) iter.next();
					if (! isMaybeSerializable(entry.getKey(), visitedObjects) || ! isMaybeSerializable(entry.getValue(), visitedObjects)) {
						return false;
					}
				}
			} catch (RuntimeException rte) {
				//e.g. Hibernate Lazy Exception
				return false;
			}
		}
		// Array: each member of the collection must be Serializable
		if (o.getClass().isArray()) {
			// arrays of primitive types are Serializable
			if (o.getClass().getComponentType().isPrimitive()) {
				return true;
			}
//			// There's only 1 type for the Array. If this type is Serializable, then all objects in the array are Serializable
//			// Note: this can't be that simple! E.g. array of Collection, with non-serializable items inside...
//			if (Serializable.class.isAssignableFrom(o.getClass().getComponentType())) {
//				return true;
//			}
			// if object type is not Serializable, no need to check inside the array
//			if ((Object[]) o).length > 0 && ! Serializable.class.isAssignableFrom(o.getClass().getComponentType())) {
//				return false;
//			}
			// Array type is not Serializable, but maybe all entries are. We need to check.
			Object[] array = (Object[]) o;
			for (int i = 0; i < array.length; ++i) {
				Object object = array[i];
				if (! isMaybeSerializable(object, visitedObjects)) {
					return false;
				}
			}
		}
		return true;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy