diff --git a/src/main/java/com/knappsack/swagger4springweb/annotation/ApiCategory.java b/src/main/java/com/knappsack/swagger4springweb/annotation/ApiCategory.java new file mode 100644 index 0000000..207f89c --- /dev/null +++ b/src/main/java/com/knappsack/swagger4springweb/annotation/ApiCategory.java @@ -0,0 +1,19 @@ +package com.knappsack.swagger4springweb.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation which indicates if this Api should be added to a category + *

+ * This annotation is applicable to the controller class + */ +@Target(ElementType.ANNOTATION_TYPE) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface ApiCategory { + java.lang.String value(); + + java.lang.String description() default ""; +} diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/ApiOperationParser.java b/src/main/java/com/knappsack/swagger4springweb/parser/ApiOperationParser.java index a1d1d21..42e0933 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/ApiOperationParser.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/ApiOperationParser.java @@ -1,27 +1,35 @@ package com.knappsack.swagger4springweb.parser; -import com.knappsack.swagger4springweb.util.JavaToScalaUtil; -import com.wordnik.swagger.annotations.*; -import com.wordnik.swagger.converter.ModelConverters; -import com.wordnik.swagger.model.*; -import com.wordnik.swagger.model.Authorization; -import com.wordnik.swagger.model.AuthorizationScope; -import org.apache.commons.lang.ArrayUtils; -import org.springframework.http.HttpMethod; -import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import scala.Option; +import static java.lang.String.format; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import static java.lang.String.format; +import org.apache.commons.lang.ArrayUtils; +import org.springframework.http.HttpMethod; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.knappsack.swagger4springweb.util.JavaToScalaUtil; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; +import com.wordnik.swagger.converter.ModelConverters; +import com.wordnik.swagger.model.Authorization; +import com.wordnik.swagger.model.AuthorizationScope; +import com.wordnik.swagger.model.Model; +import com.wordnik.swagger.model.Operation; +import com.wordnik.swagger.model.Parameter; +import com.wordnik.swagger.model.ResponseMessage; + +import scala.Option; public class ApiOperationParser { @@ -51,6 +59,8 @@ public Operation parseDocumentationOperation(Method method) { final Type type = parameterizedType.getActualTypeArguments()[0]; if (type instanceof ParameterizedType) { documentationOperation.setResponseClass((Class) ((ParameterizedType) type).getRawType()); + } else if (type instanceof WildcardType) { + documentationOperation.setResponseClass(Object.class); } else { documentationOperation.setResponseClass((Class) type); } diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java b/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java index 765ba99..c964b4d 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java @@ -1,27 +1,46 @@ package com.knappsack.swagger4springweb.parser; +import static org.reflections.ReflectionUtils.withAnnotation; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.reflections.Reflections; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.knappsack.swagger4springweb.annotation.ApiCategory; import com.knappsack.swagger4springweb.controller.ApiDocumentationController; import com.knappsack.swagger4springweb.filter.ApiExcludeFilter; import com.knappsack.swagger4springweb.filter.Filter; import com.knappsack.swagger4springweb.util.AnnotationUtils; +import com.knappsack.swagger4springweb.util.ApiListingUtil; import com.knappsack.swagger4springweb.util.JavaToScalaUtil; import com.knappsack.swagger4springweb.util.ScalaToJavaUtil; import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.config.SwaggerConfig; -import com.wordnik.swagger.model.*; -import org.reflections.Reflections; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import scala.Option; +import com.wordnik.swagger.model.ApiDescription; +import com.wordnik.swagger.model.ApiInfo; +import com.wordnik.swagger.model.ApiListing; +import com.wordnik.swagger.model.ApiListingReference; +import com.wordnik.swagger.model.Model; +import com.wordnik.swagger.model.Operation; +import com.wordnik.swagger.model.ResourceListing; -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.*; - -import static org.reflections.ReflectionUtils.withAnnotation; +import scala.Option; +import scala.Some; public class ApiParserImpl implements ApiParser { @@ -29,7 +48,7 @@ public class ApiParserImpl implements ApiParser { private static final String swaggerVersion = com.wordnik.swagger.core.SwaggerSpec.version(); - private final Map apiListingMap = new HashMap(); + private final Map apiListingMap = new TreeMap<>(); private final List controllerPackages; private final List ignorableAnnotations; @@ -70,7 +89,7 @@ public ResourceListing getResourceListing(Map apiListingMap) List apiListingReferences = new ArrayList(); for (String key : apiListingMap.keySet()) { ApiListing apiListing = apiListingMap.get(key); - String docPath = "/doc"; //servletPath + "/doc"; //"/api/doc"; + String docPath = "/doc"; //servletPath + "/doc"; //"/api/doc"; ApiListingReference apiListingReference = new ApiListingReference(docPath + key, apiListing.description(), apiListing.position()); @@ -98,7 +117,7 @@ else if (o1.position() > o2.position()) swaggerConfig.info()); } - public Map createApiListings() { + public Map createApiListings() { Set> controllerClasses = new HashSet>(); for (String controllerPackage : controllerPackages) { Reflections reflections = new Reflections(controllerPackage); @@ -125,24 +144,43 @@ private Map processControllers(Set> controllerClass .getAllMethods(controllerClass, withAnnotation(RequestMapping.class)); ApiListing apiListing = processControllerApi(controllerClass); String description = ""; - Api controllerApi = controllerClass.getAnnotation(Api.class); - if (controllerApi != null) { + ApiCategory apiCategory = AnnotationUtils.getAnnotationAnnotation(ApiCategory.class, controllerClass); + if (apiCategory != null) { + description = apiCategory.description(); + } else { + Api controllerApi = controllerClass.getAnnotation(Api.class); + if (controllerApi != null) { description = controllerApi.description(); + } } - if (apiListing.apis() == null) { apiListing = processMethods(requestMappingMethods, controllerClass, apiListing, description); } + if (apiCategory != null && apiCategory.value() != null) { + String key = prependSlashIfMissing(apiCategory.value()); + ApiListing existingApiListing = apiListingMap.get(key); + if (existingApiListing != null) { + apiListing = ApiListingUtil.combine(existingApiListing, apiListing); + } + + addApiListingToMap(apiListing, key); + continue; + } // controllers without any operations are excluded from the apiListingMap list if (apiListing.apis() != null && !apiListing.apis().isEmpty()) { - apiListingMap.put(apiListing.resourcePath(), apiListing); + addApiListingToMap(apiListing, apiListing.resourcePath()); } } return apiListingMap; } + private void addApiListingToMap(ApiListing apiListing, String key) { + apiListingMap.put(key, ApiListingUtil.sortApisByPath(apiListing)); + } + + private ApiListing processControllerApi(Class controllerClass) { String resourcePath = ""; Api controllerApi = controllerClass.getAnnotation(Api.class); @@ -159,22 +197,39 @@ private ApiListing processControllerApi(Class controllerClass) { resourcePath = controllerClass.getName(); } } - if (!resourcePath.startsWith("/")) { - resourcePath = "/" + resourcePath; - } + resourcePath = prependSlashIfMissing(resourcePath); - String docRoot = resourcePath; + String docRoot = resourcePath; if(docRoot.contains(controllerClass.getName())) { docRoot = docRoot.replace(controllerClass.getName(), ""); } SpringApiReader reader = new SpringApiReader(); Option apiListingOption = reader.read(docRoot, controllerClass, swaggerConfig); + ApiListing apiListing = null; + Option descriptionOption = null; + String categoryValue = null; + + ApiCategory category = AnnotationUtils.getAnnotationAnnotation(ApiCategory.class, controllerClass); + String description = null; + if (category != null) { + categoryValue = category.value(); + description = category.description(); + descriptionOption = Some.apply(description); + } + if (apiListingOption.nonEmpty()) { - apiListing = apiListingOption.get(); + apiListing = apiListingOption.get(); + apiListing = ApiListingUtil.changeDescription(apiListing, description); } //Allow for multiple controllers having the same resource path. + if (categoryValue != null) { + ApiListing existingApiListing = apiListingMap.get(categoryValue); + if (existingApiListing != null) { + return existingApiListing; + } + } ApiListing existingApiListing = apiListingMap.get(resourcePath); if (existingApiListing != null) { return existingApiListing; @@ -185,7 +240,7 @@ private ApiListing processControllerApi(Class controllerClass) { } return new ApiListing(apiVersion, swaggerVersion, basePath, resourcePath, null, null, null, null, null, null, - null, 0); + descriptionOption, 0); } private ApiListing processMethods(Collection methods, Class controllerClass, ApiListing apiListing, String description) { @@ -269,4 +324,11 @@ private boolean ignore(Method method) { return false; } + private String prependSlashIfMissing(String key) { + if (!key.startsWith("/")) { + key = "/" + key; + } + return key; + } + } diff --git a/src/main/java/com/knappsack/swagger4springweb/util/AnnotationUtils.java b/src/main/java/com/knappsack/swagger4springweb/util/AnnotationUtils.java index 5e3df60..7aba25d 100644 --- a/src/main/java/com/knappsack/swagger4springweb/util/AnnotationUtils.java +++ b/src/main/java/com/knappsack/swagger4springweb/util/AnnotationUtils.java @@ -1,18 +1,19 @@ package com.knappsack.swagger4springweb.util; -import com.google.common.collect.Lists; -import com.knappsack.swagger4springweb.model.AnnotatedParameter; -import com.thoughtworks.paranamer.BytecodeReadingParanamer; -import com.thoughtworks.paranamer.Paranamer; -import com.wordnik.swagger.annotations.ApiParam; -import org.springframework.web.bind.annotation.RequestMapping; - import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.google.common.collect.Lists; +import com.knappsack.swagger4springweb.model.AnnotatedParameter; +import com.thoughtworks.paranamer.BytecodeReadingParanamer; +import com.thoughtworks.paranamer.Paranamer; +import com.wordnik.swagger.annotations.ApiParam; + public class AnnotationUtils { /** @@ -84,4 +85,23 @@ public static List getAnnotatedParameters(Method method) { } return annotatedParameters; } + + + public static T getAnnotationAnnotation(Class annotationClass, Class controllerClass) { + Annotation[] annotations = controllerClass.getAnnotations(); + for (Annotation annotation : annotations) { + T value = getAnnotation(annotation, annotationClass); + if (value != null) { + return value; + } + } + return null; + } + + private static T getAnnotation(Annotation ann, Class annotationType) { + if (annotationType.isInstance(ann)) { + return (T) ann; + } + return ann.annotationType().getAnnotation(annotationType); + } } diff --git a/src/main/scala/com/knappsack/swagger4springweb/util/ApiListingUtil.scala b/src/main/scala/com/knappsack/swagger4springweb/util/ApiListingUtil.scala new file mode 100644 index 0000000..b622b83 --- /dev/null +++ b/src/main/scala/com/knappsack/swagger4springweb/util/ApiListingUtil.scala @@ -0,0 +1,12 @@ +package com.knappsack.swagger4springweb.util + +import com.wordnik.swagger.model.ApiListing + +/** + * @author Allar Tammik + */ +object ApiListingUtil { + def combine(main: ApiListing, additional : ApiListing) : ApiListing = main.copy(apis = main.apis ++ additional.apis) + def sortApisByPath(obj: ApiListing) : ApiListing = obj.copy(apis = obj.apis.sortBy(api => api.path)) + def changeDescription(obj: ApiListing, desc: String) : ApiListing = obj.copy(description = Some(desc)) +} diff --git a/src/test/java/com/knappsack/swagger4springweb/AbstractTest.java b/src/test/java/com/knappsack/swagger4springweb/AbstractTest.java index 4a0b48a..67f9f8e 100644 --- a/src/test/java/com/knappsack/swagger4springweb/AbstractTest.java +++ b/src/test/java/com/knappsack/swagger4springweb/AbstractTest.java @@ -1,14 +1,14 @@ package com.knappsack.swagger4springweb; -import com.wordnik.swagger.model.ApiInfo; - import java.util.Arrays; import java.util.List; +import com.wordnik.swagger.model.ApiInfo; + public abstract class AbstractTest { public static final String BASE_CONTROLLER_PACKAGE = "com.knappsack.swagger4springweb.testController"; public static final String EXCLUDE_LABEL = "exclude"; - public static final List END_POINT_PATHS = Arrays.asList("/doc/api/v1/partialExclude", "/doc/api/v1/test", "/doc/api/v1/exclude2", "/doc/com.knappsack.swagger4springweb.testController.NoClassLevelMappingController"); + public static final List END_POINT_PATHS = Arrays.asList("/doc/api/v1/partialExclude", "/doc/api/v1/test", "/doc/api/v1/exclude2", "/doc/com.knappsack.swagger4springweb.testController.NoClassLevelMappingController", "/doc/api/v1/nocolor", "/doc/dark", "/doc/light"); public static final ApiInfo API_INFO = new ApiInfo("swagger4spring-web example app", "This is a basic web app for demonstrating swagger4spring-web", "http://localhost:8080/terms", "http://localhost:8080/contact", "MIT", "http://opensource.org/licenses/MIT"); } diff --git a/src/test/java/com/knappsack/swagger4springweb/ApiCategoryTest.java b/src/test/java/com/knappsack/swagger4springweb/ApiCategoryTest.java new file mode 100644 index 0000000..0afeadd --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/ApiCategoryTest.java @@ -0,0 +1,83 @@ +package com.knappsack.swagger4springweb; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import com.knappsack.swagger4springweb.parser.ApiParser; +import com.knappsack.swagger4springweb.parser.ApiParserImpl; +import com.wordnik.swagger.model.ApiDescription; +import com.wordnik.swagger.model.ApiListing; +import com.wordnik.swagger.model.ApiListingReference; +import com.wordnik.swagger.model.ResourceListing; + +import scala.collection.Iterator; + + +public class ApiCategoryTest extends AbstractTest { + + @Test + public void category() { + + ApiParser apiParser = createApiParser(); + Map documents = apiParser.createApiListings(); + + assertEquals("api keys expected", 3, documents.size()); + assertTrue(documents.containsKey("/dark")); + assertTrue(documents.containsKey("/light")); + + ApiListing darkApiListing = documents.get("/dark"); + + scala.collection.immutable.List dark = darkApiListing.apis(); + assertEquals("dark colors expected", 4, dark.size()); + + // Validate alphabetic ordering + assertTrue("earth should be first", dark.apply(0).path().equals("/api/v1/black/earth")); + assertTrue("wildcard should be second", dark.apply(1).path().equals("/api/v1/black/wildcard")); + assertTrue("x-planet should be 3rd", dark.apply(2).path().equals("/api/v1/black/x-planet")); + assertTrue("sky should be 4th", dark.apply(3).path().equals("/api/v1/blue/sky")); + + assertEquals("This is so dark", darkApiListing.description().get()); + + } + + @Test + public void resourceListing() { + ApiParser apiParser = createApiParser(); + ResourceListing resourceListing = apiParser.getResourceListing(apiParser.createApiListings()); + assertEquals(3, resourceListing.apis().size()); + scala.collection.immutable.List apis = resourceListing.apis(); + + + boolean foundDark = false; + boolean foundLight = false; + boolean foundNoColor = false; + for (Iterator it = apis.iterator(); it.hasNext(); ) { + + ApiListingReference apiListingReference = it.next(); + if (apiListingReference.path().equals("/doc/dark")) foundDark = true; + if (apiListingReference.path().equals("/doc/light")) foundLight = true; + if (apiListingReference.path().equals("/doc/api/v1/nocolor")) foundNoColor = true; + } + assertTrue("found dark category", foundDark); + assertTrue("found light category", foundLight); + assertTrue("found no color category", foundNoColor); + } + + + private ApiParser createApiParser() { + return createApiParser(Arrays.asList(BASE_CONTROLLER_PACKAGE + ".category")); + } + + private ApiParser createApiParser(List controllerPackages) { + return new ApiParserImpl(API_INFO, controllerPackages, "http://localhost:8080/api", "/api", "v1", + new ArrayList(), true, null); + } + +} diff --git a/src/test/java/com/knappsack/swagger4springweb/controller/ApiDocumentationControllerTest.java b/src/test/java/com/knappsack/swagger4springweb/controller/ApiDocumentationControllerTest.java index 027844d..ca726e8 100644 --- a/src/test/java/com/knappsack/swagger4springweb/controller/ApiDocumentationControllerTest.java +++ b/src/test/java/com/knappsack/swagger4springweb/controller/ApiDocumentationControllerTest.java @@ -1,15 +1,18 @@ package com.knappsack.swagger4springweb.controller; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.servlet.HandlerMapping; + import com.knappsack.swagger4springweb.AbstractTest; import com.knappsack.swagger4springweb.util.ScalaToJavaUtil; import com.wordnik.swagger.model.ApiListing; import com.wordnik.swagger.model.ApiListingReference; import com.wordnik.swagger.model.ResourceListing; -import org.junit.Test; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.web.servlet.HandlerMapping; - -import static org.junit.Assert.*; public class ApiDocumentationControllerTest extends AbstractTest { @@ -41,7 +44,6 @@ public void getResourceList() { assertNotNull(documentation); assertEquals("v1", documentation.apiVersion()); assertEquals(END_POINT_PATHS.size(), documentation.apis().size()); - assertEquals("/doc/api/v1/test", documentation.apis().apply(0).path()); for (ApiListingReference endPoint : ScalaToJavaUtil.toJavaList(documentation.apis())) { assertTrue(END_POINT_PATHS.contains(endPoint.path())); diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/BlackController.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/BlackController.java new file mode 100644 index 0000000..8dd449f --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/BlackController.java @@ -0,0 +1,37 @@ +package com.knappsack.swagger4springweb.testController.category; + + +import static java.util.Arrays.asList; +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +import java.util.List; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.wordnik.swagger.annotations.ApiOperation; + +@Controller +@RequestMapping("/api/v1/black") +@DarkCategory +public class BlackController { + + @ApiOperation("This is for testing ordering") + @RequestMapping(value = "/x-planet", method = GET) + public String xPlanet() { + return "x-planet"; + } + + @ApiOperation("Black is earth") + @RequestMapping(value = "/earth", method = GET) + public String earth() { + return "earth"; + } + + @ApiOperation("Wildcard list") + @RequestMapping(value = "/wildcard", method = GET) + public List genericType() { + return asList(6L, 4L); + } + +} diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/BlueController.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/BlueController.java new file mode 100644 index 0000000..6f53a2e --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/BlueController.java @@ -0,0 +1,22 @@ +package com.knappsack.swagger4springweb.testController.category; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + +@Controller +@RequestMapping("/api/v1/blue") +@Api(value = "/api/v1/blue", description = "Test Category, blue") // this will be ignored due to @ApiCategory +@DarkCategory +public class BlueController { + + @ApiOperation("Blue is sky") + @RequestMapping(value = "/sky", method = GET) + public String sky() { + return "sky"; + } +} diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/DarkCategory.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/DarkCategory.java new file mode 100644 index 0000000..377ca39 --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/DarkCategory.java @@ -0,0 +1,17 @@ +package com.knappsack.swagger4springweb.testController.category; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.knappsack.swagger4springweb.annotation.ApiCategory; + +/** + * @author Allar Tammik + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@ApiCategory(value = "dark", description = "This is so dark") +public @interface DarkCategory { +} diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/LightCategory.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/LightCategory.java new file mode 100644 index 0000000..cf45c20 --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/LightCategory.java @@ -0,0 +1,17 @@ +package com.knappsack.swagger4springweb.testController.category; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.knappsack.swagger4springweb.annotation.ApiCategory; + +/** + * @author Allar Tammik + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@ApiCategory(value = "light", description = "This is so bright") +public @interface LightCategory { +} diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/NoColorController.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/NoColorController.java new file mode 100644 index 0000000..c07cf0c --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/NoColorController.java @@ -0,0 +1,22 @@ +package com.knappsack.swagger4springweb.testController.category; + + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + +@Controller +@RequestMapping("/api/v1/nocolor") +@Api(value = "/api/v1/nocolor", description = "Test Category, this controller does not have ApiCategory annotation, thus will be mapped as earlier") +public class NoColorController { + + @RequestMapping(value = "/invisible", method = GET) + @ApiOperation("I am invisible") + public String invisible() { + return "invisible"; + } +} diff --git a/src/test/java/com/knappsack/swagger4springweb/testController/category/WhiteController.java b/src/test/java/com/knappsack/swagger4springweb/testController/category/WhiteController.java new file mode 100644 index 0000000..130b156 --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/testController/category/WhiteController.java @@ -0,0 +1,22 @@ +package com.knappsack.swagger4springweb.testController.category; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + +@Controller +@RequestMapping("/api/v1/white") +@Api(value = "/api/v1/white",description = "Test Category, white") +@LightCategory +public class WhiteController { + + @ApiOperation("White is fortune") + @RequestMapping(value = "/fortune", method = GET) + public String fortune() { + return "fortune"; + } +}