package org.gwtoolbox.ioc.core.rebind.processor;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.core.ext.typeinfo.JClassType;
import org.gwtoolbox.bean.rebind.BeanOracle;
import org.gwtoolbox.bean.rebind.BeanOracleBuilder;
import org.gwtoolbox.commons.generator.rebind.EasyTreeLogger;
import org.gwtoolbox.commons.generator.rebind.GeneratorUtils;
import org.gwtoolbox.commons.generator.rebind.JMethodVisitor;
import org.gwtoolbox.ioc.core.client.annotation.*;
import org.gwtoolbox.ioc.core.rebind.config.SimpleComponentDefinition;
import org.gwtoolbox.commons.generator.rebind.JClassTypeVisitor;
/**
* @author Uri Boness
*/
public class StandardComponentDefinitionProcessor implements SimpleComponentDefinitionProcessor {
public void process(EasyTreeLogger logger, SimpleComponentDefinition definition, TypeOracle typeOracle)
throws UnableToCompleteException {
BeanOracle beanOracle = new BeanOracleBuilder(typeOracle).build(logger, definition.getComponentType());
processAnnotations(logger, definition, beanOracle);
}
protected void processAnnotations(final EasyTreeLogger logger, final SimpleComponentDefinition definition, BeanOracle beanOracle)
throws UnableToCompleteException {
if (beanOracle.getType().isAnnotationPresent(Order.class)) {
Order order = beanOracle.getType().getAnnotation(Order.class);
definition.setOrder(order.value());
}
GeneratorUtils.visitHierarchy(beanOracle.getType(), new JClassTypeVisitor() {
public boolean visit(JClassType type) {
JClassType generatedType = resolveGeneratedTypeIfPresent(logger, type);
if (generatedType != null) {
logger.info("Found generated type for '" + type.getQualifiedSourceName() + "' -> '" + generatedType.getQualifiedSourceName() + "'");
definition.setGeneratedType(generatedType);
return false;
}
return true;
}
});
GeneratorUtils.visitMethods(beanOracle.getType(), new JMethodVisitor() {
public boolean visit(JMethod method) {
if (isInitMethod(method)) {
definition.setInitMethodName(method.getName());
} else if (isDisposeMethod(method)) {
definition.setDisposeMethodName(method.getName());
} else if (isEventHandlerMethod(method)) {
definition.addEventHandler(method);
}
return true;
}
});
}
protected boolean isInitMethod(JMethod method) {
return method.isAnnotationPresent(Initializer.class) || method.isAnnotationPresent(PostConstruct.class);
}
protected boolean isDisposeMethod(JMethod method) {
return method.isAnnotationPresent(Disposer.class) || method.isAnnotationPresent(PreDestroy.class);
}
protected boolean isEventHandlerMethod(JMethod method) {
return method.isAnnotationPresent(EventHandler.class);
}
protected JClassType resolveGeneratedTypeIfPresent(EasyTreeLogger logger, JClassType type) {
if (!type.isAnnotationPresent(Generated.class)) {
return null;
}
logger.info("Found @Generated annotation on type '" + type.getQualifiedSourceName() + "'");
Generated generated = type.getAnnotation(Generated.class);
Class generatedClass = generated.value();
if (Object.class == generatedClass) {
logger.info("Generated type: '" + type.getQualifiedSourceName() + "'");
return type;
}
logger.info("Generated type: '" + generatedClass.getName() + "'");
return type.getOracle().findType(generatedClass.getName());
}
}