private Map<String, SpringResource> generateResourceMap(Set<Class<?>> validClasses) throws GenerateException { Map<String, SpringResource> resourceMap = new HashMap<String, SpringResource>(); for (Class<?> c : validClasses) { RequestMapping requestMapping = c.getAnnotation(RequestMapping.class); String description = ""; // This try/catch block is to stop a bamboo build from failing due to NoClassDefFoundError // This occurs when a class or method loaded by reflections contains a type that has no // dependency try { resourceMap = analyzeController(c, resourceMap, description); List<Method> mList = new ArrayList<Method>(Arrays.asList(c.getMethods())); if (c.getSuperclass() != null) { mList.addAll(Arrays.asList(c.getSuperclass().getMethods())); } } catch (NoClassDefFoundError e) { LOG.error(e.getMessage()); LOG.info(c.getName()); // exception occurs when a method type or annotation is not recognized by the plugin } catch (ClassNotFoundException e) { LOG.error(e.getMessage()); LOG.info(c.getName()); } } return resourceMap; }
// Helper method for loadDocuments() private Map<String, SpringResource> analyzeController( Class<?> clazz, Map<String, SpringResource> resourceMap, String description) throws ClassNotFoundException { String controllerCanonicalName = clazz.getCanonicalName(); String[] controllerRequestMappingValues = null; // Determine if we will use class-level requestmapping or dummy string if (clazz.getAnnotation(RequestMapping.class) != null && clazz.getAnnotation(RequestMapping.class).value() != null) { controllerRequestMappingValues = clazz.getAnnotation(RequestMapping.class).value(); } else { controllerRequestMappingValues = new String[1]; controllerRequestMappingValues[0] = ""; } // Iterate over all value attributes of the class-level RequestMapping annotation for (int i = 0; i < controllerRequestMappingValues.length; i++) { // Iterate over all methods inside the controller Method[] methods = clazz.getMethods(); for (Method method : methods) { RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class); // Look for method-level @RequestMapping annotation if (methodRequestMapping instanceof RequestMapping) { RequestMethod[] requestMappingRequestMethods = methodRequestMapping.method(); // For each method-level @RequestMapping annotation, iterate over HTTP Verb for (RequestMethod requestMappingRequestMethod : requestMappingRequestMethods) { String[] methodRequestMappingValues = methodRequestMapping.value(); // Check for cases where method-level @RequestMapping#value is not set, and use the // controllers @RequestMapping if (methodRequestMappingValues == null || methodRequestMappingValues.length == 0) { // The map key is a concat of the following: // 1. The controller package // 2. The controller class name // 3. The controller-level @RequestMapping#value String resourceKey = controllerCanonicalName + controllerRequestMappingValues[i] + requestMappingRequestMethod; if ((!(resourceMap.containsKey(resourceKey)))) { resourceMap.put( resourceKey, new SpringResource( clazz, controllerRequestMappingValues[i], resourceKey, description)); } resourceMap.get(resourceKey).addMethod(method); } else { // Here we know that method-level @RequestMapping#value is populated, so // iterate over all the @RequestMapping#value attributes, and add them to the resource // map. for (String methodRequestMappingValue : methodRequestMappingValues) { String resourceName = methodRequestMappingValue; // The map key is a concat of the following: // 1. The controller package // 2. The controller class name // 3. The controller-level @RequestMapping#value // 4. The method-level @RequestMapping#value // 5. The method-level @RequestMapping#method String resourceKey = controllerCanonicalName + controllerRequestMappingValues[i] + resourceName + requestMappingRequestMethod; if (!(resourceName.equals(""))) { if ((!(resourceMap.containsKey(resourceKey)))) { resourceMap.put( resourceKey, new SpringResource(clazz, resourceName, resourceKey, description)); } resourceMap.get(resourceKey).addMethod(method); } } } } } } } clazz.getFields(); clazz .getDeclaredFields(); // <--In case developer declares a field without an associated // getter/setter. // this will allow NoClassDefFoundError to be caught before it triggers bamboo failure. return resourceMap; }