{
private static final Logger log = Logger.getLogger(SerializeTranslatorFactory.class.getName());
@Override
public Translator<Object, Blob> create(TypeKey<Object> tk, CreateContext ctx, Path path) {
final Serialize serializeAnno = tk.getAnnotationAnywhere(Serialize.class);
// We only work with @Serialize classes
if (serializeAnno == null)
return null;
return new ValueTranslator<Object, Blob>(Blob.class) {
@Override
protected Object loadValue(Blob value, LoadContext ctx, Path path) throws SkipException {
// Need to be careful here because we don't really know if the data was serialized or not. Start
// with whatever the annotation says, and if that doesn't work, try the other option.
try {
ByteArrayInputStream bais = new ByteArrayInputStream(value.getBytes());
// Start with the annotation
boolean unzip = serializeAnno.zip();
try {
return readObject(bais, unzip);
} catch (IOException ex) { // will be one of ZipException or StreamCorruptedException
if (log.isLoggable(Level.INFO))
log.log(Level.INFO, "Error trying to deserialize object using unzip=" + unzip + ", retrying with " + !unzip, ex);
unzip = !unzip;
return readObject(bais, unzip); // this will pass the exception up
}
} catch (Exception ex) {
path.throwIllegalState("Unable to deserialize " + value, ex);
return null; // never gets here
}
}
@Override
protected Blob saveValue(Object value, boolean index, SaveContext ctx, Path path) throws SkipException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream out = baos;
if (serializeAnno.zip()) {
Deflater deflater = new Deflater(serializeAnno.compressionLevel());
out = new DeflaterOutputStream(out, deflater);
}
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(value);