package net.contextfw.web.commons.cloud.internal.serializer; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import net.contextfw.web.application.development.DevelopmentModeListener; import net.contextfw.web.application.development.DevelopmentTools; import org.apache.commons.io.output.ByteArrayOutputStream; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.binary.BinaryStreamDriver; import com.thoughtworks.xstream.io.binary.BinaryStreamReader; import com.thoughtworks.xstream.io.binary.BinaryStreamWriter; import com.thoughtworks.xstream.mapper.MapperWrapper; @Singleton public class Serializer implements DevelopmentModeListener { private ThreadLocal<XStream> xstream = getNewXStream(); private final Injector injector; private KeyConverter keyConverter = new KeyConverter(); private ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); @Inject public Serializer(final Injector injector, DevelopmentTools developmentTools) { this.injector = injector; developmentTools.addListener(this); } public byte[] serialize(Object obj) { ByteArrayOutputStream out = null; out = new ByteArrayOutputStream(); BinaryStreamWriter bwriter = new BinaryStreamWriter(out); xstream.get().marshal(obj, bwriter); close(out); return out.toByteArray(); } private void close(OutputStream stream) { try { stream.close(); } catch (IOException e) { // Just ignore } } public Object unserialize(byte[] serialized) { InputStream xml = new ByteArrayInputStream(serialized); return xstream.get().unmarshal(new BinaryStreamReader(xml)); } private ThreadLocal<XStream> getNewXStream() { return new ThreadLocal<XStream>() { @Override protected XStream initialValue() { XStream rv = new XStream(new BinaryStreamDriver()) { @Override protected MapperWrapper wrapMapper(MapperWrapper next) { return new DependencyMapper(next, injector, classLoader); } }; rv.registerConverter(keyConverter); rv.setClassLoader(classLoader); return rv; } }; } @Override public void classesReloaded(ClassLoader classLoader) { this.classLoader = classLoader; keyConverter.setClassLoader(classLoader); xstream = getNewXStream(); } @Override public void resourcesReloaded() { } }