├── .editorconfig ├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── github │ │ └── kongchen │ │ └── swagger │ │ └── docgen │ │ ├── AbstractDocumentSource.java │ │ ├── EnhancedSwaggerAnnotationIntrospector.java │ │ ├── EnhancedSwaggerModule.java │ │ ├── GenerateException.java │ │ ├── PropertyExampleMixIn.java │ │ ├── ResponseMessageOverride.java │ │ ├── Utils.java │ │ ├── jaxrs │ │ ├── BeanParamInjectParamExtension.java │ │ └── JaxrsParameterExtension.java │ │ ├── mavenplugin │ │ ├── ApiDocumentMojo.java │ │ ├── ApiSource.java │ │ ├── IncludeProjectDependenciesComponentConfigurator.java │ │ ├── MavenDocumentSource.java │ │ ├── SecurityDefinition.java │ │ └── SpringMavenDocumentSource.java │ │ ├── reader │ │ ├── AbstractReader.java │ │ ├── ClassSwaggerReader.java │ │ ├── JaxrsReader.java │ │ ├── ModelConverterHelper.java │ │ ├── ModelModifier.java │ │ ├── ResponseContainerConverter.java │ │ ├── ServletReader.java │ │ ├── SpringExceptionHandlerReader.java │ │ ├── SpringMvcApiReader.java │ │ └── SwaggerReader.java │ │ ├── spring │ │ ├── SpringResource.java │ │ └── SpringSwaggerExtension.java │ │ └── util │ │ ├── SpringUtils.java │ │ ├── TypeExtracter.java │ │ ├── TypeUtils.java │ │ └── TypeWithAnnotations.java └── resources │ └── log4j.xml └── test ├── java └── com │ ├── github │ └── kongchen │ │ ├── smp │ │ └── integration │ │ │ ├── JaxrsEnhancedOperationIdTest.java │ │ │ ├── SpringMvcEnhancedOperationIdTest.java │ │ │ ├── SpringMvcSkipInheritedTest.java │ │ │ ├── SpringMvcTest.java │ │ │ ├── StringWrapperModelTest.java │ │ │ ├── SwaggerMavenPluginTest.java │ │ │ ├── SwaggerReaderTest.java │ │ │ └── utils │ │ │ ├── PetIdToStringModelConverter.java │ │ │ └── TestUtils.java │ │ └── swagger │ │ └── docgen │ │ ├── AbstractDocumentSourceTest.java │ │ ├── IncludedSwaggerExtensionTest.java │ │ ├── jaxrs │ │ └── JaxrsParameterExtensionTest.java │ │ ├── mavenplugin │ │ ├── ApiSourceTest.java │ │ ├── SecurityDefinitionTest.java │ │ └── SpringMavenDocumentSourceTest.java │ │ ├── reader │ │ ├── JaxrsReaderTest.java │ │ ├── ModelModifierTest.java │ │ ├── SpringExceptionHandlerReaderTest.java │ │ └── SpringMvcApiReaderTest.java │ │ └── spring │ │ ├── SpringMVCResponseStatusTest.java │ │ └── SpringSwaggerExtensionTest.java │ └── wordnik │ ├── jaxrs │ ├── CustomJaxrsReader.java │ ├── MyBean.java │ ├── MyConstructorInjectedNestedBean.java │ ├── MyNestedBean.java │ ├── MyParentBean.java │ ├── MyResource.java │ ├── MyResourceAbstract.java │ ├── MyResourceImpl.java │ ├── PagedList.java │ ├── ParentResource.java │ ├── PetResource.java │ ├── PetStoreResource.java │ ├── RootPathResource.java │ ├── SubResource.java │ ├── SwaggerlessResource.java │ ├── SwaggerlessSubresource.java │ ├── UserResource.java │ └── VendorExtensionsJaxrsReader.java │ ├── sample │ ├── JavaRestResourceUtil.java │ ├── TestVendorExtension.java │ ├── VendorExtensionWithoutReader.java │ ├── data │ │ ├── PetData.java │ │ ├── StoreData.java │ │ └── UserData.java │ ├── exception │ │ ├── ApiException.java │ │ ├── BadRequestException.java │ │ └── NotFoundException.java │ └── model │ │ ├── ApiResponse.java │ │ ├── Category.java │ │ ├── ListItem.java │ │ ├── Order.java │ │ ├── PaginationHelper.java │ │ ├── Pet.java │ │ ├── PetId.java │ │ ├── PetName.java │ │ ├── PetStatus.java │ │ ├── Tag.java │ │ ├── User.java │ │ └── package-info.java │ ├── spring │ └── skipinherited │ │ ├── MyResourceBean.java │ │ └── MyResourceSI.java │ ├── springmvc │ ├── CustomSpringMvcReader.java │ ├── EchoResource.java │ ├── EmptyRootPathResource.java │ ├── KotlinController.kt │ ├── MyResource.java │ ├── MyResourceImpl.java │ ├── PetResource.java │ ├── PetStoreResource.java │ ├── RootPathResource.java │ ├── SwaggerlessResource.java │ ├── UpdatePetRequest.java │ ├── UserResource.java │ └── VendorExtensionsSpringMvcReader.java │ └── stringwrapper │ ├── SimpleStringWrapper.java │ └── SimpleWrappersService.java └── resources ├── com └── github │ └── kongchen │ └── swagger │ └── docgen │ ├── descriptionFile.txt │ └── mavenplugin │ └── securityDefinition.json ├── expectedOutput ├── swagger-common-parameters.json ├── swagger-enhanced-operation-id.json ├── swagger-externalDocs.json ├── swagger-spring-enhanced-operation-id.json ├── swagger-spring-skip-inherited.json ├── swagger-spring-string-wrapper-model.json ├── swagger-spring.json ├── swagger-spring.yaml ├── swagger-swaggerreader.json ├── swagger-swaggerreader.yaml ├── swagger-with-converter.json ├── swagger-with-converter.yaml ├── swagger.json └── swagger.yaml ├── options └── jsonExampleValues │ └── expected │ ├── swagger-spring.json │ └── swagger.json ├── override.map ├── plugin-config-enhanced-operation-id.xml ├── plugin-config-externalDocs.xml ├── plugin-config-feature-fail.xml ├── plugin-config-multiple-api-sources.xml ├── plugin-config-springmvc-enhanced-operation-id.xml ├── plugin-config-springmvc-skip-inherited.xml ├── plugin-config-springmvc-string-wrapper-model.xml ├── plugin-config-springmvc.xml ├── plugin-config-swaggerreader.xml ├── plugin-config.xml ├── sample-springmvc.html ├── sample.html ├── securityDefinition.json └── templates ├── markdown.hbs ├── operation.hbs ├── security.hbs └── strapdown.html.hbs /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace=true 11 | max_line_length=120 12 | 13 | # 2 space indentation as suggested in 14 | [*.{java}] 15 | indent_style = space 16 | indent_size = 4 17 | [*.{xml,json}] 18 | indent_style = space 19 | indent_size = 4 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /apidocsf/ 3 | /test.html 4 | .idea 5 | *.iml 6 | /.settings/ 7 | /.classpath 8 | /.project 9 | /generated/ 10 | /test-output/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 5 | - openjdk11 6 | 7 | before_install: 8 | 9 | install: 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | **01/21/2015 2.33-SNAPSHOT** 2 | - Added functionality for Spring MVC. Spring package contains SpringMvcApiReader.java and SpringResource.java. If user specifies supportSpringMvc configuration to true, ApiDocumentMojo calls SpringMavenDocumentSource.java instead of MavenDocumentSource.java. 3 | 4 | **05/28/2014 2.2** 5 | - 05/04/2014: *Add a new parameter `swaggerUIDocBasePath`, which is only used in swagger output. `basePath` will not be horned in service.json if `swaggerUIDocBasePath` is configured.* 6 | 7 | **04/13/2014 2.1** 8 | - 04/13/2014: *Several issues fixed* 9 | 10 | 11 | **02/15/2014 2.0** 12 | - 02/01/2014: *Fully support swagger spec [1.2](https://github.com/wordnik/swagger-core/wiki/1.2-transition), do not support swagger core 1.2.x any more.* 13 | *Fix issue #33 #35 #31 #20 #29* 14 | - 02/01/2014: *Fix issue #32* 15 | 16 | 17 | 18 | **01/20/2014 1.1.3-SNAPSHOT** 19 | - 01/20/2014: *revert pull #27* 20 | - 01/20/2014: *accept pull #22* 21 | - 01/20/2014: *fix path issue when `useOutputFlatStructure` is false* 22 | 23 | **01/19/2014 1.1.2** 24 | - 01/19/2014: *accept pull #27* 25 | - 01/19/2014: *accept pull #28* 26 | - 07/18/2013: *add `useOutputFlatStructure` and `mustacheFileRoot` in configuration.* 27 | - 07/23/2013: *Maven 3.1.0 compat (pull#15)* 28 | - 07/31/2013: *fix issue #17* 29 | 30 | **07/16/2013 1.1.1** 31 | - released in central repository 32 | - fix issue #7 33 | 34 | ----- 35 | 36 | **07/03/2013 1.1.0** 37 | - 1.1.0 released in central repository 38 | 39 | ----- 40 | 41 | **06/26/2013 1.1-SNAPSHOT** 42 | - Upgrade [mustache lib]https://github.com/spullara/mustache.java to 0.8.12 43 | - Support remote url for outputTemplatePath 44 | 45 | ----- 46 | 47 | **06/21/2013 1.1-SNAPSHOT** 48 | - Use swagger 1.2.5 which supports generic classes in response, thanks the author accept my pull request 49 | - Support document response class with generic class 50 | - Support document response header by using: 51 | ``` 52 | @ApiParamsImplicit(value = { 53 | @ApiParamImplicit(name = "ETag", 54 | paramType = "response_header", 55 | value = "version", dataType = "string")}) 56 | ``` 57 | - use requestHeader, requestBody, responseHeader, requestPath and requestQuery to help document maker distinguish parameters 58 | - fix issue #9 59 | 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/EnhancedSwaggerAnnotationIntrospector.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.fasterxml.jackson.databind.PropertyName; 4 | import com.fasterxml.jackson.databind.introspect.AnnotatedClass; 5 | 6 | import io.swagger.annotations.ApiModel; 7 | import io.swagger.jackson.SwaggerAnnotationIntrospector; 8 | 9 | /** 10 | * Extends SwaggerAnnotationIntrospector with {@link #findRootName(AnnotatedClass)} implementation. See 11 | * https://github.com/swagger-api/swagger-core/issues/2104 12 | * 13 | * @author Tomasz Juchniewicz 14 | * 15 | */ 16 | public class EnhancedSwaggerAnnotationIntrospector extends SwaggerAnnotationIntrospector { 17 | 18 | @Override 19 | public PropertyName findRootName(AnnotatedClass ac) { 20 | ApiModel model = ac.getAnnotation(ApiModel.class); 21 | if (model != null) { 22 | return new PropertyName(model.value()); 23 | } else { 24 | return super.findRootName(ac); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/EnhancedSwaggerModule.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.fasterxml.jackson.databind.module.SimpleModule; 4 | 5 | public class EnhancedSwaggerModule extends SimpleModule { 6 | private static final long serialVersionUID = 1L; 7 | 8 | public EnhancedSwaggerModule() { 9 | super("1.0.0"); 10 | } 11 | 12 | @Override 13 | public void setupModule(SetupContext context) { 14 | super.setupModule(context); 15 | context.insertAnnotationIntrospector(new EnhancedSwaggerAnnotationIntrospector()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/GenerateException.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | /** 4 | * @author chekong 5 | * 05/29/2013 6 | */ 7 | public class GenerateException extends Exception { 8 | 9 | private static final long serialVersionUID = -1641016437077276797L; 10 | 11 | public GenerateException(String errorMessage, Throwable cause) { 12 | super(errorMessage, cause); 13 | } 14 | 15 | public GenerateException(String errorMessage) { 16 | super(errorMessage); 17 | } 18 | 19 | public GenerateException(Exception e) { 20 | super(e); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/PropertyExampleMixIn.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.fasterxml.jackson.annotation.JsonRawValue; 4 | 5 | abstract class PropertyExampleMixIn { 6 | PropertyExampleMixIn() { } 7 | 8 | @JsonRawValue abstract Object getExample(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/ResponseMessageOverride.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | /** 4 | * @author bratwurzt 5 | */ 6 | public class ResponseMessageOverride { 7 | private int code; 8 | private String message; 9 | private Example example; 10 | 11 | public int getCode() { 12 | return code; 13 | } 14 | 15 | public void setCode(int code) { 16 | this.code = code; 17 | } 18 | 19 | public String getMessage() { 20 | return message; 21 | } 22 | 23 | public void setMessage(String message) { 24 | this.message = message; 25 | } 26 | 27 | public Example getExample() { 28 | return example; 29 | } 30 | 31 | public void setExample(Example example) { 32 | this.example = example; 33 | } 34 | 35 | public static class Example { 36 | private String mediaType; 37 | private String value; 38 | 39 | public String getMediaType() { 40 | return mediaType; 41 | } 42 | 43 | public void setMediaType(String mediaType) { 44 | this.mediaType = mediaType; 45 | } 46 | 47 | public String getValue() { 48 | return value; 49 | } 50 | 51 | public void setValue(String value) { 52 | this.value = value; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/Utils.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.github.jknack.handlebars.io.ClassPathTemplateLoader; 4 | import com.github.jknack.handlebars.io.FileTemplateLoader; 5 | import io.swagger.models.Model; 6 | import io.swagger.models.Operation; 7 | import io.swagger.models.Path; 8 | import io.swagger.models.Response; 9 | import io.swagger.models.Swagger; 10 | import io.swagger.models.Tag; 11 | 12 | import java.lang.reflect.InvocationTargetException; 13 | import java.lang.reflect.Method; 14 | import java.util.Collections; 15 | import java.util.Comparator; 16 | import java.util.Map; 17 | import java.util.TreeMap; 18 | 19 | /** 20 | * @author chekong on 14-11-25. 21 | */ 22 | public class Utils { 23 | 24 | private static final java.lang.String CLASSPATH = "classpath:"; 25 | 26 | public static TemplatePath parseTemplateUrl(String templatePath) throws GenerateException { 27 | if (templatePath == null) { 28 | return null; 29 | } 30 | TemplatePath tp; 31 | if (templatePath.startsWith(CLASSPATH)) { 32 | String resPath = templatePath.substring(CLASSPATH.length()); 33 | tp = extractTemplateObject(resPath); 34 | tp.loader = new ClassPathTemplateLoader(tp.prefix, tp.suffix); 35 | } else { 36 | tp = extractTemplateObject(templatePath); 37 | tp.loader = new FileTemplateLoader(tp.prefix, tp.suffix); 38 | } 39 | 40 | return tp; 41 | } 42 | 43 | private static TemplatePath extractTemplateObject(String resPath) throws GenerateException { 44 | TemplatePath tp = new TemplatePath(); 45 | String prefix = ""; 46 | String suffix = ""; 47 | String name = ""; 48 | 49 | int prefixidx = resPath.lastIndexOf("/"); 50 | if (prefixidx != -1) { 51 | prefix = resPath.substring(0, prefixidx + 1); 52 | } 53 | 54 | int extidx = resPath.lastIndexOf("."); 55 | if (extidx != -1) { 56 | suffix = resPath.substring(extidx); 57 | if (extidx < prefix.length()) { 58 | throw new GenerateException("You have an interesting template path:" + resPath); 59 | } 60 | name = resPath.substring(prefix.length(), extidx); 61 | } 62 | tp.name = name; 63 | tp.prefix = prefix; 64 | tp.suffix = suffix; 65 | 66 | return tp; 67 | } 68 | 69 | public static void sortSwagger(Swagger swagger) throws GenerateException { 70 | if (swagger == null || swagger.getPaths() == null) { 71 | return; 72 | } 73 | 74 | TreeMap sortedMap = new TreeMap(); 75 | if (swagger.getPaths() == null) { 76 | return; 77 | } 78 | sortedMap.putAll(swagger.getPaths()); 79 | swagger.paths(sortedMap); 80 | 81 | for (Path path : swagger.getPaths().values()) { 82 | String methods[] = {"Get", "Delete", "Post", "Put", "Options", "Patch"}; 83 | for (String m : methods) { 84 | sortResponses(path, m); 85 | } 86 | } 87 | 88 | //reorder definitions 89 | if (swagger.getDefinitions() != null) { 90 | TreeMap defs = new TreeMap(); 91 | defs.putAll(swagger.getDefinitions()); 92 | swagger.setDefinitions(defs); 93 | } 94 | 95 | // order the tags 96 | if (swagger.getTags() != null) { 97 | Collections.sort(swagger.getTags(), new Comparator() { 98 | public int compare(final Tag a, final Tag b) { 99 | return a.toString().toLowerCase().compareTo(b.toString().toLowerCase()); 100 | } 101 | }); 102 | } 103 | 104 | } 105 | 106 | private static void sortResponses(Path path, String method) throws GenerateException { 107 | try { 108 | Method m = Path.class.getDeclaredMethod("get" + method); 109 | Operation op = (Operation) m.invoke(path); 110 | if (op == null) { 111 | return; 112 | } 113 | Map responses = op.getResponses(); 114 | TreeMap res = new TreeMap(); 115 | res.putAll(responses); 116 | op.setResponses(res); 117 | } catch (NoSuchMethodException e) { 118 | throw new GenerateException(e); 119 | } catch (InvocationTargetException e) { 120 | throw new GenerateException(e); 121 | } catch (IllegalAccessException e) { 122 | throw new GenerateException(e); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/jaxrs/BeanParamInjectParamExtension.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.jaxrs; 2 | 3 | import com.github.kongchen.swagger.docgen.reader.AbstractReader; 4 | import com.github.kongchen.swagger.docgen.reader.JaxrsReader; 5 | import com.google.common.collect.Lists; 6 | import com.sun.jersey.api.core.InjectParam; 7 | import com.sun.jersey.core.header.FormDataContentDisposition; 8 | import io.swagger.jaxrs.ext.AbstractSwaggerExtension; 9 | import io.swagger.jaxrs.ext.SwaggerExtension; 10 | import io.swagger.models.parameters.Parameter; 11 | import org.apache.commons.lang3.reflect.TypeUtils; 12 | 13 | import javax.ws.rs.BeanParam; 14 | import java.lang.annotation.Annotation; 15 | import java.lang.reflect.Type; 16 | import java.util.Iterator; 17 | import java.util.List; 18 | import java.util.Set; 19 | 20 | /** 21 | * This extension extracts the parameters inside a {@code @BeanParam} by 22 | * expanding the target bean type's fields/methods/constructor parameters and 23 | * recursively feeding them back through the {@link JaxrsReader}. 24 | * 25 | * @author chekong on 15/5/9. 26 | */ 27 | public class BeanParamInjectParamExtension extends AbstractSwaggerExtension { 28 | 29 | 30 | private AbstractReader reader; 31 | 32 | public BeanParamInjectParamExtension(AbstractReader reader) { 33 | this.reader = reader; 34 | } 35 | 36 | @Override 37 | public List extractParameters(List annotations, Type type, Set typesToSkip, Iterator chain) { 38 | Class cls = TypeUtils.getRawType(type, type); 39 | 40 | if (shouldIgnoreClass(cls) || typesToSkip.contains(type)) { 41 | // stop the processing chain 42 | typesToSkip.add(type); 43 | return Lists.newArrayList(); 44 | } 45 | for (Annotation annotation : annotations) { 46 | if (annotation instanceof BeanParam || annotation instanceof InjectParam) { 47 | return reader.extractTypes(cls, typesToSkip, Lists.newArrayList()); 48 | } 49 | } 50 | return super.extractParameters(annotations, type, typesToSkip, chain); 51 | } 52 | 53 | @Override 54 | public boolean shouldIgnoreClass(Class cls) { 55 | return FormDataContentDisposition.class.equals(cls); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/mavenplugin/IncludeProjectDependenciesComponentConfigurator.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | 4 | import org.codehaus.classworlds.ClassRealm; 5 | import org.codehaus.plexus.component.configurator.AbstractComponentConfigurator; 6 | import org.codehaus.plexus.component.configurator.ComponentConfigurationException; 7 | import org.codehaus.plexus.component.configurator.ConfigurationListener; 8 | import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter; 9 | import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; 10 | import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; 11 | import org.codehaus.plexus.configuration.PlexusConfiguration; 12 | 13 | import java.io.File; 14 | import java.net.MalformedURLException; 15 | import java.net.URL; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * A custom ComponentConfigurator which adds the project's runtime classpath elements 21 | * to the 22 | * 23 | * @author Brian Jackson 24 | * @plexus.component role="org.codehaus.plexus.component.configurator.ComponentConfigurator" 25 | * role-hint="include-project-dependencies" 26 | * @plexus.requirement role="org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup" 27 | * role-hint="default" 28 | * @since Aug 1, 2008 3:04:17 PM 29 | */ 30 | public class IncludeProjectDependenciesComponentConfigurator extends AbstractComponentConfigurator { 31 | 32 | @Override 33 | public void configureComponent(Object component, PlexusConfiguration configuration, 34 | ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm, 35 | ConfigurationListener listener) 36 | throws ComponentConfigurationException { 37 | addProjectDependenciesToClassRealm(expressionEvaluator, containerRealm); 38 | 39 | ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter(); 40 | converter.processConfiguration(converterLookup, component, containerRealm.getClassLoader(), configuration, 41 | expressionEvaluator, listener); 42 | } 43 | 44 | private void addProjectDependenciesToClassRealm(ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm) throws ComponentConfigurationException { 45 | List compileClasspathElements; 46 | try { 47 | //noinspection unchecked 48 | compileClasspathElements = (List) expressionEvaluator.evaluate("${project.compileClasspathElements}"); 49 | } catch (ExpressionEvaluationException e) { 50 | throw new ComponentConfigurationException("There was a problem evaluating: ${project.compileClasspathElements}", e); 51 | } 52 | 53 | // Add the project dependencies to the ClassRealm 54 | final URL[] urls = buildURLs(compileClasspathElements); 55 | for (URL url : urls) { 56 | containerRealm.addConstituent(url); 57 | } 58 | } 59 | 60 | private URL[] buildURLs(List runtimeClasspathElements) throws ComponentConfigurationException { 61 | // Add the projects classes and dependencies 62 | List urls = new ArrayList(runtimeClasspathElements.size()); 63 | for (String element : runtimeClasspathElements) { 64 | try { 65 | final URL url = new File(element).toURI().toURL(); 66 | urls.add(url); 67 | } catch (MalformedURLException e) { 68 | throw new ComponentConfigurationException("Unable to access project dependency: " + element, e); 69 | } 70 | } 71 | 72 | // Add the plugin's dependencies (so Trove stuff works if Trove isn't on 73 | return urls.toArray(new URL[urls.size()]); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/mavenplugin/MavenDocumentSource.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | import com.github.kongchen.swagger.docgen.AbstractDocumentSource; 4 | import com.github.kongchen.swagger.docgen.reader.JaxrsReader; 5 | import com.google.common.collect.Sets; 6 | import org.apache.maven.plugin.MojoFailureException; 7 | import org.apache.maven.plugin.logging.Log; 8 | 9 | import javax.ws.rs.Path; 10 | import java.util.Set; 11 | 12 | /** 13 | * @author chekong 14 | * 05/13/2013 15 | */ 16 | public class MavenDocumentSource extends AbstractDocumentSource { 17 | 18 | public MavenDocumentSource(ApiSource apiSource, Log log, String encoding) throws MojoFailureException { 19 | super(log, apiSource, encoding); 20 | } 21 | 22 | @Override 23 | protected Set> getValidClasses() { 24 | return Sets.union( 25 | super.getValidClasses(), 26 | apiSource.getValidClasses(Path.class)); 27 | } 28 | 29 | @Override 30 | protected JaxrsReader createReader() { 31 | return new JaxrsReader(swagger, LOG); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/mavenplugin/SpringMavenDocumentSource.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | import com.github.kongchen.swagger.docgen.AbstractDocumentSource; 4 | import com.github.kongchen.swagger.docgen.reader.SpringMvcApiReader; 5 | import org.apache.maven.plugin.MojoFailureException; 6 | import org.apache.maven.plugin.logging.Log; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.Set; 11 | 12 | /** 13 | * @author tedleman 14 | * 01/21/15 15 | * @author chekong 16 | * 05/13/2013 17 | */ 18 | public class SpringMavenDocumentSource extends AbstractDocumentSource { 19 | 20 | public SpringMavenDocumentSource(ApiSource apiSource, Log log, String encoding) throws MojoFailureException { 21 | super(log, apiSource, encoding); 22 | } 23 | 24 | @Override 25 | protected Set> getValidClasses() { 26 | Set> result = super.getValidClasses(); 27 | result.addAll(apiSource.getValidClasses(RestController.class)); 28 | result.addAll(apiSource.getValidClasses(ControllerAdvice.class)); 29 | return result; 30 | } 31 | 32 | @Override 33 | protected SpringMvcApiReader createReader() { 34 | return new SpringMvcApiReader(swagger, LOG); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/ClassSwaggerReader.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import com.github.kongchen.swagger.docgen.GenerateException; 4 | import io.swagger.models.Swagger; 5 | 6 | import java.util.Set; 7 | 8 | /** 9 | * @author chekong on 15/4/28. 10 | */ 11 | public interface ClassSwaggerReader { 12 | Swagger read(Set> classes) throws GenerateException; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/ModelConverterHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.github.kongchen.swagger.docgen.reader; 7 | 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import io.swagger.converter.ModelConverter; 10 | import io.swagger.jackson.AbstractModelConverter; 11 | 12 | /** 13 | * 14 | * @author andrewbird 15 | */ 16 | public class ModelConverterHelper extends AbstractModelConverter implements ModelConverter { 17 | 18 | public ModelConverterHelper(ObjectMapper mapper) { 19 | super(mapper); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/ResponseContainerConverter.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import io.swagger.models.properties.ArrayProperty; 4 | import io.swagger.models.properties.MapProperty; 5 | import io.swagger.models.properties.Property; 6 | 7 | /** 8 | * Property wrapper for response container. 9 | */ 10 | class ResponseContainerConverter { 11 | Property withResponseContainer(String responseContainer, Property property) { 12 | if ("list".equalsIgnoreCase(responseContainer)) { 13 | return new ArrayProperty(property); 14 | } 15 | if ("set".equalsIgnoreCase(responseContainer)) { 16 | return new ArrayProperty(property).uniqueItems(); 17 | } 18 | if ("map".equalsIgnoreCase(responseContainer)) { 19 | return new MapProperty(property); 20 | } 21 | return property; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/ServletReader.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import java.util.Set; 4 | 5 | import org.apache.maven.plugin.logging.Log; 6 | 7 | import com.github.kongchen.swagger.docgen.GenerateException; 8 | 9 | import io.swagger.models.Swagger; 10 | import io.swagger.servlet.Reader; 11 | 12 | /** 13 | * A dedicated {@link ClassSwaggerReader} to scan Serlet classes. 14 | */ 15 | public class ServletReader extends AbstractReader implements ClassSwaggerReader { 16 | 17 | public ServletReader(Swagger swagger, Log LOG) { 18 | super(swagger, LOG); 19 | } 20 | 21 | @Override 22 | public Swagger read(Set> classes) throws GenerateException { 23 | Reader.read(swagger, classes ); 24 | return swagger; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/SpringExceptionHandlerReader.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import org.apache.maven.plugin.logging.Log; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.ResponseStatus; 7 | 8 | import java.lang.reflect.Method; 9 | import java.util.HashMap; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.Set; 14 | 15 | import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation; 16 | import static org.springframework.core.annotation.AnnotationUtils.findAnnotation; 17 | 18 | public class SpringExceptionHandlerReader { 19 | private final Log log; 20 | 21 | private Map, ResponseStatus> exceptionMapping = 22 | new HashMap, ResponseStatus>(); 23 | 24 | public SpringExceptionHandlerReader(Log log) { 25 | this.log = log; 26 | } 27 | 28 | public void processExceptionHandlers(Set> classes) { 29 | exceptionMapping = generateExceptionMapping(classes); 30 | } 31 | 32 | protected Map, ResponseStatus> generateExceptionMapping(Set> classes) { 33 | Map, ResponseStatus> result = 34 | new HashMap, ResponseStatus>(); 35 | 36 | log.debug(String.format("Looking for classes with @ControllerAdvice annotation")); 37 | for (Class clazz: classes) { 38 | ControllerAdvice advice = findAnnotation(clazz, ControllerAdvice.class); 39 | if (advice == null) { 40 | continue; 41 | } 42 | 43 | log.debug(String.format("%s is annotated as @ControllerAdvice", clazz.getName())); 44 | 45 | for (Method method: clazz.getMethods()) { 46 | ExceptionHandler handler = findAnnotation(method, ExceptionHandler.class); 47 | if (handler == null) { 48 | log.debug(String.format("@ExceptionHandler is missing on %s method, skipping", method)); 49 | continue; 50 | } 51 | 52 | ResponseStatus responseStatus = findAnnotation(method, ResponseStatus.class); 53 | if (responseStatus == null) { 54 | log.debug(String.format("@ResponseStatus is missing on %s method, skipping", method)); 55 | continue; 56 | } 57 | 58 | Class[] exceptionClasses = handler.value(); 59 | for (Class exceptionClass: exceptionClasses) { 60 | log.debug(String.format("%s will be mapped to %s", exceptionClass, responseStatus)); 61 | result.put(exceptionClass, responseStatus); 62 | } 63 | } 64 | 65 | } 66 | return result; 67 | } 68 | 69 | protected List getResponseStatusesFromExceptions(Method method) { 70 | List result = new LinkedList(); 71 | for (Class exceptionClass: method.getExceptionTypes()) { 72 | ResponseStatus responseStatus = exceptionMapping.get(exceptionClass); 73 | 74 | // fallback to exception own annotation 75 | if (null == responseStatus) { 76 | responseStatus = findMergedAnnotation(exceptionClass, ResponseStatus.class); 77 | } 78 | 79 | if (null != responseStatus) { 80 | result.add(responseStatus); 81 | } 82 | } 83 | return result; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/reader/SwaggerReader.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import java.util.Set; 4 | 5 | import org.apache.maven.plugin.logging.Log; 6 | 7 | import com.github.kongchen.swagger.docgen.GenerateException; 8 | 9 | import io.swagger.jaxrs.Reader; 10 | import io.swagger.models.Swagger; 11 | 12 | /** 13 | * This API reader is directly using the swagger internal {@link Reader} to scan the classes. 14 | * This reader is used when the exact output as the runtime generated swagger file is necessary. 15 | */ 16 | public class SwaggerReader extends AbstractReader implements ClassSwaggerReader { 17 | 18 | public SwaggerReader(Swagger swagger, Log LOG) { 19 | super(swagger, LOG); 20 | } 21 | 22 | @Override 23 | public Swagger read(Set> classes) throws GenerateException { 24 | return new Reader(swagger).read(classes); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/spring/SpringResource.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.spring; 2 | 3 | import com.github.kongchen.swagger.docgen.util.SpringUtils; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.lang.reflect.Method; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author tedleman 12 | */ 13 | public class SpringResource { 14 | private Class controllerClass; 15 | private List methods; 16 | private String controllerMapping; //FIXME should be an array 17 | private String resourceName; 18 | private String resourceKey; 19 | private String description; 20 | 21 | /** 22 | * 23 | * @param clazz Controller class 24 | * @param resourceName resource Name 25 | * @param resourceKey key containing the controller package, class controller class name, and controller-level @RequestMapping#value 26 | * @param description description of the contrroller 27 | */ 28 | public SpringResource(Class clazz, String resourceName, String resourceKey, String description) { 29 | this.controllerClass = clazz; 30 | this.resourceName = resourceName; 31 | this.resourceKey = resourceKey; 32 | this.description = description; 33 | methods = new ArrayList(); 34 | 35 | String[] controllerRequestMappingValues = SpringUtils.getControllerResquestMapping(controllerClass); 36 | 37 | this.controllerMapping = StringUtils.removeEnd(controllerRequestMappingValues[0], "/"); 38 | } 39 | 40 | public Class getControllerClass() { 41 | return controllerClass; 42 | } 43 | 44 | public void setControllerClass(Class controllerClass) { 45 | this.controllerClass = controllerClass; 46 | } 47 | 48 | public List getMethods() { 49 | return methods; 50 | } 51 | 52 | public void setMethods(List methods) { 53 | this.methods = methods; 54 | } 55 | 56 | public void addMethod(Method m) { 57 | this.methods.add(m); 58 | } 59 | 60 | public String getControllerMapping() { 61 | return controllerMapping; 62 | } 63 | 64 | public void setControllerMapping(String controllerMapping) { 65 | this.controllerMapping = controllerMapping; 66 | } 67 | 68 | public String getResourceName() { 69 | return resourceName; 70 | } 71 | 72 | public void setResource(String resource) { 73 | this.resourceName = resource; 74 | } 75 | 76 | public String getResourcePath() { 77 | return "/" + resourceName; 78 | } 79 | 80 | public String getResourceKey() { 81 | return resourceKey; 82 | } 83 | 84 | public void setResourceKey(String resourceKey) { 85 | this.resourceKey = resourceKey; 86 | } 87 | 88 | public String getDescription() { 89 | return description; 90 | } 91 | 92 | public void setDescription(String description) { 93 | this.description = description; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/util/SpringUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.util; 2 | 3 | import org.springframework.core.annotation.AnnotationUtils; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | /** 7 | * @author kongchen 8 | * Date: 1/21/14 9 | * @author tedleman 10 | */ 11 | public class SpringUtils { 12 | /** 13 | * Extracts all routes from the annotated class 14 | * 15 | * @param controllerClazz 16 | * Instrospected class 17 | * @return At least 1 route value (empty string) 18 | */ 19 | public static String[] getControllerResquestMapping(Class controllerClazz) { 20 | String[] controllerRequestMappingValues = {}; 21 | 22 | // Determine if we will use class-level requestmapping or dummy string 23 | RequestMapping classRequestMapping = AnnotationUtils.findAnnotation(controllerClazz, RequestMapping.class); 24 | if (classRequestMapping != null) { 25 | controllerRequestMappingValues = classRequestMapping.value(); 26 | } 27 | 28 | if (controllerRequestMappingValues.length == 0) { 29 | controllerRequestMappingValues = new String[1]; 30 | controllerRequestMappingValues[0] = ""; 31 | } 32 | return controllerRequestMappingValues; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/util/TypeExtracter.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.util; 2 | 3 | import com.github.kongchen.swagger.docgen.reader.JaxrsReader; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.lang.reflect.*; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.Collection; 10 | import java.util.List; 11 | 12 | public class TypeExtracter { 13 | 14 | private static final AccessibleObjectGetter FIELD_GETTER = new AccessibleObjectGetter() { 15 | @Override 16 | public Field[] get(Class clazz) { 17 | return clazz.getDeclaredFields(); 18 | } 19 | }; 20 | 21 | private static final AccessibleObjectGetter METHOD_GETTER = new AccessibleObjectGetter() { 22 | @Override 23 | public Method[] get(Class clazz) { 24 | return clazz.getDeclaredMethods(); 25 | } 26 | }; 27 | 28 | private static final AccessibleObjectGetter> CONSTRUCTOR_GETTER = new AccessibleObjectGetter>() { 29 | @Override 30 | public Constructor[] get(Class clazz) { 31 | return clazz.getDeclaredConstructors(); 32 | } 33 | }; 34 | 35 | public Collection extractTypes(Class cls) { 36 | 37 | ArrayList typesWithAnnotations = new ArrayList(); 38 | 39 | typesWithAnnotations.addAll(getPropertyTypes(cls)); 40 | typesWithAnnotations.addAll(getMethodParameterTypes(cls)); 41 | typesWithAnnotations.addAll(getConstructorParameterTypes(cls)); 42 | 43 | return typesWithAnnotations; 44 | } 45 | 46 | private Collection getPropertyTypes(Class clazz) { 47 | Collection typesWithAnnotations = new ArrayList(); 48 | for (Field field : getDeclaredAndInheritedMembers(clazz, FIELD_GETTER)) { 49 | Type type = field.getGenericType(); 50 | List annotations = Arrays.asList(field.getAnnotations()); 51 | typesWithAnnotations.add(new TypeWithAnnotations(type, annotations)); 52 | } 53 | 54 | return typesWithAnnotations; 55 | } 56 | 57 | private Collection getMethodParameterTypes(Class clazz) { 58 | Collection typesWithAnnotations = new ArrayList(); 59 | /* 60 | * For methods we will only examine setters and will only look at the 61 | * annotations on the parameter, not the method itself. 62 | */ 63 | for (Method method : getDeclaredAndInheritedMembers(clazz, METHOD_GETTER)) { 64 | 65 | Type[] parameterTypes = method.getGenericParameterTypes(); 66 | // skip methods that don't look like setters 67 | if (parameterTypes.length != 1 || method.getReturnType() != void.class) { 68 | continue; 69 | } 70 | Type type = parameterTypes[0]; 71 | List annotations = Arrays.asList(JaxrsReader.findParamAnnotations(method)[0]); 72 | typesWithAnnotations.add(new TypeWithAnnotations(type, annotations)); 73 | } 74 | 75 | return typesWithAnnotations; 76 | } 77 | 78 | private Collection getConstructorParameterTypes(Class clazz) { 79 | Collection typesWithAnnotations = new ArrayList(); 80 | for (Constructor constructor : getDeclaredAndInheritedMembers(clazz, CONSTRUCTOR_GETTER)) { 81 | 82 | Type[] parameterTypes = constructor.getGenericParameterTypes(); 83 | Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); 84 | 85 | for (int i = 0; i < parameterTypes.length; i++) { 86 | Type type = parameterTypes[i]; 87 | List annotations = Arrays.asList(parameterAnnotations[i]); 88 | typesWithAnnotations.add(new TypeWithAnnotations(type, annotations)); 89 | } 90 | } 91 | 92 | return typesWithAnnotations; 93 | } 94 | 95 | private List getDeclaredAndInheritedMembers(Class clazz, AccessibleObjectGetter getter) { 96 | List fields = new ArrayList(); 97 | Class inspectedClass = clazz; 98 | while (inspectedClass != null) { 99 | fields.addAll(Arrays.asList(getter.get(inspectedClass))); 100 | inspectedClass = inspectedClass.getSuperclass(); 101 | } 102 | return fields; 103 | } 104 | 105 | // get rid of this and use lambdas instead once Java 8 is supported 106 | private interface AccessibleObjectGetter { 107 | 108 | T[] get(Class clazz); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/util/TypeUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.util; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import io.swagger.converter.ModelConverters; 6 | import io.swagger.models.properties.Property; 7 | 8 | public class TypeUtils { 9 | 10 | public static boolean isPrimitive(Type cls) { 11 | boolean isPrimitive = false; 12 | 13 | Property property = ModelConverters.getInstance().readAsProperty(cls); 14 | if (property == null) { 15 | isPrimitive = false; 16 | } else if ("integer".equals(property.getType())) { 17 | isPrimitive = true; 18 | } else if ("string".equals(property.getType())) { 19 | isPrimitive = true; 20 | } else if ("number".equals(property.getType())) { 21 | isPrimitive = true; 22 | } else if ("boolean".equals(property.getType())) { 23 | isPrimitive = true; 24 | } else if ("array".equals(property.getType())) { 25 | isPrimitive = true; 26 | } else if ("file".equals(property.getType())) { 27 | isPrimitive = true; 28 | } 29 | return isPrimitive; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/kongchen/swagger/docgen/util/TypeWithAnnotations.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.util; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Type; 5 | import java.util.List; 6 | 7 | public class TypeWithAnnotations { 8 | 9 | private final Type type; 10 | private final List annotations; 11 | 12 | TypeWithAnnotations(Type type, List annotations) { 13 | this.type = type; 14 | this.annotations = annotations; 15 | } 16 | 17 | public Type getType() { 18 | return type; 19 | } 20 | 21 | public List getAnnotations() { 22 | return annotations; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/JaxrsEnhancedOperationIdTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import io.swagger.jaxrs.ext.SwaggerExtension; 7 | import io.swagger.jaxrs.ext.SwaggerExtensions; 8 | import io.swagger.util.Json; 9 | import net.javacrumbs.jsonunit.core.Configuration; 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 12 | import org.testng.annotations.AfterMethod; 13 | import org.testng.annotations.BeforeMethod; 14 | import org.testng.annotations.Test; 15 | 16 | import java.io.File; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals; 21 | import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; 22 | 23 | public class JaxrsEnhancedOperationIdTest extends AbstractMojoTestCase { 24 | private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui-enhanced-operation-id"); 25 | private ApiDocumentMojo mojo; 26 | private ObjectMapper mapper = Json.mapper(); 27 | private List extensions; 28 | 29 | @Override 30 | @BeforeMethod 31 | protected void setUp() throws Exception { 32 | extensions = new ArrayList(SwaggerExtensions.getExtensions()); 33 | super.setUp(); 34 | 35 | try { 36 | FileUtils.deleteDirectory(swaggerOutputDir); 37 | } catch(Exception e) { 38 | //ignore 39 | } 40 | 41 | File testPom = new File(getBasedir(), "target/test-classes/plugin-config-enhanced-operation-id.xml"); 42 | mojo = (ApiDocumentMojo) lookupMojo("generate", testPom); 43 | } 44 | 45 | @Override 46 | @AfterMethod 47 | protected void tearDown() throws Exception { 48 | super.tearDown(); 49 | SwaggerExtensions.setExtensions(extensions); 50 | } 51 | 52 | @Test 53 | public void testGeneratedSwaggerSpecJson() throws Exception { 54 | mojo.execute(); 55 | JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json")); 56 | JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-enhanced-operation-id.json")); 57 | 58 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/SpringMvcEnhancedOperationIdTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import io.swagger.jaxrs.ext.SwaggerExtension; 7 | import io.swagger.jaxrs.ext.SwaggerExtensions; 8 | import io.swagger.util.Json; 9 | import net.javacrumbs.jsonunit.core.Configuration; 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.maven.plugin.MojoExecutionException; 12 | import org.apache.maven.plugin.MojoFailureException; 13 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 14 | import org.testng.annotations.AfterMethod; 15 | import org.testng.annotations.BeforeMethod; 16 | import org.testng.annotations.Test; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals; 24 | import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; 25 | 26 | public class SpringMvcEnhancedOperationIdTest extends AbstractMojoTestCase { 27 | private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui-spring-enhanced-operation-id"); 28 | private ApiDocumentMojo mojo; 29 | private List extensions; 30 | 31 | @Override 32 | @BeforeMethod 33 | protected void setUp() throws Exception { 34 | extensions = new ArrayList(SwaggerExtensions.getExtensions()); 35 | super.setUp(); 36 | 37 | try { 38 | FileUtils.deleteDirectory(swaggerOutputDir); 39 | } catch (Exception e) { 40 | //ignore 41 | } 42 | 43 | File testPom = new File(getBasedir(), "target/test-classes/plugin-config-springmvc-enhanced-operation-id.xml"); 44 | mojo = (ApiDocumentMojo) lookupMojo("generate", testPom); 45 | } 46 | 47 | @Override 48 | @AfterMethod 49 | protected void tearDown() throws Exception { 50 | super.tearDown(); 51 | SwaggerExtensions.setExtensions(extensions); 52 | } 53 | 54 | @Test 55 | public void testAssertGeneratedSwaggerSpecJson() throws MojoExecutionException, MojoFailureException, IOException { 56 | mojo.execute(); 57 | ObjectMapper mapper = Json.mapper(); 58 | JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json")); 59 | JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-spring-enhanced-operation-id.json")); 60 | 61 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/SpringMvcSkipInheritedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import io.swagger.jaxrs.ext.SwaggerExtension; 7 | import io.swagger.jaxrs.ext.SwaggerExtensions; 8 | import io.swagger.util.Json; 9 | import net.javacrumbs.jsonunit.core.Configuration; 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.maven.plugin.MojoExecutionException; 12 | import org.apache.maven.plugin.MojoFailureException; 13 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 14 | import org.testng.annotations.AfterMethod; 15 | import org.testng.annotations.BeforeMethod; 16 | import org.testng.annotations.Test; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals; 24 | import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; 25 | 26 | public class SpringMvcSkipInheritedTest extends AbstractMojoTestCase { 27 | private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui-spring-skip-inherited"); 28 | private File docOutput = new File(getBasedir(), "generated/document-spring-skip-inherited.html"); 29 | private ApiDocumentMojo mojo; 30 | private List extensions; 31 | 32 | @Override 33 | @BeforeMethod 34 | protected void setUp() throws Exception { 35 | extensions = new ArrayList(SwaggerExtensions.getExtensions()); 36 | super.setUp(); 37 | 38 | try { 39 | FileUtils.deleteDirectory(swaggerOutputDir); 40 | FileUtils.forceDelete(docOutput); 41 | } catch (Exception e) { 42 | //ignore 43 | } 44 | 45 | File testPom = new File(getBasedir(), "target/test-classes/plugin-config-springmvc-skip-inherited.xml"); 46 | mojo = (ApiDocumentMojo) lookupMojo("generate", testPom); 47 | } 48 | 49 | @Override 50 | @AfterMethod 51 | protected void tearDown() throws Exception { 52 | super.tearDown(); 53 | SwaggerExtensions.setExtensions(extensions); 54 | } 55 | 56 | @Test 57 | public void testAssertGeneratedSwaggerSpecJson() throws MojoExecutionException, MojoFailureException, IOException { 58 | mojo.execute(); 59 | ObjectMapper mapper = Json.mapper(); 60 | JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json")); 61 | JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-spring-skip-inherited.json")); 62 | 63 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/StringWrapperModelTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import io.swagger.jaxrs.ext.SwaggerExtension; 7 | import io.swagger.jaxrs.ext.SwaggerExtensions; 8 | import io.swagger.util.Json; 9 | import net.javacrumbs.jsonunit.core.Configuration; 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.maven.plugin.MojoExecutionException; 12 | import org.apache.maven.plugin.MojoFailureException; 13 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 14 | import org.testng.annotations.AfterMethod; 15 | import org.testng.annotations.BeforeMethod; 16 | import org.testng.annotations.Test; 17 | 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals; 24 | import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; 25 | 26 | /** 27 | * @author chekong on 8/15/14. 28 | */ 29 | public class StringWrapperModelTest extends AbstractMojoTestCase { 30 | private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui-spring-string-wrapper-model"); 31 | private ApiDocumentMojo mojo; 32 | private List extensions; 33 | 34 | @Override 35 | @BeforeMethod 36 | protected void setUp() throws Exception { 37 | extensions = new ArrayList(SwaggerExtensions.getExtensions()); 38 | super.setUp(); 39 | 40 | try { 41 | FileUtils.deleteDirectory(swaggerOutputDir); 42 | } catch (Exception e) { 43 | //ignore 44 | } 45 | 46 | File testPom = new File(getBasedir(), "target/test-classes/plugin-config-springmvc-string-wrapper-model.xml"); 47 | mojo = (ApiDocumentMojo) lookupMojo("generate", testPom); 48 | } 49 | 50 | @Override 51 | @AfterMethod 52 | protected void tearDown() throws Exception { 53 | super.tearDown(); 54 | SwaggerExtensions.setExtensions(extensions); 55 | } 56 | 57 | @Test 58 | public void testAssertGeneratedSwaggerSpecJson() throws MojoExecutionException, MojoFailureException, IOException { 59 | mojo.execute(); 60 | ObjectMapper mapper = Json.mapper(); 61 | JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json")); 62 | JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-spring-string-wrapper-model.json")); 63 | 64 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/SwaggerReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import io.swagger.util.Json; 7 | import net.javacrumbs.jsonunit.core.Configuration; 8 | import org.apache.commons.io.FileUtils; 9 | import org.apache.maven.plugin.testing.AbstractMojoTestCase; 10 | import org.testng.annotations.BeforeMethod; 11 | import org.testng.annotations.Test; 12 | import org.yaml.snakeyaml.Yaml; 13 | 14 | import java.io.File; 15 | 16 | import static com.github.kongchen.smp.integration.utils.TestUtils.YamlToJson; 17 | import static com.github.kongchen.smp.integration.utils.TestUtils.changeDescription; 18 | import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals; 19 | import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER; 20 | 21 | /** 22 | * @author chekong on 8/15/14. 23 | */ 24 | public class SwaggerReaderTest extends AbstractMojoTestCase { 25 | private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui"); 26 | private ApiDocumentMojo mojo; 27 | private ObjectMapper mapper = Json.mapper(); 28 | 29 | @Override 30 | @BeforeMethod 31 | protected void setUp() throws Exception { 32 | super.setUp(); 33 | 34 | try { 35 | FileUtils.deleteDirectory(swaggerOutputDir); 36 | } catch(Exception e) { 37 | //ignore 38 | } 39 | 40 | File testPom = new File(getBasedir(), "target/test-classes/plugin-config-swaggerreader.xml"); 41 | mojo = (ApiDocumentMojo) lookupMojo("generate", testPom); 42 | } 43 | 44 | @Test 45 | public void testGeneratedSwaggerSpecJson() throws Exception { 46 | mojo.execute(); 47 | 48 | JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json")); 49 | JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-swaggerreader.json")); 50 | 51 | changeDescription(expectJson, "This is a sample."); 52 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 53 | } 54 | 55 | @Test 56 | public void testGeneratedSwaggerSpecYaml() throws Exception { 57 | mojo.getApiSources().get(0).setOutputFormats("yaml"); 58 | mojo.execute(); 59 | 60 | String actualYaml = io.swagger.util.Yaml.pretty().writeValueAsString( 61 | new Yaml().load(FileUtils.readFileToString(new File(swaggerOutputDir, "swagger.yaml")))); 62 | String expectYaml = io.swagger.util.Yaml.pretty().writeValueAsString( 63 | new Yaml().load(this.getClass().getResourceAsStream("/expectedOutput/swagger-swaggerreader.yaml"))); 64 | 65 | JsonNode actualJson = mapper.readTree(YamlToJson(actualYaml)); 66 | JsonNode expectJson = mapper.readTree(YamlToJson(expectYaml)); 67 | 68 | changeDescription(expectJson, "This is a sample."); 69 | assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER)); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/utils/PetIdToStringModelConverter.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration.utils; 2 | 3 | import io.swagger.converter.ModelConverter; 4 | import io.swagger.converter.ModelConverterContext; 5 | import io.swagger.jackson.AbstractModelConverter; 6 | import io.swagger.models.properties.Property; 7 | import io.swagger.util.Json; 8 | 9 | import java.lang.annotation.Annotation; 10 | import java.lang.reflect.Type; 11 | import java.util.Iterator; 12 | 13 | /** 14 | * A ModelConverter used for testing adding custom model converters. 15 | */ 16 | public class PetIdToStringModelConverter extends AbstractModelConverter { 17 | 18 | public PetIdToStringModelConverter() { 19 | super(Json.mapper().copy()); 20 | } 21 | 22 | @Override 23 | public Property resolveProperty(Type type, ModelConverterContext modelConverterContext, Annotation[] annotations, Iterator iterator) { 24 | try { 25 | Type expectedType = _mapper.constructType(Class.forName("com.wordnik.sample.model.PetId")); 26 | if (type.equals(expectedType)) { 27 | return super.resolveProperty(_mapper.constructType(Class.forName("java.lang.String")), modelConverterContext, annotations, iterator); 28 | } 29 | } catch (ClassNotFoundException e) { 30 | throw new RuntimeException(e); 31 | } 32 | return super.resolveProperty(type, modelConverterContext, annotations, iterator); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/smp/integration/utils/TestUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.smp.integration.utils; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ObjectNode; 5 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo; 6 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource; 7 | import org.codehaus.jettison.json.JSONObject; 8 | import org.yaml.snakeyaml.Yaml; 9 | 10 | import java.io.File; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author Igor Gursky 15 | * 15.12.2015. 16 | */ 17 | public class TestUtils { 18 | 19 | public static String YamlToJson(String yamlString) { 20 | Yaml yaml = new Yaml(); 21 | Map map = (Map) yaml.load(yamlString); 22 | return new JSONObject(map).toString(); 23 | } 24 | 25 | public static String createTempDirPath() throws Exception { 26 | File tempFile = File.createTempFile("swagmvn", "test"); 27 | String path = tempFile.getAbsolutePath(); 28 | tempFile.delete(); 29 | return path; 30 | } 31 | 32 | public static void setCustomReader(ApiDocumentMojo mojo, String location) { 33 | for (ApiSource apiSource : mojo.getApiSources()) { 34 | apiSource.setSwaggerApiReader(location); 35 | } 36 | } 37 | 38 | public static void changeDescription(JsonNode root, String text) { 39 | JsonNode node = root.path("info"); 40 | ((ObjectNode) node).put("description", text); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/AbstractDocumentSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource; 4 | import com.github.kongchen.swagger.docgen.reader.AbstractReader; 5 | import com.github.kongchen.swagger.docgen.reader.ClassSwaggerReader; 6 | import io.swagger.models.ExternalDocs; 7 | import io.swagger.models.Info; 8 | import io.swagger.models.Path; 9 | import io.swagger.models.Swagger; 10 | import org.apache.maven.plugin.MojoFailureException; 11 | import org.apache.maven.plugin.logging.Log; 12 | import org.mockito.Mock; 13 | import org.mockito.MockitoAnnotations; 14 | import org.testng.annotations.BeforeMethod; 15 | import org.testng.annotations.Test; 16 | 17 | import java.io.File; 18 | import java.net.URI; 19 | import java.net.URISyntaxException; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import static org.hamcrest.CoreMatchers.*; 24 | import static org.hamcrest.MatcherAssert.assertThat; 25 | import static org.mockito.Mockito.when; 26 | 27 | public class AbstractDocumentSourceTest { 28 | @Mock 29 | private Log log; 30 | @Mock 31 | private ApiSource apiSource; 32 | 33 | private AbstractDocumentSource source; 34 | 35 | @BeforeMethod 36 | public void setUp() throws MojoFailureException { 37 | MockitoAnnotations.initMocks(this); 38 | source = new AbstractDocumentSource(log, apiSource, null) { 39 | @Override 40 | protected ClassSwaggerReader resolveApiReader() throws GenerateException { 41 | return null; 42 | } 43 | 44 | @Override 45 | protected AbstractReader createReader() { 46 | return null; 47 | } 48 | }; 49 | } 50 | 51 | @Test 52 | public void removeBasePathFromEndpoints() { 53 | // arrange 54 | Swagger swagger = new Swagger(); 55 | Map pathMap = new HashMap(); 56 | pathMap.put("/a/b/c", new Path()); 57 | swagger.setPaths(pathMap); 58 | swagger.setBasePath("/a/b"); 59 | 60 | // act 61 | Swagger result = source.removeBasePathFromEndpoints(swagger, true); 62 | 63 | // assert 64 | assertThat(result.getPath("/c"), notNullValue()); 65 | assertThat(result.getPath("/a/b/c"), nullValue()); 66 | } 67 | 68 | @Test 69 | public void testExternalDocsGetAdded() throws MojoFailureException { 70 | // arrange 71 | when(apiSource.getExternalDocs()).thenReturn(new ExternalDocs("Example external docs", "https://example.com/docs")); 72 | 73 | // act 74 | AbstractDocumentSource externalDocsSource = new AbstractDocumentSource(log, apiSource, null) { 75 | @Override 76 | protected ClassSwaggerReader resolveApiReader() throws GenerateException { 77 | return null; 78 | } 79 | 80 | @Override 81 | protected AbstractReader createReader() { 82 | return null; 83 | } 84 | }; 85 | 86 | // assert 87 | assertThat(externalDocsSource.swagger.getExternalDocs(), notNullValue()); 88 | assertThat(externalDocsSource.swagger.getExternalDocs().getDescription(), equalTo("Example external docs")); 89 | assertThat(externalDocsSource.swagger.getExternalDocs().getUrl(), equalTo("https://example.com/docs")); 90 | } 91 | 92 | @Test 93 | public void testAddDescriptionFile() throws URISyntaxException, MojoFailureException { 94 | 95 | // arrange 96 | URI fileUri = this.getClass().getResource("descriptionFile.txt").toURI(); 97 | File descriptionFile = new File(fileUri); 98 | 99 | when(apiSource.getDescriptionFile()).thenReturn(descriptionFile); 100 | when(apiSource.getInfo()).thenReturn(new Info()); 101 | 102 | // act 103 | AbstractDocumentSource externalDocsSource = new AbstractDocumentSource(log, apiSource, "UTF-8") { 104 | @Override 105 | protected ClassSwaggerReader resolveApiReader() throws GenerateException { 106 | return null; 107 | } 108 | 109 | @Override 110 | protected AbstractReader createReader() { 111 | return null; 112 | } 113 | }; 114 | 115 | // assert 116 | assertThat(externalDocsSource.swagger.getInfo().getDescription(), is("Description file content\n")); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/IncludedSwaggerExtensionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen; 2 | 3 | import com.github.kongchen.swagger.docgen.jaxrs.BeanParamInjectParamExtension; 4 | import com.github.kongchen.swagger.docgen.jaxrs.JaxrsParameterExtension; 5 | import com.github.kongchen.swagger.docgen.reader.JaxrsReader; 6 | import com.github.kongchen.swagger.docgen.spring.SpringSwaggerExtension; 7 | import com.google.common.collect.Lists; 8 | import io.swagger.jaxrs.ext.AbstractSwaggerExtension; 9 | import io.swagger.jaxrs.ext.SwaggerExtension; 10 | import io.swagger.models.parameters.Parameter; 11 | import org.apache.maven.plugin.logging.SystemStreamLog; 12 | import org.testng.annotations.Test; 13 | 14 | import java.lang.annotation.Annotation; 15 | import java.lang.reflect.Type; 16 | import java.util.*; 17 | 18 | import static org.mockito.Mockito.*; 19 | 20 | /** 21 | * Test class which ensures common functionality across all of the currently included Swagger Extensions, namely

