/* * Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved * http://www.griddynamics.com * * This library is free software; you can redistribute it and/or modify it under the terms of * the Apache License; either * version 2.0 of the License, or any later version. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.griddynamics.jagger.util; import biz.source_code.base64Coder.Base64Coder; import com.griddynamics.jagger.exception.TechnicalException; import org.apache.commons.io.input.ClassLoaderObjectInputStream; import org.jboss.serial.io.JBossObjectInputStream; import org.jboss.serial.io.JBossObjectOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.io.Closeables; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.concurrent.atomic.AtomicLong; // TODO Avoid static code. Extract interface and make this one default implementation. public class SerializationUtils { private static final Logger log = LoggerFactory.getLogger(SerializationUtils.class); private static final AtomicLong fromStringCount = new AtomicLong(0); private static final AtomicLong toStringCount = new AtomicLong(0); private static boolean useJBoss=true;//if false - using default java serialization private SerializationUtils() { } public static <T extends Serializable> T fromString(String s) { if (s.isEmpty()) { log.info("fromString({}, '{}')", fromStringCount.getAndIncrement(), s); } ObjectInputStream ois = null; try { byte[] data = Base64Coder.decode(s); try{ //TODO fixes for support old reports ois=new JBossObjectInputStream(new ByteArrayInputStream(data)); } catch (IOException e) { // /data stored not with JBoss ois=new ObjectInputStream(new ByteArrayInputStream(data)); } T obj = (T) ois.readObject(); return obj; } catch (IOException e) { log.error("Deserialization exception ", e); log.error("fromString('{}')", s); throw new TechnicalException(e); } catch (ClassNotFoundException e) { log.error("Deserialization exception ", e); throw new TechnicalException(e); } finally { try { Closeables.close(ois, true); } catch (IOException e) { log.warn("IOException should not have been thrown.", e); } } } public static String toString(Serializable o) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try { if(useJBoss){ oos=new JBossObjectOutputStream(baos); } else{ baos = new ByteArrayOutputStream(); oos=new ObjectOutputStream(baos); } oos.writeObject(o); } catch (IOException e) { log.error("Serialization exception ", e); throw new TechnicalException(e); } finally { String s = new String(Base64Coder.encode(baos.toByteArray())); if (s.isEmpty()) { log.info("toString({}, '{}', '{}')", toStringCount.getAndIncrement(), s, o); } try { Closeables.close(oos, true); } catch (IOException e) { log.warn("IOException should not have been thrown.", e); } return s; } } public static byte[] serialize(Object obj) { ObjectOutputStream ous = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { if(useJBoss){ ous=new JBossObjectOutputStream(baos); } else { baos = new ByteArrayOutputStream(); ous=new ObjectOutputStream(baos); } ous.writeObject(obj); return baos.toByteArray(); } catch (Exception e) { throw new RuntimeException("Error during " + obj + " serialization", e); } finally { try { Closeables.close(ous, true); } catch (IOException e) { log.warn("IOException should not have been thrown.", e); } try { Closeables.close(baos, true); } catch (IOException e) { log.warn("IOException should not have been thrown.", e); } } } public static Object deserialize(byte[] data) { return deserialize(data, SerializationUtils.class.getClassLoader()); } public static Object deserialize(byte[] data, ClassLoader classLoader) { ObjectInputStream ois = null; try { try{ //TODO fixes for support old reports ois= new JBossObjectInputStream(new ByteArrayInputStream(data), classLoader); } catch (IOException e){ //data stored not with JBoss ois=new ClassLoaderObjectInputStream(classLoader, new ByteArrayInputStream(data)); } return ois.readObject(); } catch (Exception e) { throw new RuntimeException(e); } finally { try { Closeables.close(ois, true); } catch (IOException e) { log.warn("IOException should not have been thrown.", e); } } } public static Configurator getConfigurator() { return Configurator.configuratorInstance; } public static class Configurator { private static final Configurator configuratorInstance = new Configurator(); private Configurator() {} public void setUseJBoss(boolean useJBoss) { log.info("setting useJBoss= {}",useJBoss); SerializationUtils.useJBoss = useJBoss; } } }