From 48771c238ee3c0f52800d0e593e0b5d301973837 Mon Sep 17 00:00:00 2001 From: Andrey Antonov Date: Wed, 3 Jul 2013 20:32:17 +0400 Subject: [PATCH 1/3] New ignoreUnusedPathVariables property added to ApiDocumentationController, true by default. Sometimes there are path variables which are not used in method directly. For instance, we have /user/pets/{petId}, but method doesn't have @PathVariable petId because it's used for MethodArgumentResolver in upper level, but we still need this fields Such fields are not documented by Swagger by default. Minor changes: 1. Utility methods moved to DocumentationUtils 2. Default Java version(1.5) added to pom.xml --- pom.xml | 9 +++ .../ApiDocumentationController.java | 28 +++++--- .../parser/ApiParserImpl.java | 14 ++-- .../parser/DocumentationOperationParser.java | 39 ++++++++--- .../parser/DocumentationParameterParser.java | 66 +++--------------- .../parser/DocumentationPathParser.java | 69 +++++++++++++++++++ .../util/DocumentationUtils.java | 56 +++++++++++++++ .../swagger4springweb/ApiParserTest.java | 7 +- .../parser/DocumentationPathParserTest.java | 66 ++++++++++++++++++ 9 files changed, 275 insertions(+), 79 deletions(-) create mode 100644 src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java create mode 100644 src/main/java/com/knappsack/swagger4springweb/util/DocumentationUtils.java create mode 100644 src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java diff --git a/pom.xml b/pom.xml index 35bb4a2..e3af596 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ 1.2.4 1.6.4 1.0.1 + 1.5 @@ -143,6 +144,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + org.apache.maven.plugins maven-source-plugin diff --git a/src/main/java/com/knappsack/swagger4springweb/controller/ApiDocumentationController.java b/src/main/java/com/knappsack/swagger4springweb/controller/ApiDocumentationController.java index 6b69a71..f838e0f 100644 --- a/src/main/java/com/knappsack/swagger4springweb/controller/ApiDocumentationController.java +++ b/src/main/java/com/knappsack/swagger4springweb/controller/ApiDocumentationController.java @@ -26,10 +26,10 @@ public class ApiDocumentationController { private List additionalModelPackages = new ArrayList(); private String basePath = ""; private String apiVersion = "v1"; - private Documentation resourceList; private Map documentation; private List ignorableAnnotations = new ArrayList(); - + private boolean ignoreUnusedPathVariables = true; + private Documentation resourceList; @RequestMapping(value = "/resourceList", method = RequestMethod.GET, produces = "application/json") public @@ -46,11 +46,13 @@ Documentation getDocumentation(HttpServletRequest request) { HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); //trim the operation request mapping from the desired value handlerMappingPath = handlerMappingPath.substring(handlerMappingPath.lastIndexOf("/doc") + 4, handlerMappingPath.length()); - if (getDocs(request) == null) { + + Map docs = getDocs(request); + if (docs == null) { return new Documentation(); } - return getDocs(request).get(handlerMappingPath); + return docs.get(handlerMappingPath); } @SuppressWarnings("unused") @@ -139,8 +141,9 @@ private Map getDocs(HttpServletRequest request) { if(request != null) { servletPath = request.getServletPath(); } - ApiParser apiParser = new ApiParserImpl(getControllerPackages(), getModelPackages(), getBasePath(), servletPath, apiVersion, ignorableAnnotations); - this.documentation = apiParser.createDocuments(); + ApiParser apiParser = new ApiParserImpl(getControllerPackages(), getModelPackages(), getBasePath(), + servletPath, apiVersion, ignorableAnnotations, ignoreUnusedPathVariables); + documentation = apiParser.createDocuments(); } return documentation; } @@ -152,8 +155,9 @@ private Documentation getResourceList(HttpServletRequest request) { servletPath = request.getServletPath(); servletPath = servletPath.replace("/resourceList", ""); } - ApiParser apiParser = new ApiParserImpl(getControllerPackages(), getModelPackages(), getBasePath(), servletPath, apiVersion, ignorableAnnotations); - this.resourceList = apiParser.getResourceListing(getDocs(request)); + ApiParser apiParser = new ApiParserImpl(getControllerPackages(), getModelPackages(), getBasePath(), + servletPath, apiVersion, ignorableAnnotations, ignoreUnusedPathVariables); + resourceList = apiParser.getResourceListing(getDocs(request)); } return resourceList; } @@ -196,4 +200,12 @@ public List getIgnorableAnnotations() { public void setIgnorableAnnotations(List ignorableAnnotations) { this.ignorableAnnotations = ignorableAnnotations; } + + public boolean isIgnoreUnusedPathVariables() { + return ignoreUnusedPathVariables; + } + + public void setIgnoreUnusedPathVariables(final boolean ignoreUnusedPathVariables) { + this.ignoreUnusedPathVariables = ignoreUnusedPathVariables; + } } diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java b/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java index 2b59724..cef37cd 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/ApiParserImpl.java @@ -33,13 +33,16 @@ public class ApiParserImpl implements ApiParser { private String servletPath = "/api"; private String apiVersion = "v1"; private List ignorableAnnotations; + private boolean ignoreUnusedPathVariables; private final Map documents = new HashMap(); - public ApiParserImpl(List baseControllerPackage, List baseModelPackage, String basePath, String servletPath, String apiVersion, List ignorableAnnotations) { + public ApiParserImpl(List baseControllerPackage, List baseModelPackage, String basePath, String servletPath, + String apiVersion, List ignorableAnnotations, boolean ignoreUnusedPathVariables) { this.controllerPackages = baseControllerPackage; this.modelPackages = baseModelPackage; this.ignorableAnnotations = ignorableAnnotations; + this.ignoreUnusedPathVariables = ignoreUnusedPathVariables; this.basePath = basePath; this.apiVersion = apiVersion; if (servletPath != null && !servletPath.isEmpty()) { @@ -117,8 +120,9 @@ private Documentation processControllerDocumentation(Class controllerClass) { } //Allow for multiple controllers having the same resource path. - if (documents.containsKey(resourcePath)){ - return documents.get(resourcePath); + Documentation documentation = documents.get(resourcePath); + if (documentation != null){ + return documentation; } return new Documentation(apiVersion, swaggerVersion, basePath, resourcePath); @@ -143,7 +147,7 @@ private void processMethods(Set methods, Documentation documentation, St String value = AnnotationUtils.getMethodRequestMappingValue(method); DocumentationEndPoint documentationEndPoint = endPointMap.get(value); - DocumentationOperationParser documentationOperationParser = new DocumentationOperationParser(ignorableAnnotations); + DocumentationOperationParser documentationOperationParser = new DocumentationOperationParser(documentation.resourcePath(), ignorableAnnotations, ignoreUnusedPathVariables); DocumentationOperation documentationOperation = documentationOperationParser.getDocumentationOperation(method); documentationEndPoint.addOperation(documentationOperation); @@ -159,7 +163,7 @@ private void processMethods(Set methods, Documentation documentation, St } } } - + private void populateEndpointMapForDocumentation(Documentation documentation, Map endPointMap){ if (documentation.getApis() != null){ for (DocumentationEndPoint endpoint : documentation.getApis()){ diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationOperationParser.java b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationOperationParser.java index 9470b59..b624e7c 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationOperationParser.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationOperationParser.java @@ -10,19 +10,18 @@ import org.springframework.web.bind.annotation.RequestMethod; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.List; public class DocumentationOperationParser { + private String resourcePath; private List ignorableAnnotations; + private boolean ignoreUnusedPathVariables; - public DocumentationOperationParser() { - ignorableAnnotations = new ArrayList(); - } - - public DocumentationOperationParser(List ignorableAnnotations) { + public DocumentationOperationParser(String resourcePath, List ignorableAnnotations, boolean ignoreUnusedPathVariables) { this.ignorableAnnotations = ignorableAnnotations; + this.ignoreUnusedPathVariables = ignoreUnusedPathVariables; + this.resourcePath = resourcePath; } public DocumentationOperation getDocumentationOperation(Method method) { @@ -72,15 +71,39 @@ public DocumentationOperation getDocumentationOperation(Method method) { List documentationParameters = documentationParameterParser .getDocumentationParams(method); documentationOperation.setParameters(documentationParameters); + addUnusedPathVariables(documentationOperation, methodRequestMapping.value()); return documentationOperation; } - private void addError(DocumentationOperation documentationOperation, - ApiError apiError) { + private void addError(DocumentationOperation documentationOperation, ApiError apiError) { DocumentationError documentationError = new DocumentationError(); documentationError.setCode(apiError.code()); documentationError.setReason(apiError.reason()); documentationOperation.addErrorResponse(documentationError); } + + private void addUnusedPathVariables(DocumentationOperation documentationOperation, String[] methodPath) { + if(ignoreUnusedPathVariables){ + return; + } + + for(DocumentationParameter documentationParameter : new DocumentationPathParser().getPathParameters(resourcePath, methodPath)){ + if(!isParameterPresented(documentationOperation, documentationParameter.getName())){ + documentationOperation.addParameter(documentationParameter); + } + } + } + + private boolean isParameterPresented(DocumentationOperation documentationOperation, String parameter){ + if(parameter == null || documentationOperation.getParameters() == null){ + return false; + } + for(DocumentationParameter documentationParameter : documentationOperation.getParameters()){ + if(parameter.equals(documentationParameter.getName())){ + return true; + } + } + return false; + } } diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationParameterParser.java b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationParameterParser.java index 87e3357..a6b9150 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationParameterParser.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationParameterParser.java @@ -2,18 +2,17 @@ import com.knappsack.swagger4springweb.model.AnnotatedParameter; import com.knappsack.swagger4springweb.util.AnnotationUtils; +import com.knappsack.swagger4springweb.util.DocumentationUtils; import com.wordnik.swagger.annotations.ApiParam; import com.wordnik.swagger.core.ApiValues; import com.wordnik.swagger.core.DocumentationAllowableListValues; import com.wordnik.swagger.core.DocumentationParameter; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; public class DocumentationParameterParser { @@ -38,10 +37,10 @@ public List getDocumentationParams(Method method) { } DocumentationParameter documentationParameter = new DocumentationParameter(); // default values from the Method - documentationParameter.setDataType(getSwaggerTypeFor(annotatedParameter.getParameterType())); + documentationParameter.setDataType(DocumentationUtils.getSwaggerTypeFor(annotatedParameter.getParameterType())); documentationParameter.setName(annotatedParameter.getParameterName()); documentationParameter.setValueTypeInternal(annotatedParameter.getParameterType().getName()); - documentationParameter.setAllowMultiple(isAllowMultiple(annotatedParameter.getParameterType())); + documentationParameter.setAllowMultiple(DocumentationUtils.isAllowMultiple(annotatedParameter.getParameterType())); // apply default values from spring annotations first for (Annotation annotation : annotatedParameter.getAnnotations()) { addSpringParams(annotation, documentationParameter); @@ -58,41 +57,6 @@ public List getDocumentationParams(Method method) { return documentationParameters; } - private String getSwaggerTypeFor(Class parameterType) { - Class type = parameterType; - if(parameterType.isArray()) { - type = type.getComponentType(); - } - // swagger types are - // byte - // boolean - // int - // long - // float - // double - // string - // Date - if (String.class.isAssignableFrom(type)) { - return "string"; - } else if (Boolean.class.isAssignableFrom(type)) { - return "boolean"; - } else if(Byte.class.isAssignableFrom(type)) { - return "byte"; - } else if(Long.class.isAssignableFrom(type)) { - return "long"; - } else if(Integer.class.isAssignableFrom(type)) { - return "int"; - } else if(Float.class.isAssignableFrom(type)) { - return "float"; - } else if(MultipartFile.class.isAssignableFrom(type)) { - return "file"; - } else if (Number.class.isAssignableFrom(type)) { - return "double"; - } - // others - return type.getSimpleName(); - } - private void addSpringParams(Annotation annotation, DocumentationParameter documentationParameter) { if (annotation instanceof RequestParam) { addRequestParams((RequestParam) annotation, documentationParameter); @@ -114,7 +78,7 @@ private void addRequestBody(DocumentationParameter documentationParameter) { } private void addPathVariable(PathVariable pathVariable, DocumentationParameter documentationParameter) { - if (isSet(pathVariable.value())) { + if (DocumentationUtils.isSet(pathVariable.value())) { documentationParameter.setName(pathVariable.value()); } @@ -124,10 +88,10 @@ private void addPathVariable(PathVariable pathVariable, DocumentationParameter d private void addRequestParams(RequestParam requestParam, DocumentationParameter documentationParameter) { - if (isSet(requestParam.value())) { + if (DocumentationUtils.isSet(requestParam.value())) { documentationParameter.setName(requestParam.value()); } - if (isSet(requestParam.defaultValue())) { + if (DocumentationUtils.isSet(requestParam.defaultValue())) { documentationParameter.setDefaultValue(requestParam.defaultValue()); } documentationParameter.setRequired(requestParam.required()); @@ -138,16 +102,12 @@ private void addRequestParams(RequestParam requestParam, } } - private boolean isSet(String value) { - return value != null && !value.trim().isEmpty() && !ValueConstants.DEFAULT_NONE.equals(value); - } - private void addRequestHeader(RequestHeader requestHeader, DocumentationParameter documentationParameter) { - if (isSet(requestHeader.value())) { + if (DocumentationUtils.isSet(requestHeader.value())) { documentationParameter.setName(requestHeader.value()); } - if (isSet(requestHeader.defaultValue())) { + if (DocumentationUtils.isSet(requestHeader.defaultValue())) { documentationParameter.setDefaultValue(requestHeader.defaultValue()); } documentationParameter.setRequired(requestHeader.required()); @@ -156,21 +116,21 @@ private void addRequestHeader(RequestHeader requestHeader, private void addApiParams(ApiParam apiParam, DocumentationParameter documentationParameter) { - if (isSet(apiParam.allowableValues())) { + if (DocumentationUtils.isSet(apiParam.allowableValues())) { // we use only one simple string List allowableValues = Arrays.asList(apiParam.allowableValues().split("\\s*,\\s*")); documentationParameter.setAllowableValues(new DocumentationAllowableListValues(allowableValues)); } documentationParameter.setAllowMultiple(apiParam.allowMultiple()); - if (isSet(apiParam.defaultValue())) { + if (DocumentationUtils.isSet(apiParam.defaultValue())) { documentationParameter.setDefaultValue(apiParam.defaultValue()); } documentationParameter.setDescription(apiParam.value()); documentationParameter.setInternalDescription(apiParam .internalDescription()); // overwrite default name - if (isSet(apiParam.name())) { + if (DocumentationUtils.isSet(apiParam.name())) { documentationParameter.setName(apiParam.name()); } // documentationParameter.setNotes(apiParam.); @@ -182,10 +142,6 @@ private void addApiParams(ApiParam apiParam, } } - private boolean isAllowMultiple(Class parameterType) { - return parameterType != null && (parameterType.isArray() || Collection.class.isAssignableFrom(parameterType)); - } - private boolean hasIgnorableAnnotations(List annotations) { for(Annotation annotation : annotations) { if(ignorableAnnotations.contains(annotation.annotationType().getCanonicalName())) { diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java new file mode 100644 index 0000000..841f684 --- /dev/null +++ b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java @@ -0,0 +1,69 @@ +package com.knappsack.swagger4springweb.parser; + +import com.knappsack.swagger4springweb.util.DocumentationUtils; +import com.wordnik.swagger.core.ApiValues; +import com.wordnik.swagger.core.DocumentationParameter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DocumentationPathParser { + + private static final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z]+)\\}"); + private static final Class TYPE = String.class; + + public List getPathParameters(String resourcePath, String[] methodPaths){ + Map parameters = new HashMap(); + + addParameters(parameters, resourcePath); + + if(methodPaths != null){ + for(String methodPath : methodPaths){ + addParameters(parameters, methodPath); + } + } + + return new ArrayList(parameters.values()); + } + + private void addParameters(Map parameters, String path){ + for(String parameter : getPathParameters(path)){ + parameters.put(parameter, createParameter(parameter)); + } + } + + private DocumentationParameter createParameter(String parameter){ + DocumentationParameter documentationParameter = new DocumentationParameter(); + documentationParameter.setName(parameter); + documentationParameter.setRequired(true); + documentationParameter.setDataType(DocumentationUtils.getSwaggerTypeFor(TYPE)); + documentationParameter.setValueTypeInternal(TYPE.getName()); + documentationParameter.setAllowMultiple(DocumentationUtils.isAllowMultiple(TYPE)); + documentationParameter.setParamType(ApiValues.TYPE_PATH); + + return documentationParameter; + } + + private List getPathParameters(String path){ + List parameters = new ArrayList(); + + if(path == null || path.trim().length() == 0){ + return Collections.emptyList(); + } + + Matcher matcher = PATTERN.matcher(path); + + if(matcher.find()){ + for(int i = 0; i < matcher.groupCount(); i++){ + parameters.add(matcher.group(i + 1)); + } + } + + return parameters; + } +} diff --git a/src/main/java/com/knappsack/swagger4springweb/util/DocumentationUtils.java b/src/main/java/com/knappsack/swagger4springweb/util/DocumentationUtils.java new file mode 100644 index 0000000..7752528 --- /dev/null +++ b/src/main/java/com/knappsack/swagger4springweb/util/DocumentationUtils.java @@ -0,0 +1,56 @@ +package com.knappsack.swagger4springweb.util; + +import org.springframework.web.bind.annotation.ValueConstants; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Collection; + +/** + * Author: andrey.antonov + * Date: 7/3/13 + */ +public class DocumentationUtils { + + public static String getSwaggerTypeFor(Class parameterType) { + Class type = parameterType; + if(parameterType.isArray()) { + type = type.getComponentType(); + } + // swagger types are + // byte + // boolean + // int + // long + // float + // double + // string + // Date + if (String.class.isAssignableFrom(type)) { + return "string"; + } else if (Boolean.class.isAssignableFrom(type)) { + return "boolean"; + } else if(Byte.class.isAssignableFrom(type)) { + return "byte"; + } else if(Long.class.isAssignableFrom(type)) { + return "long"; + } else if(Integer.class.isAssignableFrom(type)) { + return "int"; + } else if(Float.class.isAssignableFrom(type)) { + return "float"; + } else if(MultipartFile.class.isAssignableFrom(type)) { + return "file"; + } else if (Number.class.isAssignableFrom(type)) { + return "double"; + } + // others + return type.getSimpleName(); + } + + public static boolean isSet(String value) { + return value != null && !value.trim().isEmpty() && !ValueConstants.DEFAULT_NONE.equals(value); + } + + public static boolean isAllowMultiple(Class parameterType) { + return parameterType != null && (parameterType.isArray() || Collection.class.isAssignableFrom(parameterType)); + } +} diff --git a/src/test/java/com/knappsack/swagger4springweb/ApiParserTest.java b/src/test/java/com/knappsack/swagger4springweb/ApiParserTest.java index a54ff2a..a6a3633 100644 --- a/src/test/java/com/knappsack/swagger4springweb/ApiParserTest.java +++ b/src/test/java/com/knappsack/swagger4springweb/ApiParserTest.java @@ -23,7 +23,8 @@ public void testParseControllerDocumentation() { controllerPackage.add(BASE_CONTROLLER_PACKAGE); List modelPackage = new ArrayList(); modelPackage.add(BASE_MODEL_PACKAGE); - ApiParser apiParser = new ApiParserImpl(controllerPackage, modelPackage, "http://localhost:8080/api", "/api", "v1", new ArrayList()); + ApiParser apiParser = new ApiParserImpl(controllerPackage, modelPackage, "http://localhost:8080/api", "/api", + "v1", new ArrayList(), true); Map documentList = apiParser.createDocuments(); for (String key : documentList.keySet()) { Documentation documentation = documentList.get(key); @@ -42,14 +43,14 @@ public void testParseControllerDocumentation() { } } - @Test public void testResourceListing() { List controllerPackage = new ArrayList(); controllerPackage.add(BASE_CONTROLLER_PACKAGE); List modelPackage = new ArrayList(); modelPackage.add(BASE_MODEL_PACKAGE); - ApiParser apiParser = new ApiParserImpl(controllerPackage, modelPackage, "http://localhost:8080/api", "/api", "v1", new ArrayList()); + ApiParser apiParser = new ApiParserImpl(controllerPackage, modelPackage, "http://localhost:8080/api", "/api", + "v1", new ArrayList(), true); Map documentList = apiParser.createDocuments(); Documentation resourceList = apiParser.getResourceListing(documentList); assertTrue(resourceList.basePath().equals("http://localhost:8080/api")); diff --git a/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java new file mode 100644 index 0000000..c5f7daa --- /dev/null +++ b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2013 AlertMe.com Ltd + */ + +package com.knappsack.swagger4springweb.parser; + +import com.wordnik.swagger.core.ApiValues; +import com.wordnik.swagger.core.DocumentationParameter; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Author: andrey.antonov + * Date: 7/3/13 + */ +public class DocumentationPathParserTest { + + @Test + public void getPathParametersReturnsCorrectParametersList(){ + String resourcePath = "/owner/{ownername}/pets"; + String[] methodPaths = {"/dogs/{dogId}", "/legacy/path/to/dogs/breed/{dogId}"}; + + List parameters = new DocumentationPathParser().getPathParameters(resourcePath, methodPaths); + + assertEquals(2, parameters.size()); + assertTrue(contains(parameters, "ownername")); + assertTrue(contains(parameters, "dogId")); + } + + @Test + public void getPathParametersReturnsCorrectParameterFields(){ + String resourcePath = "/owner/{ownername}/pets"; + + List parameters = new DocumentationPathParser().getPathParameters(resourcePath, null); + + assertEquals(1, parameters.size()); + + DocumentationParameter documentationParameter = parameters.get(0); + + assertEquals("ownername", documentationParameter.getName()); + assertEquals(true, documentationParameter.getRequired()); + assertEquals(ApiValues.TYPE_PATH, documentationParameter.getParamType()); + assertEquals("string", documentationParameter.getDataType()); + assertEquals(String.class.getName(), documentationParameter.getValueTypeInternal()); + assertEquals(false, documentationParameter.getAllowMultiple()); + } + + @Test + public void getPathParametersReturnsEmptyListWhenBadParametersArePassed(){ + List parameters = new DocumentationPathParser().getPathParameters(null, null); + assertEquals(parameters.size(), 0); + } + + private boolean contains(List parameters, String parameter){ + for(DocumentationParameter documentationParameter : parameters){ + if(parameter.equals(documentationParameter.getName())){ + return true; + } + } + return false; + } +} From d7f112533bdff500133091b15e39fb7c3dd4585c Mon Sep 17 00:00:00 2001 From: Andrey Antonov Date: Wed, 3 Jul 2013 20:35:11 +0400 Subject: [PATCH 2/3] Copyright deleted --- .../parser/DocumentationPathParserTest.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java index c5f7daa..5ac914f 100644 --- a/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java +++ b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java @@ -1,7 +1,3 @@ -/** - * Copyright (C) 2013 AlertMe.com Ltd - */ - package com.knappsack.swagger4springweb.parser; import com.wordnik.swagger.core.ApiValues; @@ -13,10 +9,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -/** - * Author: andrey.antonov - * Date: 7/3/13 - */ public class DocumentationPathParserTest { @Test From 705b69c4994795fd6223048f8b7ae501a4f039cd Mon Sep 17 00:00:00 2001 From: Andrey Antonov Date: Thu, 11 Jul 2013 16:12:05 +0400 Subject: [PATCH 3/3] Bug fixed: other variables than first in path were ignored. Default description added for such variables, for "ownerName" description would be "Owner name" --- .../parser/DocumentationPathParser.java | 50 ++++++++++++++----- .../parser/DocumentationPathParserTest.java | 29 ++++++----- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java index 841f684..c2d8ed2 100644 --- a/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java +++ b/src/main/java/com/knappsack/swagger4springweb/parser/DocumentationPathParser.java @@ -17,13 +17,13 @@ public class DocumentationPathParser { private static final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z]+)\\}"); private static final Class TYPE = String.class; - public List getPathParameters(String resourcePath, String[] methodPaths){ + public List getPathParameters(String resourcePath, String[] methodPaths) { Map parameters = new HashMap(); addParameters(parameters, resourcePath); - if(methodPaths != null){ - for(String methodPath : methodPaths){ + if (methodPaths != null) { + for (String methodPath : methodPaths) { addParameters(parameters, methodPath); } } @@ -31,13 +31,13 @@ public List getPathParameters(String resourcePath, Strin return new ArrayList(parameters.values()); } - private void addParameters(Map parameters, String path){ - for(String parameter : getPathParameters(path)){ + private void addParameters(Map parameters, String path) { + for (String parameter : getPathParameters(path)) { parameters.put(parameter, createParameter(parameter)); } } - private DocumentationParameter createParameter(String parameter){ + private DocumentationParameter createParameter(String parameter) { DocumentationParameter documentationParameter = new DocumentationParameter(); documentationParameter.setName(parameter); documentationParameter.setRequired(true); @@ -45,23 +45,49 @@ private DocumentationParameter createParameter(String parameter){ documentationParameter.setValueTypeInternal(TYPE.getName()); documentationParameter.setAllowMultiple(DocumentationUtils.isAllowMultiple(TYPE)); documentationParameter.setParamType(ApiValues.TYPE_PATH); + documentationParameter.setDescription(getDescription(parameter)); return documentationParameter; } - private List getPathParameters(String path){ + private String getDescription(String parameter) { + StringBuffer buffer = new StringBuffer(); + + //Parameters with name length less then 3 will have description equal to their name + if (parameter == null || parameter.length() < 3) { + return parameter; + } + + String tmp = parameter; + + for (int i = 0; i < tmp.length(); i++) { + if (Character.isUpperCase(tmp.charAt(i))) { + if (buffer.length() == 0) { + // First letter is capital + buffer.append(tmp.substring(0, 1).toUpperCase()).append(tmp.substring(1, i)); + } else { + buffer.append(tmp.substring(0, i).toLowerCase()); + } + buffer.append(" "); + tmp = tmp.substring(i); + i = 0; + } + } + + return buffer.append(tmp.toLowerCase()).toString(); + } + + private List getPathParameters(String path) { List parameters = new ArrayList(); - if(path == null || path.trim().length() == 0){ + if (path == null || path.trim().length() == 0) { return Collections.emptyList(); } Matcher matcher = PATTERN.matcher(path); - if(matcher.find()){ - for(int i = 0; i < matcher.groupCount(); i++){ - parameters.add(matcher.group(i + 1)); - } + while (matcher.find()) { + parameters.add(matcher.group(1)); } return parameters; diff --git a/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java index 5ac914f..8e302cf 100644 --- a/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java +++ b/src/test/java/com/knappsack/swagger4springweb/parser/DocumentationPathParserTest.java @@ -12,20 +12,22 @@ public class DocumentationPathParserTest { @Test - public void getPathParametersReturnsCorrectParametersList(){ - String resourcePath = "/owner/{ownername}/pets"; - String[] methodPaths = {"/dogs/{dogId}", "/legacy/path/to/dogs/breed/{dogId}"}; + public void getPathParametersReturnsCorrectParametersList() { + String resourcePath = "/owner/{ownerName}/pets/{someOther}"; + String[] methodPaths = { "/dogs/{dogId}", "/legacy/path/to/dogs/breed/{dogId}" }; - List parameters = new DocumentationPathParser().getPathParameters(resourcePath, methodPaths); + List parameters = new DocumentationPathParser() + .getPathParameters(resourcePath, methodPaths); - assertEquals(2, parameters.size()); - assertTrue(contains(parameters, "ownername")); + assertEquals(3, parameters.size()); + assertTrue(contains(parameters, "ownerName")); assertTrue(contains(parameters, "dogId")); + assertTrue(contains(parameters, "someOther")); } @Test - public void getPathParametersReturnsCorrectParameterFields(){ - String resourcePath = "/owner/{ownername}/pets"; + public void getPathParametersReturnsCorrectParameterFields() { + String resourcePath = "/owner/{ownerName}/pets"; List parameters = new DocumentationPathParser().getPathParameters(resourcePath, null); @@ -33,23 +35,24 @@ public void getPathParametersReturnsCorrectParameterFields(){ DocumentationParameter documentationParameter = parameters.get(0); - assertEquals("ownername", documentationParameter.getName()); + assertEquals("ownerName", documentationParameter.getName()); assertEquals(true, documentationParameter.getRequired()); assertEquals(ApiValues.TYPE_PATH, documentationParameter.getParamType()); assertEquals("string", documentationParameter.getDataType()); assertEquals(String.class.getName(), documentationParameter.getValueTypeInternal()); assertEquals(false, documentationParameter.getAllowMultiple()); + assertEquals("Owner name", documentationParameter.getDescription()); } @Test - public void getPathParametersReturnsEmptyListWhenBadParametersArePassed(){ + public void getPathParametersReturnsEmptyListWhenBadParametersArePassed() { List parameters = new DocumentationPathParser().getPathParameters(null, null); assertEquals(parameters.size(), 0); } - private boolean contains(List parameters, String parameter){ - for(DocumentationParameter documentationParameter : parameters){ - if(parameter.equals(documentationParameter.getName())){ + private boolean contains(List parameters, String parameter) { + for (DocumentationParameter documentationParameter : parameters) { + if (parameter.equals(documentationParameter.getName())) { return true; } }