All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jvnet.jaxb2_commons.lang.DefaultCopyStrategy Maven / Gradle / Ivy

The newest version!
package org.jvnet.jaxb2_commons.lang;

import static org.jvnet.jaxb2_commons.locator.util.LocatorUtils.item;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.jvnet.jaxb2_commons.locator.ObjectLocator;

@SuppressWarnings("deprecation")
public class DefaultCopyStrategy implements CopyStrategy2, CopyStrategy {

	protected Object copyInternal(ObjectLocator locator, Object object) {
		if (object == null) {
			return null;
		} else if (object instanceof String) {
			return object;
		} else if (object instanceof Number) {
			return object;
		} else if (object instanceof CopyTo2) {
			return ((CopyTo2) object).copyTo(locator,
					((CopyTo2) object).createNewInstance(), this);
		} else if (object instanceof CopyTo) {
			return ((CopyTo) object).copyTo(locator,
					((CopyTo) object).createNewInstance(), this);
		} else if (object instanceof Cloneable) {
			return copyInternal(locator, (Cloneable) object);
		} else {
			return object;
		}
	}

	public Object copy(ObjectLocator locator, Object value) {
		if (value == null) {
			return null;
		}
		Class lhsClass = value.getClass();
		if (!lhsClass.isArray()) {
			return copyInternal(locator, value);
		}
		// 'Switch' on type of array, to dispatch to the correct handler
		// This handles multi dimensional arrays of the same depth
		else if (value instanceof long[]) {
			return copy(locator, (long[]) value);
		} else if (value instanceof int[]) {
			return copy(locator, (int[]) value);
		} else if (value instanceof short[]) {
			return copy(locator, (short[]) value);
		} else if (value instanceof char[]) {
			return copy(locator, (char[]) value);
		} else if (value instanceof byte[]) {
			return copy(locator, (byte[]) value);
		} else if (value instanceof double[]) {
			return copy(locator, (double[]) value);
		} else if (value instanceof float[]) {
			return copy(locator, (float[]) value);
		} else if (value instanceof boolean[]) {
			return copy(locator, (boolean[]) value);
		} else {
			// Not an array of primitives
			return copy(locator, (Object[]) value);
		}
	}

	public long copy(ObjectLocator locator, long value) {
		return value;
	}

	public int copy(ObjectLocator locator, int value) {
		return value;
	}

	public short copy(ObjectLocator locator, short value) {
		return value;
	}

	public char copy(ObjectLocator locator, char value) {
		return value;
	}

	public byte copy(ObjectLocator locator, byte value) {
		return value;
	}

	public double copy(ObjectLocator locator, double value) {
		return value;
	}

	public float copy(ObjectLocator locator, float value) {
		return value;
	}

	public boolean copy(ObjectLocator locator, boolean value) {
		return value;
	}

