diff --git a/modules/swagger-core/src/main/java/io/swagger/util/ReflectionUtils.java b/modules/swagger-core/src/main/java/io/swagger/util/ReflectionUtils.java
index 08c19acf0a..5c8d0c1b77 100644
--- a/modules/swagger-core/src/main/java/io/swagger/util/ReflectionUtils.java
+++ b/modules/swagger-core/src/main/java/io/swagger/util/ReflectionUtils.java
@@ -64,20 +64,19 @@ public static boolean isOverriddenMethod(Method methodToFind, Class> cls) {
public static Method getOverriddenMethod(Method method) {
Class> declaringClass = method.getDeclaringClass();
Class> superClass = declaringClass.getSuperclass();
+ Method result = null;
if (superClass != null && !(superClass.equals(Object.class))) {
- Method result = findMethod(method, superClass);
- if (result == null) {
- for (Class> anInterface : declaringClass.getInterfaces()) {
- result = findMethod(method, anInterface);
- if (result != null) {
- return result;
- }
+ result = findMethod(method, superClass);
+ }
+ if (result == null) {
+ for (Class> anInterface : declaringClass.getInterfaces()) {
+ result = findMethod(method, anInterface);
+ if (result != null) {
+ return result;
}
- } else {
- return result;
}
}
- return null;
+ return result;
}
/**
@@ -182,6 +181,25 @@ public static A getAnnotation(Method method, Class ann
return annotation;
}
+ public static A getAnnotation(Class> cls, Class annotationClass) {
+ A annotation = cls.getAnnotation(annotationClass);
+ if (annotation == null) {
+ Class> superClass = cls.getSuperclass();
+ if (superClass != null && !(superClass.equals(Object.class))) {
+ annotation = getAnnotation(superClass, annotationClass);
+ }
+ }
+ if (annotation == null) {
+ for (Class> anInterface : cls.getInterfaces()) {
+ annotation = getAnnotation(anInterface, annotationClass);
+ if (annotation != null) {
+ return annotation;
+ }
+ }
+ }
+ return annotation;
+ }
+
/**
* Checks if the type is void.
*
diff --git a/modules/swagger-core/src/test/java/io/swagger/ReflectionUtilsTest.java b/modules/swagger-core/src/test/java/io/swagger/ReflectionUtilsTest.java
index 1fe0bcb5ea..5ac1d7b5da 100644
--- a/modules/swagger-core/src/test/java/io/swagger/ReflectionUtilsTest.java
+++ b/modules/swagger-core/src/test/java/io/swagger/ReflectionUtilsTest.java
@@ -13,6 +13,8 @@
import java.lang.reflect.Type;
import java.util.Arrays;
+import javax.ws.rs.Path;
+
public class ReflectionUtilsTest {
@Test
@@ -105,4 +107,11 @@ public void isVoidTest() {
Assert.assertTrue(ReflectionUtils.isVoid(Void.TYPE));
Assert.assertFalse(ReflectionUtils.isVoid(String.class));
}
+
+ @Test
+ public void testDerivedAnnotation() {
+ final Path annotation = ReflectionUtils.getAnnotation(Child.class, javax.ws.rs.Path.class);
+ Assert.assertNotNull(annotation);
+ Assert.assertEquals(annotation.value(), "parentInterfacePath");
+ }
}
diff --git a/modules/swagger-core/src/test/java/io/swagger/reflection/IParent.java b/modules/swagger-core/src/test/java/io/swagger/reflection/IParent.java
index e818a970c6..e438528afd 100644
--- a/modules/swagger-core/src/test/java/io/swagger/reflection/IParent.java
+++ b/modules/swagger-core/src/test/java/io/swagger/reflection/IParent.java
@@ -1,5 +1,8 @@
package io.swagger.reflection;
+import javax.ws.rs.Path;
+
+@Path("parentInterfacePath")
public interface IParent {
public String parametrizedMethod2(T arg);
diff --git a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java
index 937ec0a529..1c622d7b57 100644
--- a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java
+++ b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java
@@ -244,7 +244,7 @@ private Swagger read(Class> cls, String parentPath, String parentMethod, boole
globalParameters.addAll(ReaderUtils.collectFieldParameters(cls, swagger));
// parse the method
- final javax.ws.rs.Path apiPath = cls.getAnnotation(javax.ws.rs.Path.class);
+ final javax.ws.rs.Path apiPath = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Path.class);
Method methods[] = cls.getMethods();
for (Method method : methods) {
if (ReflectionUtils.isOverriddenMethod(method, cls)) {
diff --git a/modules/swagger-jaxrs/src/test/java/io/swagger/ReaderTest.java b/modules/swagger-jaxrs/src/test/java/io/swagger/ReaderTest.java
index 04685cf8e6..8d935f5d5b 100644
--- a/modules/swagger-jaxrs/src/test/java/io/swagger/ReaderTest.java
+++ b/modules/swagger-jaxrs/src/test/java/io/swagger/ReaderTest.java
@@ -9,6 +9,7 @@
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;
+import io.swagger.resources.AnnotatedInterfaceImpl;
import io.swagger.resources.ApiConsumesProducesResource;
import io.swagger.resources.BookResource;
import io.swagger.resources.BothConsumesProducesResource;
@@ -20,6 +21,7 @@
import io.swagger.resources.ResourceWithKnownInjections;
import io.swagger.resources.RsConsumesProducesResource;
import io.swagger.resources.SimpleMethods;
+
import org.testng.annotations.Test;
import javax.ws.rs.DELETE;
@@ -161,6 +163,13 @@ public void scanOverriddenMethod() {
assertNotNull(methodFromInterface);
}
+ @Test(description = "scan annotation from interface, issue#1427")
+ public void scanInterfaceTest() {
+ final Swagger swagger = new Reader(new Swagger()).read(AnnotatedInterfaceImpl.class);
+ assertNotNull(swagger);
+ assertNotNull(swagger.getPath("/v1/users/{id}").getGet());
+ }
+
@Test(description = "scan implicit params")
public void scanImplicitParam() {
Swagger swagger = getSwagger(ResourceWithImplicitParams.class);
diff --git a/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterface.java b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterface.java
new file mode 100644
index 0000000000..fd6372a807
--- /dev/null
+++ b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterface.java
@@ -0,0 +1,18 @@
+package io.swagger.resources;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/v1/users")
+public interface AnnotatedInterface {
+
+ @GET
+ @Path("/{id}")
+ String findById(@PathParam("id") String id);
+}
diff --git a/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterfaceImpl.java b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterfaceImpl.java
new file mode 100644
index 0000000000..766199213b
--- /dev/null
+++ b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/AnnotatedInterfaceImpl.java
@@ -0,0 +1,14 @@
+package io.swagger.resources;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value = "/v1/users", tags = "annotatedInterface")
+public class AnnotatedInterfaceImpl implements AnnotatedInterface {
+
+ @Override
+ @ApiOperation(value = "Load by userId")
+ public String findById(String id) {
+ return "";
+ }
+}