
clime.messadmin.providers.serializable.MaybeSerializableProvider Maven / Gradle / Ivy
The 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 - 2025 Weber Informatics LLC | Privacy Policy