diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/persistence/AbstractConstructorEntityInstantiator.java b/spring-data-commons-core/src/main/java/org/springframework/data/persistence/AbstractConstructorEntityInstantiator.java index 3684953a8..6f1fdab81 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/persistence/AbstractConstructorEntityInstantiator.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/persistence/AbstractConstructorEntityInstantiator.java @@ -17,24 +17,20 @@ import java.util.Map; */ public abstract class AbstractConstructorEntityInstantiator implements EntityInstantiator { - interface Instantiator { - T create(STATE n, Class c) throws Exception; - } - - private final Logger log = LoggerFactory.getLogger(getClass()); - private final Map,Instantiator> cache = new HashMap,Instantiator>(); + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Map,StateBackedCreator> cache = new HashMap,StateBackedCreator>(); final public T createEntityFromState(STATE n, Class c) { try { - Instantiator instantiator = (Instantiator) cache.get(c); - if (instantiator!=null) return instantiator.create(n,c); + StateBackedCreator creator = (StateBackedCreator) cache.get(c); + if (creator !=null) return creator.create(n,c); synchronized (cache) { - instantiator = (Instantiator) cache.get(c); - if (instantiator!=null) return instantiator.create(n,c); + creator = (StateBackedCreator) cache.get(c); + if (creator !=null) return creator.create(n,c); Class stateClass = (Class) n.getClass(); - instantiator=createInstantiator(c, stateClass); - cache.put(c,instantiator); - return instantiator.create(n,c); + creator =createInstantiator(c, stateClass); + cache.put(c, creator); + return creator.create(n,c); } } catch (IllegalArgumentException e) { throw e; @@ -46,20 +42,20 @@ public abstract class AbstractConstructorEntityInstantiator,Instantiator> instantiators) { + public void setInstantiators(Map,StateBackedCreator> instantiators) { this.cache.putAll(instantiators); } - protected Instantiator createInstantiator(Class type, final Class stateType) { - Instantiator instantiator=stateTakingConstructorInstantiator(type,stateType); - if (instantiator!=null) return instantiator; - instantiator = emptyConstructorStateSettingInstantiator(type,stateType); - if (instantiator!=null) return instantiator; + protected StateBackedCreator createInstantiator(Class type, final Class stateType) { + StateBackedCreator creator =stateTakingConstructorInstantiator(type,stateType); + if (creator !=null) return creator; + creator = emptyConstructorStateSettingInstantiator(type,stateType); + if (creator !=null) return creator; return createFailingInstantiator(stateType); } - private Instantiator createFailingInstantiator(final Class stateType) { - return new Instantiator() { + private StateBackedCreator createFailingInstantiator(final Class stateType) { + return new StateBackedCreator() { public T create(STATE n, Class c) throws Exception { throw new IllegalArgumentException(getClass().getSimpleName() + ": entity " + c + " must have either a constructor taking [" + stateType + "] or a no-arg constructor and state set method"); @@ -67,13 +63,13 @@ public abstract class AbstractConstructorEntityInstantiator Instantiator emptyConstructorStateSettingInstantiator(Class type, Class stateType) { + private StateBackedCreator emptyConstructorStateSettingInstantiator(Class type, Class stateType) { final Constructor constructor = getNoArgConstructor(type); if (constructor == null) return null; log.info("Using " + type + " no-arg constructor"); - return new Instantiator() { + return new StateBackedCreator() { public T create(STATE n, Class c) throws Exception { try { StateProvider.setUnderlyingState(n); @@ -93,13 +89,13 @@ public abstract class AbstractConstructorEntityInstantiator Instantiator stateTakingConstructorInstantiator(Class type, Class stateType) { + private StateBackedCreator stateTakingConstructorInstantiator(Class type, Class stateType) { Class stateInterface = (Class) stateType.getInterfaces()[0]; final Constructor constructor = ClassUtils.getConstructorIfAvailable(type, stateInterface); if (constructor == null) return null; log.info("Using " + type + " constructor taking " + stateInterface); - return new Instantiator() { + return new StateBackedCreator() { public T create(STATE n, Class c) throws Exception { return constructor.newInstance(n); } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/persistence/StateBackedCreator.java b/spring-data-commons-core/src/main/java/org/springframework/data/persistence/StateBackedCreator.java new file mode 100644 index 000000000..c65e97895 --- /dev/null +++ b/spring-data-commons-core/src/main/java/org/springframework/data/persistence/StateBackedCreator.java @@ -0,0 +1,11 @@ +package org.springframework.data.persistence; + +/** +* encapsulates the instantiator of state-backed classes and populating them with the provided state. +* +* Can be implemented and registered with the concrete AbstractConstructorEntityInstantiator to provide +* non reflection bases instantiaton for domain classes +*/ +public interface StateBackedCreator { + T create(STATE n, Class c) throws Exception; +}