package es.internna.spring.context;
import es.internna.spring.annotations.AutowireToController;
import es.internna.spring.annotations.Bean;
import es.internna.spring.annotations.UrlMapping;
import es.internna.spring.annotations.UrlMappings;
import es.internna.spring.mvc.api.AdvisableController;
import es.internna.spring.mvc.api.RequestHandler;
import es.internna.spring.mvc.api.validation.ValidatorHolder;
import es.internna.spring.utils.ClassUtils;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.validation.Validator;
@Bean(name="annotationUrlHandlerMapping")
public class AnnotationUrlHandlerMapping extends AbstractUrlHandlerMapping implements ApplicationListener {
private Log log = LogFactory.getLog(AnnotationUrlHandlerMapping.class);
private Class<?> getClass (Object bean) {
Class clazz = bean.getClass();
if (Advised.class.isInstance(bean)) {
Advised advised = (Advised) bean;
clazz = advised.getTargetSource().getTargetClass();
}
return clazz;
}
private void registerController(Object bean, String beanName)
{
Class<?> clazz = this.getClass(bean);
UrlMapping mapping = clazz.getAnnotation(UrlMapping.class);
if (mapping != null) registerHandler(mapping.value(), beanName);
UrlMappings mappings = clazz.getAnnotation(UrlMappings.class);
if (mappings != null)
for (UrlMapping map : mappings.value())
registerHandler(map.value(), beanName);
}
private void configureMappings(Map beans) {
log.info("AnnotationUrlHandlerMapping started configuring mappings");
if (beans != null) {
for (Object beanName : beans.keySet()) {
registerController(beans.get(beanName), (String) beanName);
}
}
}
private void configureInterceptors(Map beans) {
log.info("AnnotationUrlHandlerMapping started configuring interceptors");
if (beans != null) {
Set<Object> interceptors = new HashSet<Object>();
for (Object beanName : beans.keySet()) interceptors.add(beans.get(beanName));
if (!interceptors.isEmpty()) {
if (log.isDebugEnabled()) log.debug("Initing request interceptors: " + beans.keySet());
this.setInterceptors(interceptors.toArray());
this.initInterceptors();
}
}
}
private void wire(ApplicationContext context, RequestHandler bean, AutowireToController autowireTo) {
String toBean = autowireTo.controllerBean();
if ((toBean != null) && (toBean.length() > 0)) {
AdvisableController controller = (AdvisableController) context.getBean(toBean);
if (controller != null) {
if (log.isInfoEnabled()) log.info("Wiring request handler bean " + bean + " to controller \"" + toBean + "\"");
controller.addRequestHandler(bean);
}
} else {
Class beanClass = autowireTo.controllerClass();
if ((beanClass != null) & (!AutowireToController.class.equals(beanClass))) {
Map controllers = context.getBeansOfType(beanClass);
if (controllers != null) {
for (Object controllerName : controllers.keySet()) {
AdvisableController controller = (AdvisableController) controllers.get(controllerName);
if (log.isInfoEnabled()) log.info("Wiring request handler bean " + bean + " to controller \"" + controllerName + "\"");
controller.addRequestHandler(bean);
}
}
}
}
}
private void configureRequestHandlers(ApplicationContext context) {
log.info("AnnotationUrlHandlerMapping started configuring request handlers");
Map beans = context.getBeansOfType(RequestHandler.class);
log.info("Got request handlers " + beans.keySet().size());
if (beans != null) {
for (Object beanName : beans.keySet()) {
log.info("Processing " + beanName);
RequestHandler requestHandler = (RequestHandler) beans.get(beanName);
log.info("Obtained " + requestHandler);
AutowireToController autowireTo = ClassUtils.getAnnotation(AutowireToController.class, requestHandler);
log.info("Autowire? " + autowireTo);
if (autowireTo != null) wire (context, requestHandler, autowireTo);
log.info("Wired");
}
}
}
private void configureValidators(ApplicationContext context) {
log.info("AnnotationUrlHandlerMapping started configuring validators");
Map beans = context.getBeansOfType(ValidatorHolder.class);
if (beans != null) {
for (Object beanName : beans.keySet()) {
if (log.isDebugEnabled()) log.debug("Found validator holder " + beanName);
ValidatorHolder holder = (ValidatorHolder) beans.get(beanName);
Map validatorBeans = context.getBeansOfType(Validator.class);
for (Object validatorBeanName : validatorBeans.keySet()) {
if (log.isDebugEnabled()) log.debug("Found validator " + validatorBeanName);
holder.addValidator(validatorBeans.get(validatorBeanName));
if (log.isDebugEnabled()) log.debug("Adding validator " + validatorBeanName + " to " + beanName);
}
}
}
}
public void onApplicationEvent(ApplicationEvent applicationEvent)
{
if (applicationEvent instanceof ContextRefreshedEvent) {
ContextRefreshedEvent initEvent = (ContextRefreshedEvent) applicationEvent;
ApplicationContext context = initEvent.getApplicationContext();
if (context != null) {
configureMappings(context.getBeansOfType(Controller.class));
configureInterceptors(context.getBeansOfType(HandlerInterceptor.class));
configureRequestHandlers(context);
configureValidators(context);
}
}
}
}