package net.sourceforge.javautil.groovy.builder.interceptor.objectfactory;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassMethod;
import net.sourceforge.javautil.groovy.builder.GroovyBuilder;
import net.sourceforge.javautil.groovy.builder.interceptor.annotation.Attributes;
/**
* This extends the standard implementation and allows annotations to define how attributes are applied
* and how parent<->child nodes are associated.
*
* @author elponderador
*/
public class AnnotatedAttributeApplicator extends StandardAttributeApplicator {
private Map<Class, ClassMethod> apply = new HashMap<Class, ClassMethod>();
/**
* This will see if there is a {@link Attributes} annotation so as to specify a method that will
* take a single {@link Map} attribute so as to apply its attributes in a specific way. Otherwise
* it will simply pass on to the {@link StandardAttributeApplicator#applyAttributes(ObjectFactoryInterceptor, String, Object, Map)}.
*/
public void applyAttributes(GroovyBuilder builder, ObjectFactoryInterceptor ofi, String nodeName, Object instance, Map<Object, Object> attributes) {
ClassMethod apply = this.getAttributeApplicator(instance.getClass());
if (apply != null && attributes != null) apply.invoke(instance, attributes);
else if (attributes != null) super.applyAttributes(builder, ofi, nodeName, instance, attributes);
}
protected ClassMethod getAttributeApplicator (Class clazz) {
if (!this.apply.containsKey(clazz)) {
this.apply.put(clazz, ClassCache.getFor(clazz).getMethod(Attributes.class));
}
return this.apply.get(clazz);
}
}