Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/get generic annotation #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
Expand All @@ -20,10 +21,10 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.ServletContextAware;

import com.cinefms.apitester.annotations.ApiDescription;
Expand Down Expand Up @@ -110,21 +111,23 @@ public List<ApiCall> scanControllers(ApplicationContext ctx) {
if (ctx.getId() != null) {
namespace = ctx.getId();
}
List<ApiCall> outa = scanControllers(namespace, new ArrayList<Object>(ctx.getBeansWithAnnotation(Controller.class).values()));
List<ApiCall> outb = scanControllers(namespace, new ArrayList<Object>(ctx.getBeansWithAnnotation(RestController.class).values()));
outa.addAll(outb);
return outa;
return scanControllers(namespace, new ArrayList<Object>(ctx.getBeansWithAnnotation(Controller.class).values()));
}

public <T extends Annotation> T getClassAnnotation(Class<?> clazz, Class<T> annotationClass){
return AnnotationUtils.findAnnotation(clazz, annotationClass);
}

public <T extends Annotation> T getMethodAnnotation(Method method, Class<T> annotationClass){
return AnnotationUtils.findAnnotation(method, annotationClass);
}

public List<ApiCall> scanControllers(String namespace, List<Object> controllers) {

List<ApiCall> out = new ArrayList<ApiCall>();

for (Object controller : controllers) {

// com.cinefms.apitester.springmvc.crawlers.TestController2$$EnhancerByCGLIB$$84793797

Class<?> clazz = controller.getClass();
Class<?> clazz = controller.getClass();

String handlerClass = clazz.getName();

Expand All @@ -135,16 +138,14 @@ public List<ApiCall> scanControllers(String namespace, List<Object> controllers)
} catch (ClassNotFoundException e) {
}
}



log.info(" ## FOUND " + controllers.size() + " CONTROLLERS ... " + handlerClass);

Method[] methods = clazz.getMethods();

String[] classLevelPaths = new String[] { "" };

