package org.genedb.crawl.controller; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.genedb.crawl.model.Argument; import org.genedb.crawl.model.Resource; import org.genedb.crawl.model.Service; import org.genedb.crawl.annotations.ResourceDescription; import org.genedb.crawl.controller.editor.DatePropertyEditor; import org.genedb.crawl.controller.editor.ListSplittingPropertyEditor; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ValueConstants; public abstract class BaseController { private Logger logger = Logger.getLogger(BaseController.class); @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(List.class, new ListSplittingPropertyEditor()); binder.registerCustomEditor(Date.class, new DatePropertyEditor()); } @RequestMapping(method=RequestMethod.GET, value={"/", "/index"}) @ResourceDescription("lists the resources") public Service index() { logger.info("Returning index of " + this); Service service = new Service(); Class<? extends BaseController> cls = getClass(); RequestMapping requestMapping = cls.getAnnotation(RequestMapping.class); if (requestMapping != null) { service.name = requestMapping.value()[0]; } ResourceDescription description = cls.getAnnotation(ResourceDescription.class); if (description != null) { service.description = description.value(); } Method[] methods = cls.getMethods(); for (Method method : methods) { if (! Modifier.isPublic(method.getModifiers())) { continue; } Resource resource = new Resource(); boolean addMethod = false; // resource.returnType = method.getReturnType().getSimpleName(); ResourceDescription methodDescription = method.getAnnotation(ResourceDescription.class); if (methodDescription != null) { addMethod = true; resource.description = methodDescription.value(); resource.returnType =methodDescription.type(); } for (Annotation annotation : method.getAnnotations()) { if (annotation instanceof RequestMapping) { addMethod = true; RequestMapping methodRequestMapping = (RequestMapping)annotation; resource.name = methodRequestMapping.value()[0]; Annotation[][] methodAnnotations = method.getParameterAnnotations(); int index = 0; Class<?>[] types = method.getParameterTypes(); Map<Integer, Argument> parameterMap = new LinkedHashMap<Integer, Argument>(); for (Annotation[] paramAnnotations : methodAnnotations) { for (Annotation paramAnnotation : paramAnnotations) { if (paramAnnotation instanceof RequestParam) { Argument arg = getOrCreateArgument(parameterMap, index); RequestParam requestParamAnnotation = (RequestParam)paramAnnotation; arg.name = requestParamAnnotation.value(); String defaultValue = requestParamAnnotation.defaultValue(); if (! defaultValue.equals(ValueConstants.DEFAULT_NONE)) { arg.defaultValue = defaultValue; } arg.type = types[index].getSimpleName(); } else if (paramAnnotation instanceof ResourceDescription) { Argument arg = getOrCreateArgument(parameterMap, index); ResourceDescription resourceDescriptionParamAnnotation = (ResourceDescription)paramAnnotation; arg.description = resourceDescriptionParamAnnotation.value(); } } index++; } resource.args = new ArrayList<Argument> ( parameterMap.values() ); } } if (addMethod) { service.resources.add(resource); } } return service; } private Argument getOrCreateArgument(Map<Integer, Argument> arguments, int index) { if (! arguments.containsKey(index)) { arguments.put(index, new Argument()); } return arguments.get(index); } }