22 | *
    23 | *
  • @{@link com.github.kongchen.swagger.docgen.spring.SpringSwaggerExtension}
  • 24 | *
  • {@link com.github.kongchen.swagger.docgen.jaxrs.JaxrsParameterExtension}
  • 25 | *
  • {@link BeanParamInjectParamExtension}
  • 26 | *
27 | * 28 | */ 29 | public class IncludedSwaggerExtensionTest { 30 | private static final List SWAGGER_EXTENSIONS = Lists.newArrayList(); 31 | 32 | static { 33 | //TODO: Maybe use a Classpath Scanner to automatically figure out the included extensions? 34 | SWAGGER_EXTENSIONS.add(new JaxrsParameterExtension()); 35 | SWAGGER_EXTENSIONS.add(new SpringSwaggerExtension(new SystemStreamLog())); 36 | SWAGGER_EXTENSIONS.add(new BeanParamInjectParamExtension(mock(JaxrsReader.class))); 37 | } 38 | 39 | @Test 40 | /** 41 | * This tests acts more like an integration test than a real unit test. It tests whether the extensions return 42 | * generally correct values. 43 | */ 44 | public void testExtractParametersReturnsEmptyList() { 45 | for (AbstractSwaggerExtension swaggerExtension : SWAGGER_EXTENSIONS) { 46 | Set typesToSkip = Collections.emptySet(); 47 | List annotations = Lists.newArrayList(AnnotationBearer.class.getAnnotation(Deprecated.class)); 48 | AbstractSwaggerExtension extension = mock(AbstractSwaggerExtension.class, CALLS_REAL_METHODS); 49 | doReturn(new ArrayList()).when(extension).extractParameters(any(), any(), any(), any()); 50 | 51 | Iterator iterator = Lists.newArrayList(extension).iterator(); 52 | 53 | // Not possible to add any parameters for the extensions, since no annotation / field is given to the extensions 54 | // only the previously created mock AbstractSwaggerExtension is in the chain 55 | // This allows to test if first the chain is called, and only then empty, modifiable lists are returned as last resort 56 | List parameters = swaggerExtension.extractParameters( 57 | annotations, 58 | Void.class, 59 | typesToSkip, 60 | iterator); 61 | // Has to return a collection we can later modify. 62 | try { 63 | parameters.add(null); 64 | } catch (Exception e) { 65 | throw new IllegalStateException("Extension "+ swaggerExtension.getClass().getName() + " did not return a modifiable list.", e); 66 | } 67 | 68 | // Test if the next extension in the chain was called 69 | try { 70 | verify(extension).extractParameters( 71 | anyListOf(Annotation.class), 72 | any(Type.class), 73 | anySetOf(Type.class), 74 | eq(iterator) 75 | ); 76 | } catch (Throwable t) { 77 | // Catch everything here. 78 | // We need to output the currently tested extension here 79 | // so that the reason why the test failed can be easier recognized later on 80 | // Still need to rethrow the exception though, to make the test fail 81 | 82 | // TODO: Is there any better wrapper exception type? 83 | throw new IllegalStateException("Extension "+ swaggerExtension.getClass().getName() + " failed this Test.", t); 84 | } 85 | } 86 | } 87 | 88 | // Class specificly for holding default value annotations 89 | @Deprecated 90 | private static class AnnotationBearer { 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/jaxrs/JaxrsParameterExtensionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.jaxrs; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.google.common.collect.Sets; 5 | import io.swagger.jaxrs.ext.SwaggerExtension; 6 | import io.swagger.models.parameters.AbstractSerializableParameter; 7 | import io.swagger.models.parameters.Parameter; 8 | import org.apache.commons.lang3.reflect.MethodUtils; 9 | import org.testng.annotations.Test; 10 | 11 | import javax.ws.rs.DefaultValue; 12 | import javax.ws.rs.QueryParam; 13 | import java.lang.annotation.Annotation; 14 | import java.lang.reflect.Type; 15 | import java.util.List; 16 | 17 | import static org.testng.Assert.assertEquals; 18 | import static org.testng.Assert.assertFalse; 19 | 20 | public class JaxrsParameterExtensionTest { 21 | @Test 22 | public void testExtractParametersReturnsRetrievedParameters() { 23 | List parameters = new JaxrsParameterExtension().extractParameters( 24 | Lists.newArrayList(getTestAnnotation("get", QueryParam.class)), 25 | String.class, 26 | Sets.newHashSet(), 27 | Lists.newArrayList().iterator()); 28 | 29 | assertFalse(parameters.isEmpty()); 30 | assertEquals(parameters.size(), 1); 31 | } 32 | 33 | 34 | private Annotation getTestAnnotation(String name, Class wantedAnnotation) { 35 | return MethodUtils.getMatchingMethod(SomeResource.class, name, String.class).getAnnotation(wantedAnnotation); 36 | } 37 | 38 | @Test 39 | public void testParameterDefaultValue() { 40 | List parameters = new JaxrsParameterExtension().extractParameters( 41 | Lists.newArrayList( 42 | getTestAnnotation("getWithDefault", QueryParam.class), 43 | getTestAnnotation("getWithDefault", DefaultValue.class) 44 | ), 45 | String.class, 46 | Sets.newHashSet(), 47 | Lists.newArrayList().iterator()); 48 | 49 | assertFalse(parameters.isEmpty()); 50 | assertEquals(parameters.size(), 1); 51 | 52 | Parameter extracted = parameters.get(0); 53 | assertEquals(((AbstractSerializableParameter)extracted).getDefaultValue(), "en-US"); 54 | } 55 | 56 | private static class SomeResource { 57 | @QueryParam("lang") 58 | public void get(String lang) { 59 | // no implementation needed. Method is only for the test cases, so that the annotation QueryParam 60 | // can easily be retrieved and used 61 | } 62 | 63 | @QueryParam("lang") 64 | @DefaultValue("en-US") 65 | public void getWithDefault(String lang) { 66 | // Needed for testing default values with jaxrs 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/mavenplugin/ApiSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | import com.google.common.collect.Sets; 4 | import io.swagger.annotations.Extension; 5 | import io.swagger.annotations.ExtensionProperty; 6 | import io.swagger.annotations.SwaggerDefinition; 7 | import io.swagger.models.ExternalDocs; 8 | import io.swagger.models.Info; 9 | import org.mockito.MockitoAnnotations; 10 | import org.testng.Assert; 11 | import org.testng.annotations.BeforeMethod; 12 | import org.testng.annotations.Test; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | import java.util.Set; 17 | 18 | import static org.mockito.Mockito.spy; 19 | import static org.mockito.Mockito.when; 20 | 21 | public class ApiSourceTest { 22 | 23 | @BeforeMethod 24 | public void setUp() { 25 | MockitoAnnotations.initMocks(this); 26 | } 27 | 28 | @Test 29 | public void testGetExternalDocsNoneFound() { 30 | // given 31 | @SwaggerDefinition 32 | class TestClassNoExternalDocs { } 33 | 34 | ApiSource apiSource = spy(ApiSource.class); 35 | when(apiSource.getValidClasses(SwaggerDefinition.class)).thenReturn(Sets.newHashSet(TestClassNoExternalDocs.class)); 36 | 37 | // when 38 | ExternalDocs externalDocs = apiSource.getExternalDocs(); 39 | 40 | // then 41 | Assert.assertNull(externalDocs); 42 | } 43 | 44 | @Test 45 | public void testGetExternalDocsFound() { 46 | // given 47 | @SwaggerDefinition(externalDocs = @io.swagger.annotations.ExternalDocs(value = "Example external docs", url = "https://example.com/docs")) 48 | class TestClassExternalDocs { } 49 | 50 | ApiSource apiSource = spy(ApiSource.class); 51 | when(apiSource.getValidClasses(SwaggerDefinition.class)).thenReturn(Sets.newHashSet(TestClassExternalDocs.class)); 52 | 53 | // when 54 | ExternalDocs externalDocs = apiSource.getExternalDocs(); 55 | 56 | // then 57 | Assert.assertNotNull(externalDocs); 58 | Assert.assertEquals(externalDocs.getDescription(), "Example external docs"); 59 | Assert.assertEquals(externalDocs.getUrl(), "https://example.com/docs"); 60 | } 61 | 62 | @Test 63 | public void testGetInfo0VendorExtensions() { 64 | Map logo = new HashMap(); 65 | logo.put("logo", "logo url"); 66 | logo.put("description", "This is our logo."); 67 | 68 | Map website = new HashMap(); 69 | website.put("website", "website url"); 70 | website.put("description", "This is our website."); 71 | 72 | Map expectedExtensions = new HashMap(); 73 | expectedExtensions.put("x-logo", logo); 74 | expectedExtensions.put("x-website", website); 75 | 76 | 77 | Set> validClasses = Sets.newHashSet(ApiSourceTestClass.class); 78 | ApiSource apiSource = spy(ApiSource.class); 79 | 80 | when(apiSource.getValidClasses(SwaggerDefinition.class)).thenReturn(validClasses); 81 | Info info = apiSource.getInfo(); 82 | 83 | Map vendorExtensions = info.getVendorExtensions(); 84 | Assert.assertEquals(vendorExtensions.size(), 2); 85 | Assert.assertEquals(vendorExtensions, expectedExtensions); 86 | } 87 | 88 | @SwaggerDefinition(info = @io.swagger.annotations.Info( 89 | title = "ApiSourceTestClass", 90 | version = "1.0.0", 91 | extensions = { 92 | @Extension(name = "logo", properties = { 93 | @ExtensionProperty(name = "logo", value = "logo url"), 94 | @ExtensionProperty(name = "description", value = "This is our logo.") 95 | }), 96 | @Extension(name = "website", properties = { 97 | @ExtensionProperty(name = "website", value = "website url"), 98 | @ExtensionProperty(name = "description", value = "This is our website.") 99 | }) 100 | } 101 | )) 102 | private static class ApiSourceTestClass { 103 | 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/mavenplugin/SecurityDefinitionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | import com.github.kongchen.swagger.docgen.GenerateException; 4 | import io.swagger.models.auth.ApiKeyAuthDefinition; 5 | import io.swagger.models.auth.OAuth2Definition; 6 | import io.swagger.models.auth.SecuritySchemeDefinition; 7 | import org.testng.Assert; 8 | import org.testng.annotations.Test; 9 | 10 | import java.util.Map; 11 | 12 | public class SecurityDefinitionTest { 13 | @Test 14 | public void testSecurityDefinitionRetainsWantedName() throws GenerateException { 15 | SecurityDefinition definition = new SecurityDefinition(); 16 | definition.setJson("securityDefinition.json"); 17 | 18 | Map definitions = definition.generateSecuritySchemeDefinitions(); 19 | 20 | SecuritySchemeDefinition api_key = definitions.get("api_key"); 21 | Assert.assertNotNull(api_key); 22 | Assert.assertTrue(api_key instanceof ApiKeyAuthDefinition); 23 | Assert.assertEquals(((ApiKeyAuthDefinition)api_key).getName(), "api_key_name"); 24 | 25 | // No name is set for this auth 26 | // The name should be set to the name of the definition 27 | // So that the name is never actually empty 28 | SecuritySchemeDefinition api_key_empty_name = definitions.get("api_key_empty_name"); 29 | Assert.assertNotNull(api_key_empty_name); 30 | Assert.assertTrue(api_key_empty_name instanceof ApiKeyAuthDefinition); 31 | Assert.assertEquals(((ApiKeyAuthDefinition)api_key_empty_name).getName(), "api_key_empty_name"); 32 | 33 | 34 | SecuritySchemeDefinition petstore_auth = definitions.get("petstore_auth"); 35 | Assert.assertNotNull(petstore_auth); 36 | Assert.assertTrue(petstore_auth instanceof OAuth2Definition); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/mavenplugin/SpringMavenDocumentSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.mavenplugin; 2 | 3 | import java.util.Collections; 4 | import java.util.Set; 5 | 6 | import org.apache.maven.plugin.logging.Log; 7 | import org.apache.maven.plugin.logging.SystemStreamLog; 8 | import org.springframework.web.bind.annotation.RestController; 9 | import org.testng.Assert; 10 | import org.testng.annotations.Test; 11 | 12 | import io.swagger.annotations.Api; 13 | 14 | public class SpringMavenDocumentSourceTest 15 | { 16 | @Test 17 | public void testGetValidClasses() throws Exception 18 | { 19 | Log log = new SystemStreamLog(); 20 | 21 | ApiSource apiSource = new ApiSource(); 22 | apiSource.setLocations(Collections.singletonList(this.getClass().getPackage().getName())); 23 | apiSource.setSwaggerDirectory("./"); 24 | 25 | SpringMavenDocumentSource springMavenDocumentSource = new SpringMavenDocumentSource(apiSource, log, "UTF-8"); 26 | 27 | Set> validClasses = springMavenDocumentSource.getValidClasses(); 28 | 29 | Assert.assertEquals(validClasses.size(), 2); 30 | Assert.assertTrue(validClasses.contains(ExampleController1.class)); 31 | Assert.assertTrue(validClasses.contains(ExampleController2.class)); 32 | } 33 | 34 | 35 | @RestController 36 | private static class ExampleController1 37 | { 38 | } 39 | 40 | @Api 41 | @RestController 42 | private static class ExampleController2 43 | { 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/reader/ModelModifierTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import com.fasterxml.jackson.databind.JavaType; 4 | import com.fasterxml.jackson.databind.type.SimpleType; 5 | import io.swagger.annotations.ApiModelProperty; 6 | import io.swagger.converter.ModelConverter; 7 | import io.swagger.converter.ModelConverterContext; 8 | import io.swagger.converter.ModelConverterContextImpl; 9 | import io.swagger.models.ArrayModel; 10 | import io.swagger.models.Model; 11 | import io.swagger.models.properties.Property; 12 | import io.swagger.models.properties.StringProperty; 13 | import io.swagger.util.Json; 14 | import org.testng.Assert; 15 | import org.testng.annotations.Test; 16 | 17 | import java.lang.annotation.Annotation; 18 | import java.lang.reflect.Type; 19 | import java.util.Arrays; 20 | import java.util.HashMap; 21 | import java.util.Iterator; 22 | import java.util.Map; 23 | 24 | /** 25 | * Created by mkosiorek on 25.04.17. 26 | */ 27 | public class ModelModifierTest { 28 | 29 | @Test 30 | public void testProcessFieldInParentClass() throws Exception { 31 | ModelModifier modelModifier = new ModelModifier(Json.mapper()); 32 | modelModifier.setApiModelPropertyAccessExclusions(Arrays.asList("public")); 33 | 34 | JavaType type = SimpleType.constructUnsafe(B.class); 35 | ModelConverterContext context = new ModelConverterContextImpl(new ModelConverter() { 36 | @Override 37 | public Property resolveProperty(Type type, ModelConverterContext modelConverterContext, Annotation[] annotations, Iterator iterator) { 38 | return null; 39 | } 40 | 41 | @Override 42 | public Model resolve(Type type, ModelConverterContext modelConverterContext, Iterator iterator) { 43 | ArrayModel model = new ArrayModel(); 44 | Map properties = new HashMap(); 45 | properties.put("sample1", new StringProperty()); 46 | properties.put("sample2", new StringProperty()); 47 | model.setProperties(properties); 48 | return model; 49 | } 50 | }); 51 | Iterator chain = null; 52 | Model model = modelModifier.resolve(type, context, chain); 53 | Assert.assertFalse(model.getProperties().containsKey("sample1")); 54 | Assert.assertTrue(model.getProperties().containsKey("sample2")); 55 | } 56 | 57 | static class A { 58 | 59 | @ApiModelProperty(name = "sample1", access = "public") 60 | private String sample1; 61 | 62 | @ApiModelProperty(name = "sample2", access = "other") 63 | private String sample2; 64 | } 65 | 66 | static class B extends A { 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/reader/SpringExceptionHandlerReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import org.apache.maven.plugin.logging.Log; 4 | import org.hamcrest.FeatureMatcher; 5 | import org.hamcrest.Matcher; 6 | import org.mockito.Mock; 7 | import org.mockito.MockitoAnnotations; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.ControllerAdvice; 11 | import org.springframework.web.bind.annotation.ExceptionHandler; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.ResponseStatus; 14 | import org.testng.annotations.BeforeMethod; 15 | import org.testng.annotations.Test; 16 | 17 | import java.util.HashSet; 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | import static org.hamcrest.MatcherAssert.assertThat; 22 | import static org.hamcrest.Matchers.equalTo; 23 | import static org.hamcrest.Matchers.hasItem; 24 | import static org.hamcrest.Matchers.hasSize; 25 | import static org.springframework.http.HttpStatus.LOCKED; 26 | import static org.springframework.http.HttpStatus.NOT_FOUND; 27 | import static org.springframework.http.HttpStatus.OK; 28 | import static org.springframework.web.bind.annotation.RequestMethod.GET; 29 | import static org.springframework.web.bind.annotation.RequestMethod.POST; 30 | import static org.springframework.web.bind.annotation.RequestMethod.PUT; 31 | 32 | public class SpringExceptionHandlerReaderTest { 33 | @Mock 34 | protected Log log; 35 | 36 | private SpringExceptionHandlerReader exceptionHandlerReader; 37 | 38 | @BeforeMethod 39 | public void setUp() { 40 | MockitoAnnotations.initMocks(this); 41 | exceptionHandlerReader = new SpringExceptionHandlerReader(log); 42 | } 43 | 44 | @Test 45 | public void getResponseStatusesFromExceptions() throws NoSuchMethodException { 46 | List result = exceptionHandlerReader.getResponseStatusesFromExceptions( 47 | this.getClass().getMethod("tryGetIt")); 48 | assertThat(result, hasItem(withValue(equalTo(NOT_FOUND)))); 49 | } 50 | 51 | @Test 52 | public void getResponseStatusesFromExceptionsReturnsEmptyList() throws NoSuchMethodException { 53 | List result = exceptionHandlerReader.getResponseStatusesFromExceptions( 54 | this.getClass().getMethod("safeToPost")); 55 | assertThat(result, hasSize(0)); 56 | } 57 | 58 | @Test 59 | public void getResponseStatusFromExceptionHandler() throws NoSuchMethodException { 60 | Set> classesToRead = new HashSet>(); 61 | classesToRead.add(CustomExceptionHandler.class); 62 | exceptionHandlerReader.processExceptionHandlers(classesToRead); 63 | List result = exceptionHandlerReader.getResponseStatusesFromExceptions( 64 | this.getClass().getMethod("overridenInHandler")); 65 | assertThat(result, hasItem(withValue(equalTo(LOCKED)))); 66 | } 67 | 68 | @RequestMapping(value = "/", method = GET) 69 | public ResponseEntity tryGetIt() throws NotFoundException { 70 | return new ResponseEntity(OK); 71 | } 72 | 73 | @RequestMapping(value = "/", method = POST) 74 | public ResponseEntity safeToPost() { 75 | return new ResponseEntity(OK); 76 | } 77 | 78 | @RequestMapping(value = "/", method = PUT) 79 | public ResponseEntity overridenInHandler() throws OverridenInHandlerException { 80 | return null; 81 | } 82 | 83 | @ControllerAdvice 84 | class CustomExceptionHandler { 85 | @ExceptionHandler(OverridenInHandlerException.class) 86 | @ResponseStatus(LOCKED) 87 | public void handle(OverridenInHandlerException exception) { 88 | } 89 | } 90 | 91 | @ResponseStatus(NOT_FOUND) 92 | class NotFoundException extends Exception { 93 | } 94 | 95 | @ResponseStatus(OK) 96 | class OverridenInHandlerException extends Exception { 97 | } 98 | 99 | private static Matcher withValue(Matcher submatcher) { 100 | return new FeatureMatcher(submatcher, "", "") { 101 | @Override 102 | protected HttpStatus featureValueOf(ResponseStatus responseStatus) { 103 | return responseStatus.value(); 104 | } 105 | }; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/reader/SpringMvcApiReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.reader; 2 | 3 | import com.github.kongchen.swagger.docgen.GenerateException; 4 | import com.github.kongchen.swagger.docgen.spring.SpringResource; 5 | import io.swagger.models.Swagger; 6 | import org.apache.maven.monitor.logging.DefaultLog; 7 | import org.apache.maven.plugin.logging.Log; 8 | import org.codehaus.plexus.logging.console.ConsoleLogger; 9 | import org.codehaus.plexus.logging.console.ConsoleLoggerManager; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.testng.annotations.Test; 13 | import org.codehaus.plexus.logging.Logger; 14 | 15 | import java.util.Collections; 16 | import java.util.Map; 17 | import java.util.Set; 18 | 19 | import static org.testng.AssertJUnit.assertEquals; 20 | 21 | public class SpringMvcApiReaderTest { 22 | 23 | @Test 24 | public void testMethodsInheritingPathFromClassLevelRequestMapping() throws GenerateException { 25 | Swagger swagger = new Swagger(); 26 | SpringMvcApiReader reader = new SpringMvcApiReader(swagger, null); 27 | Set> classes = Collections.singleton( SomeResourceWithClassOnlyPaths.class ); 28 | Map resourceMap = reader.generateResourceMap(classes); 29 | assertEquals(3, resourceMap.size()); 30 | } 31 | 32 | @RequestMapping("/some/path") 33 | private static class SomeResourceWithClassOnlyPaths { 34 | 35 | // GET /some/path (explicit value="") 36 | @RequestMapping(value="", method=RequestMethod.GET) 37 | public String get() { return null; } 38 | 39 | // POST /some/path (value=null) 40 | @RequestMapping(method=RequestMethod.POST) 41 | public void post() { } 42 | 43 | // GET /some/path/search 44 | @RequestMapping(value="/search", method=RequestMethod.GET) 45 | public String search() { return null; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/github/kongchen/swagger/docgen/spring/SpringSwaggerExtensionTest.java: -------------------------------------------------------------------------------- 1 | package com.github.kongchen.swagger.docgen.spring; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.google.common.collect.Sets; 5 | import com.wordnik.sample.model.PaginationHelper; 6 | import io.swagger.jaxrs.ext.SwaggerExtension; 7 | import io.swagger.models.parameters.Parameter; 8 | import org.apache.commons.lang3.reflect.MethodUtils; 9 | import org.apache.maven.plugin.logging.SystemStreamLog; 10 | import org.springframework.web.bind.annotation.ModelAttribute; 11 | import org.testng.annotations.Test; 12 | 13 | import java.lang.annotation.Annotation; 14 | import java.lang.reflect.Type; 15 | import java.util.List; 16 | 17 | import static org.testng.Assert.assertEquals; 18 | 19 | public class SpringSwaggerExtensionTest { 20 | @Test 21 | public void testExtractParametersReturnsRetrievedParameters() { 22 | List parameters = new SpringSwaggerExtension(new SystemStreamLog()).extractParameters( 23 | Lists.newArrayList(getTestAnnotation()), 24 | PaginationHelper.class, 25 | Sets.newHashSet(), 26 | Lists.newArrayList().iterator()); 27 | 28 | assertEquals(parameters.size(), 2); 29 | } 30 | 31 | @Test 32 | public void testExtractParametersNoModelAttributeAnnotation() { 33 | List parameters = new SpringSwaggerExtension(new SystemStreamLog()).extractParameters( 34 | Lists.newArrayList(), 35 | PaginationHelper.class, 36 | Sets.newHashSet(), 37 | Lists.newArrayList().iterator()); 38 | 39 | assertEquals(parameters.size(), 2); 40 | } 41 | 42 | private Annotation getTestAnnotation() { 43 | return MethodUtils.getMethodsWithAnnotation(SpringSwaggerExtensionTest.SomeResource.class, ModelAttribute.class)[0].getAnnotation(ModelAttribute.class); 44 | } 45 | 46 | private static class SomeResource { 47 | @ModelAttribute 48 | public void get() { 49 | // no implementation needed. Method is only for the test cases, so that the annotation ModelAttribute 50 | // can easily be retrieved and used 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/CustomJaxrsReader.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import io.swagger.models.Swagger; 4 | import org.apache.maven.plugin.logging.Log; 5 | 6 | import java.util.Set; 7 | 8 | /** 9 | * @author Igor Gursky 10 | * 11.12.2015. 11 | */ 12 | public class CustomJaxrsReader extends VendorExtensionsJaxrsReader { 13 | 14 | public CustomJaxrsReader(Swagger swagger, Log LOG) { 15 | super(swagger, LOG); 16 | } 17 | 18 | @Override 19 | public Swagger read(Set> classes) { 20 | Swagger swagger = super.read(classes); 21 | swagger.getInfo().setDescription("Processed with CustomJaxrsReader"); 22 | return swagger; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyBean.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import io.swagger.annotations.ApiParam; 4 | 5 | import javax.validation.constraints.Max; 6 | import javax.validation.constraints.Min; 7 | import javax.validation.constraints.NotNull; 8 | import javax.validation.constraints.Pattern; 9 | import javax.ws.rs.*; 10 | import java.util.List; 11 | 12 | /** 13 | * @author chekong on 15/5/9. 14 | */ 15 | public class MyBean extends MyParentBean { 16 | 17 | @ApiParam(value = "ID of pet that needs to be updated", required = true) 18 | @PathParam("petId") 19 | private String petId; 20 | 21 | @ApiParam(value = "Updated name of the pet", required = false, defaultValue = "defaultValue") 22 | @FormParam("name") 23 | private String name; 24 | 25 | @ApiParam(value = "Updated status of the pet", required = false, allowableValues = "value1, value2") 26 | @FormParam("status") 27 | private String status; 28 | 29 | @HeaderParam("myHeader") 30 | private String myHeader; 31 | 32 | @HeaderParam("intValue") 33 | private int intValue; 34 | 35 | @ApiParam(value = "hidden", hidden = true) 36 | @QueryParam(value = "hiddenValue") 37 | private String hiddenValue; 38 | 39 | @QueryParam(value = "listValue") 40 | private List listValue; 41 | 42 | @BeanParam 43 | private MyNestedBean nestedBean; 44 | 45 | /** 46 | * This field is to test that bean params using constructor injection behave 47 | * correctly. It's also nested just to avoid adding too much test code. 48 | */ 49 | @BeanParam 50 | private MyConstructorInjectedNestedBean constructorInjectedNestedBean; 51 | 52 | @ApiParam(value = "testIntegerAllowableValues", defaultValue = "25", allowableValues = "25, 50, 100") 53 | @QueryParam("testIntegerAllowableValues") 54 | public Integer testIntegerAllowableValues; 55 | 56 | /** 57 | * This field's allowableValues, required, pattern, and defaultValue should 58 | * be derived based on its JAX-RS and validation annotations. 59 | */ 60 | @QueryParam("constrainedField") 61 | @Min(25L) 62 | @Max(75L) 63 | @NotNull 64 | @Pattern(regexp = "[0-9]5") 65 | @DefaultValue("55") 66 | private int constrainedField; 67 | 68 | public String getMyheader() { 69 | return myHeader; 70 | } 71 | 72 | public void setmyHeader(String myHeader) { 73 | this.myHeader = myHeader; 74 | } 75 | 76 | public String getPetId() { 77 | return petId; 78 | } 79 | 80 | public void setPetId(String petId) { 81 | this.petId = petId; 82 | } 83 | 84 | public String getName() { 85 | return name; 86 | } 87 | 88 | public void setName(String name) { 89 | this.name = name; 90 | } 91 | 92 | public String getStatus() { 93 | return status; 94 | } 95 | 96 | public void setStatus(String status) { 97 | this.status = status; 98 | } 99 | 100 | public int getIntValue() { 101 | return intValue; 102 | } 103 | 104 | public void setIntValue(int intValue) { 105 | this.intValue = intValue; 106 | } 107 | 108 | public List getListValue() { 109 | return listValue; 110 | } 111 | 112 | public void setListValue(List listValue) { 113 | this.listValue = listValue; 114 | } 115 | 116 | public MyNestedBean getNestedBean() { 117 | return nestedBean; 118 | } 119 | 120 | public void setNestedBean(MyNestedBean nestedBean) { 121 | this.nestedBean = nestedBean; 122 | } 123 | 124 | public MyConstructorInjectedNestedBean getConstructorInjectedNestedBean() { 125 | return constructorInjectedNestedBean; 126 | } 127 | 128 | public void setConstructorInjectedNestedBean(MyConstructorInjectedNestedBean constructorInjectedNestedBean) { 129 | this.constructorInjectedNestedBean = constructorInjectedNestedBean; 130 | } 131 | 132 | public int getConstrainedField() { 133 | return constrainedField; 134 | } 135 | 136 | public void setConstrainedField(int constrainedField) { 137 | this.constrainedField = constrainedField; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyConstructorInjectedNestedBean.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import javax.ws.rs.DefaultValue; 4 | import javax.ws.rs.HeaderParam; 5 | 6 | import io.swagger.annotations.ApiParam; 7 | 8 | /** 9 | * Represents a nested {@code @BeanParam} target that is injected by constructor. 10 | * 11 | * @see MyNestedBean 12 | */ 13 | public class MyConstructorInjectedNestedBean { 14 | 15 | /** 16 | * Note: this property will not be found by 17 | * {@link com.github.kongchen.swagger.docgen.reader.SwaggerReader}, which 18 | * seems to be a limitation of {@link io.swagger.jaxrs.Reader} itself. 19 | */ 20 | private final String constructorInjectedHeader; 21 | 22 | // @Inject would typically go here in real life, telling e.g. Jersey to use constructor injection 23 | public MyConstructorInjectedNestedBean( 24 | @ApiParam("Header injected at constructor") 25 | @HeaderParam("constructorInjectedHeader") 26 | @DefaultValue("foo") 27 | String constructorInjectedHeader 28 | ) { 29 | this.constructorInjectedHeader = constructorInjectedHeader; 30 | } 31 | 32 | public String getConstructorInjectedHeader() { 33 | return constructorInjectedHeader; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyNestedBean.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import javax.ws.rs.HeaderParam; 4 | 5 | import io.swagger.annotations.ApiParam; 6 | 7 | /** 8 | * Represents a {@code @BeanParam} target that is nested within another bean. 9 | */ 10 | public class MyNestedBean { 11 | 12 | @ApiParam("Header from nested bean") 13 | @HeaderParam("myNestedBeanHeader") 14 | private String myNestedBeanHeader; 15 | 16 | public String getMyNestedBeanHeader() { 17 | return myNestedBeanHeader; 18 | } 19 | 20 | public void setMyNestedBeanHeader(String myNestedBeanHeader) { 21 | this.myNestedBeanHeader = myNestedBeanHeader; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyParentBean.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import io.swagger.annotations.ApiParam; 4 | 5 | import javax.ws.rs.HeaderParam; 6 | 7 | /** 8 | * @author Vinayak Hulawale [vinhulawale@gmail.com] 9 | */ 10 | public class MyParentBean { 11 | 12 | @ApiParam(value = "Header from parent", required = false) 13 | @HeaderParam("myParentHeader") 14 | private String myParentheader; 15 | 16 | public String getMyParentheader() { 17 | return myParentheader; 18 | } 19 | 20 | public void setMyParentheader(String myParentheader) { 21 | this.myParentheader = myParentheader; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.wordnik.sample.model.ListItem; 4 | import com.wordnik.sample.model.Pet; 5 | import io.swagger.annotations.*; 6 | 7 | import javax.ws.rs.GET; 8 | import javax.ws.rs.PathParam; 9 | import javax.ws.rs.Produces; 10 | import javax.ws.rs.QueryParam; 11 | import javax.ws.rs.core.Response; 12 | import java.util.List; 13 | 14 | @Api(description = "Operations about pets") 15 | @Produces({"application/json", "application/xml"}) 16 | public interface MyResource { 17 | 18 | //contrived example test case for swagger-maven-plugin issue #358 19 | @GET 20 | @ApiOperation(value = "Find pet(s) by ID", 21 | notes = "This is a contrived example", 22 | response = Pet.class 23 | ) 24 | @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid ID supplied"), 25 | @ApiResponse(code = 404, message = "Pet not found")}) 26 | public abstract Response getPetsById( 27 | @ApiParam(value = "start ID of pets that need to be fetched", allowableValues = "range[1,99]", required = true) 28 | @QueryParam("startId") Long startId, 29 | @ApiParam(value = "end ID of pets that need to be fetched", allowableValues = "range[1,99]", required = true) 30 | @QueryParam("endId") Long endId) 31 | throws com.wordnik.sample.exception.NotFoundException; 32 | 33 | //contrived example test case for swagger-maven-plugin issue #505 34 | @GET 35 | @ApiOperation(value = "Get a list of items", 36 | notes = "This is a contrived example" 37 | ) 38 | public abstract List getListOfItems(); 39 | 40 | //contrived example test case for swagger-maven-plugin issue #504 41 | @GET 42 | @ApiOperation(value = "Get a response", notes = "This is a contrived example") 43 | Response testParamInheritance( 44 | @PathParam("firstParamInterface") String firstParam, 45 | @PathParam("secondParamInterface") String secondParam, 46 | @QueryParam("thirdParamInterface") String thirdParam); 47 | 48 | Response insertResource(T resource); 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyResourceAbstract.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.wordnik.sample.exception.NotFoundException; 4 | import com.wordnik.sample.model.ListItem; 5 | import io.swagger.annotations.ApiParam; 6 | 7 | import javax.ws.rs.PathParam; 8 | import javax.ws.rs.QueryParam; 9 | import javax.ws.rs.core.Response; 10 | import java.util.List; 11 | 12 | /** 13 | * @author daniele.orler 14 | */ 15 | public abstract class MyResourceAbstract implements MyResource { 16 | @Override 17 | public abstract Response getPetsById(Long startId, Long endId) throws NotFoundException; 18 | 19 | @Override 20 | public abstract List getListOfItems(); 21 | 22 | @Override 23 | public abstract Response testParamInheritance( 24 | @PathParam("firstParamAbstract") String firstParam, 25 | @ApiParam(required = true) @QueryParam("secondParamAbstract") String secondParam, 26 | String thirdParam); 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/MyResourceImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.jaxrs; 18 | 19 | import com.wordnik.sample.JavaRestResourceUtil; 20 | import com.wordnik.sample.data.PetData; 21 | import com.wordnik.sample.model.ListItem; 22 | import com.wordnik.sample.model.Pet; 23 | 24 | import io.swagger.annotations.ApiOperation; 25 | import io.swagger.annotations.ApiParam; 26 | import javax.ws.rs.POST; 27 | import javax.ws.rs.Path; 28 | import javax.ws.rs.PathParam; 29 | import javax.ws.rs.core.Response; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | @Path("/myResourceImpl") 34 | public class MyResourceImpl extends MyResourceAbstract { 35 | static PetData petData = new PetData(); 36 | static JavaRestResourceUtil ru = new JavaRestResourceUtil(); 37 | 38 | //contrived example test case for swagger-maven-plugin issue #358 39 | /* (non-Javadoc) 40 | * @see com.wordnik.jaxrs.MyResource#getPetsById(java.lang.Long, java.lang.Long) 41 | */ 42 | @Override 43 | public Response getPetsById(Long startId, Long endId) 44 | throws com.wordnik.sample.exception.NotFoundException { 45 | Pet pet = petData.getPetbyId(startId); 46 | if (pet != null) { 47 | return Response.ok().entity(pet).build(); 48 | } else { 49 | throw new com.wordnik.sample.exception.NotFoundException(404, "Pet not found"); 50 | } 51 | } 52 | 53 | //contrived example test case for swagger-maven-plugin issue #505 54 | /* (non-Javadoc) 55 | * @see com.wordnik.jaxrs.MyResource#getListOfItems() 56 | */ 57 | @Path("list") 58 | @Override 59 | public List getListOfItems() { 60 | return new ArrayList(); 61 | } 62 | 63 | //contrived example test case for swagger-maven-plugin issue #504 64 | /* (non-Javadoc) 65 | * @see com.wordnik.jaxrs.MyResource#testParamInheritance(java.lang.String, java.lang.String, java.lang.String) 66 | */ 67 | @Path("{firstParamConcrete}/properties") 68 | @Override 69 | public Response testParamInheritance( 70 | @PathParam("firstParamConcrete") String firstParam, 71 | String secondParam, 72 | String thirdParam) { 73 | return Response.ok().build(); 74 | } 75 | 76 | @POST 77 | @ApiOperation(value = "Insert a response", notes = "This is a contrived example") 78 | @Override 79 | public Response insertResource(@ApiParam(value = "Resource to insert", required = true) String resource) { 80 | return Response.ok().build(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/PagedList.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import java.util.List; 4 | 5 | public class PagedList { 6 | 7 | private int pageNumber; 8 | private int totalItems; 9 | private List items; 10 | 11 | public PagedList(int pageNumber, int totalItems, List itemsOnPage) { 12 | this.pageNumber = pageNumber; 13 | this.totalItems = totalItems; 14 | this.items = itemsOnPage; 15 | } 16 | 17 | public int getPageNumber() { 18 | return pageNumber; 19 | } 20 | 21 | public int getTotalItems() { 22 | return totalItems; 23 | } 24 | 25 | public List getItems() { 26 | return items; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/ParentResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package com.wordnik.jaxrs; 7 | 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import javax.ws.rs.Path; 11 | 12 | /** 13 | * 14 | * @author pradeep.chaudhary 15 | */ 16 | @Path("/v1.0") 17 | @Api 18 | public class ParentResource { 19 | @Path("/sub") 20 | @ApiOperation(value="SubResource") 21 | public SubResource getStudyResource() { 22 | return new SubResource(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/RootPathResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import io.swagger.annotations.Api; 4 | import io.swagger.annotations.ApiOperation; 5 | 6 | import javax.ws.rs.GET; 7 | import javax.ws.rs.Path; 8 | 9 | /** 10 | * @author andrewb 11 | */ 12 | @Path("/") 13 | @Api(value = "/") 14 | public class RootPathResource { 15 | @GET 16 | @ApiOperation(value = "testingRootPathResource") 17 | public String testingRootPathResource() { 18 | return "testingRootPathResource"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/SubResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.wordnik.sample.model.User; 4 | import io.swagger.annotations.Api; 5 | import io.swagger.annotations.ApiOperation; 6 | import io.swagger.annotations.ApiParam; 7 | import io.swagger.annotations.ApiResponse; 8 | import io.swagger.annotations.ApiResponses; 9 | import io.swagger.annotations.Authorization; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | import javax.ws.rs.GET; 13 | import javax.ws.rs.PUT; 14 | import javax.ws.rs.Path; 15 | import javax.ws.rs.PathParam; 16 | import javax.ws.rs.Produces; 17 | import javax.ws.rs.core.MediaType; 18 | import javax.ws.rs.core.Response; 19 | 20 | /** 21 | * 22 | * @author pradeep.chaudhary 23 | */ 24 | @Produces(MediaType.APPLICATION_JSON) 25 | @Api(hidden=true, authorizations = {@Authorization(value="api_key")}, tags = {"Resource-V1"}) 26 | public class SubResource { 27 | 28 | @GET 29 | @ApiOperation(value="List of users",notes="Get user list") 30 | @ApiResponses(value = { 31 | @ApiResponse(code = 200, message = "Successful operation", response = List.class) 32 | }) 33 | public Response getUsers() { 34 | User john = new User(); 35 | john.setFirstName("John"); 36 | john.setEmail("john@testdomain.com"); 37 | 38 | User max = new User(); 39 | max.setFirstName("Max"); 40 | max.setEmail("max@testdomain.com"); 41 | 42 | return Response.ok(Arrays.asList(john, max)).build(); 43 | } 44 | 45 | @Path("/{username}") 46 | @GET 47 | @ApiOperation(value="Fetch a user by username") 48 | @ApiResponses(value = { 49 | @ApiResponse(code = 200, message = "Successful operation", response = User.class) 50 | }) 51 | public Response getUserByName(@ApiParam(value = "Username of user that needs to be fetched", required = true) 52 | @PathParam("username") String username) { 53 | User max = new User(); 54 | max.setFirstName("Max"); 55 | max.setEmail("max@testdomain.com"); 56 | max.setUsername("max"); 57 | 58 | return Response.ok(max).build(); 59 | } 60 | 61 | @PUT 62 | @ApiOperation(value="Update User") 63 | @ApiResponses(value = { 64 | @ApiResponse(code = 200, message = "Successful operation") 65 | }) 66 | public Response updateUser(@ApiParam(value = "User to be updated", required = true) User user) { 67 | return Response.ok().build(); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/SwaggerlessResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.wordnik.sample.model.Pet; 4 | import com.wordnik.sample.model.PetName; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | import javax.ws.rs.GET; 8 | import javax.ws.rs.Path; 9 | import javax.ws.rs.PathParam; 10 | import javax.ws.rs.QueryParam; 11 | 12 | @Path("/") 13 | public class SwaggerlessResource { 14 | 15 | @GET 16 | @Path("/swaggerless/{petId : [0-9]}") 17 | public Pet getPetByName(@PathParam(value = "name") String name) { 18 | // Just create and return a new pet 19 | Pet pet = new Pet(); 20 | pet.setName(new PetName(name)); 21 | return pet; 22 | } 23 | 24 | public Pet notAnEndpoint(@PathParam(value = "name") String name) { 25 | // Just create and return a new pet 26 | Pet pet = new Pet(); 27 | pet.setName(new PetName(name)); 28 | return pet; 29 | } 30 | 31 | @Path("/swaggerless") 32 | public Pet notAnEndpointWithPath(@RequestParam(value = "name") String name) { 33 | // Just create and return a new pet 34 | Pet pet = new Pet(); 35 | pet.setName(new PetName(name)); 36 | return pet; 37 | } 38 | 39 | @Path("/swaggerless/subresource") 40 | public SwaggerlessSubresource subresourceEndpoint() { 41 | return new SwaggerlessSubresource(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/SwaggerlessSubresource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.wordnik.sample.model.Pet; 4 | import com.wordnik.sample.model.PetName; 5 | 6 | import javax.ws.rs.GET; 7 | import javax.ws.rs.Path; 8 | import javax.ws.rs.PathParam; 9 | 10 | public class SwaggerlessSubresource { 11 | 12 | @GET 13 | @Path("/{name}") 14 | public Pet getPetByNameSubresource(@PathParam(value = "name") String name) { 15 | // Just create and return a new pet 16 | Pet pet = new Pet(); 17 | pet.setName(new PetName(name)); 18 | return pet; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/jaxrs/VendorExtensionsJaxrsReader.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.jaxrs; 2 | 3 | import com.github.kongchen.swagger.docgen.reader.JaxrsReader; 4 | import com.wordnik.sample.TestVendorExtension; 5 | import io.swagger.jaxrs.ext.SwaggerExtension; 6 | import io.swagger.jaxrs.ext.SwaggerExtensions; 7 | import io.swagger.models.Swagger; 8 | import org.apache.maven.plugin.logging.Log; 9 | 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | 13 | public class VendorExtensionsJaxrsReader extends JaxrsReader { 14 | 15 | public VendorExtensionsJaxrsReader(Swagger swagger, Log LOG) { 16 | super(swagger, LOG); 17 | 18 | List extensions = new LinkedList(SwaggerExtensions.getExtensions()); 19 | extensions.add(new TestVendorExtension()); 20 | SwaggerExtensions.setExtensions(extensions); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/JavaRestResourceUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample; 18 | 19 | import java.text.SimpleDateFormat; 20 | import java.util.Date; 21 | 22 | public class JavaRestResourceUtil { 23 | public int getInt(int minVal, int maxVal, int defaultValue, String inputString) { 24 | int output; 25 | try { 26 | output = Integer.parseInt(inputString); 27 | } catch (Exception e) { 28 | output = defaultValue; 29 | } 30 | 31 | if (output < minVal) { 32 | output = minVal; 33 | } 34 | if (maxVal == -1) { 35 | if (output < minVal) { 36 | output = minVal; 37 | } 38 | } else if (output > maxVal) { 39 | output = maxVal; 40 | } 41 | return output; 42 | } 43 | 44 | public long getLong(long minVal, long maxVal, long defaultValue, String inputString) { 45 | long output; 46 | try { 47 | output = Long.parseLong(inputString); 48 | } catch (Exception e) { 49 | output = defaultValue; 50 | } 51 | 52 | if (output < minVal) { 53 | output = minVal; 54 | } 55 | if (maxVal == -1) { 56 | if (output < minVal) { 57 | output = minVal; 58 | } 59 | } else if (output > maxVal) { 60 | output = maxVal; 61 | } 62 | return output; 63 | } 64 | 65 | public double getDouble(double minVal, double maxVal, double defaultValue, String inputString) { 66 | double output; 67 | try { 68 | output = Double.parseDouble(inputString); 69 | } catch (Exception e) { 70 | output = defaultValue; 71 | } 72 | 73 | if (output < minVal) { 74 | output = minVal; 75 | } 76 | if (maxVal == -1) { 77 | if (output < minVal) { 78 | output = minVal; 79 | } 80 | } else if (output > maxVal) { 81 | output = maxVal; 82 | } 83 | return output; 84 | } 85 | 86 | public boolean getBoolean(boolean defaultValue, String booleanString) { 87 | boolean output; 88 | 89 | // treat "", "YES" as "true" 90 | if ("".equals(booleanString) || "YES".equalsIgnoreCase(booleanString)) { 91 | output = true; 92 | } else if ("NO".equalsIgnoreCase(booleanString)) { 93 | output = false; 94 | } else { 95 | try { 96 | output = Boolean.parseBoolean(booleanString); 97 | } catch (Exception e) { 98 | output = defaultValue; 99 | } 100 | } 101 | return output; 102 | } 103 | 104 | public Date getDate(Date defaultValue, String dateString) { 105 | try { 106 | return new SimpleDateFormat("yyyy-MM-dd").parse(dateString); 107 | } catch (Exception e) { 108 | return defaultValue; 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/TestVendorExtension.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample; 2 | 3 | import io.swagger.jaxrs.ext.AbstractSwaggerExtension; 4 | import io.swagger.jaxrs.ext.SwaggerExtension; 5 | import io.swagger.models.Operation; 6 | import io.swagger.models.Response; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | import java.lang.reflect.Method; 13 | import java.util.HashMap; 14 | import java.util.Iterator; 15 | import java.util.Map; 16 | 17 | /** 18 | * @see com.wordnik.jaxrs.VendorExtensionsJaxrsReader 19 | * @see com.wordnik.springmvc.VendorExtensionsSpringMvcReader 20 | */ 21 | public class TestVendorExtension extends AbstractSwaggerExtension { 22 | 23 | private static final String RESPONSE_DESCRIPTION = "Some vendor error description"; 24 | 25 | private static final String RESPONSE_STATUS_401 = "401"; 26 | 27 | @Override 28 | public void decorateOperation(final Operation operation, final Method method, final Iterator chain) { 29 | 30 | final TestVendorAnnotation annotation = method.getAnnotation(TestVendorAnnotation.class); 31 | if (annotation != null) { 32 | 33 | Map map = new HashMap(operation.getResponses()); 34 | final Response value = new Response(); 35 | value.setDescription(RESPONSE_DESCRIPTION); 36 | map.put(RESPONSE_STATUS_401, value); 37 | operation.setResponses(map); 38 | } 39 | 40 | if (chain.hasNext()) { 41 | chain.next().decorateOperation(operation, method, chain); 42 | } 43 | } 44 | 45 | /** 46 | * Processed by {@link TestVendorExtension} 47 | */ 48 | @Target(ElementType.METHOD) 49 | @Retention(RetentionPolicy.RUNTIME) 50 | public @interface TestVendorAnnotation {} 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/VendorExtensionWithoutReader.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.Map; 7 | 8 | import com.wordnik.sample.TestVendorExtension.TestVendorAnnotation; 9 | 10 | import io.swagger.jaxrs.ext.AbstractSwaggerExtension; 11 | import io.swagger.jaxrs.ext.SwaggerExtension; 12 | import io.swagger.models.Operation; 13 | import io.swagger.models.Response; 14 | 15 | /** 16 | * Custom swagger extension which will be configured using the <swaggerExtension> tag. 17 | */ 18 | public class VendorExtensionWithoutReader extends AbstractSwaggerExtension { 19 | 20 | private static final String RESPONSE_DESCRIPTION = "Some vendor error description added using swaggerExtension"; 21 | 22 | private static final String RESPONSE_STATUS_501 = "501"; 23 | 24 | @Override 25 | public void decorateOperation(final Operation operation, final Method method, final Iterator chain) { 26 | 27 | final TestVendorAnnotation annotation = method.getAnnotation(TestVendorAnnotation.class); 28 | if (annotation != null) { 29 | 30 | Map map = new HashMap(operation.getResponses()); 31 | final Response value = new Response(); 32 | value.setDescription(RESPONSE_DESCRIPTION); 33 | map.put(RESPONSE_STATUS_501, value); 34 | operation.setResponses(map); 35 | } 36 | 37 | if (chain.hasNext()) { 38 | chain.next().decorateOperation(operation, method, chain); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/data/StoreData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.data; 18 | 19 | import com.wordnik.sample.model.Order; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Date; 23 | import java.util.List; 24 | 25 | public class StoreData { 26 | static List orders = new ArrayList(); 27 | 28 | static { 29 | orders.add(createOrder(1, 1, 2, new Date(), "placed")); 30 | orders.add(createOrder(2, 1, 2, new Date(), "delivered")); 31 | orders.add(createOrder(3, 2, 2, new Date(), "placed")); 32 | orders.add(createOrder(4, 2, 2, new Date(), "delivered")); 33 | orders.add(createOrder(5, 3, 2, new Date(), "placed")); 34 | orders.add(createOrder(11, 3, 2, new Date(), "placed")); 35 | orders.add(createOrder(12, 3, 2, new Date(), "placed")); 36 | orders.add(createOrder(13, 3, 2, new Date(), "placed")); 37 | orders.add(createOrder(14, 3, 2, new Date(), "placed")); 38 | orders.add(createOrder(15, 3, 2, new Date(), "placed")); 39 | } 40 | 41 | public Order findOrderById(long orderId) { 42 | for (Order order : orders) { 43 | if (order.getId() == orderId) { 44 | return order; 45 | } 46 | } 47 | return null; 48 | } 49 | 50 | public Order placeOrder(Order order) { 51 | if (!orders.isEmpty()) { 52 | for (int i = orders.size() - 1; i >= 0; i--) { 53 | if (orders.get(i).getId() == order.getId()) { 54 | orders.remove(i); 55 | } 56 | } 57 | } 58 | orders.add(order); 59 | return order; 60 | } 61 | 62 | public void deleteOrder(long orderId) { 63 | if (!orders.isEmpty()) { 64 | for (int i = orders.size() - 1; i >= 0; i--) { 65 | if (orders.get(i).getId() == orderId) { 66 | orders.remove(i); 67 | } 68 | } 69 | } 70 | } 71 | 72 | private static Order createOrder(long id, long petId, int quantity, Date shipDate, String status) { 73 | Order order = new Order(); 74 | order.setId(id); 75 | order.setPetId(petId); 76 | order.setQuantity(quantity); 77 | order.setShipDate(shipDate); 78 | order.setStatus(status); 79 | return order; 80 | } 81 | } -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/data/UserData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.data; 18 | 19 | import com.wordnik.sample.model.User; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class UserData { 25 | static List users = new ArrayList(); 26 | 27 | static { 28 | users.add(createUser(1, "user1", "first name 1", "last name 1", 29 | "email1@test.com", "123-456-7890", 1)); 30 | users.add(createUser(2, "user2", "first name 2", "last name 2", 31 | "email2@test.com", "123-456-7890", 2)); 32 | users.add(createUser(3, "user3", "first name 3", "last name 3", 33 | "email3@test.com", "123-456-7890", 3)); 34 | users.add(createUser(4, "user4", "first name 4", "last name 4", 35 | "email4@test.com", "123-456-7890", 1)); 36 | users.add(createUser(5, "user5", "first name 5", "last name 5", 37 | "email5@test.com", "123-456-7890", 2)); 38 | users.add(createUser(6, "user6", "first name 6", "last name 6", 39 | "email6@test.com", "123-456-7890", 3)); 40 | users.add(createUser(7, "user7", "first name 7", "last name 7", 41 | "email7@test.com", "123-456-7890", 1)); 42 | users.add(createUser(8, "user8", "first name 8", "last name 8", 43 | "email8@test.com", "123-456-7890", 2)); 44 | users.add(createUser(9, "user9", "first name 9", "last name 9", 45 | "email9@test.com", "123-456-7890", 3)); 46 | users.add(createUser(10, "user10", "first name 10", "last name 10", 47 | "email10@test.com", "123-456-7890", 1)); 48 | users.add(createUser(11, "user?10", "first name ?10", "last name ?10", 49 | "email101@test.com", "123-456-7890", 1)); 50 | 51 | } 52 | 53 | public User findUserByName(String username) { 54 | for (User user : users) { 55 | if (user.getUsername().equals(username)) { 56 | return user; 57 | } 58 | } 59 | return null; 60 | } 61 | 62 | public void addUser(User user) { 63 | if (!users.isEmpty()) { 64 | for (int i = users.size() - 1; i >= 0; i--) { 65 | if (users.get(i).getUsername().equals(user.getUsername())) { 66 | users.remove(i); 67 | } 68 | } 69 | } 70 | users.add(user); 71 | } 72 | 73 | public void removeUser(String username) { 74 | if (!users.isEmpty()) { 75 | for (int i = users.size() - 1; i >= 0; i--) { 76 | if (users.get(i).getUsername().equals(username)) { 77 | users.remove(i); 78 | } 79 | } 80 | } 81 | } 82 | 83 | private static User createUser(long id, String username, String firstName, 84 | String lastName, String email, String phone, int userStatus) { 85 | User user = new User(); 86 | user.setId(id); 87 | user.setUsername(username); 88 | user.setFirstName(firstName); 89 | user.setLastName(lastName); 90 | user.setEmail(email); 91 | user.setPassword("XXXXXXXXXXX"); 92 | user.setPhone(phone); 93 | user.setUserStatus(userStatus); 94 | return user; 95 | } 96 | } -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/exception/ApiException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.exception; 18 | 19 | public class ApiException extends Exception { 20 | private int code; 21 | 22 | public ApiException(int code, String msg) { 23 | super(msg); 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/exception/BadRequestException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.exception; 18 | 19 | public class BadRequestException extends ApiException { 20 | private int code; 21 | 22 | public BadRequestException(int code, String msg) { 23 | super(code, msg); 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.exception; 18 | 19 | public class NotFoundException extends ApiException { 20 | private int code; 21 | 22 | public NotFoundException(int code, String msg) { 23 | super(code, msg); 24 | this.code = code; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/ApiResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import javax.xml.bind.annotation.XmlTransient; 20 | 21 | @javax.xml.bind.annotation.XmlRootElement 22 | public class ApiResponse { 23 | public static final int ERROR = 1; 24 | public static final int WARNING = 2; 25 | public static final int INFO = 3; 26 | public static final int OK = 4; 27 | public static final int TOO_BUSY = 5; 28 | 29 | int code; 30 | String type; 31 | String message; 32 | 33 | public ApiResponse() { 34 | } 35 | 36 | public ApiResponse(int code, String message) { 37 | this.code = code; 38 | switch (code) { 39 | case ERROR: 40 | setType("error"); 41 | break; 42 | case WARNING: 43 | setType("warning"); 44 | break; 45 | case INFO: 46 | setType("info"); 47 | break; 48 | case OK: 49 | setType("ok"); 50 | break; 51 | case TOO_BUSY: 52 | setType("too busy"); 53 | break; 54 | default: 55 | setType("unknown"); 56 | break; 57 | } 58 | this.message = message; 59 | } 60 | 61 | @XmlTransient 62 | public int getCode() { 63 | return code; 64 | } 65 | 66 | public void setCode(int code) { 67 | this.code = code; 68 | } 69 | 70 | public String getType() { 71 | return type; 72 | } 73 | 74 | public void setType(String type) { 75 | this.type = type; 76 | } 77 | 78 | public String getMessage() { 79 | return message; 80 | } 81 | 82 | public void setMessage(String message) { 83 | this.message = message; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/Category.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import javax.xml.bind.annotation.XmlElement; 20 | import javax.xml.bind.annotation.XmlRootElement; 21 | 22 | @XmlRootElement(name = "Category", namespace = "http://com.wordnik/sample/model/category") 23 | public class Category { 24 | private long id; 25 | private String name; 26 | 27 | @XmlElement(name = "id", namespace = "http://com.wordnik/sample/model/category") 28 | public long getId() { 29 | return id; 30 | } 31 | 32 | public void setId(long id) { 33 | this.id = id; 34 | } 35 | 36 | @XmlElement(name = "name", namespace = "http://com.wordnik/sample/model/category") 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/ListItem.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample.model; 2 | 3 | import javax.xml.bind.annotation.XmlElement; 4 | import javax.xml.bind.annotation.XmlRootElement; 5 | 6 | @XmlRootElement(name = "ListItem") 7 | public class ListItem { 8 | private long id; 9 | 10 | @XmlElement(name = "id") 11 | public long getId() { 12 | return id; 13 | } 14 | 15 | public void setId(long id) { 16 | this.id = id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/Order.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import com.google.common.base.Optional; // Must be Google Guava Optional, because we run Java 6. 20 | import io.swagger.annotations.ApiModelProperty; 21 | 22 | import javax.xml.bind.annotation.XmlElement; 23 | import javax.xml.bind.annotation.XmlRootElement; 24 | import java.util.Date; 25 | 26 | @XmlRootElement(name = "Order") 27 | public class Order { 28 | private long id; 29 | private long petId; 30 | private int quantity; 31 | private Date shipDate; 32 | private String status; 33 | private boolean complete; 34 | @SuppressWarnings("OptionalUsedAsFieldOrParameterType") 35 | private Optional optionalStatus; 36 | 37 | private String internalThing; 38 | private String anotherInternalThing; 39 | 40 | @XmlElement(name = "id") 41 | public long getId() { 42 | return id; 43 | } 44 | 45 | public void setId(long id) { 46 | this.id = id; 47 | } 48 | 49 | public boolean isComplete() { 50 | return complete; 51 | } 52 | 53 | public void setComplete(boolean complete) { 54 | this.complete = complete; 55 | } 56 | 57 | @XmlElement(name = "petId") 58 | public long getPetId() { 59 | return petId; 60 | } 61 | 62 | public void setPetId(long petId) { 63 | this.petId = petId; 64 | } 65 | 66 | @XmlElement(name = "quantity") 67 | public int getQuantity() { 68 | return quantity; 69 | } 70 | 71 | public void setQuantity(int quantity) { 72 | this.quantity = quantity; 73 | } 74 | 75 | @XmlElement(name = "status") 76 | @ApiModelProperty(value = "Order Status", allowableValues = "placed, approved, delivered") 77 | public String getStatus() { 78 | return status; 79 | } 80 | 81 | public void setStatus(String status) { 82 | this.status = status; 83 | } 84 | 85 | @XmlElement(name = "shipDate") 86 | public Date getShipDate() { 87 | return shipDate; 88 | } 89 | 90 | public void setShipDate(Date shipDate) { 91 | this.shipDate = shipDate; 92 | } 93 | 94 | @XmlElement(name = "optionalStatus") 95 | public Optional getOptionalStatus() { return optionalStatus; } 96 | 97 | public void setOptionalStatus(@SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional optionalStatus) { this.optionalStatus = optionalStatus; } 98 | 99 | @ApiModelProperty(name = "internalThing", access = "secret-property") 100 | public String getInternalThing() { 101 | return internalThing; 102 | } 103 | 104 | @ApiModelProperty(name = "anotherInternalThing", access = "another-secret-property") 105 | public String getAnotherInternalThing() { 106 | return anotherInternalThing; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/PaginationHelper.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample.model; 2 | 3 | import io.swagger.annotations.ApiParam; 4 | 5 | public class PaginationHelper { 6 | private Integer limit; 7 | private Integer offset; 8 | 9 | public PaginationHelper() { 10 | } 11 | 12 | public Integer getLimit() { 13 | return limit; 14 | } 15 | 16 | @ApiParam(value = "The pagination limit", name = "limit") 17 | public void setLimit(Integer limit) { 18 | this.limit = limit; 19 | } 20 | 21 | public Integer getOffset() { 22 | return offset; 23 | } 24 | 25 | @ApiParam(value = "The pagination offset", name = "offset") 26 | public void setOffset(Integer offset) { 27 | this.offset = offset; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/Pet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import io.swagger.annotations.ApiModelProperty; 20 | 21 | import javax.xml.bind.annotation.XmlElement; 22 | import javax.xml.bind.annotation.XmlElementWrapper; 23 | import javax.xml.bind.annotation.XmlRootElement; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | @XmlRootElement(name = "Pet") 28 | public class Pet { 29 | private PetId id; 30 | private Category category; 31 | private PetName name; 32 | private List photoUrls = new ArrayList(); 33 | private List tags = new ArrayList(); 34 | private String status; 35 | 36 | @XmlElement(name = "id") 37 | public PetId getId() { 38 | return id; 39 | } 40 | 41 | public void setId(PetId id) { 42 | this.id = id; 43 | } 44 | 45 | @XmlElement(name = "category") 46 | public Category getCategory() { 47 | return category; 48 | } 49 | 50 | public void setCategory(Category category) { 51 | this.category = category; 52 | } 53 | 54 | @XmlElement(name = "name") 55 | @ApiModelProperty(name = "name", example = "doggie", required = true, access = "exclude-when-jev-option-set") 56 | public PetName getName() { 57 | return name; 58 | } 59 | 60 | public void setName(PetName name) { 61 | this.name = name; 62 | } 63 | 64 | @XmlElementWrapper(name = "photoUrls") 65 | @XmlElement(name = "photoUrl", required = true) 66 | public List getPhotoUrls() { 67 | return photoUrls; 68 | } 69 | 70 | public void setPhotoUrls(List photoUrls) { 71 | this.photoUrls = photoUrls; 72 | } 73 | 74 | @XmlElementWrapper(name = "tags") 75 | @XmlElement(name = "tag") 76 | public List getTags() { 77 | return tags; 78 | } 79 | 80 | public void setTags(List tags) { 81 | this.tags = tags; 82 | } 83 | 84 | @XmlElement(name = "status") 85 | @ApiModelProperty(value = "pet status in the store", allowableValues = "available,pending,sold") 86 | public String getStatus() { 87 | return status; 88 | } 89 | 90 | public void setStatus(String status) { 91 | this.status = status; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/PetId.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample.model; 2 | 3 | /** 4 | * @author chekong on 15/5/19. 5 | */ 6 | public class PetId { 7 | private final long id; 8 | 9 | public PetId(long id) { 10 | this.id = id; 11 | } 12 | 13 | public long value() { 14 | return id; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/PetName.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | /** 7 | * @author chekong on 15/5/19. 8 | */ 9 | public class PetName { 10 | private final String name; 11 | 12 | @JsonCreator 13 | public static PetName fromString(@JsonProperty("name") String name) { 14 | 15 | return new PetName(name); 16 | } 17 | 18 | public PetName(String name) { 19 | this.name = name; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return name; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/PetStatus.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.sample.model; 2 | 3 | /** 4 | * @author chekong on 15/5/12. 5 | */ 6 | public enum PetStatus { 7 | AVAILABLE, 8 | PENDING, 9 | SOLD 10 | } -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/Tag.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import javax.xml.bind.annotation.XmlElement; 20 | import javax.xml.bind.annotation.XmlRootElement; 21 | 22 | @XmlRootElement(name = "Tag") 23 | public class Tag { 24 | private long id; 25 | private String name; 26 | 27 | @XmlElement(name = "id") 28 | public long getId() { 29 | return id; 30 | } 31 | 32 | public void setId(long id) { 33 | this.id = id; 34 | } 35 | 36 | @XmlElement(name = "name") 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | } -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.sample.model; 18 | 19 | import io.swagger.annotations.ApiModelProperty; 20 | import io.swagger.annotations.Extension; 21 | import io.swagger.annotations.ExtensionProperty; 22 | 23 | import javax.xml.bind.annotation.XmlElement; 24 | import javax.xml.bind.annotation.XmlRootElement; 25 | 26 | @XmlRootElement(name = "User") 27 | public class User { 28 | private long id; 29 | private String username; 30 | private String firstName; 31 | private String lastName; 32 | private String nickName; 33 | private String email; 34 | private String password; 35 | private String phone; 36 | private int userStatus; 37 | 38 | @XmlElement(name = "id") 39 | public long getId() { 40 | return id; 41 | } 42 | 43 | public void setId(long id) { 44 | this.id = id; 45 | } 46 | 47 | @XmlElement(name = "firstName") 48 | public String getFirstName() { 49 | return firstName; 50 | } 51 | 52 | public void setFirstName(String firstName) { 53 | this.firstName = firstName; 54 | } 55 | 56 | @XmlElement(name = "username") 57 | public String getUsername() { 58 | return username; 59 | } 60 | 61 | public void setUsername(String username) { 62 | this.username = username; 63 | } 64 | 65 | @XmlElement(name = "lastName") 66 | public String getLastName() { 67 | return lastName; 68 | } 69 | 70 | public void setLastName(String lastName) { 71 | this.lastName = lastName; 72 | } 73 | 74 | @XmlElement(name = "nickName") 75 | @ApiModelProperty(name = "nickName", example = "\"Bob\"", access = "exclude-when-jev-option-not-set") 76 | public String getNickName() { 77 | return nickName; 78 | } 79 | 80 | public void setNickName(String nickName) { 81 | this.nickName = nickName; 82 | } 83 | 84 | @XmlElement(name = "email") 85 | public String getEmail() { 86 | return email; 87 | } 88 | 89 | public void setEmail(String email) { 90 | this.email = email; 91 | } 92 | 93 | @XmlElement(name = "password") 94 | public String getPassword() { 95 | return password; 96 | } 97 | 98 | public void setPassword(String password) { 99 | this.password = password; 100 | } 101 | 102 | @XmlElement(name = "phone") 103 | @ApiModelProperty(name = "phone", extensions = @Extension(properties = @ExtensionProperty(name = "test", value = "value"))) 104 | public String getPhone() { 105 | return phone; 106 | } 107 | 108 | public void setPhone(String phone) { 109 | this.phone = phone; 110 | } 111 | 112 | @XmlElement(name = "userStatus") 113 | @ApiModelProperty(value = "User Status", allowableValues = "1-registered,2-active,3-closed", example = "2") 114 | public int getUserStatus() { 115 | return userStatus; 116 | } 117 | 118 | public void setUserStatus(int userStatus) { 119 | this.userStatus = userStatus; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/sample/model/package-info.java: -------------------------------------------------------------------------------- 1 | @javax.xml.bind.annotation.XmlSchema(namespace = "http://com.wordnik/sample/model", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 2 | package com.wordnik.sample.model; 3 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/spring/skipinherited/MyResourceBean.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.spring.skipinherited; 2 | 3 | import java.util.List; 4 | 5 | import com.wordnik.sample.model.ListItem; 6 | 7 | public class MyResourceBean implements MyResourceSI { 8 | 9 | @Override 10 | public List getListOfItems(String param) { 11 | return null; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/spring/skipinherited/MyResourceSI.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.spring.skipinherited; 2 | 3 | import com.wordnik.sample.model.ListItem; 4 | import io.swagger.annotations.Api; 5 | import io.swagger.annotations.ApiOperation; 6 | import io.swagger.annotations.ApiParam; 7 | 8 | import org.springframework.web.bind.annotation.RequestHeader; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | 12 | import java.util.List; 13 | 14 | @Api(description = "Operations about pets") 15 | @RequestMapping(value = "/myResourceSkipInherited", produces = {"application/json", "application/xml"}) 16 | public interface MyResourceSI { 17 | 18 | @RequestMapping(method = RequestMethod.GET, value = "list") 19 | @ApiOperation(value = "Get a list of items", 20 | notes = "This is a contrived example" 21 | ) 22 | public List getListOfItems( 23 | @RequestHeader(name = "X-Simple-Param", required = true) 24 | @ApiParam(name = "X-Simple-Param", 25 | value = "The Simple Param", required = true, 26 | example = "ABC45678901234567") String param); 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/CustomSpringMvcReader.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import com.github.kongchen.swagger.docgen.GenerateException; 4 | import com.github.kongchen.swagger.docgen.reader.SpringMvcApiReader; 5 | import com.github.kongchen.swagger.docgen.spring.SpringResource; 6 | import io.swagger.models.Swagger; 7 | 8 | import java.util.Map; 9 | import java.util.Set; 10 | import org.apache.maven.plugin.logging.Log; 11 | 12 | /** 13 | * @author Igor Gursky 14 | * 11.12.2015. 15 | */ 16 | public class CustomSpringMvcReader extends VendorExtensionsSpringMvcReader { 17 | public CustomSpringMvcReader(Swagger swagger, Log log) { 18 | super(swagger, log); 19 | } 20 | 21 | @Override 22 | public Swagger read(Set> classes) throws GenerateException { 23 | Map resourceMap = generateResourceMap(classes); 24 | for (String str : resourceMap.keySet()) { 25 | SpringResource resource = resourceMap.get(str); 26 | read(resource); 27 | } 28 | swagger.getInfo().setDescription("Processed with CustomSpringMvcReader"); 29 | return swagger; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/EchoResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import io.swagger.annotations.Api; 4 | import io.swagger.annotations.ApiOperation; 5 | import org.springframework.web.bind.annotation.*; 6 | 7 | @Api(value = "/echo", description = "Set of simple endpoints that return whatever value you pass in") 8 | @RequestMapping(value = "/echo", produces = {"application/json", "application/xml"}) 9 | public class EchoResource { 10 | 11 | // Tests for @PathVariable 12 | @RequestMapping(value = "/pathVariableExpectParameterName/{parameterName}", method = RequestMethod.GET, produces = "application/json") 13 | @ApiOperation(value = "") 14 | public String pathVariableExpectParameterName(@PathVariable String parameterName) { 15 | return parameterName; 16 | } 17 | 18 | @RequestMapping(value = "/pathVariableExpectVariableName/{parameterName}", method = RequestMethod.GET, produces = "application/json") 19 | @ApiOperation(value = "") 20 | public String pathVariableExpectVariableName(@PathVariable(name = "pathVariableName") String parameterName) { 21 | return parameterName; 22 | } 23 | 24 | @RequestMapping(value = "/pathVariableExpectVariableValue/{parameterName}", method = RequestMethod.GET, produces = "application/json") 25 | @ApiOperation(value = "") 26 | public String pathVariableExpectVariableValue(@PathVariable(value = "pathVariableValue") String parameterName) { 27 | return parameterName; 28 | } 29 | 30 | // Tests for @RequestParam 31 | @RequestMapping(value = "/requestParamExpectParameterName", method = RequestMethod.GET, produces = "application/json") 32 | @ApiOperation(value = "") 33 | public String requestParamExpectParameterName(@RequestParam String parameterName) { 34 | return parameterName; 35 | } 36 | 37 | @RequestMapping(value = "/requestParamExpectParamName", method = RequestMethod.GET, produces = "application/json") 38 | @ApiOperation(value = "") 39 | public String requestParamExpectParamName(@RequestParam(name = "requestParamName") String parameterName) { 40 | return parameterName; 41 | } 42 | 43 | @RequestMapping(value = "/requestParamExpectParamValue", method = RequestMethod.GET, produces = "application/json") 44 | @ApiOperation(value = "") 45 | public String requestParamExpectParamValue(@RequestParam(value = "requestParamValue") String parameterName) { 46 | return parameterName; 47 | } 48 | 49 | // Tests for @RequestHeader 50 | @RequestMapping(value = "/requestHeaderExpectParameterName", method = RequestMethod.GET, produces = "application/json") 51 | @ApiOperation(value = "") 52 | public String requestHeaderExpectParameterName(@RequestHeader String parameterName) { 53 | return parameterName; 54 | } 55 | 56 | @RequestMapping(value = "/requestHeaderExpectHeaderName", method = RequestMethod.GET, produces = "application/json") 57 | @ApiOperation(value = "") 58 | public String requestHeaderExpectHeaderName(@RequestHeader(name = "requestHeaderName") String parameterName) { 59 | return parameterName; 60 | } 61 | 62 | @RequestMapping(value = "/requestHeaderExpectHeaderValue", method = RequestMethod.GET, produces = "application/json") 63 | @ApiOperation(value = "") 64 | public String requestHeaderExpectHeaderValue(@RequestHeader(value = "requestHeaderValue") String parameterName) { 65 | return parameterName; 66 | } 67 | 68 | // Tests for @CookieValue 69 | @RequestMapping(value = "/cookieValueExpectParameterName", method = RequestMethod.GET, produces = "application/json") 70 | @ApiOperation(value = "") 71 | public String cookieValueExpectParameterName(@CookieValue String parameterName) { 72 | return parameterName; 73 | } 74 | 75 | @RequestMapping(value = "/cookieValueExpectCookieName", method = RequestMethod.GET, produces = "application/json") 76 | @ApiOperation(value = "") 77 | public String cookieValueExpectCookieName(@CookieValue(name = "cookieValueName") String parameterName) { 78 | return parameterName; 79 | } 80 | 81 | @RequestMapping(value = "/cookieValueExpectCookieValue", method = RequestMethod.GET, produces = "application/json") 82 | @ApiOperation(value = "") 83 | public String cookieValueExpectCookieValue(@CookieValue(value = "cookieValueValue") String parameterName) { 84 | return parameterName; 85 | } 86 | 87 | // Tests for @RequestPart 88 | @RequestMapping(value = "/requestPartExpectParameterName", method = RequestMethod.GET, produces = "application/json") 89 | @ApiOperation(value = "") 90 | public String requestPartExpectParameterName(@RequestPart String parameterName) { 91 | return parameterName; 92 | } 93 | 94 | @RequestMapping(value = "/requestPartExpectPartName", method = RequestMethod.GET, produces = "application/json") 95 | @ApiOperation(value = "") 96 | public String requestPartExpectPartName(@RequestPart(name = "requestPartName") String parameterName) { 97 | return parameterName; 98 | } 99 | 100 | @RequestMapping(value = "/requestPartExpectPartValue", method = RequestMethod.GET, produces = "application/json") 101 | @ApiOperation(value = "") 102 | public String requestPartExpectPartValue(@RequestPart(value = "requestPartValue") String parameterName) { 103 | return parameterName; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/EmptyRootPathResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import io.swagger.annotations.Api; 4 | import io.swagger.annotations.ApiOperation; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | 10 | /** 11 | * @author carlosjgp 12 | */ 13 | @RequestMapping 14 | @Api 15 | public class EmptyRootPathResource { 16 | @ApiOperation(value = "testingEmptyRootPathResource") 17 | @RequestMapping(value="/testingEmptyRootPathResource",method = RequestMethod.GET) 18 | public ResponseEntity testingEmptyRootPathResource() { 19 | return new ResponseEntity("testingEmptyRootPathResource", HttpStatus.OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/KotlinController.kt: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc 2 | 3 | import org.springframework.web.bind.annotation.GetMapping 4 | import org.springframework.web.bind.annotation.RequestParam 5 | import org.springframework.web.bind.annotation.RestController 6 | 7 | @RestController 8 | class KotlinController { 9 | 10 | @GetMapping("/getWithParam") 11 | fun getWithParam(@RequestParam optionalParam: Boolean = false) { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/MyResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import com.wordnik.sample.model.ListItem; 4 | import io.swagger.annotations.Api; 5 | import io.swagger.annotations.ApiOperation; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | 9 | import java.util.List; 10 | 11 | @Api(description = "Operations about pets") 12 | @RequestMapping(value = "/myResourceImpl", produces = {"application/json", "application/xml"}) 13 | public interface MyResource { 14 | 15 | //contrived example test case for swagger-maven-plugin issue #505 16 | @RequestMapping(method = RequestMethod.GET, value = "list") 17 | @ApiOperation(value = "Get a list of items", 18 | notes = "This is a contrived example" 19 | ) 20 | public abstract List getListOfItems(); 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/MyResourceImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Reverb Technologies, Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wordnik.springmvc; 18 | 19 | import com.wordnik.sample.model.ListItem; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class MyResourceImpl implements MyResource { 25 | 26 | //contrived example test case for swagger-maven-plugin issue #505 27 | /* (non-Javadoc) 28 | * @see com.wordnik.springmvc.MyResource#getListOfItems() 29 | */ 30 | @Override 31 | public List getListOfItems() { 32 | return new ArrayList(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/RootPathResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import io.swagger.annotations.Api; 4 | import io.swagger.annotations.ApiOperation; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | 10 | /** 11 | * @author andrewb 12 | */ 13 | @RequestMapping(value = "/") 14 | @Api(value = "/") 15 | public class RootPathResource { 16 | @ApiOperation(value = "testingRootPathResource") 17 | @RequestMapping(method = RequestMethod.GET) 18 | public ResponseEntity testingRootPathResource() { 19 | return new ResponseEntity("testingRootPathResource", HttpStatus.OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/SwaggerlessResource.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import com.wordnik.sample.model.Pet; 4 | import com.wordnik.sample.model.PetName; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | public class SwaggerlessResource { 12 | 13 | @RequestMapping(value = "/swaggerless/{petId}", method = RequestMethod.GET) 14 | public Pet getPetByName(@PathVariable(value = "name") String name) { 15 | // Just create and return a new pet 16 | Pet pet = new Pet(); 17 | pet.setName(new PetName(name)); 18 | return pet; 19 | } 20 | 21 | public Pet notAnEndpoint(@PathVariable(value = "name") String name) { 22 | // Just create and return a new pet 23 | Pet pet = new Pet(); 24 | pet.setName(new PetName(name)); 25 | return pet; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/UpdatePetRequest.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import io.swagger.annotations.ApiParam; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | 6 | public class UpdatePetRequest { 7 | private String petId; 8 | private String name; 9 | private String status; 10 | 11 | public String getName() { 12 | return name; 13 | } 14 | 15 | @ApiParam(value = "ID of pet that needs to be updated", required = true) 16 | public void setPetId(@PathVariable("petId") String petId) { 17 | this.petId = petId; 18 | } 19 | 20 | public String getStatus() { 21 | return status; 22 | } 23 | 24 | @ApiParam(value = "Updated name of the pet", required = false) 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public String getPetId() { 30 | return petId; 31 | } 32 | 33 | @ApiParam(value = "Updated status of the pet", required = false) 34 | public void setStatus(String status) { 35 | this.status = status; 36 | } 37 | 38 | public UpdatePetRequest() { 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/springmvc/VendorExtensionsSpringMvcReader.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.springmvc; 2 | 3 | import com.github.kongchen.swagger.docgen.reader.SpringMvcApiReader; 4 | import com.wordnik.sample.TestVendorExtension; 5 | import io.swagger.jaxrs.ext.SwaggerExtension; 6 | import io.swagger.jaxrs.ext.SwaggerExtensions; 7 | import io.swagger.models.Swagger; 8 | import org.apache.maven.plugin.logging.Log; 9 | 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | 13 | public class VendorExtensionsSpringMvcReader extends SpringMvcApiReader { 14 | 15 | public VendorExtensionsSpringMvcReader(Swagger swagger, Log log) { 16 | super(swagger, log); 17 | 18 | List extensions = new LinkedList(SwaggerExtensions.getExtensions()); 19 | extensions.add(new TestVendorExtension()); 20 | SwaggerExtensions.setExtensions(extensions); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/stringwrapper/SimpleStringWrapper.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.stringwrapper; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | 5 | public class SimpleStringWrapper { 6 | 7 | private String value; 8 | 9 | public SimpleStringWrapper() { 10 | } 11 | 12 | @JsonCreator 13 | public SimpleStringWrapper(String value) { 14 | this.value = value; 15 | } 16 | 17 | public String getValue() { 18 | return value; 19 | } 20 | 21 | public void setValue(String value) { 22 | this.value = value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/wordnik/stringwrapper/SimpleWrappersService.java: -------------------------------------------------------------------------------- 1 | package com.wordnik.stringwrapper; 2 | 3 | import org.springframework.web.bind.annotation.CookieValue; 4 | import org.springframework.web.bind.annotation.PathVariable; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.RequestHeader; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | 11 | import io.swagger.annotations.Api; 12 | import io.swagger.annotations.ApiParam; 13 | 14 | @Api 15 | @RequestMapping(value = "/wrappers", produces = {"application/json"}) 16 | public class SimpleWrappersService { 17 | 18 | @RequestMapping(method = RequestMethod.POST, value = "/body") 19 | public String stringWrapperBody( 20 | @RequestBody @ApiParam(value = "Must be passed as JSON object", required = true) SimpleStringWrapper wrapper) { 21 | return null; 22 | } 23 | 24 | @RequestMapping(method = RequestMethod.GET, value = "/param") 25 | public String stringWrapperParam( 26 | @RequestParam @ApiParam(value = "Must be passed as String", required = true) SimpleStringWrapper wrapper) { 27 | return null; 28 | } 29 | 30 | @RequestMapping(method = RequestMethod.GET, value = "/header") 31 | public String stringWrapperHeader( 32 | @RequestHeader @ApiParam(value = "Must be passed as String", required = true) SimpleStringWrapper wrapper) { 33 | return null; 34 | } 35 | 36 | @RequestMapping(method = RequestMethod.GET, value = "/path/{wrapper}") 37 | public String stringWrapperPath( 38 | @PathVariable @ApiParam(value = "Must be passed as String", required = true) SimpleStringWrapper wrapper) { 39 | return null; 40 | } 41 | 42 | @RequestMapping(method = RequestMethod.GET, value = "/cookie") 43 | public String stringWrapperCookie( 44 | @CookieValue @ApiParam(value = "Must be passed as String", required = true) SimpleStringWrapper wrapper) { 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/com/github/kongchen/swagger/docgen/descriptionFile.txt: -------------------------------------------------------------------------------- 1 | Description file content 2 | -------------------------------------------------------------------------------- /src/test/resources/com/github/kongchen/swagger/docgen/mavenplugin/securityDefinition.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key": { 3 | "type": "apiKey", 4 | "name": "api_key_name", 5 | "in": "header" 6 | }, 7 | "api_key_empty_name": { 8 | "type": "apiKey", 9 | "in": "header" 10 | }, 11 | "petstore_auth": { 12 | "type": "oauth2", 13 | "authorizationUrl": "http://swagger.io/api/oauth/dialog", 14 | "flow": "implicit", 15 | "scopes": { 16 | "write:pets": "modify pets in your account", 17 | "read:pets": "read your pets" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/resources/expectedOutput/swagger-common-parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger" : "2.0", 3 | "paths" : { 4 | "/apath" : { 5 | "get" : { 6 | "operationId" : "getOperation", 7 | "parameters" : [ { 8 | "$ref" : "#/parameters/headerParam" 9 | }, { 10 | "$ref" : "#/parameters/queryParam" 11 | } ], 12 | "responses" : { 13 | "default" : { 14 | "description" : "successful operation" 15 | } 16 | } 17 | } 18 | } 19 | }, 20 | "parameters" : { 21 | "headerParam" : { 22 | "name" : "headerParam", 23 | "in" : "header", 24 | "required" : false, 25 | "type" : "string" 26 | }, 27 | "queryParam" : { 28 | "name" : "queryParam", 29 | "in" : "query", 30 | "required" : false, 31 | "type" : "string" 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/test/resources/expectedOutput/swagger-spring-skip-inherited.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger" : "2.0", 3 | "info" : { 4 | "description" : "This is a sample.", 5 | "version" : "v1", 6 | "title" : "Swagger Maven Plugin Sample", 7 | "termsOfService" : "http://www.github.com/kongchen/swagger-maven-plugin", 8 | "contact" : { 9 | "name" : "Kong Chen", 10 | "url" : "http://kongch.com", 11 | "email" : "kongchen@gmail.com" 12 | }, 13 | "license" : { 14 | "name" : "Apache 2.0", 15 | "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" 16 | } 17 | }, 18 | "host" : "www.example.com:8080", 19 | "basePath" : "/api", 20 | "schemes" : [ "http", "https" ], 21 | "paths" : { 22 | "/myResourceSkipInherited/list" : { 23 | "get" : { 24 | "summary" : "Get a list of items", 25 | "description" : "This is a contrived example", 26 | "operationId" : "getListOfItems", 27 | "produces" : [ "application/json", "application/xml" ], 28 | "parameters" : [ { 29 | "name" : "X-Simple-Param", 30 | "in" : "header", 31 | "description" : "The Simple Param", 32 | "required" : true, 33 | "type" : "string", 34 | "x-example" : "ABC45678901234567" 35 | } ], 36 | "responses" : { 37 | "200" : { 38 | "description" : "successful operation", 39 | "schema" : { 40 | "type" : "array", 41 | "items" : { 42 | "$ref" : "#/definitions/ListItem" 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | }, 50 | "securityDefinitions" : { 51 | "api_key" : { 52 | "type" : "apiKey", 53 | "name" : "api_key", 54 | "in" : "header" 55 | }, 56 | "basicAuth" : { 57 | "type" : "basic" 58 | }, 59 | "petstore_auth" : { 60 | "type" : "oauth2", 61 | "authorizationUrl" : "http://swagger.io/api/oauth/dialog", 62 | "flow" : "implicit", 63 | "scopes" : { 64 | "write:pets" : "modify pets in your account", 65 | "read:pets" : "read your pets" 66 | } 67 | } 68 | }, 69 | "definitions" : { 70 | "ListItem" : { 71 | "type" : "object", 72 | "properties" : { 73 | "id" : { 74 | "type" : "integer", 75 | "format" : "int64" 76 | } 77 | }, 78 | "xml" : { 79 | "name" : "ListItem", 80 | "namespace" : "http://com.wordnik/sample/model" 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/test/resources/expectedOutput/swagger-spring-string-wrapper-model.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger" : "2.0", 3 | "info" : { 4 | "description" : "This is a sample.", 5 | "version" : "v1", 6 | "title" : "Swagger Maven Plugin Sample", 7 | "termsOfService" : "http://www.github.com/kongchen/swagger-maven-plugin", 8 | "contact" : { 9 | "name" : "Kong Chen", 10 | "url" : "http://kongch.com", 11 | "email" : "kongchen@gmail.com" 12 | }, 13 | "license" : { 14 | "name" : "Apache 2.0", 15 | "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" 16 | } 17 | }, 18 | "host" : "www.example.com:8080", 19 | "basePath" : "/api", 20 | "schemes" : [ "http", "https" ], 21 | "paths" : { 22 | "/wrappers/body" : { 23 | "post" : { 24 | "operationId" : "stringWrapperBody", 25 | "produces" : [ "application/json" ], 26 | "parameters" : [ { 27 | "in" : "body", 28 | "name" : "body", 29 | "description" : "Must be passed as JSON object", 30 | "required" : true, 31 | "schema" : { 32 | "$ref" : "#/definitions/SimpleStringWrapper" 33 | } 34 | } ], 35 | "responses" : { 36 | "200" : { 37 | "description" : "successful operation", 38 | "schema" : { 39 | "type" : "string" 40 | } 41 | } 42 | } 43 | } 44 | }, 45 | "/wrappers/cookie" : { 46 | "get" : { 47 | "operationId" : "stringWrapperCookie", 48 | "produces" : [ "application/json" ], 49 | "parameters" : [ { 50 | "name" : "wrapper", 51 | "in" : "cookie", 52 | "description" : "Must be passed as String", 53 | "required" : true, 54 | "type" : "string" 55 | } ], 56 | "responses" : { 57 | "200" : { 58 | "description" : "successful operation", 59 | "schema" : { 60 | "type" : "string" 61 | } 62 | } 63 | } 64 | } 65 | }, 66 | "/wrappers/header" : { 67 | "get" : { 68 | "operationId" : "stringWrapperHeader", 69 | "produces" : [ "application/json" ], 70 | "parameters" : [ { 71 | "name" : "wrapper", 72 | "in" : "header", 73 | "description" : "Must be passed as String", 74 | "required" : true, 75 | "type" : "string" 76 | } ], 77 | "responses" : { 78 | "200" : { 79 | "description" : "successful operation", 80 | "schema" : { 81 | "type" : "string" 82 | } 83 | } 84 | } 85 | } 86 | }, 87 | "/wrappers/param" : { 88 | "get" : { 89 | "operationId" : "stringWrapperParam", 90 | "produces" : [ "application/json" ], 91 | "parameters" : [ { 92 | "name" : "wrapper", 93 | "in" : "query", 94 | "description" : "Must be passed as String", 95 | "required" : true, 96 | "type" : "string" 97 | } ], 98 | "responses" : { 99 | "200" : { 100 | "description" : "successful operation", 101 | "schema" : { 102 | "type" : "string" 103 | } 104 | } 105 | } 106 | } 107 | }, 108 | "/wrappers/path/{wrapper}" : { 109 | "get" : { 110 | "operationId" : "stringWrapperPath", 111 | "produces" : [ "application/json" ], 112 | "parameters" : [ { 113 | "name" : "wrapper", 114 | "in" : "path", 115 | "description" : "Must be passed as String", 116 | "required" : true, 117 | "type" : "string" 118 | } ], 119 | "responses" : { 120 | "200" : { 121 | "description" : "successful operation", 122 | "schema" : { 123 | "type" : "string" 124 | } 125 | } 126 | } 127 | } 128 | } 129 | }, 130 | "securityDefinitions" : { 131 | "api_key" : { 132 | "type" : "apiKey", 133 | "name" : "api_key", 134 | "in" : "header" 135 | }, 136 | "basicAuth" : { 137 | "type" : "basic" 138 | }, 139 | "petstore_auth" : { 140 | "type" : "oauth2", 141 | "authorizationUrl" : "http://swagger.io/api/oauth/dialog", 142 | "flow" : "implicit", 143 | "scopes" : { 144 | "write:pets" : "modify pets in your account", 145 | "read:pets" : "read your pets" 146 | } 147 | } 148 | }, 149 | "definitions" : { 150 | "SimpleStringWrapper" : { 151 | "type" : "object", 152 | "properties" : { 153 | "value" : { 154 | "type" : "string" 155 | } 156 | } 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /src/test/resources/override.map: -------------------------------------------------------------------------------- 1 | com.wordnik.sample.model.PetName:java.lang.String 2 | com.wordnik.sample.model.PetId: java.math.BigInteger 3 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-enhanced-operation-id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | false 12 | {{className}}_{{methodName}}_{{httpMethod}} 13 | 14 | com.wordnik.jaxrs 15 | 16 | 17 | http 18 | https 19 | 20 | 21 | 22 | basicAuth 23 | basic 24 | 25 | 26 | api_key_2 27 | apiKey 28 | header 29 | 30 | 31 | /securityDefinition.json 32 | 33 | 34 | json 35 | ${basedir}/generated/swagger-ui-enhanced-operation-id 36 | com.wordnik.jaxrs.VendorExtensionsJaxrsReader 37 | true 38 | http://www.example.com/restapi/doc 39 | /override.map 40 | 41 | secret-property 42 | another-secret-property 43 | exclude-when-jev-option-not-set 44 | 45 | 46 | com.wordnik.sample.VendorExtensionWithoutReader 47 | 48 | 49 | 50 | 51 | 52 | 53 | compile 54 | 55 | generate 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-externalDocs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | false 12 | 13 | com.wordnik.jaxrs 14 | 15 | 16 | http 17 | https 18 | 19 | 20 | 21 | basicAuth 22 | basic 23 | 24 | 25 | api_key_2 26 | apiKey 27 | header 28 | 29 | 30 | /securityDefinition.json 31 | 32 | 33 | 37 | classpath:/templates/strapdown.html.hbs 38 | ${basedir}/generated/document.html 39 | json 40 | ${basedir}/generated/swagger-ui 41 | com.wordnik.jaxrs.VendorExtensionsJaxrsReader 42 | true 43 | http://www.example.com/restapi/doc 44 | /override.map 45 | 46 | secret-property 47 | another-secret-property 48 | exclude-when-jev-option-not-set 49 | 50 | 51 | com.wordnik.sample.VendorExtensionWithoutReader 52 | 53 | 54 | Example external docs 55 | https://example.com/docs 56 | 57 | 58 | 59 | 60 | 61 | 62 | compile 63 | 64 | generate 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-feature-fail.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | false 12 | 13 | com.wordnik.jaxrs 14 | 15 | 16 | http 17 | https 18 | 19 | 20 | 21 | basicAuth 22 | basic 23 | 24 | 25 | api_key_2 26 | apiKey 27 | header 28 | 29 | 30 | /securityDefinition.json 31 | 32 | 33 | 37 | classpath:/templates/strapdown.html.hbs 38 | ${basedir}/generated/document.html 39 | json 40 | ${basedir}/generated/swagger-ui 41 | com.wordnik.jaxrs.VendorExtensionsJaxrsReader 42 | true 43 | http://www.example.com/restapi/doc 44 | /override.map 45 | 46 | secret-property 47 | another-secret-property 48 | exclude-when-jev-option-not-set 49 | 50 | 51 | com.wordnik.sample.VendorExtensionWithoutReader 52 | 53 | 54 | 55 | 56 | com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING 57 | com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS 58 | 59 | 60 | 61 | 62 | compile 63 | 64 | generate 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-springmvc-enhanced-operation-id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | true 12 | {{className}}_{{methodName}}_{{httpMethod}} 13 | 14 | com.wordnik.springmvc 15 | 16 | 17 | http 18 | https 19 | 20 | www.example.com:8080 21 | /api 22 | 23 | Swagger Maven Plugin Sample 24 | v1 25 | 28 | 29 | This is a sample. 30 | 31 | 32 | http://www.github.com/kongchen/swagger-maven-plugin 33 | 34 | 35 | kongchen@gmail.com 36 | Kong Chen 37 | http://kongch.com 38 | 39 | 40 | http://www.apache.org/licenses/LICENSE-2.0.html 41 | Apache 2.0 42 | 43 | 44 | 45 | 46 | basicAuth 47 | basic 48 | 49 | 50 | /securityDefinition.json 51 | 52 | 53 | json 54 | ${basedir}/generated/swagger-ui-spring-enhanced-operation-id 55 | com.wordnik.springmvc.VendorExtensionsSpringMvcReader 56 | http://www.example.com/restapi/doc 57 | /override.map 58 | 59 | secret-property 60 | another-secret-property 61 | exclude-when-jev-option-not-set 62 | 63 | 64 | com.wordnik.sample.VendorExtensionWithoutReader 65 | 66 | 67 | 68 | 69 | 70 | 71 | compile 72 | 73 | generate 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-springmvc-skip-inherited.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | true 12 | true 13 | 14 | com.wordnik.spring.skipinherited 15 | 16 | 17 | http 18 | https 19 | 20 | www.example.com:8080 21 | /api 22 | 23 | Swagger Maven Plugin Sample 24 | v1 25 | 28 | 29 | This is a sample. 30 | 31 | 32 | http://www.github.com/kongchen/swagger-maven-plugin 33 | 34 | 35 | kongchen@gmail.com 36 | Kong Chen 37 | http://kongch.com 38 | 39 | 40 | http://www.apache.org/licenses/LICENSE-2.0.html 41 | Apache 2.0 42 | 43 | 44 | 45 | 46 | basicAuth 47 | basic 48 | 49 | 50 | /securityDefinition.json 51 | 52 | 53 | json 54 | ${basedir}/generated/swagger-ui-spring-skip-inherited 55 | com.wordnik.springmvc.VendorExtensionsSpringMvcReader 56 | http://www.example.com/restapi/doc 57 | /override.map 58 | 59 | secret-property 60 | another-secret-property 61 | exclude-when-jev-option-not-set 62 | 63 | 64 | com.wordnik.sample.VendorExtensionWithoutReader 65 | 66 | 67 | 68 | 69 | 70 | 71 | compile 72 | 73 | generate 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-springmvc-string-wrapper-model.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | true 12 | 13 | com.wordnik.stringwrapper 14 | 15 | 16 | http 17 | https 18 | 19 | www.example.com:8080 20 | /api 21 | 22 | Swagger Maven Plugin Sample 23 | v1 24 | 27 | 28 | This is a sample. 29 | 30 | 31 | http://www.github.com/kongchen/swagger-maven-plugin 32 | 33 | 34 | kongchen@gmail.com 35 | Kong Chen 36 | http://kongch.com 37 | 38 | 39 | http://www.apache.org/licenses/LICENSE-2.0.html 40 | Apache 2.0 41 | 42 | 43 | 44 | 45 | basicAuth 46 | basic 47 | 48 | 49 | /securityDefinition.json 50 | 51 | 52 | json 53 | ${basedir}/generated/swagger-ui-spring-string-wrapper-model 54 | com.wordnik.springmvc.VendorExtensionsSpringMvcReader 55 | http://www.example.com/restapi/doc 56 | 57 | secret-property 58 | another-secret-property 59 | exclude-when-jev-option-not-set 60 | 61 | 62 | com.wordnik.sample.VendorExtensionWithoutReader 63 | 64 | 65 | 66 | 67 | 68 | 69 | compile 70 | 71 | generate 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-springmvc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | true 12 | 13 | com.wordnik.springmvc 14 | 15 | 16 | http 17 | https 18 | 19 | www.example.com:8080 20 | /api 21 | 22 | Swagger Maven Plugin Sample 23 | v1 24 | 27 | 28 | This is a sample. 29 | 30 | 31 | http://www.github.com/kongchen/swagger-maven-plugin 32 | 33 | 34 | kongchen@gmail.com 35 | Kong Chen 36 | http://kongch.com 37 | 38 | 39 | http://www.apache.org/licenses/LICENSE-2.0.html 40 | Apache 2.0 41 | 42 | 43 | 44 | 45 | basicAuth 46 | basic 47 | 48 | 49 | /securityDefinition.json 50 | 51 | 52 | 56 | classpath:/templates/strapdown.html.hbs 57 | ${basedir}/generated/document-spring.html 58 | json 59 | ${basedir}/generated/swagger-ui-spring 60 | com.wordnik.springmvc.VendorExtensionsSpringMvcReader 61 | http://www.example.com/restapi/doc 62 | /override.map 63 | 64 | secret-property 65 | another-secret-property 66 | exclude-when-jev-option-not-set 67 | 68 | 69 | com.wordnik.sample.VendorExtensionWithoutReader 70 | 71 | 72 | 73 | 74 | 75 | 76 | compile 77 | 78 | generate 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config-swaggerreader.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | false 12 | 13 | com.wordnik.jaxrs 14 | 15 | 16 | http 17 | https 18 | 19 | 20 | 21 | basicAuth 22 | basic 23 | 24 | 25 | /securityDefinition.json 26 | 27 | 28 | 32 | classpath:/templates/strapdown.html.hbs 33 | ${basedir}/generated/document.html 34 | json 35 | ${basedir}/generated/swagger-ui 36 | com.github.kongchen.swagger.docgen.reader.SwaggerReader 37 | true 38 | http://www.example.com/restapi/doc 39 | /override.map 40 | 41 | secret-property 42 | another-secret-property 43 | exclude-when-jev-option-not-set 44 | 45 | 46 | com.wordnik.sample.VendorExtensionWithoutReader 47 | 48 | 49 | 50 | 51 | 52 | 53 | compile 54 | 55 | generate 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/test/resources/plugin-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.github.kongchen 6 | swagger-maven-plugin 7 | 3.0-M2-SNAPSHOT 8 | 9 | 10 | 11 | false 12 | 13 | com.wordnik.jaxrs 14 | 15 | 16 | http 17 | https 18 | 19 | 20 | 21 | basicAuth 22 | basic 23 | 24 | 25 | api_key_2 26 | apiKey 27 | header 28 | 29 | 30 | /securityDefinition.json 31 | 32 | 33 | 37 | classpath:/templates/strapdown.html.hbs 38 | ${basedir}/generated/document.html 39 | json 40 | ${basedir}/generated/swagger-ui 41 | com.wordnik.jaxrs.VendorExtensionsJaxrsReader 42 | true 43 | http://www.example.com/restapi/doc 44 | /override.map 45 | 46 | secret-property 47 | another-secret-property 48 | exclude-when-jev-option-not-set 49 | 50 | 51 | com.wordnik.sample.VendorExtensionWithoutReader 52 | 53 | 54 | 55 | 56 | com.fasterxml.jackson.databind.SerializationFeature.WRITE_ENUMS_USING_TO_STRING 57 | com.fasterxml.jackson.core.JsonParser$Feature.ALLOW_NUMERIC_LEADING_ZEROS 58 | 59 | 60 | com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS 61 | 62 | 63 | 64 | 65 | compile 66 | 67 | generate 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/test/resources/securityDefinition.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key": { 3 | "type": "apiKey", 4 | "name": "api_key", 5 | "in": "header" 6 | }, 7 | "petstore_auth": { 8 | "type": "oauth2", 9 | "authorizationUrl": "http://swagger.io/api/oauth/dialog", 10 | "flow": "implicit", 11 | "scopes": { 12 | "write:pets": "modify pets in your account", 13 | "read:pets": "read your pets" 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/resources/templates/markdown.hbs: -------------------------------------------------------------------------------- 1 | #{{#info}}{{title}} 2 | 3 | 4 | ## {{join schemes " | "}}://{{host}}{{basePath}} 5 | 6 | 7 | {{description}} 8 | 9 | {{#contact}} 10 | [**Contact the developer**](mailto:{{email}}) 11 | {{/contact}} 12 | 13 | **Version** {{version}} 14 | 15 | [**Terms of Service**]({{termsOfService}}) 16 | 17 | {{#license}}[**{{name}}**]({{url}}){{/license}} 18 | 19 | {{/info}} 20 | 21 | {{#if consumes}}**Consumes:** {{join consumes ", "}}{{/if}} 22 | 23 | {{#if produces}}**Produces:** {{join produces ", "}}{{/if}} 24 | 25 | {{#if securityDefinitions}} 26 | # Security Definitions 27 | {{/if}} 28 | {{> security}} 29 | 30 | # APIs 31 | 32 | {{#each paths}} 33 | ## {{@key}} 34 | {{#this}} 35 | {{#get}} 36 | ### GET 37 | {{> operation}} 38 | {{/get}} 39 | 40 | {{#put}} 41 | ### PUT 42 | {{> operation}} 43 | {{/put}} 44 | 45 | {{#post}} 46 | ### POST 47 | 48 | {{> operation}} 49 | 50 | {{/post}} 51 | 52 | {{#delete}} 53 | ### DELETE 54 | {{> operation}} 55 | {{/delete}} 56 | 57 | {{#option}} 58 | ### OPTION 59 | {{> operation}} 60 | {{/option}} 61 | 62 | {{#patch}} 63 | ### PATCH 64 | {{> operation}} 65 | {{/patch}} 66 | 67 | {{#head}} 68 | ### HEAD 69 | {{> operation}} 70 | {{/head}} 71 | 72 | {{/this}} 73 | {{/each}} 74 | 75 | # Definitions 76 | {{#each definitions}} 77 | ## {{@key}} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | {{#each this.properties}} 88 | 89 | 90 | 101 | 102 | 103 | 104 | 105 | {{/each}} 106 |
nametyperequireddescriptionexample
{{@key}} 91 | {{#ifeq type "array"}} 92 | {{#items.$ref}} 93 | {{type}}[{{basename items.$ref}}] 94 | {{/items.$ref}} 95 | {{^items.$ref}}{{type}}[{{items.type}}]{{/items.$ref}} 96 | {{else}} 97 | {{#$ref}}{{basename $ref}}{{/$ref}} 98 | {{^$ref}}{{type}}{{#format}} ({{format}}){{/format}}{{/$ref}} 99 | {{/ifeq}} 100 | {{#required}}required{{/required}}{{^required}}optional{{/required}}{{#description}}{{{description}}}{{/description}}{{^description}}-{{/description}}{{example}}
107 | {{/each}} 108 | 109 | -------------------------------------------------------------------------------- /src/test/resources/templates/operation.hbs: -------------------------------------------------------------------------------- 1 | {{#deprecated}}-deprecated-{{/deprecated}} 2 | {{summary}} 3 | 4 | {{description}} 5 | 6 | {{#if externalDocs.url}}{{externalDocs.description}}. [See external documents for more details]({{externalDocs.url}}) 7 | {{/if}} 8 | 9 | {{#if security}} 10 | #### Security 11 | {{/if}} 12 | 13 | {{#security}} 14 | {{#each this}} 15 | * {{@key}} 16 | {{#this}} * {{this}} 17 | {{/this}} 18 | {{/each}} 19 | {{/security}} 20 | 21 | #### Request 22 | 23 | {{#if consumes}} 24 | **Content-Type: ** {{join consumes ", "}}{{/if}} 25 | 26 | ##### Parameters 27 | {{#if parameters}} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {{/if}} 38 | 39 | {{#parameters}} 40 | 41 | 42 | 43 | 44 | 45 | 46 | {{#ifeq in "body"}} 47 | 51 | {{else}} 52 | {{#ifeq type "array"}} 53 | 54 | {{else}} 55 | 56 | {{/ifeq}} 57 | {{/ifeq}} 58 | 59 | {{/parameters}} 60 | {{#if parameters}} 61 |
NameLocated inRequiredDescriptionDefaultSchema
{{name}}{{in}}{{#if required}}yes{{else}}no{{/if}}{{description}}{{#if pattern}} (**Pattern**: `{{pattern}}`){{/if}} - 48 | {{#ifeq schema.type "array"}}Array[{{basename schema.items.$ref}}]{{/ifeq}} 49 | {{#schema.$ref}}{{basename schema.$ref}} {{/schema.$ref}} 50 | Array[{{items.type}}] ({{collectionFormat}}){{type}} {{#format}}({{format}}){{/format}}
62 | {{/if}} 63 | 64 | 65 | #### Response 66 | 67 | {{#if produces}}**Content-Type: ** {{join produces ", "}}{{/if}} 68 | 69 | 70 | | Status Code | Reason | Response Model | 71 | |-------------|-------------|----------------| 72 | {{#each responses}}| {{@key}} | {{description}} | {{#schema.$ref}}{{basename schema.$ref}}{{/schema.$ref}}{{^schema.$ref}}{{#ifeq schema.type "array"}}Array[{{basename schema.items.$ref}}]{{else}}{{schema.type}}{{/ifeq}}{{/schema.$ref}}{{^schema}} - {{/schema}}| 73 | {{/each}} 74 | -------------------------------------------------------------------------------- /src/test/resources/templates/security.hbs: -------------------------------------------------------------------------------- 1 | {{#each securityDefinitions}} 2 | ### {{@key}} 3 | {{#this}} 4 | {{#ifeq type "oauth2"}} 5 | 6 | 7 | 8 | 9 | 10 | {{#if description}} 11 | 12 | 13 | 14 | 15 | {{/if}} 16 | {{#if authorizationUrl}} 17 | 18 | 19 | 20 | 21 | {{/if}} 22 | {{#if flow}} 23 | 24 | 25 | 26 | 27 | {{/if}} 28 | {{#if tokenUrl}} 29 | 30 | 31 | 32 | 33 | {{/if}} 34 | {{#if scopes}} 35 | 36 | 37 | {{#each scopes}} 38 | 39 | 40 | 41 | 42 | {{/each}} 43 | 44 | {{/if}} 45 |
type{{type}}
description{{description}}
authorizationUrl{{authorizationUrl}}
flow{{flow}}
tokenUrl{{tokenUrl}}
scopes{{@key}}{{this}}
46 | {{/ifeq}} 47 | {{#ifeq type "apiKey"}} 48 | 49 | 50 | 51 | 52 | 53 | {{#if description}} 54 | 55 | 56 | 57 | 58 | {{/if}} 59 | {{#if name}} 60 | 61 | 62 | 63 | 64 | {{/if}} 65 | {{#if in}} 66 | 67 | 68 | 69 | 70 | {{/if}} 71 |
type{{type}}
description{{description}}
name{{name}}
in{{in}}
72 | {{/ifeq}} 73 | {{#ifeq type "basic"}} 74 | 75 | 76 | 77 | 78 | 79 | {{#if description}} 80 | 81 | 82 | 83 | 84 | {{/if}} 85 |
type{{type}}
description{{description}}
86 | {{/ifeq}} 87 | {{/this}} 88 | {{/each}} -------------------------------------------------------------------------------- /src/test/resources/templates/strapdown.html.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | API Document 4 | 5 |

6 | {{>markdown}} 7 | 8 | 9 | 10 | --------------------------------------------------------------------------------