package org.apereo.cas.util.serialization;
import com.google.common.base.Throwables;
import org.apereo.cas.CipherExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
/**
* This is {@link SerializationUtils}
* that encapsulates common serialization operations
* in one spot.
*
* @author Timur Duehr timur.duehr@nccgroup.trust
* @since 5.0.0
*/
public final class SerializationUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(SerializationUtils.class);
private SerializationUtils() {
}
/**
* Serialize an object.
*
* @param object The object to be serialized
* @return the +byte[]+ containing the object
* @since 5.0.0
*/
public static byte[] serialize(final Serializable object) {
final ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
serialize(object, outBytes);
return outBytes.toByteArray();
}
/**
* Serialize an object.
*
* @param object The object to be serialized
* @param outputStream The stream to receive the object
* @since 5.0.0
*/
public static void serialize(final Serializable object, final OutputStream outputStream) {
try (ObjectOutputStream out = new ObjectOutputStream(outputStream)) {
out.writeObject(object);
} catch (final IOException e) {
throw Throwables.propagate(e);
}
}
/**
* Deserialize an object.
*
* @param <T> the type parameter
* @param inBytes The bytes to be deserialized
* @return the object
* @since 5.0.0
*/
public static <T> T deserialize(final byte[] inBytes) {
final ByteArrayInputStream inputStream = new ByteArrayInputStream(inBytes);
return deserialize(inputStream);
}
/**
* Deserialize an object.
*
* @param <T> the type parameter
* @param inputStream The stream to be deserialized
* @return the object
* @since 5.0.0
*/
public static <T> T deserialize(final InputStream inputStream) {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(inputStream);
final T obj = (T) in.readObject();
return obj;
} catch (final ClassNotFoundException | IOException e) {
throw Throwables.propagate(e);
} finally {
if (in != null) {
try {
in.close();
} catch (final IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
}
/**
* Serialize and encode object.
*
* @param cipher the cipher
* @param object the object
* @return the byte []
* @since 4.2
*/
public static byte[] serializeAndEncodeObject(final CipherExecutor cipher,
final Serializable object) {
final byte[] outBytes = serialize(object);
return (byte[]) cipher.encode(outBytes);
}
/**
* Decode and serialize object.
*
* @param <T> the type parameter
* @param object the object
* @param cipher the cipher
* @param type the type
* @return the t
* @since 4.2
*/
public static <T> T decodeAndDeserializeObject(final byte[] object,
final CipherExecutor cipher,
final Class<? extends Serializable> type) {
try {
final byte[] decoded = (byte[]) cipher.decode(object);
return deserializeAndCheckObject(decoded, type);
} catch (final Exception e) {
throw Throwables.propagate(e);
}
}
/**
* Decode and serialize object.
*
* @param <T> the type parameter
* @param object the object
* @param type the type
* @return the t
* @since 4.2
*/
public static <T> T deserializeAndCheckObject(final byte[] object, final Class<? extends Serializable> type) {
final Object result = deserialize(object);
if (!type.isAssignableFrom(result.getClass())) {
throw new ClassCastException("Decoded object is of type " + result.getClass()
+ " when we were expecting " + type);
}
return (T) result;
}
}