From de5276c3f2ad19528e036120b7b52c7649ac034d Mon Sep 17 00:00:00 2001 From: trisberg Date: Tue, 27 Jul 2010 20:51:45 -0400 Subject: [PATCH] needed for graph tests --- ...AbstractConstructorEntityInstantiator.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/main/java/org/springframework/persistence/support/AbstractConstructorEntityInstantiator.java diff --git a/src/main/java/org/springframework/persistence/support/AbstractConstructorEntityInstantiator.java b/src/main/java/org/springframework/persistence/support/AbstractConstructorEntityInstantiator.java new file mode 100644 index 000000000..9d7efbc10 --- /dev/null +++ b/src/main/java/org/springframework/persistence/support/AbstractConstructorEntityInstantiator.java @@ -0,0 +1,61 @@ +package org.springframework.persistence.support; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.util.ClassUtils; + +/** + * Try for a constructor taking state: failing that, try a no-arg + * constructor and then setUnderlyingNode(). + * + * @author Rod Johnson + */ +public abstract class AbstractConstructorEntityInstantiator implements EntityInstantiator { + + private final Log log = LogFactory.getLog(getClass()); + + final public T createEntityFromState(STATE n, Class c) { + try { + return fromStateInternal(n, c); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } + + final private T fromStateInternal(STATE n, Class c) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { + // TODO this is fragile + Class stateInterface = (Class) n.getClass().getInterfaces()[0]; + Constructor nodeConstructor = ClassUtils.getConstructorIfAvailable(c, stateInterface); + if (nodeConstructor != null) { + // TODO is this the correct way to instantiate or does Spring have a preferred way? + log.info("Using " + c + " constructor taking " + stateInterface); + return nodeConstructor.newInstance(n); + } + + Constructor noArgConstructor = ClassUtils.getConstructorIfAvailable(c); + if (noArgConstructor != null) { + log.info("Using " + c + " no-arg constructor"); + T t = noArgConstructor.newInstance(); + setState(t, n); + return t; + } + + throw new IllegalArgumentException(getClass().getSimpleName() + ": entity " + c + " must have either a constructor taking [" + stateInterface + + "] or a no-arg constructor and state set method"); + } + + /** + * Subclasses must implement to set state + * @param entity + * @param s + */ + protected abstract void setState(BACKING_INTERFACE entity, STATE s); + +}