/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.util; import org.pepsoft.util.undo.*; import org.pepsoft.util.undo.Cloneable; import java.awt.*; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferDouble; import java.awt.image.DataBufferFloat; import java.awt.image.DataBufferInt; import java.awt.image.DataBufferShort; import java.awt.image.DataBufferUShort; import java.util.*; import java.util.List; /** * * @author SchmitzP */ public final class ObjectUtils { private ObjectUtils() { // Prevent instantiation } /** * Make a deep copy of an object. Only a restricted set of types is * supported. * * @param <T> The type of the object. * @param object The object to copy. * @return A deep copy of the object. * @throws OutOfMemoryError If there is not enough memory to copy the * object. */ @SuppressWarnings("unchecked") public static <T> T copyObject(T object) { // Point isn't actually immutable, but it is used as such by WorldPainter, at least in all data structures // managed by an undo manager if ((object == null) || (object instanceof Number) || (object instanceof Character) || (object instanceof Boolean) || (object instanceof String) || (object instanceof Enum) || (object instanceof Point) || (object instanceof Immutable)) { // Object is null or immutable; making a copy not necessary return object; } else { if (object instanceof BitSet) { return (T) ((BitSet) object).clone(); } else if (object instanceof EnumSet) { return (T) ((EnumSet) object).clone(); } else if (object instanceof byte[]) { return (T) ((byte[]) object).clone(); } else if (object instanceof short[]) { return (T) ((short[]) object).clone(); } else if (object instanceof int[]) { return (T) ((int[]) object).clone(); } else if (object instanceof long[]) { return (T) ((long[]) object).clone(); } else if (object instanceof float[]) { return (T) ((float[]) object).clone(); } else if (object instanceof double[]) { return (T) ((double[]) object).clone(); } else if (object instanceof String[]) { return (T) ((String[]) object).clone(); } else if (object instanceof Map) { final Map<Object, Object> copy; if (object instanceof SortedMap) { copy = new TreeMap<>(); } else { copy = new HashMap<>(((Map) object).size()); } boolean first = true, deeplyCopyKeys = false; for (Map.Entry entry: ((Map<?, ?>) object).entrySet()) { if (first) { deeplyCopyKeys = entry.getKey() instanceof DeeplyCopyable; first = false; } copy.put(deeplyCopyKeys ? copyObject(entry.getKey()) : entry.getKey(), copyObject(entry.getValue())); } return (T) copy; } else if (object instanceof List) { final List<Object> copy; if (object instanceof RandomAccess) { copy = new ArrayList<>(((List) object).size()); } else { copy = new LinkedList<>(); } for (Object entry: (List) object) { copy.add(copyObject(entry)); } return (T) copy; } else if (object instanceof Set) { final Set<Object> copy; if (object instanceof SortedSet) { copy = new TreeSet<>(); } else { copy = new HashSet<>(((Set) object).size()); } for (Object entry: (Set) object) { copy.add(copyObject(entry)); } return (T) copy; } else if (object instanceof DeeplyCopyable) { return ((DeeplyCopyable<T>) object).deepCopy(); } else if (object instanceof Cloneable) { return ((Cloneable<T>) object).clone(); } else { throw new UnsupportedOperationException("Don't know how to copy a " + object.getClass()); } } } public static DataBuffer clone(DataBuffer dataBuffer) { if (dataBuffer instanceof DataBufferByte) { return clone((DataBufferByte) dataBuffer); } else if (dataBuffer instanceof DataBufferDouble) { return clone((DataBufferDouble) dataBuffer); } else if (dataBuffer instanceof DataBufferFloat) { return clone((DataBufferFloat) dataBuffer); } else if (dataBuffer instanceof DataBufferInt) { return clone((DataBufferInt) dataBuffer); } else if (dataBuffer instanceof DataBufferShort) { return clone((DataBufferShort) dataBuffer); } else if (dataBuffer instanceof DataBufferUShort) { return clone((DataBufferUShort) dataBuffer); } else { throw new UnsupportedOperationException("Don't know how to clone " + dataBuffer.getClass().getName()); } } public static DataBufferByte clone(DataBufferByte dataBuffer) { return new DataBufferByte(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static DataBufferDouble clone(DataBufferDouble dataBuffer) { return new DataBufferDouble(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static DataBufferFloat clone(DataBufferFloat dataBuffer) { return new DataBufferFloat(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static DataBufferInt clone(DataBufferInt dataBuffer) { return new DataBufferInt(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static DataBufferShort clone(DataBufferShort dataBuffer) { return new DataBufferShort(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static DataBufferUShort clone(DataBufferUShort dataBuffer) { return new DataBufferUShort(clone(dataBuffer.getBankData()), dataBuffer.getSize(), dataBuffer.getOffsets()); } public static byte[][] clone(byte[][] array) { byte[][] clone = new byte[array.length][]; for (int i = 0; i < array.length; i++) { clone[i] = array[i].clone(); } return clone; } public static double[][] clone(double[][] array) { double[][] clone = new double[array.length][]; for (int i = 0; i < array.length; i++) { clone[i] = array[i].clone(); } return clone; } public static float[][] clone(float[][] array) { float[][] clone = new float[array.length][]; for (int i = 0; i < array.length; i++) { clone[i] = array[i].clone(); } return clone; } public static int[][] clone(int[][] array) { int[][] clone = new int[array.length][]; for (int i = 0; i < array.length; i++) { clone[i] = array[i].clone(); } return clone; } public static short[][] clone(short[][] array) { short[][] clone = new short[array.length][]; for (int i = 0; i < array.length; i++) { clone[i] = array[i].clone(); } return clone; } }