/* * HA-JDBC: High-Availability JDBC * Copyright (C) 2012 Paul Ferraro * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.hajdbc.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.util.Arrays; /** * Object utility methods. * @author Paul Ferraro */ public class Objects { /** * Compares two objects for equality. * If the objects are arrays, then an array comparison is performed. * @param object1 an object * @param object2 another object * @return true, if the objects are equal, false otherwise */ public static boolean equals(Object object1, Object object2) { if ((object1 == null) || (object2 == null)) return object1 == object2; if (object1.getClass().isArray() && object2.getClass().isArray()) { if ((object1 instanceof boolean[]) && (object2 instanceof boolean[])) { return Arrays.equals((boolean[]) object1, (boolean[]) object2); } if ((object1 instanceof byte[]) && (object2 instanceof byte[])) { return Arrays.equals((byte[]) object1, (byte[]) object2); } if ((object1 instanceof char[]) && (object2 instanceof char[])) { return Arrays.equals((char[]) object1, (char[]) object2); } if ((object1 instanceof double[]) && (object2 instanceof double[])) { return Arrays.equals((double[]) object1, (double[]) object2); } if ((object1 instanceof float[]) && (object2 instanceof float[])) { return Arrays.equals((float[]) object1, (float[]) object2); } if ((object1 instanceof int[]) && (object2 instanceof int[])) { return Arrays.equals((int[]) object1, (int[]) object2); } if ((object1 instanceof long[]) && (object2 instanceof long[])) { return Arrays.equals((long[]) object1, (long[]) object2); } if ((object1 instanceof short[]) && (object2 instanceof short[])) { return Arrays.equals((short[]) object1, (short[]) object2); } return Arrays.equals((Object[]) object1, (Object[]) object2); } return object1.equals(object2); } /** * Serializes the specified object. * @param object the serialization target * @return a serialized object */ public static byte[] serialize(Object object) { if (object == null) return null; ByteArrayOutputStream bytes = new ByteArrayOutputStream(); try (ObjectOutput output = new ObjectOutputStream(bytes)) { output.writeObject(object); output.flush(); return bytes.toByteArray(); } catch (IOException e) { throw new IllegalStateException(e); } } /** * Deserializes the specified bytes into the object of the specified type using the classloader of the target class. * @param bytes a serialized object * @param targetClass the target class * @return a deserialized object */ public static <T> T deserialize(byte[] bytes, Class<T> targetClass) { if (bytes == null) return null; try (ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(bytes), targetClass.getClassLoader())) { return readObject(input, targetClass); } catch (IOException e) { throw new IllegalStateException(e); } } /** * Reads an object from the input stream using the classloader of the specified target class. * @param input an input stream * @param targetClass the target class * @return a deserialized object */ public static <T> T readObject(ObjectInput input, Class<T> targetClass) { // ClassLoader originalLoader = getThreadContextClassLoader(); // setThreadContextClassLoader(targetClass.getClassLoader()); try { return targetClass.cast(input.readObject()); } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } catch (IOException e) { throw new IllegalStateException(e); } // finally // { // setThreadContextClassLoader(originalLoader); // } } private Objects() { // Hide } /* private static ClassLoader getThreadContextClassLoader() { PrivilegedAction<ClassLoader> action = new PrivilegedAction<ClassLoader>() { @Override public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } }; return Security.run(action); } private static void setThreadContextClassLoader(final ClassLoader loader) { PrivilegedAction<Void> action = new PrivilegedAction<Void>() { @Override public Void run() { Thread.currentThread().setContextClassLoader(loader); return null; } }; Security.run(action); } */ }