RequestMapping rmType = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
RequestMapping rmType = getClassAnnotation(clazz, RequestMapping.class);
if (rmType != null) {
classLevelPaths = rmType.value();
}
Expand All @@ -157,10 +158,12 @@ public List<ApiCall> scanControllers(String namespace, List<Object> controllers)
String deprecatedSince = null;
String since = null;
boolean deprecated = false;
if (m.getAnnotation(Deprecated.class) != null) {
deprecated = true;

if(getMethodAnnotation(m, Deprecated.class)!=null){
deprecated = true;
}
ApiDescription ad = m.getAnnotation(ApiDescription.class);

ApiDescription ad = getMethodAnnotation(m, ApiDescription.class);
if (ad != null) {
if (ad.deprecatedSince().length() > 0) {
deprecatedSince = ad.deprecatedSince();
Expand All @@ -173,13 +176,12 @@ public List<ApiCall> scanControllers(String namespace, List<Object> controllers)
description = ad.value();
}
if (ad.file().length() > 0) {
description = loadResource(clazz,
ad.file());
description = loadResource(clazz,ad.file());
}
}

String handlerMethod = m.getName();
RequestMapping rmm = m.getAnnotation(RequestMapping.class);
RequestMapping rmm = getMethodAnnotation(m, RequestMapping.class);

if (rmm != null) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,27 @@

import javax.servlet.ServletContext;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.support.GenericWebApplicationContext;

import com.cinefms.apitester.core.ApitesterService;
import com.cinefms.apitester.model.info.ApiCall;
import com.cinefms.apitester.springmvc.crawlers.mapping.AbstractController2;
import com.cinefms.apitester.springmvc.crawlers.mapping.AbstractControllerMethod;
import com.cinefms.apitester.springmvc.crawlers.mapping.Controller3;
import com.cinefms.apitester.springmvc.crawlers.mapping.ControllerImpl1;
import com.cinefms.apitester.springmvc.crawlers.mapping.ControllerImpl2;
import com.cinefms.apitester.springmvc.crawlers.mapping.ControllerImpl3;
import com.cinefms.apitester.springmvc.crawlers.mapping.ControllerMethod;
import com.cinefms.apitester.springmvc.crawlers.mapping.ControllerMethodImpl;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

public class SpringAnnotationCrawlerTest {

Expand Down Expand Up @@ -386,28 +395,64 @@ public void testDescriptionInFileExpectSuccess() {
}

@Test
public void testGenericController() {
ApplicationContext acc = mock(ApplicationContext.class);

Map<String,Object> cMap = new HashMap<String, Object>();
Map<String,Object> rcMap = new HashMap<String, Object>();
Object a = new GenericTestControllerImpl();
rcMap.put("a",a);

when(acc.getBeansWithAnnotation(Controller.class)).thenReturn(cMap);
when(acc.getBeansWithAnnotation(RestController.class)).thenReturn(rcMap);

public void testGenericControllerRequestMapping_implmenation(){
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();
RequestMapping actual = sac.getClassAnnotation(ControllerImpl1.class, RequestMapping.class);

RequestMapping expect = ControllerImpl1.class.getAnnotation(RequestMapping.class);

Assert.assertEquals(expect.value()[0], actual.value()[0]);
}

@Test
public void testGenericControllerRequestMapping_abstract(){
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();
RequestMapping actual = sac.getClassAnnotation(ControllerImpl2.class, RequestMapping.class);

RequestMapping expect = AbstractController2.class.getAnnotation(RequestMapping.class);

Assert.assertEquals(expect.value()[0], actual.value()[0]);
}

@Test
public void testGenericControllerRequestMapping_interface(){
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();
RequestMapping actual = sac.getClassAnnotation(ControllerImpl3.class, RequestMapping.class);

RequestMapping expect = Controller3.class.getAnnotation(RequestMapping.class);
Assert.assertEquals(expect.value()[0], actual.value()[0]);
}

@Test
public void testGenericMethodRequestMapping_implmenation() throws NoSuchMethodException, SecurityException{
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();
sac.setApplicationContext(acc);
sac.setService(new ApitesterService());

List<ApiCall> calls = sac.getApiCalls();

assertEquals(3, calls.size());
//assertEquals("java.lang.String", calls.get(0).getReturnType().getReturnClass().getClassName());
assertEquals("put", calls.get(1).getHandlerMethod());
assertEquals(1, calls.get(1).getPathParameters().size());
RequestMapping actual = sac.getMethodAnnotation(ControllerMethodImpl.class.getMethod("testMethod", String.class, String.class), RequestMapping.class);

RequestMapping expect = ControllerMethodImpl.class.getMethod("testMethod", String.class, String.class).getAnnotation(RequestMapping.class);

Assert.assertEquals(expect.value()[0], actual.value()[0]);
}

@Test
public void testGenericMethodRequestMapping_abstract() throws NoSuchMethodException, SecurityException{
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();

RequestMapping actual = sac.getMethodAnnotation(ControllerMethodImpl.class.getMethod("testMethod", Long.class), RequestMapping.class);

RequestMapping expect = AbstractControllerMethod.class.getMethod("testMethod", Long.class).getAnnotation(RequestMapping.class);

Assert.assertEquals(expect.value()[0], actual.value()[0]);
}

@Test
public void testGenericMethodRequestMapping_interface() throws NoSuchMethodException, SecurityException{
SpringAnnotationCrawler sac = new SpringAnnotationCrawler();

RequestMapping actual = sac.getMethodAnnotation(ControllerMethodImpl.class.getMethod("testMethod", String.class), RequestMapping.class);

RequestMapping expect = ControllerMethod.class.getMethod("testMethod", String.class).getAnnotation(RequestMapping.class);

Assert.assertEquals(expect.value()[0], actual.value()[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/abstract1")
public abstract class AbstractController1 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/abstract2")
public abstract class AbstractController2 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/abstract3")
public abstract class AbstractController3 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

public abstract class AbstractControllerMethod {

@RequestMapping("/api/method/implementation/id")
public abstract void testMethod(Long id);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/interface1")
public interface Controller1 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

public interface Controller2 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/interface3")
public interface Controller3 {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/test/api/implementation1")
public class ControllerImpl1 extends AbstractController1 implements Controller1{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

public class ControllerImpl2 extends AbstractController2 implements Controller2{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

public class ControllerImpl3 extends AbstractController3 implements Controller3{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

public interface ControllerMethod {

@RequestMapping("/api/method/interface/a")
public void testMethod(String a);

@RequestMapping("/api/method/interface/a")
public void testMethod(String a, String b);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.cinefms.apitester.springmvc.crawlers.mapping;

import org.springframework.web.bind.annotation.RequestMapping;

public class ControllerMethodImpl extends AbstractControllerMethod implements ControllerMethod{

@Override
public void testMethod(String a) {

}

@Override
@RequestMapping("/api/method/implementation/ab")
public void testMethod(String a, String b) {

}

@Override
public void testMethod(Long id) {

}
}