	public Object[] copy(ObjectLocator locator, Object[] array) {
		if (array == null) {
			return null;
		}
		final Object[] copy = new Object[array.length];
		for (int index = 0; index < array.length; index++) {
			final Object element = array[index];
			final Object elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public long[] copy(ObjectLocator locator, long[] array) {
		if (array == null) {
			return null;
		}
		final long[] copy = new long[array.length];
		for (int index = 0; index < array.length; index++) {
			final long element = array[index];
			final long elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public int[] copy(ObjectLocator locator, int[] array) {
		if (array == null) {
			return null;
		}
		final int[] copy = new int[array.length];
		for (int index = 0; index < array.length; index++) {
			final int element = array[index];
			final int elementCopy = copy(item(locator, index, element), element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public short[] copy(ObjectLocator locator, short[] array) {
		if (array == null) {
			return null;
		}
		final short[] copy = new short[array.length];
		for (int index = 0; index < array.length; index++) {
			final short element = array[index];
			final short elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public char[] copy(ObjectLocator locator, char[] array) {
		if (array == null) {
			return null;
		}
		final char[] copy = new char[array.length];
		for (int index = 0; index < array.length; index++) {
			final char element = array[index];
			final char elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public byte[] copy(ObjectLocator locator, byte[] array) {
		if (array == null) {
			return null;
		}
		final byte[] copy = new byte[array.length];
		for (int index = 0; index < array.length; index++) {
			final byte element = array[index];
			final byte elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public double[] copy(ObjectLocator locator, double[] array) {
		if (array == null) {
			return null;
		}
		final double[] copy = new double[array.length];
		for (int index = 0; index < array.length; index++) {
			final double element = array[index];
			final double elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public float[] copy(ObjectLocator locator, float[] array) {
		if (array == null) {
			return null;
		}
		final float[] copy = new float[array.length];
		for (int index = 0; index < array.length; index++) {
			final float element = array[index];
			final float elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	public boolean[] copy(ObjectLocator locator, boolean[] array) {
		if (array == null) {
			return null;
		}
		final boolean[] copy = new boolean[array.length];
		for (int index = 0; index < array.length; index++) {
			final boolean element = array[index];
			final boolean elementCopy = copy(item(locator, index, element),
					element);
			copy[index] = elementCopy;
		}
		return copy;
	}

	protected Object copyInternal(ObjectLocator locator, Cloneable object) {
		return copyInternal(locator, object, false);
	}

	protected Object copyInternal(ObjectLocator locator, Cloneable object, boolean checkCloneable) {
		Class clazz = object.getClass();
		Method method = null;

		if (checkCloneable) {
			Class parentClazz = clazz.getSuperclass();

			while (parentClazz != null && hasCloneableInterface(parentClazz)) {
				clazz = parentClazz;
				parentClazz = clazz.getSuperclass();
			}
		}

		try {
			method = clazz.getMethod("clone", (Class[]) null);
		} catch (NoSuchMethodException nsmex) {
			method = null;
		}

		if (method == null || !Modifier.isPublic(method.getModifiers())) {

			throw new UnsupportedOperationException(
					"Could not clone object [" + object + "].",
					new CloneNotSupportedException(
							"Object class ["
									+ object.getClass()
									+ "] implements java.lang.Cloneable interface, "
									+ (checkCloneable ? ("with final determined class [" + clazz + "]") : "")
									+ "but does not provide a public no-arg clone() method. "
									+ "By convention, classes that implement java.lang.Cloneable "
									+ "should override java.lang.Object.clone() method (which is protected) "
									+ "with a public method."));
		}

		final boolean wasAccessible = method.isAccessible();
		try {
			if (!wasAccessible) {
				try {
					method.setAccessible(true);
				} catch (SecurityException ignore) {
				}
			}

			return method.invoke(object, (Object[]) null);
		} catch (Exception ex) {
			if (!checkCloneable && "java.lang.reflect.InaccessibleObjectException".equals(ex.getClass().getName())) {
				return copyInternal(locator, object, true);
			}
			throw new UnsupportedOperationException(
					"Could not clone the object ["
							+ object
							+ "] as invocation of the clone() method has thrown an exception.",
					ex);
		} finally {
			if (!wasAccessible) {
				try {
					method.setAccessible(false);
				} catch (SecurityException ignore) {
				}
			}
		}
	}

	private static boolean hasCloneableInterface(Class clazz) {
		if (clazz != null) {
			for (Class iface : clazz.getInterfaces()) {
				if (iface.isAssignableFrom(Cloneable.class)) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public Boolean shouldBeCopiedAndSet(ObjectLocator locator, boolean valueSet) {
		return valueSet;
	}

	@Override
	public boolean copy(ObjectLocator locator, boolean value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public byte copy(ObjectLocator locator, byte value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public char copy(ObjectLocator locator, char value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public double copy(ObjectLocator locator, double value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public float copy(ObjectLocator locator, float value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public int copy(ObjectLocator locator, int value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public long copy(ObjectLocator locator, long value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public short copy(ObjectLocator locator, short value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public Object copy(ObjectLocator locator, Object value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public boolean[] copy(ObjectLocator locator, boolean[] value,
			boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public byte[] copy(ObjectLocator locator, byte[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public char[] copy(ObjectLocator locator, char[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public double[] copy(ObjectLocator locator, double[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public float[] copy(ObjectLocator locator, float[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public int[] copy(ObjectLocator locator, int[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public long[] copy(ObjectLocator locator, long[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public short[] copy(ObjectLocator locator, short[] value, boolean valueSet) {
		return copy(locator, value);
	}

	@Override
	public Object[] copy(ObjectLocator locator, Object[] value, boolean valueSet) {
		return copy(locator, value);
	}

	public static final DefaultCopyStrategy INSTANCE2 = new DefaultCopyStrategy();
	public static final CopyStrategy INSTANCE = INSTANCE2;

	public static DefaultCopyStrategy getInstance() {
		return INSTANCE2;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy