/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * CloneHelper.java * * Created on 18. August 2004, 15:47 */ package Sirius.navigator.tools; import java.io.*; import java.lang.reflect.*; /** * Hilfsmethoden zum Klonen von beliebigen Objekten. * * @author Pascal * @version $Revision$, $Date$ */ public class CloneHelper { //~ Methods ---------------------------------------------------------------- /** * Klont ein beliebiges Objekt, sofern dieses Cloneable implementiert und eine Methode public Object clone() oder * Serializable implementiert. * * @param toBeCloned DOCUMENT ME! * * @return ein Kopie des Objekts * * @throws CloneNotSupportedException wenn das Objekt nicht cloneable ist */ public static Object clone(final Object toBeCloned) throws CloneNotSupportedException { final CloneNotSupportedException cloneNotSupportedException; try { return cloneCloneable(toBeCloned); } catch (CloneNotSupportedException cnsexp) { cloneNotSupportedException = cnsexp; try { return cloneSerializable(toBeCloned); } catch (NotSerializableException nsexp) { throw cloneNotSupportedException; } } } /** * Klont ein beliebiges Objekt, sofern dieses Serializable implementiert. * * @param toBeCloned DOCUMENT ME! * * @return ein Kopie des Objekts * * @throws NotSerializableException wenn das Objekt nicht serialisierbar ist */ public static Object cloneSerializable(final Object toBeCloned) throws NotSerializableException { final Class toBeClonedClass = toBeCloned.getClass(); // cloning not necessary if (toBeClonedClass.isPrimitive() || CloneHelper.isImmutable(toBeClonedClass)) { return toBeCloned; } else if (Serializable.class.isAssignableFrom(toBeClonedClass)) { try { final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(toBeCloned); final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); final ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } catch (Exception exp) { throw new NotSerializableException(toBeClonedClass.getName() + " is not serializable: \n" + exp.getMessage()); // NOI18N } } else { throw new NotSerializableException(toBeClonedClass.getName() + " is not serializable"); // NOI18N } } /** * Klont ein beliebiges Objekt, sofern dieses Cloneable implementiert und eine Methode public Object clone() * besitzt. * * @param toBeCloned DOCUMENT ME! * * @return ein Kopie des Objekts * * @throws CloneNotSupportedException wenn das Objekt nicht cloneable ist */ public static Object cloneCloneable(final Object toBeCloned) throws CloneNotSupportedException { final Class toBeClonedClass = toBeCloned.getClass(); // cloning not necessary if (toBeClonedClass.isPrimitive() || CloneHelper.isImmutable(toBeClonedClass)) { return toBeCloned; } else if (Cloneable.class.isAssignableFrom(toBeClonedClass)) { try { final Method method = toBeClonedClass.getMethod("clone", new Class[0]); // NOI18N try { return method.invoke(toBeCloned, new Object[0]); } catch (InvocationTargetException e) { final Throwable t = e.getTargetException(); if (t instanceof Error) { throw (Error)t; } else if (t instanceof RuntimeException) { throw (RuntimeException)t; } else if (t instanceof CloneNotSupportedException) { throw (CloneNotSupportedException)t; } else { throw new RuntimeException(t); } } } catch (NoSuchMethodException ne) { throw new CloneNotSupportedException(toBeClonedClass.getName() + " is not cloneable: \n" + ne.getMessage()); // NOI18N } catch (IllegalAccessException ie) { throw new CloneNotSupportedException(toBeClonedClass.getName() + " is not cloneable: \n" + ie.getMessage()); // NOI18N } } else { throw new CloneNotSupportedException(toBeClonedClass.getName() + " is not cloneable"); // NOI18N } } /** * Gibt an, ob es sich bei der \u00FCbergebenen Klasse um einen unver\u00E4nderliches Java Object handelt, da\u00DF * nicht geklont werden mu\u00DF. * * @param clazz DOCUMENT ME! * * @return true/false */ public static boolean isImmutable(final Class clazz) { return (clazz == String.class) || (clazz == Integer.class) || (clazz == Long.class) || (clazz == Short.class) || (clazz == Byte.class) || (clazz == Character.class) || (clazz == Float.class) || (clazz == Double.class) || (clazz == Boolean.class); } }