package net.sourceforge.javautil.groovy.builder.interceptor.objectfactory;
import groovy.lang.MetaClass;
import groovy.lang.MetaProperty;
import java.lang.reflect.Field;
import java.util.Map;
import net.sourceforge.javautil.groovy.builder.GroovyBuilder;
import org.codehaus.groovy.runtime.InvokerHelper;
/**
* This is a standard implementation of {@link NodeAttributeApplicator}.
*
* @author elponderador
*/
public class StandardAttributeApplicator implements NodeAttributeApplicator {
/**
* This will first see if the node instance implements {@link SelfAttributeApplicator}. If it does
* it will simply call its delegating method. Otherwise it will attempt to get {@link MetaProperty}'s
* for each key name in the attributes map and set it on the instance.
*/
public void applyAttributes(GroovyBuilder builder, ObjectFactoryInterceptor ofi, String nodeName, Object instance, Map<Object, Object> attributes) {
if (attributes == null) return;
if (instance instanceof SelfAttributeApplicator) {
((SelfAttributeApplicator)instance).applyAttributes(attributes);
} else {
MetaClass mc = ofi.getMetaClassForNode(nodeName);
if (mc.getTheClass() != instance.getClass()) mc = InvokerHelper.getMetaClass(instance.getClass());
for (Object key : attributes.keySet()) {
MetaProperty prop = mc.getMetaProperty(String.valueOf(key));
if (prop == null) {
try {
Field field = mc.getTheClass().getField(String.valueOf(key));
field.set(instance, attributes.get(key));
}
catch (SecurityException e) {}
catch (NoSuchFieldException e) {}
catch (IllegalAccessException e) {}
throw new RuntimeException("Could not find " + key + " property/attribute on " + instance);
} else {
prop.setProperty(instance, attributes.get(key));
}
}
}
}
/**
* This will assume that parent nodes will have a method called 'addChild'
* that takes a single argument which is the child node. It will also assume
* that child nodes will have a method called 'setParent'.
*
* @see ObjectFactoryInterceptor#isPassParentToConstructor()
*/
public void associate(GroovyBuilder builder, ObjectFactoryInterceptor ofi, Object child, Object parent) {
if (parent != null) {
MetaClass pmc = InvokerHelper.getMetaClass(child.getClass());
pmc.invokeMethod(parent, "addChild", new Object[] { parent });
}
MetaClass cmc = InvokerHelper.getMetaClass(child.getClass());
cmc.invokeMethod(child, "setParent", new Object[] { parent });
}
}