Compare commits

..

2 Commits

Author SHA1 Message Date
Hugo de Paix de Coeur
85c5b7aa97 switched swagger-parser to 1.0.21-SNAPSHOT
Added a use case in tests : object array with examples
Added a workaround for object array examples because swagger-parser returns a string and not an ArrayNode as expected
2016-06-10 11:45:19 +02:00
Hugo de Paix de Coeur
662cc3f40f Added inline schemas in generatedExample test
Ignore inline schema tests because of a bug in swagger-parser-1.0.21
2016-06-10 11:42:05 +02:00
304 changed files with 9175 additions and 19481 deletions

4
.gitignore vendored
View File

@@ -3,7 +3,3 @@
.gradle
build
/bin/
/.classpath
/.project
/.settings/
/out/

View File

@@ -27,7 +27,7 @@ image::src/docs/asciidoc/images/Swagger2Markup.PNG[]
image::src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[]
== Reference documentation
- http://swagger2markup.github.io/swagger2markup/1.3.1/[Reference Documentation]
- http://swagger2markup.github.io/swagger2markup/1.0.0/[Reference Documentation]
- https://github.com/Swagger2Markup/swagger2markup/blob/master/RELEASENOTES.adoc[Release notes]
- https://github.com/Swagger2Markup/spring-swagger2markup-demo[Demo using Swagger2Markup, Spring Boot, Springfox and spring-restdocs]
@@ -54,8 +54,6 @@ If youd like an enhancement to be made to Swagger2Markup, pull requests are m
* http://www.appdirect.com/[AppDirect] -- The leading commerce platform for selling cloud services.
* http://www.wescale.com[wescale]
* http://taskassure.com[TaskAssure]
* https://www.isaac.nl[ISAAC]
* https://www.spreadshirt.de[Spreadshirt]
== License

View File

@@ -78,9 +78,9 @@
=== Version 0.9.3
* Updated swagger-parser from v1.0.13 to v1.0.16
* Enhancement #61: Refactor separated documents logic to support inter-document cross-references
* Enhancement #53: Support for tags, paths and methods ordering
* Enhancement #51: Support for separated operations files
* Enhancement #61 Refactor separated documents logic to support inter-document cross-references
* Enhancement #53 : support for tags, paths and methods ordering
* Enhancement #51 : Support for separated operations files
* Enhancement #52: Markdown generation for inline schemas
== Version 1.0.0
@@ -91,44 +91,3 @@
* Inline schema support
* New configuration options
* Support of deprecated path operations
=== Version 1.0.1
* Enhancement: Support to render validation constraints of properties
* Enhancement: Possibility to disable rendering of the security chapter below operations
== Version 1.1.0
* PR #177: Fixed rendering of recursive examples
* PR #186: Add support for Chinese language
* PR #190: Add support for Spanish language
* PR #192: Updated min/max value to format correctly based on the data type
* PR #193: Added support for exclusiveMin and exclusiveMax
=== Version 1.1.1
* Issue #194: Added a config parameter which allows to prepend the basePath to all paths.
* Updated swagger-parser from v1.0.16 to v1.0.23
* Added javslang v2.0.4 as a dependency
* Added paleo-core v0.10.1 as a dependency
* Updated markup-document-builder from 1.0.0 to 1.1.0
* PR #201: Add support for Brazilian Portuguese language
* PR #202: Add support for Japanese language
* Issue #205: Fixed the option to influence resource ordering
* Issue #198: Chinese chinese language encoding
* Issue #207: Properties that start with an underscore are displayed correctly now
* Refactored Swagger2Markup to use a Component-Based design. A document can be composed of components and components can be composed of other components.
== Version 1.2.0
* Issue #214: Add page break locations
* Issue #223: Improve example rendering
* Issue #215: Add ability to group operations by RegEx
* Added new configuration options: pageBreakLocations, headerRegex
* Added new valid value for configuration headerRegex: REGEX
* Updated markup-document-builder from 1.1.0 to 1.1.1
== Version 1.3.0
* Updated javslang from 2.0.4 to 2.0.5
* Updated paleo-core from 0.10.1 to 0.10.2
* Updated swagger-parser from v1.0.23 to v1.0.25
* Decimal numbers are formatted into locale-specific strings
=== Version 1.3.1
* PR #247: Fix request path and query params example support.

View File

@@ -13,12 +13,10 @@ buildscript {
}
}
description = 'swagger2markup Build'
version = '1.3.2-SNAPSHOT'
ext.releaseVersion = '1.3.1'
version = '1.0.1-SNAPSHOT'
group = 'io.github.swagger2markup'
apply plugin: 'java'
apply plugin: 'eclipse'
apply from: 'gradle/publishing.gradle'
apply from: 'gradle/coverage.gradle'
apply from: 'gradle/documentation.gradle'
@@ -37,21 +35,19 @@ repositories {
}
jcenter()
mavenCentral()
//mavenLocal()
mavenLocal()
}
dependencies {
compile 'io.github.swagger2markup:markup-document-builder:1.1.1'
compile 'io.swagger:swagger-compat-spec-parser:1.0.25'
compile 'org.apache.commons:commons-configuration2:2.1'
compile 'io.github.swagger2markup:markup-document-builder:1.0.0'
compile 'io.swagger:swagger-compat-spec-parser:1.0.21-SNAPSHOT'
compile 'org.apache.commons:commons-configuration2:2.0'
compile 'commons-beanutils:commons-beanutils:1.9.2'
compile 'org.apache.commons:commons-collections4:4.1'
compile 'io.javaslang:javaslang:2.0.5'
compile 'ch.netzwerg:paleo-core:0.10.2'
testCompile 'junit:junit:4.11'
testCompile 'org.asciidoctor:asciidoctorj:1.5.4'
testCompile 'ch.qos.logback:logback-classic:1.1.2'
testCompile 'org.assertj:assertj-core:3.5.2'
testCompile 'org.assertj:assertj-core:3.4.0'
testCompile 'io.github.robwin:assertj-diff:0.1.1'
}
@@ -62,9 +58,10 @@ test {
systemProperty 'http.nonProxyHosts', System.properties['http.nonProxyHosts']
}
systemProperty 'file.encoding', 'UTF-8'
ignoreFailures = true
}
task wrapper(type: Wrapper) {
gradleVersion = '3.3'
gradleVersion = '2.12'
}

View File

@@ -1,2 +0,0 @@
systemProp.file.encoding=UTF-8
systemProp.sun.jnu.encoding=UTF-8

View File

@@ -14,7 +14,6 @@ asciidoctor {
sectlinks: '',
sectanchors: '',
hardbreaks: '',
'release-version': project.releaseVersion
]
}
@@ -30,6 +29,6 @@ githubPages {
pages {
from file(asciidoctor.outputDir.path + '/html5')
into project.releaseVersion
into project.version
}
}

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Thu Jan 05 14:27:30 CET 2017
#Thu Mar 31 16:29:35 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip

51
gradlew vendored
View File

@@ -6,30 +6,12 @@
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -48,7 +30,6 @@ die ( ) {
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -59,11 +40,26 @@ case "`uname`" in
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -89,7 +85,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -161,9 +157,4 @@ function splitJvmOpts() {
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

14
gradlew.bat vendored
View File

@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,9 +46,10 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -59,6 +60,11 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@@ -16,7 +16,7 @@ You can show the help:
[source, subs="attributes"]
----
java -jar swagger2markup-cli-{release-version}.jar help convert
java -jar swagger2markup-cli-{project-version}.jar help convert
----
Output:
@@ -57,7 +57,7 @@ You can convert a Swagger file into a folder as follows:
[source, subs="attributes"]
----
java -jar swagger2markup-cli-{release-version}.jar convert -i /path/to/swagger_petstore.yaml -d /tmp/asiidoc
java -jar swagger2markup-cli-1.0.0-SNAPSHOT.jar convert -i /path/to/swagger_petstore.yaml -d /tmp/asiidoc
----
It generates the Markup documents into the `/tmp/asiidoc` folder.
@@ -68,7 +68,7 @@ You can convert a local Swagger file into a file as follows:
[source, subs="attributes"]
----
java -jar swagger2markup-cli-{release-version}.jar convert -i /path/to/swagger_petstore.yaml -f /tmp/asiidoc/swagger
java -jar swagger2markup-cli-1.0.0-SNAPSHOT.jar convert -i /path/to/swagger_petstore.yaml -f /tmp/asiidoc/swagger
----
NOTE: The input file must not have a file extension
@@ -81,7 +81,7 @@ You can convert a remote Swagger specification which must be accessible via HTTP
[source, subs="attributes"]
----
java -jar swagger2markup-cli-{release-version}.jar convert -i "http://petstore.swagger.io/v2/swagger.json" -d /tmp
java -jar swagger2markup-cli-1.0.0-SNAPSHOT.jar convert -i "http://petstore.swagger.io/v2/swagger.json" -d /tmp
----
=== Configuration
@@ -98,6 +98,6 @@ Invoke the CLI as follows:
[source, subs="attributes"]
----
java -jar swagger2markup-cli-{release-version}.jar convert -i /path/to/swagger_petstore.yaml -o /tmp -c /path/to/config.properties
java -jar swagger2markup-cli-1.0.0-SNAPSHOT.jar convert -i /path/to/swagger_petstore.yaml -o /tmp -c /path/to/config.properties
----

View File

@@ -1,13 +0,0 @@
== Docker image
The Swagger2Markup-CLI has been published as a Docker image on DockerHub.
=== Usage guide
You can pull the Swagger2Markup image as follows:
`docker pull swagger2markup/swagger2markup`
You can convert a Swagger Spec by running a Docker container as follows:
`docker run --rm -v $(pwd):/opt swagger2markup/swagger2markup convert -i /opt/swagger.yaml -f /opt/swagger -c /opt/config.properties`

View File

@@ -19,7 +19,7 @@ repositories {
jCenter()
}
compile "io.github.swagger2markup:swagger2markup:{release-version}"
compile "io.github.swagger2markup:swagger2markup:{project-version}"
----
==== Snapshot
@@ -50,7 +50,7 @@ repositories {
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>{release-version}</version>
<version>{project-version}</version>
</dependency>
----

View File

@@ -18,7 +18,7 @@ buildscript {
}
dependencies {
classpath 'io.github.swagger2markup:swagger2markup-gradle-plugin:{release-version}'
classpath 'io.github.swagger2markup:swagger2markup-gradle-plugin:{project-version}'
}
}

View File

@@ -5,7 +5,7 @@ Robert Winkler
:source-highlighter: coderay
:numbered:
:hardbreaks:
:revnumber: {release-version}
:revnumber: {project-version}
:revdate: {localdate}
:icons: font
:pagenums:
@@ -26,8 +26,6 @@ include::maven_plugin.adoc[]
include::command_line_interface.adoc[]
include::docker.adoc[]
include::demo.adoc[]
include::contributing.adoc[]

View File

@@ -1,6 +1,6 @@
== License
Copyright 2017 Robert Winkler
Copyright 2016 Robert Winkler
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

View File

@@ -31,7 +31,7 @@ Add the following snippet to your Maven POM file:
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>{release-version}</version>
<version>{project-version}</version>
</plugin>
</plugins>
</build>
@@ -45,14 +45,14 @@ The plugin adds a new task goal `swagger2markup:convertSwagger2markup`. You can
You can customize the task by configuring a Map of <<Swagger2Markup properties>>.
[source,xml, subs="specialcharacters,attributes"]
[source,xml]
----
<build>
<plugins>
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>{release-version}</version>
<version>{project-version}</version>
<configuration>
<swaggerInput>${project.basedir}/src/docs/swagger/swagger_petstore.yaml</swaggerInput>
<outputDir>${project.build.directory}/asciidoc</outputDir>

View File

@@ -136,15 +136,12 @@ The following tables list all available properties of Swagger2Markup:
|Name | Description | Possible Values | Default
|swagger2markup.markupLanguage| Specifies the markup language which should be used to generate the files. | ASCIIDOC, MARKDOWN, CONFLUENCE_MARKUP | ASCIIDOC
|swagger2markup.swaggerMarkupLanguage| Specifies the markup language used in Swagger descriptions. | ASCIIDOC, MARKDOWN, CONFLUENCE_MARKUP | MARKDOWN
|swagger2markup.pathsGroupedBy| Specifies how the paths should be grouped | AS_IS, TAGS, REGEX | AS_IS
|swagger2markup.pathsGroupedBy| Specifies how the paths should be grouped | AS_IS, TAGS | AS_IS
|swagger2markup.outputLanguage| Specifies the language of the labels | EN, DE, FR, RU | EN
|swagger2markup.lineSeparator| Specifies the line separator which should be used | UNIX, WINDOWS, MAC | <System-dependent>
|swagger2markup.generatedExamplesEnabled| Specifies if HTTP request and response examples should be generated | true, false | false
|swagger2markup.flatBodyEnabled| Optionally isolate the body parameter, if any, from other parameters | true, false | false
|swagger2markup.pathSecuritySectionEnabled| Optionally disable the security section for path sections | true, false | true
|swagger2markup.anchorPrefix| Optionally prefix all anchors for uniqueness if you want to include generated documents into a global documentation | Any String |
|swagger2markup.basePathPrefixEnabled| Prepend the basePath to all paths | true, false | false
|swagger2markup.headerRegex | Regular expression to use when grouping by RegEx | Any valid RegEx pattern with at least one capture group |
|swagger2markup.anchorPrefix| Optionally prefix all anchors for uniqueness if you want to include generated documents into a global documentation | Any String |
|===
[options="header"]
@@ -194,13 +191,6 @@ The following tables list all available properties of Swagger2Markup:
|swagger2markup.inlineSchemaEnabled| Enable inline object schema support | true, false | true
|===
[options="header"]
.Properties which configure page breaking
|===
|Name | Description | Possible Values | Default
|swagger2markup.pageBreakLocations | Specifies where page breaks should be inserted. | BEFORE_OPERATION, BEFORE_OPERATION_DESCRIPTION, BEFORE_OPERATION_PARAMETERS, BEFORE_OPERATION_RESPONSES, BEFORE_OPERATION_CONSUMES, BEFORE_OPERATION_PRODUCES, BEFORE_OPERATION_EXAMPLE_REQUEST, BEFORE_OPERATION_EXAMPLE_RESPONSE, BEFORE_DEFINITION, AFTER_OPERATION, AFTER_OPERATION_DESCRIPTION, AFTER_OPERATION_PARAMETERS, AFTER_OPERATION_RESPONSES, AFTER_OPERATION_CONSUMES, AFTER_OPERATION_PRODUCES, AFTER_OPERATION_EXAMPLE_REQUEST, AFTER_OPERATION_EXAMPLE_RESPONSE, AFTER_DEFINITION | empty
|===
=== Logging
Swagger2Markup uses http://www.slf4j.org/[SLF4J] for all internal logging, but leaves the underlying log implementation open. To change the log level, you have the set the log level of the `io.github.swagger2markup` package.

View File

@@ -1,14 +0,0 @@
package io.github.swagger2markup;
/**
* swagger2markup (c) Duco Hosting
* Created by cas on 02-Oct-17.
*/
public enum ExampleType {
QUERY,
POST,
HEADER,
PATH,
BODY,
OTHER
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,5 @@ package io.github.swagger2markup;
public enum GroupBy {
AS_IS,
TAGS,
REGEX
TAGS
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup;
import java.util.ResourceBundle;
public class Labels {
public static final String DEFAULT_COLUMN = "default_column";
public static final String MAXLENGTH_COLUMN = "maxlength_column";
public static final String MINLENGTH_COLUMN = "minlength_column";
public static final String LENGTH_COLUMN = "length_column";
public static final String PATTERN_COLUMN = "pattern_column";
public static final String MINVALUE_COLUMN = "minvalue_column";
public static final String MINVALUE_EXCLUSIVE_COLUMN = "minvalue_exclusive_column";
public static final String MAXVALUE_COLUMN = "maxvalue_column";
public static final String MAXVALUE_EXCLUSIVE_COLUMN = "maxvalue_exclusive_column";
public static final String EXAMPLE_COLUMN = "example_column";
public static final String SCHEMA_COLUMN = "schema_column";
public static final String NAME_COLUMN = "name_column";
public static final String DESCRIPTION_COLUMN = "description_column";
public static final String SCOPES_COLUMN = "scopes_column";
public static final String DESCRIPTION = DESCRIPTION_COLUMN;
public static final String PRODUCES = "produces";
public static final String CONSUMES = "consumes";
public static final String TAGS = "tags";
public static final String NO_CONTENT = "no_content";
public static final String FLAGS_COLUMN = "flags.column";
public static final String FLAGS_REQUIRED = "flags.required";
public static final String FLAGS_OPTIONAL = "flags.optional";
public static final String FLAGS_READ_ONLY = "flags.read_only";
// Overview Document
public static final String CONTACT_INFORMATION = "contact_information";
public static final String CONTACT_NAME = "contact_name";
public static final String CONTACT_EMAIL = "contact_email";
public static final String LICENSE_INFORMATION = "license_information";
public static final String LICENSE = "license";
public static final String LICENSE_URL = "license_url";
public static final String TERMS_OF_SERVICE = "terms_of_service";
public static final String CURRENT_VERSION = "current_version";
public static final String VERSION = "version";
public static final String OVERVIEW = "overview";
public static final String URI_SCHEME = "uri_scheme";
public static final String HOST = "host";
public static final String BASE_PATH = "base_path";
public static final String SCHEMES = "schemes";
public static final String EXTERNAL_DOCS = "external_docs";
public static final String EXTERNAL_DOCS_DESC = "external_docs_desc";
public static final String EXTERNAL_DOCS_URL = "external_docs_url";
//Security Document
public static final String SECURITY = "security";
public static final String TYPE = "security_type";
public static final String NAME = "security_name";
public static final String IN = "security_in";
public static final String FLOW = "security_flow";
public static final String AUTHORIZATION_URL = "security_authorizationUrl";
public static final String TOKEN_URL = "security_tokenUrl";
//Definitions Document
public static final String DEFINITIONS = "definitions";
public static final String POLYMORPHISM_COLUMN = "polymorphism.column";
public static final String POLYMORPHISM_DISCRIMINATOR_COLUMN = "polymorphism.discriminator";
public static final String TYPE_COLUMN = "type_column";
public static final String POLYMORPHISM_NATURE_COMPOSITION = "polymorphism.nature.COMPOSITION";
public static final String POLYMORPHISM_NATURE_INHERITANCE = "polymorphism.nature.INHERITANCE";
//Paths Document
public static final String RESPONSE = "response";
public static final String REQUEST = "request";
public static final String PATHS = "paths";
public static final String RESOURCES = "resources";
public static final String OPERATIONS = "operations";
public static final String PARAMETERS = "parameters";
public static final String BODY_PARAMETER = "body_parameter";
public static final String RESPONSES = "responses";
public static final String HEADERS_COLUMN = "headers_column";
public static final String EXAMPLE_REQUEST = "example_request";
public static final String EXAMPLE_RESPONSE = "example_response";
public static final String HTTP_CODE_COLUMN = "http_code_column";
public static final String DEPRECATED_OPERATION = "operation.deprecated";
public static final String UNKNOWN = "unknown";
private ResourceBundle resourceBundle;
public Labels(Swagger2MarkupConfig config) {
this.resourceBundle = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
}
/**
* Gets a label for the given key from this resource bundle.
*
* @param key the key for the desired label
* @return the label for the given key
*/
public String getLabel(String key) {
return resourceBundle.getString(key);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,15 +22,11 @@ import java.util.Locale;
* @author Maksim Myshkin
*/
public enum Language {
EN(Locale.ENGLISH),
EN(new Locale("en")),
RU(new Locale("ru")),
FR(Locale.FRENCH),
DE(Locale.GERMAN),
TR(new Locale("tr")),
ZH(Locale.CHINESE),
ES(new Locale("es")),
BR(new Locale("pt", "BR")),
JA(Locale.JAPANESE);
FR(new Locale("fr")),
DE(new Locale("de")),
TR(new Locale("tr"));
private final Locale lang;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup;
public enum PageBreakLocations {
BEFORE_OPERATION,
BEFORE_OPERATION_DESCRIPTION,
BEFORE_OPERATION_PARAMETERS,
BEFORE_OPERATION_RESPONSES,
BEFORE_OPERATION_CONSUMES,
BEFORE_OPERATION_PRODUCES,
BEFORE_OPERATION_EXAMPLE_REQUEST,
BEFORE_OPERATION_EXAMPLE_RESPONSE,
BEFORE_DEFINITION,
AFTER_OPERATION,
AFTER_OPERATION_DESCRIPTION,
AFTER_OPERATION_PARAMETERS,
AFTER_OPERATION_RESPONSES,
AFTER_OPERATION_CONSUMES,
AFTER_OPERATION_PRODUCES,
AFTER_OPERATION_EXAMPLE_REQUEST,
AFTER_OPERATION_EXAMPLE_RESPONSE,
AFTER_DEFINITION
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,6 @@ import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.parameters.Parameter;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Swagger2Markup configuration interface.
@@ -45,11 +43,6 @@ public interface Swagger2MarkupConfig {
*/
boolean isGeneratedExamplesEnabled();
/**
* Prepend the base path to all paths.
*/
boolean isBasePathPrefixEnabled();
/**
* In addition to the Definitions file, also create separate definition files for each model definition.
*/
@@ -80,11 +73,6 @@ public interface Swagger2MarkupConfig {
*/
OrderBy getTagOrderBy();
/**
* Specifies the regex pattern used for header matching
*/
Pattern getHeaderPattern();
/**
* Specifies a custom comparator function to order tags.
*/
@@ -155,11 +143,6 @@ public interface Swagger2MarkupConfig {
*/
boolean isFlatBodyEnabled();
/**
* Optionally disable the security section for path sections
*/
boolean isPathSecuritySectionEnabled();
/**
* Optionally prefix all anchors for uniqueness.
*/
@@ -214,30 +197,10 @@ public interface Swagger2MarkupConfig {
*/
LineSeparator getLineSeparator();
/**
* Specifies the array element delimiter to use for multi-valued properties.
* @return the element delimiter if any
*/
Character getListDelimiter();
/**
* Optionally allow lists in property values. Uses the {{@link #getListDelimiter()} to
* delimit list values.
* @return whether lists are converted to arrays
*/
boolean isListDelimiterEnabled();
/**
* Returns properties for extensions.
*
* @return the extension properties
*/
Swagger2MarkupProperties getExtensionsProperties();
/**
* Returns the list of page break locations
*
* @return List of PageBreakLocations
*/
List<PageBreakLocations> getPageBreakLocations();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,11 @@ package io.github.swagger2markup;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.builder.Swagger2MarkupExtensionRegistryBuilder;
import io.github.swagger2markup.internal.document.DefinitionsDocument;
import io.github.swagger2markup.internal.document.OverviewDocument;
import io.github.swagger2markup.internal.document.PathsDocument;
import io.github.swagger2markup.internal.document.SecurityDocument;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.markup.builder.MarkupDocBuilders;
import io.github.swagger2markup.internal.document.builder.DefinitionsDocumentBuilder;
import io.github.swagger2markup.internal.document.builder.OverviewDocumentBuilder;
import io.github.swagger2markup.internal.document.builder.PathsDocumentBuilder;
import io.github.swagger2markup.internal.document.builder.SecurityDocumentBuilder;
import io.github.swagger2markup.spi.*;
import io.github.swagger2markup.utils.URIUtils;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
@@ -48,18 +47,22 @@ import java.nio.file.StandardOpenOption;
*/
public class Swagger2MarkupConverter {
private final Context context;
private final OverviewDocument overviewDocument;
private final PathsDocument pathsDocument;
private final DefinitionsDocument definitionsDocument;
private final SecurityDocument securityDocument;
private Context context;
public Swagger2MarkupConverter(Context context) {
this.context = context;
this.overviewDocument = new OverviewDocument(context);
this.pathsDocument = new PathsDocument(context);
this.definitionsDocument = new DefinitionsDocument(context);
this.securityDocument = new SecurityDocument(context);
private Swagger2MarkupExtensionRegistry extensionRegistry;
public Swagger2MarkupConverter(Context globalContext, Swagger2MarkupExtensionRegistry extensionRegistry) {
this.context = globalContext;
this.extensionRegistry = extensionRegistry;
}
/**
* Returns the global Context
*
* @return the global Context
*/
Context getContext(){
return context;
}
/**
@@ -71,15 +74,17 @@ public class Swagger2MarkupConverter {
public static Builder from(URI swaggerUri) {
Validate.notNull(swaggerUri, "swaggerUri must not be null");
String scheme = swaggerUri.getScheme();
if (scheme != null && swaggerUri.getScheme().startsWith("http")) {
if(scheme != null && swaggerUri.getScheme().startsWith("http")){
try {
return from(swaggerUri.toURL());
} catch (MalformedURLException e) {
}
catch (MalformedURLException e) {
throw new RuntimeException("Failed to convert URI to URL", e);
}
} else if (scheme != null && swaggerUri.getScheme().startsWith("file")) {
} else if(scheme != null && swaggerUri.getScheme().startsWith("file")){
return from(Paths.get(swaggerUri));
} else {
}
else {
return from(URIUtils.convertUriWithoutSchemeToFileScheme(swaggerUri));
}
}
@@ -90,7 +95,7 @@ public class Swagger2MarkupConverter {
* @param swaggerURL the remote URL
* @return a Swagger2MarkupConverter
*/
public static Builder from(URL swaggerURL) {
public static Builder from(URL swaggerURL){
Validate.notNull(swaggerURL, "swaggerURL must not be null");
return new Builder(swaggerURL);
}
@@ -103,11 +108,11 @@ public class Swagger2MarkupConverter {
*/
public static Builder from(Path swaggerPath) {
Validate.notNull(swaggerPath, "swaggerPath must not be null");
if (Files.notExists(swaggerPath)) {
if(Files.notExists(swaggerPath)){
throw new IllegalArgumentException(String.format("swaggerPath does not exist: %s", swaggerPath));
}
try {
if (Files.isHidden(swaggerPath)) {
if(Files.isHidden(swaggerPath)){
throw new IllegalArgumentException("swaggerPath must not be a hidden file");
}
} catch (IOException e) {
@@ -158,57 +163,18 @@ public class Swagger2MarkupConverter {
return new Builder(swagger);
}
/**
* Returns the global Context
*
* @return the global Context
*/
public Context getContext() {
return context;
}
/**
* Converts the Swagger specification into the given {@code outputDirectory}.
*
* @param outputDirectory the output directory path
*/
public void toFolder(Path outputDirectory) {
public void toFolder(Path outputDirectory){
Validate.notNull(outputDirectory, "outputDirectory must not be null");
context.setOutputPath(outputDirectory);
applyOverviewDocument()
.writeToFile(outputDirectory.resolve(context.config.getOverviewDocument()), StandardCharsets.UTF_8);
applyPathsDocument()
.writeToFile(outputDirectory.resolve(context.config.getPathsDocument()), StandardCharsets.UTF_8);
applyDefinitionsDocument()
.writeToFile(outputDirectory.resolve(context.config.getDefinitionsDocument()), StandardCharsets.UTF_8);
applySecurityDocument()
.writeToFile(outputDirectory.resolve(context.config.getSecurityDocument()), StandardCharsets.UTF_8);
}
private MarkupDocBuilder applyOverviewDocument() {
return overviewDocument.apply(
context.createMarkupDocBuilder(),
OverviewDocument.parameters(context.getSwagger()));
}
private MarkupDocBuilder applyPathsDocument() {
return pathsDocument.apply(
context.createMarkupDocBuilder(),
PathsDocument.parameters(context.getSwagger().getPaths()));
}
private MarkupDocBuilder applyDefinitionsDocument() {
return definitionsDocument.apply(
context.createMarkupDocBuilder(),
DefinitionsDocument.parameters(context.getSwagger().getDefinitions()));
}
private MarkupDocBuilder applySecurityDocument() {
return securityDocument.apply(
context.createMarkupDocBuilder(),
SecurityDocument.parameters(context.getSwagger().getSecurityDefinitions()));
new OverviewDocumentBuilder(context, extensionRegistry, outputDirectory).build().writeToFile(outputDirectory.resolve(context.config.getOverviewDocument()), StandardCharsets.UTF_8);
new PathsDocumentBuilder(context, extensionRegistry, outputDirectory).build().writeToFile(outputDirectory.resolve(context.config.getPathsDocument()), StandardCharsets.UTF_8);
new DefinitionsDocumentBuilder(context, extensionRegistry, outputDirectory).build().writeToFile(outputDirectory.resolve(context.config.getDefinitionsDocument()), StandardCharsets.UTF_8);
new SecurityDocumentBuilder(context, extensionRegistry, outputDirectory).build().writeToFile(outputDirectory.resolve(context.config.getSecurityDocument()), StandardCharsets.UTF_8);
}
/**
@@ -236,10 +202,10 @@ public class Swagger2MarkupConverter {
public void toFile(Path outputFile) {
Validate.notNull(outputFile, "outputFile must not be null");
applyOverviewDocument().writeToFile(outputFile, StandardCharsets.UTF_8);
applyPathsDocument().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
applyDefinitionsDocument().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
applySecurityDocument().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new OverviewDocumentBuilder(context,extensionRegistry, null).build().writeToFile(outputFile, StandardCharsets.UTF_8);
new PathsDocumentBuilder(context, extensionRegistry, null).build().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new DefinitionsDocumentBuilder(context, extensionRegistry, null).build().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new SecurityDocumentBuilder(context, extensionRegistry, null).build().writeToFile(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
}
/**
@@ -247,13 +213,13 @@ public class Swagger2MarkupConverter {
*
* @param outputFile the output file
*/
public void toFileWithoutExtension(Path outputFile) {
public void toFileWithoutExtension(Path outputFile){
Validate.notNull(outputFile, "outputFile must not be null");
applyOverviewDocument().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8);
applyPathsDocument().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
applyDefinitionsDocument().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
applySecurityDocument().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new OverviewDocumentBuilder(context, extensionRegistry, null).build().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8);
new PathsDocumentBuilder(context, extensionRegistry, null).build().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new DefinitionsDocumentBuilder(context, extensionRegistry, null).build().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
new SecurityDocumentBuilder(context, extensionRegistry, null).build().writeToFileWithoutExtension(outputFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
}
/**
@@ -264,10 +230,10 @@ public class Swagger2MarkupConverter {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(applyOverviewDocument().toString());
sb.append(applyPathsDocument().toString());
sb.append(applyDefinitionsDocument().toString());
sb.append(applySecurityDocument().toString());
sb.append(new OverviewDocumentBuilder(context,extensionRegistry, null).build().toString());
sb.append(new PathsDocumentBuilder(context, extensionRegistry, null).build().toString());
sb.append(new DefinitionsDocumentBuilder(context, extensionRegistry, null).build().toString());
sb.append(new SecurityDocumentBuilder(context, extensionRegistry, null).build().toString());
return sb.toString();
}
@@ -317,7 +283,7 @@ public class Swagger2MarkupConverter {
* @param swaggerLocation the location of the Swagger source
* @return the Swagger model
*/
private Swagger readSwagger(String swaggerLocation) {
private Swagger readSwagger(String swaggerLocation){
Swagger swagger = new SwaggerParser().read(swaggerLocation);
if (swagger == null) {
throw new IllegalArgumentException("Failed to read the Swagger source");
@@ -344,45 +310,48 @@ public class Swagger2MarkupConverter {
if (extensionRegistry == null)
extensionRegistry = new Swagger2MarkupExtensionRegistryBuilder().build();
Context context = new Context(config, extensionRegistry, swagger, swaggerLocation);
Context context = new Context(config, swagger, swaggerLocation);
initExtensions(context);
applySwaggerExtensions(context);
return new Swagger2MarkupConverter(context);
return new Swagger2MarkupConverter(context, extensionRegistry);
}
private void initExtensions(Context context) {
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.setGlobalContext(context));
for (SwaggerModelExtension extension : extensionRegistry.getSwaggerModelExtensions())
extension.setGlobalContext(context);
for (OverviewDocumentExtension extension : extensionRegistry.getOverviewDocumentExtensions())
extension.setGlobalContext(context);
for (DefinitionsDocumentExtension extension : extensionRegistry.getDefinitionsDocumentExtensions())
extension.setGlobalContext(context);
for (PathsDocumentExtension extension : extensionRegistry.getPathsDocumentExtensions())
extension.setGlobalContext(context);
for (SecurityDocumentExtension extension : extensionRegistry.getSecurityDocumentExtensions())
extension.setGlobalContext(context);
}
private void applySwaggerExtensions(Context context) {
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.apply(context.getSwagger()));
for (SwaggerModelExtension swaggerModelExtension : extensionRegistry.getSwaggerModelExtensions()) {
swaggerModelExtension.apply(context.getSwagger());
}
}
}
public static class Context {
private final Swagger2MarkupConfig config;
private final Swagger swagger;
private final URI swaggerLocation;
private final Swagger2MarkupExtensionRegistry extensionRegistry;
private final Labels labels;
private Path outputPath;
private Swagger2MarkupConfig config;
private Swagger swagger;
private URI swaggerLocation;
public Context(Swagger2MarkupConfig config,
Swagger2MarkupExtensionRegistry extensionRegistry,
Swagger swagger,
URI swaggerLocation) {
Context(Swagger2MarkupConfig config, Swagger swagger, URI swaggerLocation) {
this.config = config;
this.extensionRegistry = extensionRegistry;
this.swagger = swagger;
this.swaggerLocation = swaggerLocation;
this.labels = new Labels(config);
}
public Swagger2MarkupConfig getConfig() {
@@ -396,27 +365,6 @@ public class Swagger2MarkupConverter {
public URI getSwaggerLocation() {
return swaggerLocation;
}
public Swagger2MarkupExtensionRegistry getExtensionRegistry() {
return extensionRegistry;
}
public Labels getLabels() {
return labels;
}
public MarkupDocBuilder createMarkupDocBuilder() {
return MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(),
config.getLineSeparator()).withAnchorPrefix(config.getAnchorPrefix());
}
public Path getOutputPath() {
return outputPath;
}
public void setOutputPath(Path outputPath) {
this.outputPath = outputPath;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,35 +25,30 @@ import java.util.List;
public interface Swagger2MarkupExtensionRegistry {
/**
* SwaggerModelExtension extension point can be used to preprocess the Swagger model.
*
* @return registered extensions extending SwaggerModelExtension extension point
*/
List<SwaggerModelExtension> getSwaggerModelExtensions();
/**
* OverviewDocumentExtension extension point can be used to extend the overview document content.
*
* @return registered extensions extending OverviewDocumentExtension extension point
*/
List<OverviewDocumentExtension> getOverviewDocumentExtensions();
/**
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
*
* @return registered extensions extending DefinitionsDocumentExtension extension point
*/
List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions();
/**
* SecurityContentExtension extension point can be used to extend the security document content.
*
* @return registered extensions extending SecurityContentExtension extension point
*/
List<SecurityDocumentExtension> getSecurityDocumentExtensions();
/**
* PathsDocumentExtension extension point can be used to extend the paths document content.
*
* @return registered extensions extending PathsDocumentExtension extension point
*/
List<PathsDocumentExtension> getPathsDocumentExtensions();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,18 +17,18 @@ package io.github.swagger2markup;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.utils.URIUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.ConfigurationConverter;
import org.apache.commons.configuration2.MapConfiguration;
import org.apache.commons.configuration2.ex.ConversionException;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
public class Swagger2MarkupProperties {
@@ -40,20 +40,15 @@ public class Swagger2MarkupProperties {
public static final String MARKUP_LANGUAGE = PROPERTIES_PREFIX + ".markupLanguage";
public static final String SWAGGER_MARKUP_LANGUAGE = PROPERTIES_PREFIX + ".swaggerMarkupLanguage";
public static final String GENERATED_EXAMPLES_ENABLED = PROPERTIES_PREFIX + ".generatedExamplesEnabled";
public static final String BASE_PATH_PREFIX_ENABLED = PROPERTIES_PREFIX + ".basePathPrefixEnabled";
public static final String SEPARATED_DEFINITIONS_ENABLED = PROPERTIES_PREFIX + ".separatedDefinitionsEnabled";
public static final String SEPARATED_OPERATIONS_ENABLED = PROPERTIES_PREFIX + ".separatedOperationsEnabled";
public static final String PATHS_GROUPED_BY = PROPERTIES_PREFIX + ".pathsGroupedBy";
public static final String HEADER_REGEX = PROPERTIES_PREFIX + ".headerRegex";
public static final String OUTPUT_LANGUAGE = PROPERTIES_PREFIX + ".outputLanguage";
public static final String INLINE_SCHEMA_ENABLED = PROPERTIES_PREFIX + ".inlineSchemaEnabled";
public static final String INTER_DOCUMENT_CROSS_REFERENCES_ENABLED = PROPERTIES_PREFIX + ".interDocumentCrossReferencesEnabled";
public static final String INTER_DOCUMENT_CROSS_REFERENCES_PREFIX = PROPERTIES_PREFIX + ".interDocumentCrossReferencesPrefix";
public static final String FLAT_BODY_ENABLED = PROPERTIES_PREFIX + ".flatBodyEnabled";
public static final String PATH_SECURITY_SECTION_ENABLED = PROPERTIES_PREFIX + ".pathSecuritySectionEnabled";
public static final String ANCHOR_PREFIX = PROPERTIES_PREFIX + ".anchorPrefix";
public static final String LIST_DELIMITER = PROPERTIES_PREFIX + ".listDelimiter";
public static final String LIST_DELIMITER_ENABLED = PROPERTIES_PREFIX + ".listDelimiterEnabled";
public static final String OVERVIEW_DOCUMENT = PROPERTIES_PREFIX + ".overviewDocument";
public static final String PATHS_DOCUMENT = PROPERTIES_PREFIX + ".pathsDocument";
public static final String DEFINITIONS_DOCUMENT = PROPERTIES_PREFIX + ".definitionsDocument";
@@ -67,7 +62,6 @@ public class Swagger2MarkupProperties {
public static final String PROPERTY_ORDER_BY = PROPERTIES_PREFIX + ".propertyOrderBy";
public static final String RESPONSE_ORDER_BY = PROPERTIES_PREFIX + ".responseOrderBy";
public static final String LINE_SEPARATOR = PROPERTIES_PREFIX + ".lineSeparator";
public static final String PAGE_BREAK_LOCATIONS = PROPERTIES_PREFIX + ".pageBreakLocations";
/**
* Prefix for Swagger2Markup extension properties
@@ -84,63 +78,63 @@ public class Swagger2MarkupProperties {
this(new MapConfiguration(map));
}
public Swagger2MarkupProperties(Configuration configuration) {
public Swagger2MarkupProperties(Configuration configuration){
this.configuration = configuration;
}
/**
* Returns an optional String property value associated with the given key.
*
* @param key the property name to resolve
*
* @return The string property
*/
public Optional<String> getString(String key) {
public Optional<String> getString(String key){
return Optional.ofNullable(configuration.getString(key));
}
/**
* Return the String property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @param key the property name to resolve
* @param defaultValue the default value to return if no value is found
*
* @return The string property
*/
public String getString(String key, String defaultValue) {
public String getString(String key, String defaultValue){
return configuration.getString(key, defaultValue);
}
/**
* Return the int property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @param key the property name to resolve
* @param defaultValue the default value to return if no value is found
*
* @return The int property
*/
public int getInt(String key, int defaultValue) {
public int getInt(String key, int defaultValue){
return configuration.getInt(key, defaultValue);
}
/**
* Returns an optional Integer property value associated with the given key.
*
* @param key the property name to resolve
*
* @return An optional Integer property
*/
public Optional<Integer> getInteger(String key) {
public Optional<Integer> getInteger(String key){
return Optional.ofNullable(configuration.getInteger(key, null));
}
/**
* Return the int property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be
*
* @return The int property
* @throws IllegalStateException if the key cannot be
*/
public int getRequiredInt(String key) {
public int getRequiredInt(String key){
Optional<Integer> value = getInteger(key);
if (value.isPresent()) {
if(value.isPresent()){
return value.get();
}
throw new IllegalStateException(String.format("required key [%s] not found", key));
@@ -148,15 +142,15 @@ public class Swagger2MarkupProperties {
/**
* Return the boolean property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be resolved
*
* @return The boolean property
* @throws IllegalStateException if the key cannot be resolved
*/
public boolean getRequiredBoolean(String key) {
public boolean getRequiredBoolean(String key){
Boolean value = configuration.getBoolean(key, null);
if (value != null) {
if(value != null){
return value;
} else {
}else{
throw new IllegalStateException(String.format("required key [%s] not found", key));
}
}
@@ -164,43 +158,43 @@ public class Swagger2MarkupProperties {
/**
* Return the boolean property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @param key the property name to resolve
* @param defaultValue the default value to return if no value is found
*
* @return The boolean property
*/
public boolean getBoolean(String key, boolean defaultValue) {
public boolean getBoolean(String key, boolean defaultValue){
return configuration.getBoolean(key, defaultValue);
}
/**
* Return the URI property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @return The URI property
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @return The URI property
*/
public Optional<URI> getURI(String key) {
public Optional<URI> getURI(String key){
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return Optional.of(URIUtils.create(property.get()));
} else {
}else{
return Optional.empty();
}
}
/**
* Return the URI property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be resolved
*
* @return The URI property
* @throws IllegalStateException if the key cannot be resolved
*/
public URI getRequiredURI(String key) {
public URI getRequiredURI(String key){
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return URIUtils.create(property.get());
} else {
}else{
throw new IllegalStateException(String.format("required key [%s] not found", key));
}
}
@@ -208,55 +202,31 @@ public class Swagger2MarkupProperties {
/**
* Return the Path property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @return The Path property
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @return The Path property
*/
public Optional<Path> getPath(String key) {
public Optional<Path> getPath(String key){
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return Optional.of(Paths.get(property.get()));
} else {
}else{
return Optional.empty();
}
}
/**
* Return a list of Path property values associated with the given key,
* or {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @return The list of Path properties
* @throws IllegalStateException if the value cannot be mapped to an array of strings
*/
public List<Path> getPathList(String key) {
List<Path> pathList = new ArrayList<>();
try {
String[] stringList = configuration.getStringArray(key);
for (String pathStr : stringList) {
pathList.add(Paths.get(pathStr));
}
} catch (ConversionException ce) {
throw new IllegalStateException(String.format("requested key [%s] is not convertable to an array", key));
}
return pathList;
}
/**
* Return the Path property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be resolved
*
* @return The Path property
* @throws IllegalStateException if the key cannot be resolved
*/
public Path getRequiredPath(String key) {
public Path getRequiredPath(String key){
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return Paths.get(property.get());
} else {
}else{
throw new IllegalStateException(String.format("required key [%s] not found", key));
}
}
@@ -264,75 +234,75 @@ public class Swagger2MarkupProperties {
/**
* Return the MarkupLanguage property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
*
* @return The MarkupLanguage property
*/
public Optional<MarkupLanguage> getMarkupLanguage(String key) {
public Optional<MarkupLanguage> getMarkupLanguage(String key){
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return Optional.of(MarkupLanguage.valueOf(property.get()));
} else {
}else{
return Optional.empty();
}
}
/**
* Return the MarkupLanguage property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be resolved
*
* @return The MarkupLanguage property
* @throws IllegalStateException if the key cannot be resolved
*/
public MarkupLanguage getRequiredMarkupLanguage(String key) {
public MarkupLanguage getRequiredMarkupLanguage(String key){
return MarkupLanguage.valueOf(configuration.getString(key));
}
/**
* Return the Language property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
*
* @return The Language property
*/
public Language getLanguage(String key) {
public Language getLanguage(String key){
return Language.valueOf(configuration.getString(key));
}
/**
* Return the GroupBy property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @return The GroupBy property
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @return The GroupBy property
*/
public GroupBy getGroupBy(String key) {
public GroupBy getGroupBy(String key){
return GroupBy.valueOf(configuration.getString(key));
}
/**
* Return the OrderBy property value associated with the given key, or
* {@code defaultValue} if the key cannot be resolved.
*
* @param key the property name to resolve
* @return The OrderBy property
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @return The OrderBy property
*/
public OrderBy getOrderBy(String key) {
public OrderBy getOrderBy(String key){
return OrderBy.valueOf(configuration.getString(key));
}
/**
* Return the String property value associated with the given key (never {@code null}).
* @throws IllegalStateException if the key cannot be resolved
*
* @return The String property
* @throws IllegalStateException if the key cannot be resolved
*/
public String getRequiredString(String key) throws IllegalStateException {
public String getRequiredString(String key) throws IllegalStateException{
Optional<String> property = getString(key);
if (property.isPresent()) {
if(property.isPresent()){
return property.get();
} else {
}else{
throw new IllegalStateException(String.format("required key [%s] not found", key));
}
}
@@ -342,7 +312,7 @@ public class Swagger2MarkupProperties {
*
* @return the list of keys.
*/
public List<String> getKeys() {
public List<String> getKeys(){
return IteratorUtils.toList(configuration.getKeys());
}
@@ -359,25 +329,10 @@ public class Swagger2MarkupProperties {
* interpreted - depends on a concrete implementation.
*
* @param prefix The prefix to test against.
*
* @return the list of keys.
*/
public List<String> getKeys(String prefix) {
public List<String> getKeys(String prefix){
return IteratorUtils.toList(configuration.getKeys(prefix));
}
public List<PageBreakLocations> getPageBreakLocations(String key) {
List<PageBreakLocations> result = configuration.getList(PageBreakLocations.class, key);
if(result == null) result = new ArrayList<PageBreakLocations>();
return result;
}
public Optional<Pattern> getHeaderPattern(String key) {
Optional<String> property = getString(key);
if (property.isPresent()) {
return Optional.of(Pattern.compile(property.get()));
} else {
return Optional.empty();
}
}
}

View File

@@ -1,6 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Modified December 12 2016 by Cas Eliëns
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +15,7 @@
*/
package io.github.swagger2markup.builder;
import com.google.common.base.Function;
import com.google.common.collect.Ordering;
import io.github.swagger2markup.*;
import io.github.swagger2markup.markup.builder.LineSeparator;
@@ -25,32 +25,57 @@ import io.swagger.models.HttpMethod;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.configuration2.*;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import static io.github.swagger2markup.Swagger2MarkupProperties.*;
public class Swagger2MarkupConfigBuilder {
public class Swagger2MarkupConfigBuilder {
private static final Logger logger = LoggerFactory.getLogger(Swagger2MarkupConfigBuilder.class);
private static final String PROPERTIES_DEFAULT = "io/github/swagger2markup/config/default.properties";
static final Ordering<PathOperation> OPERATION_METHOD_NATURAL_ORDERING = Ordering
.explicit(HttpMethod.POST, HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.PATCH, HttpMethod.HEAD, HttpMethod.OPTIONS)
.onResultOf(PathOperation::getMethod);
.onResultOf(new Function<PathOperation, HttpMethod>() {
public HttpMethod apply(PathOperation operation) {
return operation.getMethod();
}
});
static final Ordering<PathOperation> OPERATION_PATH_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(PathOperation::getPath);
.onResultOf(new Function<PathOperation, String>() {
public String apply(PathOperation operation) {
return operation.getPath();
}
});
static final Ordering<Parameter> PARAMETER_IN_NATURAL_ORDERING = Ordering
.explicit("header", "path", "query", "formData", "body")
.onResultOf(Parameter::getIn);
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getIn();
}
});
static final Ordering<Parameter> PARAMETER_NAME_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(Parameter::getName);
private static final String PROPERTIES_DEFAULT = "io/github/swagger2markup/config/default.properties";
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getName();
}
});
DefaultSwagger2MarkupConfig config = new DefaultSwagger2MarkupConfig();
public Swagger2MarkupConfigBuilder() {
@@ -76,7 +101,6 @@ public class Swagger2MarkupConfigBuilder {
config.markupLanguage = swagger2MarkupProperties.getRequiredMarkupLanguage(MARKUP_LANGUAGE);
config.swaggerMarkupLanguage = swagger2MarkupProperties.getRequiredMarkupLanguage(SWAGGER_MARKUP_LANGUAGE);
config.generatedExamplesEnabled = swagger2MarkupProperties.getRequiredBoolean(GENERATED_EXAMPLES_ENABLED);
config.basePathPrefixEnabled = swagger2MarkupProperties.getRequiredBoolean(BASE_PATH_PREFIX_ENABLED);
config.separatedDefinitionsEnabled = swagger2MarkupProperties.getRequiredBoolean(SEPARATED_DEFINITIONS_ENABLED);
config.separatedOperationsEnabled = swagger2MarkupProperties.getRequiredBoolean(SEPARATED_OPERATIONS_ENABLED);
config.pathsGroupedBy = swagger2MarkupProperties.getGroupBy(PATHS_GROUPED_BY);
@@ -85,7 +109,6 @@ public class Swagger2MarkupConfigBuilder {
config.interDocumentCrossReferencesEnabled = swagger2MarkupProperties.getRequiredBoolean(INTER_DOCUMENT_CROSS_REFERENCES_ENABLED);
config.interDocumentCrossReferencesPrefix = swagger2MarkupProperties.getString(INTER_DOCUMENT_CROSS_REFERENCES_PREFIX, null);
config.flatBodyEnabled = swagger2MarkupProperties.getRequiredBoolean(FLAT_BODY_ENABLED);
config.pathSecuritySectionEnabled = swagger2MarkupProperties.getRequiredBoolean(PATH_SECURITY_SECTION_ENABLED);
config.anchorPrefix = swagger2MarkupProperties.getString(ANCHOR_PREFIX, null);
config.overviewDocument = swagger2MarkupProperties.getRequiredString(OVERVIEW_DOCUMENT);
config.pathsDocument = swagger2MarkupProperties.getRequiredString(PATHS_DOCUMENT);
@@ -100,23 +123,10 @@ public class Swagger2MarkupConfigBuilder {
config.propertyOrderBy = swagger2MarkupProperties.getOrderBy(PROPERTY_ORDER_BY);
config.responseOrderBy = swagger2MarkupProperties.getOrderBy(RESPONSE_ORDER_BY);
Optional<String> lineSeparator = swagger2MarkupProperties.getString(LINE_SEPARATOR);
if (lineSeparator.isPresent() && StringUtils.isNoneBlank(lineSeparator.get())) {
if(lineSeparator.isPresent() && StringUtils.isNoneBlank(lineSeparator.get())){
config.lineSeparator = LineSeparator.valueOf(lineSeparator.get());
}
config.pageBreakLocations = swagger2MarkupProperties.getPageBreakLocations(PAGE_BREAK_LOCATIONS);
Optional<Pattern> headerPattern = swagger2MarkupProperties.getHeaderPattern(HEADER_REGEX);
config.headerPattern = headerPattern.orElse(null);
config.listDelimiterEnabled = swagger2MarkupProperties.getBoolean(LIST_DELIMITER_ENABLED, false);
config.listDelimiter = swagger2MarkupProperties.getString(LIST_DELIMITER, ",").charAt(0);
if (config.listDelimiterEnabled && configuration instanceof AbstractConfiguration) {
((AbstractConfiguration) configuration).setListDelimiterHandler(new DefaultListDelimiterHandler(config.listDelimiter));
}
Configuration swagger2markupConfiguration = compositeConfiguration.subset(PROPERTIES_PREFIX);
Configuration extensionsConfiguration = swagger2markupConfiguration.subset(EXTENSION_PREFIX);
config.extensionsProperties = new Swagger2MarkupProperties(extensionsConfiguration);
@@ -217,29 +227,6 @@ public class Swagger2MarkupConfigBuilder {
return this;
}
/**
* Allows properties to contain a list of elements delimited by a specified character.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withListDelimiter() {
config.listDelimiterEnabled = true;
return this;
}
/**
* Specifies the list delimiter which should be used.
*
* @param delimiter the delimiter
* @return this builder
*/
public Swagger2MarkupConfigBuilder withListDelimiter(Character delimiter) {
Validate.notNull(delimiter, "%s must not be null", "delimiter");
config.listDelimiter = delimiter;
config.listDelimiterEnabled = true;
return this;
}
/**
* Specifies if the paths should be grouped by tags or stay as-is.
@@ -253,19 +240,6 @@ public class Swagger2MarkupConfigBuilder {
return this;
}
/**
* Specifies the regex pattern to use for grouping paths.
*
* @param headerRegex regex pattern string containing one capture group
* @return this builder
* @throws PatternSyntaxException when pattern cannot be compiled
*/
public Swagger2MarkupConfigBuilder withHeaderRegex(String headerRegex) {
Validate.notNull(headerRegex, "%s must not be null", headerRegex);
config.headerPattern = Pattern.compile(headerRegex);
return this;
}
/**
* Specifies labels language of output files.
*
@@ -492,26 +466,6 @@ public class Swagger2MarkupConfigBuilder {
return this;
}
/**
* Optionally disable the security section for path sections
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withoutPathSecuritySection() {
config.pathSecuritySectionEnabled = false;
return this;
}
/**
* Prepend the base path to all paths.
*
* @return this builder
*/
public Swagger2MarkupConfigBuilder withBasePathPrefix() {
config.basePathPrefixEnabled = true;
return this;
}
/**
* Optionally prefix all anchors for uniqueness.
*
@@ -519,23 +473,11 @@ public class Swagger2MarkupConfigBuilder {
* @return this builder
*/
public Swagger2MarkupConfigBuilder withAnchorPrefix(String anchorPrefix) {
Validate.notNull(anchorPrefix, "%s must not be null", "anchorPrefix");
Validate.notNull(anchorPrefix, "%s must no be null", "anchorPrefix");
config.anchorPrefix = anchorPrefix;
return this;
}
/**
* Set the page break locations
*
* @param locations List of locations to create new pages
* @return this builder
*/
public Swagger2MarkupConfigBuilder withPageBreaks(List<PageBreakLocations> locations) {
Validate.notNull(locations, "%s must not be null", "locations");
config.pageBreakLocations = locations;
return this;
}
/**
* Specifies the line separator which should be used.
*
@@ -548,12 +490,11 @@ public class Swagger2MarkupConfigBuilder {
return this;
}
static class DefaultSwagger2MarkupConfig implements Swagger2MarkupConfig {
static class DefaultSwagger2MarkupConfig implements Swagger2MarkupConfig{
private MarkupLanguage markupLanguage;
private MarkupLanguage swaggerMarkupLanguage;
private boolean generatedExamplesEnabled;
private boolean basePathPrefixEnabled;
private boolean separatedDefinitionsEnabled;
private boolean separatedOperationsEnabled;
private GroupBy pathsGroupedBy;
@@ -574,7 +515,6 @@ public class Swagger2MarkupConfigBuilder {
private boolean interDocumentCrossReferencesEnabled;
private String interDocumentCrossReferencesPrefix;
private boolean flatBodyEnabled;
private boolean pathSecuritySectionEnabled;
private String anchorPrefix;
private LineSeparator lineSeparator;
@@ -584,12 +524,6 @@ public class Swagger2MarkupConfigBuilder {
private String securityDocument;
private String separatedOperationsFolder;
private String separatedDefinitionsFolder;
private Character listDelimiter;
private boolean listDelimiterEnabled;
private List<PageBreakLocations> pageBreakLocations;
private Pattern headerPattern;
private Swagger2MarkupProperties extensionsProperties;
@@ -638,11 +572,6 @@ public class Swagger2MarkupConfigBuilder {
return tagOrderBy;
}
@Override
public Pattern getHeaderPattern() {
return headerPattern;
}
@Override
public Comparator<String> getTagOrdering() {
return tagOrdering;
@@ -713,11 +642,6 @@ public class Swagger2MarkupConfigBuilder {
return flatBodyEnabled;
}
@Override
public boolean isPathSecuritySectionEnabled() {
return pathSecuritySectionEnabled;
}
@Override
public String getAnchorPrefix() {
return anchorPrefix;
@@ -758,29 +682,9 @@ public class Swagger2MarkupConfigBuilder {
return lineSeparator;
}
@Override
public Character getListDelimiter() {
return listDelimiter;
}
@Override
public boolean isListDelimiterEnabled() {
return listDelimiterEnabled;
}
@Override
public Swagger2MarkupProperties getExtensionsProperties() {
return extensionsProperties;
}
@Override
public boolean isBasePathPrefixEnabled() {
return basePathPrefixEnabled;
}
@Override
public List<PageBreakLocations> getPageBreakLocations() {
return pageBreakLocations;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ public class Swagger2MarkupExtensionRegistryBuilder {
return this;
}
static class DefaultSwagger2MarkupExtensionRegistry implements Swagger2MarkupExtensionRegistry {
static class DefaultSwagger2MarkupExtensionRegistry implements Swagger2MarkupExtensionRegistry{
private Context context;
@@ -80,27 +80,27 @@ public class Swagger2MarkupExtensionRegistryBuilder {
}
@Override
public List<SwaggerModelExtension> getSwaggerModelExtensions() {
public List<SwaggerModelExtension> getSwaggerModelExtensions(){
return context.swaggerModelExtensions;
}
@Override
public List<OverviewDocumentExtension> getOverviewDocumentExtensions() {
public List<OverviewDocumentExtension> getOverviewDocumentExtensions(){
return context.overviewDocumentExtensions;
}
@Override
public List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions() {
public List<DefinitionsDocumentExtension> getDefinitionsDocumentExtensions(){
return context.definitionsDocumentExtensions;
}
@Override
public List<SecurityDocumentExtension> getSecurityDocumentExtensions() {
public List<SecurityDocumentExtension> getSecurityDocumentExtensions(){
return context.securityDocumentExtensions;
}
@Override
public List<PathsDocumentExtension> getPathsDocumentExtensions() {
public List<PathsDocumentExtension> getPathsDocumentExtensions(){
return context.pathsDocumentExtensions;
}
@@ -117,7 +117,7 @@ public class Swagger2MarkupExtensionRegistryBuilder {
List<OverviewDocumentExtension> overviewDocumentExtensions,
List<DefinitionsDocumentExtension> definitionsDocumentExtensions,
List<PathsDocumentExtension> pathsDocumentExtensions,
List<SecurityDocumentExtension> securityDocumentExtensions) {
List<SecurityDocumentExtension> securityDocumentExtensions){
this.swaggerModelExtensions = swaggerModelExtensions;
this.overviewDocumentExtensions = overviewDocumentExtensions;
this.definitionsDocumentExtensions = definitionsDocumentExtensions;

View File

@@ -1,205 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.adapter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.*;
import io.github.swagger2markup.internal.utils.InlineSchemaUtils;
import io.github.swagger2markup.internal.utils.ModelUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.Model;
import io.swagger.models.parameters.AbstractSerializableParameter;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.RefParameter;
import io.swagger.util.Json;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.*;
public class ParameterAdapter {
private final Parameter parameter;
private final List<ObjectType> inlineDefinitions = new ArrayList<>();
private final Swagger2MarkupConfig config;
private Type type;
public ParameterAdapter(Swagger2MarkupConverter.Context context,
PathOperation operation,
Parameter parameter,
DocumentResolver definitionDocumentResolver) {
Validate.notNull(parameter, "parameter must not be null");
this.parameter = parameter;
type = getType(context.getSwagger().getDefinitions(), definitionDocumentResolver);
config = context.getConfig();
if (config.isInlineSchemaEnabled()) {
if (config.isFlatBodyEnabled()) {
if (!(type instanceof ObjectType)) {
type = InlineSchemaUtils.createInlineType(type, parameter.getName(), operation.getId() + " " + parameter.getName(), inlineDefinitions);
}
} else {
type = InlineSchemaUtils.createInlineType(type, parameter.getName(), operation.getId() + " " + parameter.getName(), inlineDefinitions);
}
}
}
/**
* Generate a default example value for parameter.
*
* @param parameter parameter
* @return a generated example for the parameter
*/
public static Object generateExample(AbstractSerializableParameter parameter) {
switch (parameter.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
default:
return parameter.getType();
}
}
@JsonIgnore
public String getAccess() {
return parameter.getAccess();
}
public String getName() {
return parameter.getName();
}
public String getUniqueName() {
return type.getUniqueName();
}
public String displaySchema(MarkupDocBuilder docBuilder) {
return type.displaySchema(docBuilder);
}
public String displayDefaultValue(MarkupDocBuilder docBuilder) {
return getDefaultValue().map(value -> literalText(docBuilder, Json.pretty(value))).orElse("");
}
public String displayDescription(MarkupDocBuilder markupDocBuilder) {
return markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, getDescription());
}
public String displayType(MarkupDocBuilder markupDocBuilder) {
return boldText(markupDocBuilder, getIn());
}
public String getDescription() {
return parameter.getDescription();
}
public boolean getRequired() {
return parameter.getRequired();
}
public String getPattern() {
return parameter.getPattern();
}
public Map<String, Object> getVendorExtensions() {
return parameter.getVendorExtensions();
}
public String getIn() {
return WordUtils.capitalize(parameter.getIn());
}
public Type getType() {
return type;
}
public List<ObjectType> getInlineDefinitions() {
return inlineDefinitions;
}
/**
* Retrieves the type of a parameter, or otherwise null
*
* @param definitionDocumentResolver the definition document resolver
* @return the type of the parameter, or otherwise null
*/
private Type getType(Map<String, Model> definitions, DocumentResolver definitionDocumentResolver) {
Validate.notNull(parameter, "parameter must not be null!");
Type type = null;
if (parameter instanceof BodyParameter) {
BodyParameter bodyParameter = (BodyParameter) parameter;
Model model = bodyParameter.getSchema();
if (model != null) {
type = ModelUtils.getType(model, definitions, definitionDocumentResolver);
} else {
type = new BasicType("string", bodyParameter.getName());
}
} else if (parameter instanceof AbstractSerializableParameter) {
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter) parameter;
@SuppressWarnings("unchecked")
List<String> enums = serializableParameter.getEnum();
if (CollectionUtils.isNotEmpty(enums)) {
type = new EnumType(serializableParameter.getName(), enums);
} else {
type = new BasicType(serializableParameter.getType(), serializableParameter.getName(), serializableParameter.getFormat());
}
if (serializableParameter.getType().equals("array")) {
String collectionFormat = serializableParameter.getCollectionFormat();
type = new ArrayType(serializableParameter.getName(), new PropertyAdapter(serializableParameter.getItems()).getType(definitionDocumentResolver), collectionFormat);
}
} else if (parameter instanceof RefParameter) {
String refName = ((RefParameter) parameter).getSimpleRef();
type = new RefType(definitionDocumentResolver.apply(refName), new ObjectType(refName, null /* FIXME, not used for now */));
}
return type;
}
/**
* Retrieves the default value of a parameter
*
* @return the default value of the parameter
*/
public Optional<Object> getDefaultValue() {
Validate.notNull(parameter, "parameter must not be null!");
if (parameter instanceof AbstractSerializableParameter) {
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter) parameter;
return Optional.ofNullable(serializableParameter.getDefaultValue());
}
return Optional.empty();
}
}

View File

@@ -1,351 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.adapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.*;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.swagger.models.properties.*;
import io.swagger.models.refs.RefFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class PropertyAdapter {
private final Property property;
private static Logger logger = LoggerFactory.getLogger(PropertyAdapter.class);
public PropertyAdapter(Property property) {
Validate.notNull(property, "property must not be null");
this.property = property;
}
/**
* Generate a default example value for property.
*
* @param property property
* @param markupDocBuilder doc builder
* @return a generated example for the property
*/
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
switch (property.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
case "ref":
if (property instanceof RefProperty) {
if (logger.isDebugEnabled()) logger.debug("generateExample RefProperty for " + property.getName());
return markupDocBuilder.copy(false).crossReference(((RefProperty) property).getSimpleRef()).toString();
} else {
if (logger.isDebugEnabled()) logger.debug("generateExample for ref not RefProperty");
}
case "array":
if (property instanceof ArrayProperty) {
return generateArrayExample((ArrayProperty) property, markupDocBuilder);
}
default:
return property.getType();
}
}
/**
* Generate example for an ArrayProperty
*
* @param property ArrayProperty to generate example for
* @param markupDocBuilder MarkupDocBuilder containing all associated settings
* @return String example
*/
private static Object generateArrayExample(ArrayProperty property, MarkupDocBuilder markupDocBuilder) {
Property itemProperty = property.getItems();
List<Object> exampleArray = new ArrayList<>();
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
return exampleArray;
}
/**
* Convert a string {@code value} to specified {@code type}.
*
* @param value value to convert
* @param type target conversion type
* @return converted value as object
*/
public static Object convertExample(String value, String type) {
if (value == null) {
return null;
}
try {
switch (type) {
case "integer":
return Integer.valueOf(value);
case "number":
return Float.valueOf(value);
case "boolean":
return Boolean.valueOf(value);
case "string":
return value;
default:
return value;
}
} catch (NumberFormatException e) {
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
}
}
/**
* Retrieves the type and format of a property.
*
* @param definitionDocumentResolver the definition document resolver
* @return the type of the property
*/
public Type getType(DocumentResolver definitionDocumentResolver) {
Type type;
if (property instanceof RefProperty) {
RefProperty refProperty = (RefProperty) property;
if (refProperty.getRefFormat() == RefFormat.RELATIVE)
type = new ObjectType(refProperty.getTitle(), null); // FIXME : Workaround for https://github.com/swagger-api/swagger-parser/issues/177
else
type = new RefType(definitionDocumentResolver.apply(refProperty.getSimpleRef()), new ObjectType(refProperty.getSimpleRef(), null /* FIXME, not used for now */));
} else if (property instanceof ArrayProperty) {
ArrayProperty arrayProperty = (ArrayProperty) property;
Property items = arrayProperty.getItems();
if (items == null)
type = new ArrayType(arrayProperty.getTitle(), new ObjectType(null, null)); // FIXME : Workaround for Swagger parser issue with composed models (https://github.com/Swagger2Markup/swagger2markup/issues/150)
else
type = new ArrayType(arrayProperty.getTitle(), new PropertyAdapter(items).getType(definitionDocumentResolver));
} else if (property instanceof MapProperty) {
MapProperty mapProperty = (MapProperty) property;
Property additionalProperties = mapProperty.getAdditionalProperties();
if (additionalProperties == null)
type = new MapType(mapProperty.getTitle(), new ObjectType(null, null)); // FIXME : Workaround for Swagger parser issue with composed models (https://github.com/Swagger2Markup/swagger2markup/issues/150)
else
type = new MapType(mapProperty.getTitle(), new PropertyAdapter(additionalProperties).getType(definitionDocumentResolver));
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
List<String> enums = stringProperty.getEnum();
if (CollectionUtils.isNotEmpty(enums)) {
type = new EnumType(stringProperty.getTitle(), enums);
} else if (isNotBlank(stringProperty.getFormat())) {
type = new BasicType(stringProperty.getType(), stringProperty.getTitle(), stringProperty.getFormat());
} else {
type = new BasicType(stringProperty.getType(), stringProperty.getTitle());
}
} else if (property instanceof ObjectProperty) {
type = new ObjectType(property.getTitle(), ((ObjectProperty) property).getProperties());
} else {
if (isNotBlank(property.getFormat())) {
type = new BasicType(property.getType(), property.getTitle(), property.getFormat());
} else {
type = new BasicType(property.getType(), property.getTitle());
}
}
return type;
}
/**
* Retrieves the default value of a property
*
* @return the default value of the property
*/
public Optional<Object> getDefaultValue() {
if (property instanceof BooleanProperty) {
BooleanProperty booleanProperty = (BooleanProperty) property;
return Optional.ofNullable(booleanProperty.getDefault());
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
return Optional.ofNullable(stringProperty.getDefault());
} else if (property instanceof DoubleProperty) {
DoubleProperty doubleProperty = (DoubleProperty) property;
return Optional.ofNullable(doubleProperty.getDefault());
} else if (property instanceof FloatProperty) {
FloatProperty floatProperty = (FloatProperty) property;
return Optional.ofNullable(floatProperty.getDefault());
} else if (property instanceof IntegerProperty) {
IntegerProperty integerProperty = (IntegerProperty) property;
return Optional.ofNullable(integerProperty.getDefault());
} else if (property instanceof LongProperty) {
LongProperty longProperty = (LongProperty) property;
return Optional.ofNullable(longProperty.getDefault());
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
return Optional.ofNullable(uuidProperty.getDefault());
}
return Optional.empty();
}
/**
* Retrieves the minLength of a property
*
* @return the minLength of the property
*/
public Optional<Integer> getMinlength() {
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
return Optional.ofNullable(stringProperty.getMinLength());
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
return Optional.ofNullable(uuidProperty.getMinLength());
}
return Optional.empty();
}
/**
* Retrieves the maxLength of a property
*
* @return the maxLength of the property
*/
public Optional<Integer> getMaxlength() {
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
return Optional.ofNullable(stringProperty.getMaxLength());
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
return Optional.ofNullable(uuidProperty.getMaxLength());
}
return Optional.empty();
}
/**
* Retrieves the pattern of a property
*
* @return the pattern of the property
*/
public Optional<String> getPattern() {
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
return Optional.ofNullable(stringProperty.getPattern());
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
return Optional.ofNullable(uuidProperty.getPattern());
}
return Optional.empty();
}
/**
* Retrieves the minimum value of a property
*
* @return the minimum value of the property
*/
public Optional<BigDecimal> getMin() {
if (property instanceof BaseIntegerProperty) {
BaseIntegerProperty integerProperty = (BaseIntegerProperty) property;
return Optional.ofNullable(integerProperty.getMinimum() != null ? integerProperty.getMinimum() : null);
} else if (property instanceof AbstractNumericProperty) {
AbstractNumericProperty numericProperty = (AbstractNumericProperty) property;
return Optional.ofNullable(numericProperty.getMinimum());
}
return Optional.empty();
}
/**
* Retrieves the exclusiveMinimum value of a property
*
* @return the exclusiveMinimum value of the property
*/
public boolean getExclusiveMin() {
if (property instanceof AbstractNumericProperty) {
AbstractNumericProperty numericProperty = (AbstractNumericProperty) property;
return BooleanUtils.isTrue(numericProperty.getExclusiveMinimum());
}
return false;
}
/**
* Retrieves the minimum value of a property
*
* @return the minimum value of the property
*/
public Optional<BigDecimal> getMax() {
if (property instanceof BaseIntegerProperty) {
BaseIntegerProperty integerProperty = (BaseIntegerProperty) property;
return Optional.ofNullable(integerProperty.getMaximum() != null ? integerProperty.getMaximum() : null);
} else if (property instanceof AbstractNumericProperty) {
AbstractNumericProperty numericProperty = (AbstractNumericProperty) property;
return Optional.ofNullable(numericProperty.getMaximum());
}
return Optional.empty();
}
/**
* Retrieves the exclusiveMaximum value of a property
*
* @return the exclusiveMaximum value of the property
*/
public boolean getExclusiveMax() {
if (property instanceof AbstractNumericProperty) {
AbstractNumericProperty numericProperty = (AbstractNumericProperty) property;
return BooleanUtils.isTrue((numericProperty.getExclusiveMaximum()));
}
return false;
}
/**
* Return example display string for the given {@code property}.
*
* @param generateMissingExamples specifies if missing examples should be generated
* @param markupDocBuilder doc builder
* @return property example display string
*/
public Optional<Object> getExample(boolean generateMissingExamples, MarkupDocBuilder markupDocBuilder) {
if (property.getExample() != null) {
return Optional.ofNullable(property.getExample());
} else if (property instanceof MapProperty) {
Property additionalProperty = ((MapProperty) property).getAdditionalProperties();
if (additionalProperty.getExample() != null) {
return Optional.ofNullable(additionalProperty.getExample());
} else if (generateMissingExamples) {
Map<String, Object> exampleMap = new HashMap<>();
exampleMap.put("string", generateExample(additionalProperty, markupDocBuilder));
return Optional.of(exampleMap);
}
} else if (property instanceof ArrayProperty) {
if (generateMissingExamples) {
Property itemProperty = ((ArrayProperty) property).getItems();
List<Object> exampleArray = new ArrayList<>();
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
return Optional.of(exampleArray);
}
} else if (generateMissingExamples) {
return Optional.of(generateExample(property, markupDocBuilder));
}
return Optional.empty();
}
/**
* Checks if a property is read-only.
*
* @return true if the property is read-only
*/
public boolean getReadOnly() {
return BooleanUtils.isTrue(property.getReadOnly());
}
}

View File

@@ -1,127 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.adapter.ParameterAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.util.ArrayList;
import java.util.List;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class BodyParameterComponent extends MarkupComponent<BodyParameterComponent.Parameters> {
private final DocumentResolver definitionDocumentResolver;
private final PropertiesTableComponent propertiesTableComponent;
public BodyParameterComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionDocumentResolver) {
super(context);
this.definitionDocumentResolver = Validate.notNull(definitionDocumentResolver, "DocumentResolver must not be null");
this.propertiesTableComponent = new PropertiesTableComponent(context, definitionDocumentResolver);
}
public static BodyParameterComponent.Parameters parameters(PathOperation operation,
List<ObjectType> inlineDefinitions) {
return new BodyParameterComponent.Parameters(operation, inlineDefinitions);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
List<ObjectType> inlineDefinitions = params.inlineDefinitions;
if (config.isFlatBodyEnabled()) {
List<Parameter> parameters = operation.getOperation().getParameters();
if (CollectionUtils.isNotEmpty(parameters)) {
for (Parameter parameter : parameters) {
if (StringUtils.equals(parameter.getIn(), "body")) {
ParameterAdapter parameterAdapter = new ParameterAdapter(context,
operation, parameter, definitionDocumentResolver);
Type type = parameterAdapter.getType();
inlineDefinitions.addAll(parameterAdapter.getInlineDefinitions());
buildSectionTitle(markupDocBuilder, labels.getLabel(BODY_PARAMETER));
String description = parameter.getDescription();
if (isNotBlank(description)) {
markupDocBuilder.paragraph(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, description));
}
MarkupDocBuilder typeInfos = copyMarkupDocBuilder(markupDocBuilder);
typeInfos.italicText(labels.getLabel(NAME_COLUMN)).textLine(COLON + parameter.getName());
typeInfos.italicText(labels.getLabel(FLAGS_COLUMN)).textLine(COLON + (BooleanUtils.isTrue(parameter.getRequired()) ? labels.getLabel(FLAGS_REQUIRED).toLowerCase() : labels.getLabel(FLAGS_OPTIONAL).toLowerCase()));
if (!(type instanceof ObjectType)) {
typeInfos.italicText(labels.getLabel(TYPE_COLUMN)).textLine(COLON + type.displaySchema(markupDocBuilder));
}
markupDocBuilder.paragraph(typeInfos.toString(), true);
if (type instanceof ObjectType) {
List<ObjectType> localDefinitions = new ArrayList<>();
propertiesTableComponent.apply(markupDocBuilder, PropertiesTableComponent.parameters(
((ObjectType) type).getProperties(),
operation.getId(),
localDefinitions
));
inlineDefinitions.addAll(localDefinitions);
}
}
}
}
}
return markupDocBuilder;
}
private void buildSectionTitle(MarkupDocBuilder markupDocBuilder, String title) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
markupDocBuilder.sectionTitleLevel3(title);
} else {
markupDocBuilder.sectionTitleLevel4(title);
}
}
public static class Parameters {
private final List<ObjectType> inlineDefinitions;
private PathOperation operation;
public Parameters(PathOperation operation,
List<ObjectType> inlineDefinitions) {
Validate.notNull(operation, "Operation must not be null");
this.operation = operation;
this.inlineDefinitions = inlineDefinitions;
}
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.stream.Collectors;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.literalText;
public class ConsumesComponent extends MarkupComponent<ConsumesComponent.Parameters> {
public ConsumesComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static ConsumesComponent.Parameters parameters(List<String> consumes,
int titleLevel) {
return new ConsumesComponent.Parameters(consumes, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.CONSUMES));
markupDocBuilder.unorderedList(params.consumes.stream()
.map(value -> literalText(markupDocBuilder, value)).collect(Collectors.toList()));
return markupDocBuilder;
}
public static class Parameters {
private final List<String> consumes;
private final int titleLevel;
public Parameters(List<String> consumes,
int titleLevel) {
this.consumes = Validate.notNull(consumes, "Consumes must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Contact;
import org.apache.commons.lang3.Validate;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ContactInfoComponent extends MarkupComponent<ContactInfoComponent.Parameters> {
public ContactInfoComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static ContactInfoComponent.Parameters parameters(Contact contact,
int titleLevel) {
return new ContactInfoComponent.Parameters(contact, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
Contact contact = params.contact;
if (isNotBlank(contact.getName()) || isNotBlank(contact.getEmail())) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.CONTACT_INFORMATION));
MarkupDocBuilder paragraphBuilder = copyMarkupDocBuilder(markupDocBuilder);
if (isNotBlank(contact.getName())) {
paragraphBuilder.italicText(labels.getLabel(Labels.CONTACT_NAME))
.textLine(COLON + contact.getName());
}
if (isNotBlank(contact.getEmail())) {
paragraphBuilder.italicText(labels.getLabel(Labels.CONTACT_EMAIL))
.textLine(COLON + contact.getEmail());
}
markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
}
return markupDocBuilder;
}
public static class Parameters {
private final Contact contact;
private final int titleLevel;
public Parameters(Contact contact,
int titleLevel) {
this.contact = Validate.notNull(contact, "Contact must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,199 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.ObjectTypePolymorphism;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.internal.utils.ModelUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.DefinitionsDocumentExtension;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Model;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.*;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.InlineSchemaUtils.createInlineType;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static io.github.swagger2markup.spi.DefinitionsDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefinitionComponent extends MarkupComponent<DefinitionComponent.Parameters> {
/* Discriminator is only displayed for inheriting definitions */
private static final boolean ALWAYS_DISPLAY_DISCRIMINATOR = false;
private final Map<String, Model> definitions;
private final Map<ObjectTypePolymorphism.Nature, String> POLYMORPHISM_NATURE;
private final DocumentResolver definitionsDocumentResolver;
private PropertiesTableComponent propertiesTableComponent;
public DefinitionComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionsDocumentResolver) {
super(context);
this.definitions = context.getSwagger().getDefinitions();
this.definitionsDocumentResolver = definitionsDocumentResolver;
POLYMORPHISM_NATURE = new HashMap<ObjectTypePolymorphism.Nature, String>() {{
put(ObjectTypePolymorphism.Nature.COMPOSITION, labels.getLabel(POLYMORPHISM_NATURE_COMPOSITION));
put(ObjectTypePolymorphism.Nature.INHERITANCE, labels.getLabel(POLYMORPHISM_NATURE_INHERITANCE));
}};
propertiesTableComponent = new PropertiesTableComponent(context, definitionsDocumentResolver);
}
public static DefinitionComponent.Parameters parameters(String definitionName,
Model model,
int titleLevel) {
return new DefinitionComponent.Parameters(definitionName, model, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
String definitionName = params.definitionName;
Model model = params.model;
applyDefinitionsDocumentExtension(new DefinitionsDocumentExtension.Context(Position.DEFINITION_BEFORE, markupDocBuilder, definitionName, model));
markupDocBuilder.sectionTitleWithAnchorLevel(params.titleLevel, definitionName, definitionName);
applyDefinitionsDocumentExtension(new DefinitionsDocumentExtension.Context(Position.DEFINITION_BEGIN, markupDocBuilder, definitionName, model));
String description = model.getDescription();
if (isNotBlank(description)) {
markupDocBuilder.paragraph(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, description));
}
inlineDefinitions(markupDocBuilder, typeSection(markupDocBuilder, definitionName, model), definitionName);
applyDefinitionsDocumentExtension(new DefinitionsDocumentExtension.Context(Position.DEFINITION_END, markupDocBuilder, definitionName, model));
applyDefinitionsDocumentExtension(new DefinitionsDocumentExtension.Context(Position.DEFINITION_AFTER, markupDocBuilder, definitionName, model));
return markupDocBuilder;
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
* @param docBuilder the docbuilder do use for output
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor, null);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param markupDocBuilder the docbuilder do use for output
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
*/
private void inlineDefinitions(MarkupDocBuilder markupDocBuilder, List<ObjectType> definitions, String uniquePrefix) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), markupDocBuilder);
List<ObjectType> localDefinitions = new ArrayList<>();
propertiesTableComponent.apply(markupDocBuilder, new PropertiesTableComponent.Parameters(definition.getProperties(), uniquePrefix, localDefinitions));
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(markupDocBuilder, Collections.singletonList(localDefinition), localDefinition.getUniqueName());
}
}
}
/**
* Builds the type informations of a definition
*
* @param markupDocBuilder the docbuilder do use for output
* @param definitionName name of the definition to display
* @param model model of the definition to display
* @return a list of inlined types.
*/
private List<ObjectType> typeSection(MarkupDocBuilder markupDocBuilder, String definitionName, Model model) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
Type modelType = ModelUtils.resolveRefType(ModelUtils.getType(model, definitions, definitionsDocumentResolver));
if (!(modelType instanceof ObjectType) && config.isInlineSchemaEnabled()) {
modelType = createInlineType(modelType, definitionName, definitionName + " " + "inline", inlineDefinitions);
}
if (modelType instanceof ObjectType) {
ObjectType objectType = (ObjectType) modelType;
MarkupDocBuilder typeInfos = copyMarkupDocBuilder(markupDocBuilder);
switch (objectType.getPolymorphism().getNature()) {
case COMPOSITION:
typeInfos.italicText(labels.getLabel(POLYMORPHISM_COLUMN)).textLine(COLON + POLYMORPHISM_NATURE.get(objectType.getPolymorphism().getNature()));
break;
case INHERITANCE:
typeInfos.italicText(labels.getLabel(POLYMORPHISM_COLUMN)).textLine(COLON + POLYMORPHISM_NATURE.get(objectType.getPolymorphism().getNature()));
typeInfos.italicText(labels.getLabel(POLYMORPHISM_DISCRIMINATOR_COLUMN)).textLine(COLON + objectType.getPolymorphism().getDiscriminator());
break;
case NONE:
if (ALWAYS_DISPLAY_DISCRIMINATOR && isNotBlank(objectType.getPolymorphism().getDiscriminator()))
typeInfos.italicText(labels.getLabel(POLYMORPHISM_DISCRIMINATOR_COLUMN)).textLine(COLON + objectType.getPolymorphism().getDiscriminator());
break;
default:
break;
}
String typeInfosString = typeInfos.toString();
if (isNotBlank(typeInfosString))
markupDocBuilder.paragraph(typeInfosString, true);
propertiesTableComponent.apply(markupDocBuilder,
PropertiesTableComponent.parameters(
((ObjectType) modelType).getProperties(),
definitionName,
inlineDefinitions));
} else if (modelType != null) {
MarkupDocBuilder typeInfos = copyMarkupDocBuilder(markupDocBuilder);
typeInfos.italicText(labels.getLabel(TYPE_COLUMN)).textLine(COLON + modelType.displaySchema(markupDocBuilder));
markupDocBuilder.paragraph(typeInfos.toString());
}
return inlineDefinitions;
}
/**
* Apply extension context to all DefinitionsContentExtension
*
* @param context context
*/
private void applyDefinitionsDocumentExtension(DefinitionsDocumentExtension.Context context) {
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final String definitionName;
private final Model model;
private final int titleLevel;
public Parameters(String definitionName,
Model model,
int titleLevel) {
this.definitionName = Validate.notBlank(definitionName, "DefinitionName must not be empty");
this.model = Validate.notNull(model, "Model must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.ExternalDocs;
import org.apache.commons.lang3.Validate;
import static io.github.swagger2markup.Labels.EXTERNAL_DOCS;
import static io.github.swagger2markup.Labels.EXTERNAL_DOCS_DESC;
import static io.github.swagger2markup.Labels.EXTERNAL_DOCS_URL;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ExternalDocsComponent extends MarkupComponent<ExternalDocsComponent.Parameters> {
public ExternalDocsComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static ExternalDocsComponent.Parameters parameters(ExternalDocs externalDocs, int titleLevel) {
return new ExternalDocsComponent.Parameters(externalDocs, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
ExternalDocs externalDocs = params.externalDocs;
String description = externalDocs.getDescription();
String url = externalDocs.getUrl();
if ((description != null && (isNotBlank(description) || (url != null && isNotBlank(url))))) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(EXTERNAL_DOCS));
MarkupDocBuilder paragraph = copyMarkupDocBuilder(markupDocBuilder);
if (isNotBlank(description)) {
paragraph.italicText(labels.getLabel(EXTERNAL_DOCS_DESC)).textLine(COLON + description);
}
if (isNotBlank(url)) {
paragraph.italicText(labels.getLabel(EXTERNAL_DOCS_URL)).textLine(COLON + url);
}
markupDocBuilder.paragraph(paragraph.toString(), true);
}
return markupDocBuilder;
}
public static class Parameters {
private final int titleLevel;
private final ExternalDocs externalDocs;
public Parameters(ExternalDocs externalDocs,
int titleLevel) {
this.externalDocs = Validate.notNull(externalDocs, "ExternalDocs must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Info;
import io.swagger.models.License;
import org.apache.commons.lang3.Validate;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class LicenseInfoComponent extends MarkupComponent<LicenseInfoComponent.Parameters> {
public LicenseInfoComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static LicenseInfoComponent.Parameters parameters(Info info,
int titleLevel) {
return new LicenseInfoComponent.Parameters(info, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
Info info = params.info;
License license = info.getLicense();
String termOfService = info.getTermsOfService();
if ((license != null && (isNotBlank(license.getName()) || isNotBlank(license.getUrl()))) || isNotBlank(termOfService)) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(LICENSE_INFORMATION));
MarkupDocBuilder paragraph = copyMarkupDocBuilder(markupDocBuilder);
if (license != null) {
if (isNotBlank(license.getName())) {
paragraph.italicText(labels.getLabel(LICENSE)).textLine(COLON + license.getName());
}
if (isNotBlank(license.getUrl())) {
paragraph.italicText(labels.getLabel(LICENSE_URL)).textLine(COLON + license.getUrl());
}
}
paragraph.italicText(labels.getLabel(TERMS_OF_SERVICE)).textLine(COLON + termOfService);
markupDocBuilder.paragraph(paragraph.toString(), true);
}
return markupDocBuilder;
}
public static class Parameters {
private final int titleLevel;
private final Info info;
public Parameters(Info info,
int titleLevel) {
this.info = Validate.notNull(info, "Info must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,166 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.StringColumn;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.adapter.ParameterAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.github.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.stream.Collectors;
import static ch.netzwerg.paleo.ColumnIds.StringColumnId;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ParameterTableComponent extends MarkupComponent<ParameterTableComponent.Parameters> {
private final DocumentResolver definitionDocumentResolver;
private final TableComponent tableComponent;
ParameterTableComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionDocumentResolver) {
super(context);
this.definitionDocumentResolver = Validate.notNull(definitionDocumentResolver, "DocumentResolver must not be null");
this.tableComponent = new TableComponent(context);
}
public static ParameterTableComponent.Parameters parameters(PathOperation operation,
List<ObjectType> inlineDefinitions,
int titleLevel) {
return new ParameterTableComponent.Parameters(operation, inlineDefinitions, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
List<ObjectType> inlineDefinitions = params.inlineDefinitions;
List<Parameter> parameters = operation.getOperation().getParameters();
if (config.getParameterOrdering() != null)
parameters.sort(config.getParameterOrdering());
// Filter parameters to display in parameters section
List<Parameter> filteredParameters = parameters.stream()
.filter(this::filterParameter).collect(Collectors.toList());
MarkupDocBuilder parametersBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_PARAMETERS_BEGIN, parametersBuilder, operation));
if (CollectionUtils.isNotEmpty(filteredParameters)) {
StringColumn.Builder typeColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(TYPE_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "2");
StringColumn.Builder nameColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(NAME_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "3");
StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "9")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
StringColumn.Builder schemaColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(SCHEMA_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "4")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
StringColumn.Builder defaultColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DEFAULT_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "2")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
for (Parameter parameter : filteredParameters) {
ParameterAdapter parameterAdapter = new ParameterAdapter(context,
operation, parameter, definitionDocumentResolver);
inlineDefinitions.addAll(parameterAdapter.getInlineDefinitions());
typeColumnBuilder.add(parameterAdapter.displayType(markupDocBuilder));
nameColumnBuilder.add(getParameterNameColumnContent(markupDocBuilder, parameterAdapter));
descriptionColumnBuilder.add(parameterAdapter.displayDescription(markupDocBuilder));
schemaColumnBuilder.add(parameterAdapter.displaySchema(markupDocBuilder));
defaultColumnBuilder.add(parameterAdapter.displayDefaultValue(markupDocBuilder));
}
parametersBuilder = tableComponent.apply(parametersBuilder, TableComponent.parameters(
typeColumnBuilder.build(),
nameColumnBuilder.build(),
descriptionColumnBuilder.build(),
schemaColumnBuilder.build(),
defaultColumnBuilder.build()));
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_PARAMETERS_END, parametersBuilder, operation));
String parametersContent = parametersBuilder.toString();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_PARAMETERS_BEFORE, markupDocBuilder, operation));
if (isNotBlank(parametersContent)) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(PARAMETERS));
markupDocBuilder.text(parametersContent);
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_PARAMETERS_AFTER, markupDocBuilder, operation));
return markupDocBuilder;
}
private String getParameterNameColumnContent(MarkupDocBuilder markupDocBuilder, ParameterAdapter parameter) {
MarkupDocBuilder parameterNameContent = copyMarkupDocBuilder(markupDocBuilder);
parameterNameContent.boldTextLine(parameter.getName(), true);
if (parameter.getRequired())
parameterNameContent.italicText(labels.getLabel(FLAGS_REQUIRED).toLowerCase());
else
parameterNameContent.italicText(labels.getLabel(FLAGS_OPTIONAL).toLowerCase());
return parameterNameContent.toString();
}
/**
* Filter parameters to display in parameters section
*
* @param parameter parameter to filter
* @return true if parameter can be displayed
*/
private boolean filterParameter(Parameter parameter) {
return (!config.isFlatBodyEnabled() || !StringUtils.equals(parameter.getIn(), "body"));
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(PathsDocumentExtension.Context context) {
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final PathOperation operation;
private final int titleLevel;
private final List<ObjectType> inlineDefinitions;
public Parameters(PathOperation operation,
List<ObjectType> inlineDefinitions,
int titleLevel) {
this.operation = Validate.notNull(operation, "PathOperation must not be null");
this.inlineDefinitions = Validate.notNull(inlineDefinitions, "InlineDefinitions must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,482 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.PageBreakLocations;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.utils.ExamplesUtil;
import io.github.swagger2markup.markup.builder.MarkupAdmonition;
import io.github.swagger2markup.markup.builder.MarkupBlockStyle;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.github.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.Model;
import io.swagger.util.Json;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.*;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.PageBreakLocations.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class PathOperationComponent extends MarkupComponent<PathOperationComponent.Parameters> {
private final DocumentResolver definitionDocumentResolver;
private final Map<String, Model> definitions;
private final PropertiesTableComponent propertiesTableComponent;
private final ParameterTableComponent parameterTableComponent;
private final ConsumesComponent consumesComponent;
private final ProducesComponent producesComponent;
private final SecuritySchemeComponent securitySchemeComponent;
private final BodyParameterComponent bodyParameterComponent;
private final ResponseComponent responseComponent;
public PathOperationComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionDocumentResolver,
DocumentResolver securityDocumentResolver) {
super(context);
this.definitions = context.getSwagger().getDefinitions();
this.definitionDocumentResolver = Validate.notNull(definitionDocumentResolver, "DocumentResolver must not be null");
this.propertiesTableComponent = new PropertiesTableComponent(context, definitionDocumentResolver);
this.parameterTableComponent = new ParameterTableComponent(context, definitionDocumentResolver);
this.consumesComponent = new ConsumesComponent(context);
this.producesComponent = new ProducesComponent(context);
this.securitySchemeComponent = new SecuritySchemeComponent(context, securityDocumentResolver);
this.bodyParameterComponent = new BodyParameterComponent(context, definitionDocumentResolver);
this.responseComponent = new ResponseComponent(context, definitionDocumentResolver);
}
public static PathOperationComponent.Parameters parameters(PathOperation operation) {
return new PathOperationComponent.Parameters(operation);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
List<PageBreakLocations> locations = config.getPageBreakLocations();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_BEFORE, markupDocBuilder, operation));
if (locations.contains(BEFORE_OPERATION)) markupDocBuilder.pageBreak();
buildOperationTitle(markupDocBuilder, operation);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_BEGIN, markupDocBuilder, operation));
buildDeprecatedSection(markupDocBuilder, operation);
if (locations.contains(BEFORE_OPERATION_DESCRIPTION)) markupDocBuilder.pageBreak();
buildDescriptionSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_DESCRIPTION)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_PARAMETERS)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildParametersSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(AFTER_OPERATION_PARAMETERS)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildBodyParameterSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(BEFORE_OPERATION_RESPONSES)) markupDocBuilder.pageBreak();
inlineDefinitions(markupDocBuilder, buildResponsesSection(markupDocBuilder, operation), operation.getPath() + " " + operation.getMethod());
if (locations.contains(AFTER_OPERATION_RESPONSES)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_CONSUMES)) markupDocBuilder.pageBreak();
buildConsumesSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_CONSUMES)) markupDocBuilder.pageBreak();
if (locations.contains(BEFORE_OPERATION_PRODUCES)) markupDocBuilder.pageBreak();
buildProducesSection(markupDocBuilder, operation);
if (locations.contains(AFTER_OPERATION_PRODUCES)) markupDocBuilder.pageBreak();
buildTagsSection(markupDocBuilder, operation);
buildSecuritySchemeSection(markupDocBuilder, operation);
buildExamplesSection(markupDocBuilder, operation, locations);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_END, markupDocBuilder, operation));
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_AFTER, markupDocBuilder, operation));
if (locations.contains(AFTER_OPERATION)) markupDocBuilder.pageBreak();
return markupDocBuilder;
}
/**
* Adds the operation title to the document. If the operation has a summary, the title is the summary.
* Otherwise the title is the method of the operation and the URL of the operation.
*
* @param operation the Swagger Operation
*/
private void buildOperationTitle(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
buildOperationTitle(markupDocBuilder, operation.getTitle(), operation.getId());
if (operation.getTitle().equals(operation.getOperation().getSummary())) {
markupDocBuilder.block(operation.getMethod() + " " + operation.getPath(), MarkupBlockStyle.LITERAL);
}
}
/**
* Adds a operation title to the document.
*
* @param title the operation title
* @param anchor optional anchor (null => auto-generate from title)
*/
private void buildOperationTitle(MarkupDocBuilder markupDocBuilder, String title, String anchor) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
markupDocBuilder.sectionTitleWithAnchorLevel2(title, anchor);
} else {
markupDocBuilder.sectionTitleWithAnchorLevel3(title, anchor);
}
}
/**
* Builds a warning if method is deprecated.
*
* @param operation the Swagger Operation
*/
private void buildDeprecatedSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
if (BooleanUtils.isTrue(operation.getOperation().isDeprecated())) {
markupDocBuilder.block(DEPRECATED_OPERATION, MarkupBlockStyle.EXAMPLE, null, MarkupAdmonition.CAUTION);
}
}
/**
* Adds a operation description to the document.
*
* @param operation the Swagger Operation
*/
private void buildDescriptionSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
MarkupDocBuilder descriptionBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_DESCRIPTION_BEGIN, descriptionBuilder, operation));
String description = operation.getOperation().getDescription();
if (isNotBlank(description)) {
descriptionBuilder.paragraph(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, description));
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_DESCRIPTION_END, descriptionBuilder, operation));
String descriptionContent = descriptionBuilder.toString();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_DESCRIPTION_BEFORE, markupDocBuilder, operation));
if (isNotBlank(descriptionContent)) {
buildSectionTitle(markupDocBuilder, labels.getLabel(DESCRIPTION));
markupDocBuilder.text(descriptionContent);
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(Position.OPERATION_DESCRIPTION_AFTER, markupDocBuilder, operation));
}
/**
* Builds the parameters section
*
* @param operation the Swagger Operation
*/
private List<ObjectType> buildParametersSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
parameterTableComponent.apply(markupDocBuilder, ParameterTableComponent.parameters(
operation,
inlineDefinitions,
getSectionTitleLevel()
));
return inlineDefinitions;
}
/**
* Builds the body parameter section
*
* @param operation the Swagger Operation
* @return a list of inlined types.
*/
private List<ObjectType> buildBodyParameterSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
bodyParameterComponent.apply(markupDocBuilder, BodyParameterComponent.parameters(
operation,
inlineDefinitions
));
return inlineDefinitions;
}
private List<ObjectType> buildResponsesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
responseComponent.apply(markupDocBuilder, ResponseComponent.parameters(
operation,
getSectionTitleLevel(),
inlineDefinitions
));
return inlineDefinitions;
}
/**
* Adds a operation section title to the document.
*
* @param title the section title
*/
private void buildSectionTitle(MarkupDocBuilder markupDocBuilder, String title) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
markupDocBuilder.sectionTitleLevel3(title);
} else {
markupDocBuilder.sectionTitleLevel4(title);
}
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
*/
private void addInlineDefinitionTitle(MarkupDocBuilder markupDocBuilder, String title, String anchor) {
markupDocBuilder.anchor(anchor);
markupDocBuilder.newLine();
markupDocBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param markupDocBuilder the docbuilder do use for output
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
*/
private void inlineDefinitions(MarkupDocBuilder markupDocBuilder, List<ObjectType> definitions, String uniquePrefix) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(markupDocBuilder, definition.getName(), definition.getUniqueName());
List<ObjectType> localDefinitions = new ArrayList<>();
propertiesTableComponent.apply(markupDocBuilder, PropertiesTableComponent.parameters(
definition.getProperties(),
uniquePrefix,
localDefinitions
));
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(markupDocBuilder, Collections.singletonList(localDefinition), localDefinition.getUniqueName());
}
}
}
private void buildConsumesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
List<String> consumes = operation.getOperation().getConsumes();
if (CollectionUtils.isNotEmpty(consumes)) {
consumesComponent.apply(markupDocBuilder, ConsumesComponent.parameters(consumes,
getSectionTitleLevel()));
}
}
private void buildProducesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
List<String> produces = operation.getOperation().getProduces();
if (CollectionUtils.isNotEmpty(produces)) {
producesComponent.apply(markupDocBuilder, ProducesComponent.parameters(produces,
getSectionTitleLevel()));
}
}
private void buildTagsSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
List<String> tags = operation.getOperation().getTags();
if (CollectionUtils.isNotEmpty(tags)) {
buildSectionTitle(markupDocBuilder, labels.getLabel(TAGS));
if (config.getTagOrdering() != null) {
tags.sort(config.getTagOrdering());
}
markupDocBuilder.unorderedList(tags);
}
}
}
/**
* Builds the security section of a Swagger Operation.
*
* @param operation the Swagger Operation
*/
private void buildSecuritySchemeSection(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
if (config.isPathSecuritySectionEnabled()) {
securitySchemeComponent.apply(markupDocBuilder, SecuritySchemeComponent.parameters(
operation,
getSectionTitleLevel()
));
}
}
/**
* Retrieves the title level for sections
*/
private int getSectionTitleLevel() {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
return 3;
} else {
return 4;
}
}
/**
* Builds the example section of a Swagger Operation.
*
* @param operation the Swagger Operation
*/
private void buildExamplesSection(MarkupDocBuilder markupDocBuilder, PathOperation operation, List<PageBreakLocations> locations) {
// Generate examples
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
// Get page break settings
boolean beforeExampleRequestBreak = locations.contains(BEFORE_OPERATION_EXAMPLE_REQUEST);
boolean afterExampleRequestBreak = locations.contains(AFTER_OPERATION_EXAMPLE_REQUEST);
boolean beforeExampleResponseBreak = locations.contains(BEFORE_OPERATION_EXAMPLE_RESPONSE);
boolean afterExampleResponseBreak = locations.contains(AFTER_OPERATION_EXAMPLE_RESPONSE);
// Write examples
exampleMap(markupDocBuilder, generatedRequestExampleMap, labels.getLabel(EXAMPLE_REQUEST), labels.getLabel(REQUEST), beforeExampleRequestBreak, afterExampleRequestBreak);
exampleMap(markupDocBuilder, generatedResponseExampleMap, labels.getLabel(EXAMPLE_RESPONSE), labels.getLabel(RESPONSE), beforeExampleResponseBreak, afterExampleResponseBreak);
}
private void exampleMap(MarkupDocBuilder markupDocBuilder, Map<String, Object> exampleMap, String operationSectionTitle, String sectionTitle, boolean beforeBreak, boolean afterBreak) {
if (exampleMap.size() > 0) {
if (beforeBreak) markupDocBuilder.pageBreak();
buildSectionTitle(markupDocBuilder, operationSectionTitle);
for (Map.Entry<String, Object> entry : exampleMap.entrySet()) {
// Example title, like "Response 200" or "Request Body"
buildExampleTitle(markupDocBuilder, sectionTitle + " " + entry.getKey());
if (NumberUtils.isNumber(entry.getKey())) {
// Section header is an HTTP status code (numeric)
JsonNode rootNode = parseExample(entry.getValue());
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
if (!fieldsIterator.hasNext()) {
// rootNode contains a single example, no need to further iterate.
String example = Json.pretty(rootNode);
// String example = Json.pretty(stripExampleQuotes(rootNode.toString()));
// example = Json.pretty(example);
markupDocBuilder.listingBlock(example, "json");
}
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getKey().equals("application/json")) {
String example = Json.pretty(field.getValue());
example = stripExampleQuotes(StringEscapeUtils.unescapeJson(example));
markupDocBuilder.listingBlock(example, "json");
} else if (field.getKey().equals("application/xml")) {
String example = stripExampleQuotes(field.getValue().toString());
example = StringEscapeUtils.unescapeJava(example);
//TODO: pretty print XML
markupDocBuilder.listingBlock(example, "xml");
} else {
String example = Json.pretty(entry.getValue());
markupDocBuilder.listingBlock(example, "json");
break; // No need to print the same example multiple times
}
}
} else if (entry.getKey().equals("path")) {
// Path shouldn't have quotes around it
markupDocBuilder.listingBlock(entry.getValue().toString());
} else if (entry.getKey().equals("query")) {
//TODO issue #264: print query parameters in table
// markupDocBuilder.listingBlock(entry.getValue().toString());
logger.debug("Skipping query parameter: " + entry.getValue().toString());
} else {
markupDocBuilder.listingBlock(Json.pretty(entry.getValue()), "json");
}
}
if (afterBreak) markupDocBuilder.pageBreak();
}
}
/**
* Strip leading and trailing quotes from a string
*
* @param raw String containing leading or trailing quotes
* @return parsed String
*/
private String stripExampleQuotes(String raw) {
return raw
.replaceAll("^\"+", "") // Strip leading quotes
.replaceAll("\"+$", ""); // Strip trailing quotes
}
/**
* Parse a JSON array
*
* @param raw Object containing a JSON string
* @return JsonNode[contentType, example]
* @throws RuntimeException when the given JSON string cannot be parsed
*/
private JsonNode parseExample(Object raw) throws RuntimeException {
try {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
return mapper.readTree(Json.pretty(raw));
} catch (Exception ex) {
throw new RuntimeException("Failed to read example", ex);
}
}
/**
* Adds a example title to the document.
*
* @param title the section title
*/
private void buildExampleTitle(MarkupDocBuilder markupDocBuilder, String title) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
markupDocBuilder.sectionTitleLevel4(title);
} else {
markupDocBuilder.sectionTitleLevel5(title);
}
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(PathsDocumentExtension.Context context) {
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final PathOperation operation;
public Parameters(PathOperation operation) {
this.operation = Validate.notNull(operation, "PathOperation must not be null");
}
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.stream.Collectors;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.literalText;
public class ProducesComponent extends MarkupComponent<ProducesComponent.Parameters> {
public ProducesComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static ProducesComponent.Parameters parameters(List<String> consumes,
int titleLevel) {
return new ProducesComponent.Parameters(consumes, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.PRODUCES));
markupDocBuilder.unorderedList(params.produces.stream()
.map(value -> literalText(markupDocBuilder, value)).collect(Collectors.toList()));
return markupDocBuilder;
}
public static class Parameters {
private final List<String> produces;
private final int titleLevel;
public Parameters(List<String> produces, int titleLevel) {
this.produces = Validate.notNull(produces, "Produces must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,236 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.ColumnIds;
import ch.netzwerg.paleo.StringColumn;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.adapter.PropertyAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.RefType;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.Validate;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.InlineSchemaUtils.createInlineType;
import static io.github.swagger2markup.internal.utils.MapUtils.toSortedMap;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class PropertiesTableComponent extends MarkupComponent<PropertiesTableComponent.Parameters> {
private final DocumentResolver definitionDocumentResolver;
private final TableComponent tableComponent;
/**
* Build a generic property table
*
* @param definitionDocumentResolver definition document resolver to apply to property type cross-reference
*/
PropertiesTableComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionDocumentResolver) {
super(context);
this.definitionDocumentResolver = definitionDocumentResolver;
this.tableComponent = new TableComponent(context);
}
public static PropertiesTableComponent.Parameters parameters(Map<String, Property> properties,
String parameterName,
List<ObjectType> inlineDefinitions) {
return new PropertiesTableComponent.Parameters(properties, parameterName, inlineDefinitions);
}
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
//TODO: This method is too complex, split it up in smaller methods to increase readability
StringColumn.Builder nameColumnBuilder = StringColumn.builder(ColumnIds.StringColumnId.of(labels.getLabel(NAME_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "3");
StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(ColumnIds.StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "11")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
StringColumn.Builder schemaColumnBuilder = StringColumn.builder(ColumnIds.StringColumnId.of(labels.getLabel(SCHEMA_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "4")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
Map<String, Property> properties = params.properties;
if (MapUtils.isNotEmpty(properties)) {
Map<String, Property> sortedProperties = toSortedMap(properties, config.getPropertyOrdering());
sortedProperties.forEach((String propertyName, Property property) -> {
PropertyAdapter propertyAdapter = new PropertyAdapter(property);
Type propertyType = propertyAdapter.getType(definitionDocumentResolver);
if (config.isInlineSchemaEnabled()) {
propertyType = createInlineType(propertyType, propertyName, params.parameterName + " " + propertyName, params.inlineDefinitions);
}
Optional<Object> optionalExample = propertyAdapter.getExample(config.isGeneratedExamplesEnabled(), markupDocBuilder);
Optional<Object> optionalDefaultValue = propertyAdapter.getDefaultValue();
Optional<Integer> optionalMaxLength = propertyAdapter.getMaxlength();
Optional<Integer> optionalMinLength = propertyAdapter.getMinlength();
Optional<String> optionalPattern = propertyAdapter.getPattern();
Optional<BigDecimal> optionalMinValue = propertyAdapter.getMin();
boolean exclusiveMin = propertyAdapter.getExclusiveMin();
Optional<BigDecimal> optionalMaxValue = propertyAdapter.getMax();
boolean exclusiveMax = propertyAdapter.getExclusiveMax();
MarkupDocBuilder propertyNameContent = copyMarkupDocBuilder(markupDocBuilder);
propertyNameContent.boldTextLine(propertyName, true);
if (property.getRequired())
propertyNameContent.italicText(labels.getLabel(FLAGS_REQUIRED).toLowerCase());
else
propertyNameContent.italicText(labels.getLabel(FLAGS_OPTIONAL).toLowerCase());
if (propertyAdapter.getReadOnly()) {
propertyNameContent.newLine(true);
propertyNameContent.italicText(labels.getLabel(FLAGS_READ_ONLY).toLowerCase());
}
MarkupDocBuilder descriptionContent = copyMarkupDocBuilder(markupDocBuilder);
String description = markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, property.getDescription());
if (isNotBlank(description))
descriptionContent.text(description);
if (optionalDefaultValue.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
descriptionContent.boldText(labels.getLabel(DEFAULT_COLUMN)).text(COLON).literalText(Json.pretty(optionalDefaultValue.get()));
}
if (optionalMinLength.isPresent() && optionalMaxLength.isPresent()) {
// combination of minlength/maxlength
Integer minLength = optionalMinLength.get();
Integer maxLength = optionalMaxLength.get();
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
String lengthRange = minLength + " - " + maxLength;
if (minLength.equals(maxLength)) {
lengthRange = minLength.toString();
}
descriptionContent.boldText(labels.getLabel(LENGTH_COLUMN)).text(COLON).literalText(lengthRange);
} else {
if (optionalMinLength.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
descriptionContent.boldText(labels.getLabel(MINLENGTH_COLUMN)).text(COLON).literalText(optionalMinLength.get().toString());
}
if (optionalMaxLength.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
descriptionContent.boldText(labels.getLabel(MAXLENGTH_COLUMN)).text(COLON).literalText(optionalMaxLength.get().toString());
}
}
if (optionalPattern.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
descriptionContent.boldText(labels.getLabel(PATTERN_COLUMN)).text(COLON).literalText(Json.pretty(optionalPattern.get()));
}
DecimalFormat numberFormatter = new DecimalFormat("#.##",
DecimalFormatSymbols.getInstance(config.getOutputLanguage().toLocale()));
if (optionalMinValue.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
String minValueColumn = exclusiveMin ? labels.getLabel(MINVALUE_EXCLUSIVE_COLUMN) : labels.getLabel(MINVALUE_COLUMN);
descriptionContent.boldText(minValueColumn).text(COLON).literalText(numberFormatter.format(optionalMinValue.get()));
}
if (optionalMaxValue.isPresent()) {
if (isNotBlank(descriptionContent.toString())) {
descriptionContent.newLine(true);
}
String maxValueColumn = exclusiveMax ? labels.getLabel(MAXVALUE_EXCLUSIVE_COLUMN) : labels.getLabel(MAXVALUE_COLUMN);
descriptionContent.boldText(maxValueColumn).text(COLON).literalText(numberFormatter.format(optionalMaxValue.get()));
}
if (optionalExample.isPresent()) {
if (isNotBlank(description) || optionalDefaultValue.isPresent()) {
descriptionContent.newLine(true);
}
if(propertyType instanceof RefType && isReferenceLink(optionalExample.get().toString())) {
descriptionContent.boldText(labels.getLabel(EXAMPLE_COLUMN)).text(COLON).crossReference(optionalExample.get().toString());
} else {
descriptionContent.boldText(labels.getLabel(EXAMPLE_COLUMN)).text(COLON).literalText(Json.pretty(optionalExample.get()));
}
}
nameColumnBuilder.add(propertyNameContent.toString());
descriptionColumnBuilder.add(descriptionContent.toString());
schemaColumnBuilder.add(propertyType.displaySchema(markupDocBuilder));
});
}
return tableComponent.apply(markupDocBuilder, TableComponent.parameters(
nameColumnBuilder.build(),
descriptionColumnBuilder.build(),
schemaColumnBuilder.build()));
}
/*
* Check if a string is a link to a reference, format <<_referenceClass>>
*
* @param possibleAnchor String to check
* @return true if the string is a link to an anchor, false otherwise
*/
private boolean isReferenceLink(String possibleAnchor) {
return possibleAnchor.startsWith("<<_") && possibleAnchor.endsWith(">>");
}
public static class Parameters {
private final Map<String, Property> properties;
private final String parameterName;
private final List<ObjectType> inlineDefinitions;
public Parameters(Map<String, Property> properties,
String parameterName,
List<ObjectType> inlineDefinitions) {
this.properties = Validate.notNull(properties, "Properties must not be null");
this.parameterName = Validate.notBlank(parameterName, "ParameterName must not be blank");
this.inlineDefinitions = Validate.notNull(inlineDefinitions, "InlineDefinitions must not be null");
}
}
}

View File

@@ -1,173 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.StringColumn;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.adapter.PropertyAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.github.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.Response;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static ch.netzwerg.paleo.ColumnIds.StringColumnId;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.InlineSchemaUtils.createInlineType;
import static io.github.swagger2markup.internal.utils.MapUtils.toSortedMap;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ResponseComponent extends MarkupComponent<ResponseComponent.Parameters> {
private final TableComponent tableComponent;
private final DocumentResolver definitionDocumentResolver;
ResponseComponent(Swagger2MarkupConverter.Context context,
DocumentResolver definitionDocumentResolver) {
super(context);
this.definitionDocumentResolver = Validate.notNull(definitionDocumentResolver, "DocumentResolver must not be null");
this.tableComponent = new TableComponent(context);
}
public static ResponseComponent.Parameters parameters(PathOperation operation,
int titleLevel,
List<ObjectType> inlineDefinitions) {
return new ResponseComponent.Parameters(operation, titleLevel, inlineDefinitions);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
Map<String, Response> responses = operation.getOperation().getResponses();
MarkupDocBuilder responsesBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_RESPONSES_BEGIN, responsesBuilder, operation));
if (MapUtils.isNotEmpty(responses)) {
StringColumn.Builder httpCodeColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(HTTP_CODE_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "2");
StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "14")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
StringColumn.Builder schemaColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(SCHEMA_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "4")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
Map<String, Response> sortedResponses = toSortedMap(responses, config.getResponseOrdering());
sortedResponses.forEach((String responseName, Response response) -> {
String schemaContent = labels.getLabel(NO_CONTENT);
if (response.getSchema() != null) {
Property property = response.getSchema();
Type type = new PropertyAdapter(property).getType(definitionDocumentResolver);
if (config.isInlineSchemaEnabled()) {
type = createInlineType(type, labels.getLabel(RESPONSE) + " " + responseName, operation.getId() + " " + labels.getLabel(RESPONSE) + " " + responseName, params.inlineDefinitions);
}
schemaContent = type.displaySchema(markupDocBuilder);
}
MarkupDocBuilder descriptionBuilder = copyMarkupDocBuilder(markupDocBuilder);
descriptionBuilder.text(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, response.getDescription()));
Map<String, Property> headers = response.getHeaders();
if (MapUtils.isNotEmpty(headers)) {
descriptionBuilder.newLine(true).boldText(labels.getLabel(HEADERS_COLUMN)).text(COLON);
for (Map.Entry<String, Property> header : headers.entrySet()) {
descriptionBuilder.newLine(true);
Property headerProperty = header.getValue();
PropertyAdapter headerPropertyAdapter = new PropertyAdapter(headerProperty);
Type propertyType = headerPropertyAdapter.getType(definitionDocumentResolver);
String headerDescription = markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, headerProperty.getDescription());
Optional<Object> optionalDefaultValue = headerPropertyAdapter.getDefaultValue();
descriptionBuilder
.literalText(header.getKey())
.text(String.format(" (%s)", propertyType.displaySchema(markupDocBuilder)));
if (isNotBlank(headerDescription) || optionalDefaultValue.isPresent()) {
descriptionBuilder.text(COLON);
if (isNotBlank(headerDescription) && !headerDescription.endsWith("."))
headerDescription += ".";
descriptionBuilder.text(headerDescription);
optionalDefaultValue.ifPresent(o -> descriptionBuilder.text(" ")
.boldText(labels.getLabel(DEFAULT_COLUMN))
.text(COLON).literalText(Json.pretty(o)));
}
}
}
httpCodeColumnBuilder.add(boldText(markupDocBuilder, responseName));
descriptionColumnBuilder.add(descriptionBuilder.toString());
schemaColumnBuilder.add(schemaContent);
});
responsesBuilder = tableComponent.apply(responsesBuilder, TableComponent.parameters(httpCodeColumnBuilder.build(),
descriptionColumnBuilder.build(),
schemaColumnBuilder.build()));
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_RESPONSES_END, responsesBuilder, operation));
String responsesContent = responsesBuilder.toString();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_RESPONSES_BEFORE, markupDocBuilder, operation));
if (isNotBlank(responsesContent)) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(RESPONSES));
markupDocBuilder.text(responsesContent);
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_RESPONSES_AFTER, markupDocBuilder, operation));
return markupDocBuilder;
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(PathsDocumentExtension.Context context) {
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final PathOperation operation;
private final int titleLevel;
private final List<ObjectType> inlineDefinitions;
public Parameters(PathOperation operation,
int titleLevel,
List<ObjectType> inlineDefinitions) {
this.operation = Validate.notNull(operation, "PathOperation must not be null");
this.titleLevel = titleLevel;
this.inlineDefinitions = Validate.notNull(inlineDefinitions, "InlineDefinitions must not be null");
}
}
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.StringColumn;
import com.google.common.base.Joiner;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.github.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.Map;
import static ch.netzwerg.paleo.ColumnIds.StringColumnId;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class SecuritySchemeComponent extends MarkupComponent<SecuritySchemeComponent.Parameters> {
private final Map<String, SecuritySchemeDefinition> securityDefinitions;
private final DocumentResolver securityDocumentResolver;
private final TableComponent tableComponent;
public SecuritySchemeComponent(Swagger2MarkupConverter.Context context,
DocumentResolver securityDocumentResolver) {
super(context);
this.securityDefinitions = context.getSwagger().getSecurityDefinitions();
this.securityDocumentResolver = Validate.notNull(securityDocumentResolver, "SecurityDocumentResolver must not be null");
this.tableComponent = new TableComponent(context);
}
public static SecuritySchemeComponent.Parameters parameters(PathOperation operation,
int titleLevel) {
return new SecuritySchemeComponent.Parameters(operation, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
PathOperation operation = params.operation;
MarkupDocBuilder securityBuilder = copyMarkupDocBuilder(markupDocBuilder);
List<Map<String, List<String>>> securitySchemes = operation.getOperation().getSecurity();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_SECURITY_BEGIN, securityBuilder, operation));
if (CollectionUtils.isNotEmpty(securitySchemes)) {
StringColumn.Builder typeColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(TYPE_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "3");
StringColumn.Builder nameColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(NAME_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "4");
StringColumn.Builder scopeColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(SCOPES_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "13")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
for (Map<String, List<String>> securityScheme : securitySchemes) {
for (Map.Entry<String, List<String>> securityEntry : securityScheme.entrySet()) {
String securityKey = securityEntry.getKey();
String type = labels.getLabel(UNKNOWN);
if (securityDefinitions != null && securityDefinitions.containsKey(securityKey)) {
type = securityDefinitions.get(securityKey).getType();
}
typeColumnBuilder.add(boldText(markupDocBuilder, type));
nameColumnBuilder.add(boldText(markupDocBuilder, crossReference(markupDocBuilder, securityDocumentResolver.apply(securityKey), securityKey, securityKey)));
scopeColumnBuilder.add(Joiner.on(",").join(securityEntry.getValue()));
}
}
securityBuilder = tableComponent.apply(securityBuilder, TableComponent.parameters(typeColumnBuilder.build(),
nameColumnBuilder.build(),
scopeColumnBuilder.build()));
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_SECURITY_END, securityBuilder, operation));
String securityContent = securityBuilder.toString();
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_SECURITY_BEFORE, markupDocBuilder, operation));
if (isNotBlank(securityContent)) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(SECURITY));
markupDocBuilder.text(securityContent);
}
applyPathsDocumentExtension(new PathsDocumentExtension.Context(PathsDocumentExtension.Position.OPERATION_SECURITY_AFTER, markupDocBuilder, operation));
return markupDocBuilder;
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(PathsDocumentExtension.Context context) {
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final PathOperation operation;
private final int titleLevel;
public Parameters(PathOperation operation,
int titleLevel) {
this.operation = Validate.notNull(operation, "PathOperation must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,135 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.StringColumn;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.github.swagger2markup.spi.SecurityDocumentExtension;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.lang3.Validate;
import java.util.Map;
import static ch.netzwerg.paleo.ColumnIds.StringColumnId;
import static io.github.swagger2markup.Labels.*;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static io.github.swagger2markup.spi.SecurityDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class SecuritySchemeDefinitionComponent extends MarkupComponent<SecuritySchemeDefinitionComponent.Parameters> {
private final TableComponent tableComponent;
public SecuritySchemeDefinitionComponent(Swagger2MarkupConverter.Context context) {
super(context);
this.tableComponent = new TableComponent(context);
}
public static SecuritySchemeDefinitionComponent.Parameters parameters(String securitySchemeDefinitionName,
SecuritySchemeDefinition securitySchemeDefinition,
int titleLevel) {
return new SecuritySchemeDefinitionComponent.Parameters(securitySchemeDefinitionName, securitySchemeDefinition, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
String securitySchemeDefinitionName = params.securitySchemeDefinitionName;
SecuritySchemeDefinition securitySchemeDefinition = params.securitySchemeDefinition;
applySecurityDocumentExtension(new SecurityDocumentExtension.Context(Position.SECURITY_SCHEME_BEFORE, markupDocBuilder, securitySchemeDefinitionName, securitySchemeDefinition));
markupDocBuilder.sectionTitleWithAnchorLevel(params.titleLevel, securitySchemeDefinitionName);
applySecurityDocumentExtension(new SecurityDocumentExtension.Context(Position.SECURITY_SCHEME_BEGIN, markupDocBuilder, securitySchemeDefinitionName, securitySchemeDefinition));
String description = securitySchemeDefinition.getDescription();
if (isNotBlank(description)) {
markupDocBuilder.paragraph(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, description));
}
buildSecurityScheme(markupDocBuilder, securitySchemeDefinition);
applySecurityDocumentExtension(new SecurityDocumentExtension.Context(Position.SECURITY_SCHEME_END, markupDocBuilder, securitySchemeDefinitionName, securitySchemeDefinition));
applySecurityDocumentExtension(new SecurityDocumentExtension.Context(Position.SECURITY_SCHEME_AFTER, markupDocBuilder, securitySchemeDefinitionName, securitySchemeDefinition));
return markupDocBuilder;
}
private MarkupDocBuilder buildSecurityScheme(MarkupDocBuilder markupDocBuilder, SecuritySchemeDefinition securityScheme) {
String type = securityScheme.getType();
MarkupDocBuilder paragraphBuilder = copyMarkupDocBuilder(markupDocBuilder);
paragraphBuilder.italicText(labels.getLabel(TYPE)).textLine(COLON + type);
if (securityScheme instanceof ApiKeyAuthDefinition) {
paragraphBuilder.italicText(labels.getLabel(NAME)).textLine(COLON + ((ApiKeyAuthDefinition) securityScheme).getName());
paragraphBuilder.italicText(labels.getLabel(IN)).textLine(COLON + ((ApiKeyAuthDefinition) securityScheme).getIn());
return markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
} else if (securityScheme instanceof OAuth2Definition) {
OAuth2Definition oauth2Scheme = (OAuth2Definition) securityScheme;
String flow = oauth2Scheme.getFlow();
paragraphBuilder.italicText(labels.getLabel(FLOW)).textLine(COLON + flow);
if (isNotBlank(oauth2Scheme.getAuthorizationUrl())) {
paragraphBuilder.italicText(labels.getLabel(AUTHORIZATION_URL)).textLine(COLON + oauth2Scheme.getAuthorizationUrl());
}
if (isNotBlank(oauth2Scheme.getTokenUrl())) {
paragraphBuilder.italicText(labels.getLabel(TOKEN_URL)).textLine(COLON + oauth2Scheme.getTokenUrl());
}
StringColumn.Builder nameColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(NAME_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "3")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN)))
.putMetaData(TableComponent.WIDTH_RATIO, "17")
.putMetaData(TableComponent.HEADER_COLUMN, "true");
if (oauth2Scheme.getScopes() != null) {
for (Map.Entry<String, String> scope : oauth2Scheme.getScopes().entrySet()) {
nameColumnBuilder.add(scope.getKey());
descriptionColumnBuilder.add(scope.getValue());
}
}
markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
return tableComponent.apply(markupDocBuilder, TableComponent.parameters(nameColumnBuilder.build(),
descriptionColumnBuilder.build()));
} else {
return markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
}
}
/**
* Apply extension context to all SecurityContentExtension
*
* @param context context
*/
private void applySecurityDocumentExtension(SecurityDocumentExtension.Context context) {
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final String securitySchemeDefinitionName;
private final SecuritySchemeDefinition securitySchemeDefinition;
private final int titleLevel;
public Parameters(String securitySchemeDefinitionName,
SecuritySchemeDefinition securitySchemeDefinition,
int titleLevel) {
this.securitySchemeDefinitionName = Validate.notBlank(securitySchemeDefinitionName, "SecuritySchemeDefinitionName must not be empty");
this.securitySchemeDefinition = Validate.notNull(securitySchemeDefinition, "SecuritySchemeDefinition must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import ch.netzwerg.paleo.DataFrame;
import ch.netzwerg.paleo.StringColumn;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.markup.builder.MarkupTableColumn;
import io.github.swagger2markup.spi.MarkupComponent;
import javaslang.collection.Array;
import javaslang.collection.IndexedSeq;
import javaslang.collection.List;
import org.apache.commons.lang3.StringUtils;
public class TableComponent extends MarkupComponent<TableComponent.Parameters> {
public static final String WIDTH_RATIO = "widthRatio";
public static final String HEADER_COLUMN = "headerColumn";
public TableComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static TableComponent.Parameters parameters(StringColumn... columns) {
return new TableComponent.Parameters(columns);
}
public static boolean isNotBlank(StringColumn column) {
return !column.getValues().filter(StringUtils::isNotBlank).isEmpty();
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
DataFrame dataFrame = params.dataFrame;
java.util.List<MarkupTableColumn> columnSpecs = dataFrame.getColumns().map(column -> {
Integer widthRatio = Integer.valueOf(column.getMetaData().get(WIDTH_RATIO).getOrElse("0"));
return new MarkupTableColumn(column.getId().getName())
.withWidthRatio(widthRatio)
.withHeaderColumn(Boolean.parseBoolean(column.getMetaData().get(HEADER_COLUMN).getOrElse("false")))
.withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^" + widthRatio);
}
).toJavaList();
IndexedSeq<IndexedSeq<String>> columnValues = dataFrame.getColumns()
.map(column -> ((StringColumn) column).getValues());
java.util.List<java.util.List<String>> cells = Array.range(0, dataFrame.getRowCount())
.map(rowNumber -> columnValues.map(values -> values.get(rowNumber)).toJavaList()).toJavaList();
return markupDocBuilder.tableWithColumnSpecs(columnSpecs, cells);
}
public static class Parameters {
private final DataFrame dataFrame;
public Parameters(StringColumn... columns) {
this.dataFrame = DataFrame.ofAll(List.of(columns).filter(TableComponent::isNotBlank));
}
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Tag;
import org.apache.commons.lang3.Validate;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class TagsComponent extends MarkupComponent<TagsComponent.Parameters> {
public TagsComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static TagsComponent.Parameters parameters(List<Tag> tags,
int titleLevel) {
return new TagsComponent.Parameters(tags, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.TAGS));
List<String> tagsList = params.tags.stream()
.map(this::mapToString).collect(Collectors.toList());
if (config.getTagOrdering() != null)
Collections.sort(tagsList, config.getTagOrdering());
markupDocBuilder.unorderedList(tagsList);
return markupDocBuilder;
}
private String mapToString(Tag tag) {
String name = tag.getName();
String description = tag.getDescription();
if (isNotBlank(description)) {
return name + COLON + description;
} else {
return name;
}
}
public static class Parameters {
private final List<Tag> tags;
private final int titleLevel;
public Parameters(List<Tag> tags,
int titleLevel) {
this.tags = Validate.notNull(tags, "Tags must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Swagger;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.stream.Collectors;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.join;
public class UriSchemeComponent extends MarkupComponent<UriSchemeComponent.Parameters> {
public UriSchemeComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static UriSchemeComponent.Parameters parameters(Swagger swagger, int titleLevel) {
return new UriSchemeComponent.Parameters(swagger, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
Swagger swagger = params.swagger;
if (isNotBlank(swagger.getHost()) || isNotBlank(swagger.getBasePath()) || isNotEmpty(swagger.getSchemes())) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.URI_SCHEME));
MarkupDocBuilder paragraphBuilder = copyMarkupDocBuilder(markupDocBuilder);
if (isNotBlank(swagger.getHost())) {
paragraphBuilder.italicText(labels.getLabel(Labels.HOST))
.textLine(COLON + swagger.getHost());
}
if (isNotBlank(swagger.getBasePath())) {
paragraphBuilder.italicText(labels.getLabel(Labels.BASE_PATH))
.textLine(COLON + swagger.getBasePath());
}
if (isNotEmpty(swagger.getSchemes())) {
List<String> schemes = swagger.getSchemes().stream()
.map(Enum::toString)
.collect(Collectors.toList());
paragraphBuilder.italicText(labels.getLabel(Labels.SCHEMES))
.textLine(COLON + join(schemes, ", "));
}
markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
}
return markupDocBuilder;
}
public static class Parameters {
private final int titleLevel;
private final Swagger swagger;
public Parameters(Swagger swagger, int titleLevel) {
this.swagger = Validate.notNull(swagger);
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.component;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Info;
import org.apache.commons.lang3.Validate;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class VersionInfoComponent extends MarkupComponent<VersionInfoComponent.Parameters> {
public VersionInfoComponent(Swagger2MarkupConverter.Context context) {
super(context);
}
public static VersionInfoComponent.Parameters parameters(Info info,
int titleLevel) {
return new VersionInfoComponent.Parameters(info, titleLevel);
}
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, Parameters params) {
String version = params.info.getVersion();
if (isNotBlank(version)) {
markupDocBuilder.sectionTitleLevel(params.titleLevel, labels.getLabel(Labels.CURRENT_VERSION));
MarkupDocBuilder paragraphBuilder = copyMarkupDocBuilder(markupDocBuilder);
paragraphBuilder.italicText(labels.getLabel(Labels.VERSION)).textLine(COLON + version);
markupDocBuilder.paragraph(paragraphBuilder.toString(), true);
}
return markupDocBuilder;
}
public static class Parameters {
private final int titleLevel;
private final Info info;
public Parameters(
Info info,
int titleLevel) {
this.info = Validate.notNull(info, "Info must not be null");
this.titleLevel = titleLevel;
}
}
}

View File

@@ -1,194 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.component.DefinitionComponent;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentNameResolver;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverDefault;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverFromDefinition;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Model;
import org.apache.commons.collections4.MapUtils;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static io.github.swagger2markup.internal.utils.MapUtils.toSortedMap;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.crossReference;
import static io.github.swagger2markup.spi.DefinitionsDocumentExtension.Context;
import static io.github.swagger2markup.spi.DefinitionsDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class DefinitionsDocument extends MarkupComponent<DefinitionsDocument.Parameters> {
private static final String DEFINITIONS_ANCHOR = "definitions";
private static final List<String> IGNORED_DEFINITIONS = Collections.singletonList("Void");
private final DefinitionComponent definitionComponent;
private final DefinitionDocumentResolverDefault definitionDocumentResolverDefault;
private final DefinitionDocumentNameResolver definitionDocumentNameResolver;
public DefinitionsDocument(Swagger2MarkupConverter.Context context) {
super(context);
if (config.isSeparatedDefinitionsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is disabled.");
}
}
this.definitionDocumentNameResolver = new DefinitionDocumentNameResolver(context);
this.definitionComponent = new DefinitionComponent(context, new DefinitionDocumentResolverFromDefinition(context));
this.definitionDocumentResolverDefault = new DefinitionDocumentResolverDefault(context);
}
public static DefinitionsDocument.Parameters parameters(Map<String, Model> definitions) {
return new DefinitionsDocument.Parameters(definitions);
}
/**
* Builds the definitions MarkupDocument.
*
* @return the definitions MarkupDocument
*/
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, DefinitionsDocument.Parameters params) {
Map<String, Model> definitions = params.definitions;
if (MapUtils.isNotEmpty(definitions)) {
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, markupDocBuilder));
buildDefinitionsTitle(markupDocBuilder, labels.getLabel(Labels.DEFINITIONS));
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, markupDocBuilder));
buildDefinitionsSection(markupDocBuilder, definitions);
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_END, markupDocBuilder));
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_AFTER, markupDocBuilder));
}
return markupDocBuilder;
}
private void buildDefinitionsTitle(MarkupDocBuilder markupDocBuilder, String title) {
markupDocBuilder.sectionTitleWithAnchorLevel1(title, DEFINITIONS_ANCHOR);
}
private void buildDefinitionsSection(MarkupDocBuilder markupDocBuilder, Map<String, Model> definitions) {
Map<String, Model> sortedMap = toSortedMap(definitions, config.getDefinitionOrdering());
sortedMap.forEach((String definitionName, Model model) -> {
if (isNotBlank(definitionName)
&& checkThatDefinitionIsNotInIgnoreList(definitionName)) {
buildDefinition(markupDocBuilder, definitionName, model);
}
});
}
/**
* Apply extension context to all DefinitionsContentExtension
*
* @param context context
*/
private void applyDefinitionsDocumentExtension(Context context) {
extensionRegistry.getDefinitionsDocumentExtensions().forEach(extension -> extension.apply(context));
}
/**
* Generate definition files depending on the generation mode
*
* @param definitionName definition name to process
* @param model definition model to process
*/
private void buildDefinition(MarkupDocBuilder markupDocBuilder, String definitionName, Model model) {
if (logger.isDebugEnabled()) {
logger.debug("Definition processed : '{}'", definitionName);
}
if (config.isSeparatedDefinitionsEnabled()) {
MarkupDocBuilder defDocBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyDefinitionComponent(defDocBuilder, definitionName, model);
Path definitionFile = context.getOutputPath().resolve(definitionDocumentNameResolver.apply(definitionName));
defDocBuilder.writeToFileWithoutExtension(definitionFile, StandardCharsets.UTF_8);
if (logger.isDebugEnabled()) {
logger.debug("Separate definition file produced : '{}'", definitionFile);
}
definitionRef(markupDocBuilder, definitionName);
} else {
applyDefinitionComponent(markupDocBuilder, definitionName, model);
}
}
/**
* Checks that the definition is not in the list of ignored definitions.
*
* @param definitionName the name of the definition
* @return true if the definition can be processed
*/
private boolean checkThatDefinitionIsNotInIgnoreList(String definitionName) {
return !IGNORED_DEFINITIONS.contains(definitionName);
}
/**
* Builds a concrete definition
*
* @param markupDocBuilder the markupDocBuilder do use for output
* @param definitionName the name of the definition
* @param model the Swagger Model of the definition
*/
private void applyDefinitionComponent(MarkupDocBuilder markupDocBuilder, String definitionName, Model model) {
definitionComponent.apply(markupDocBuilder, DefinitionComponent.parameters(
definitionName,
model,
2));
}
/**
* Builds a cross-reference to a separated definition file.
*
* @param definitionName definition name to target
*/
private void definitionRef(MarkupDocBuilder markupDocBuilder, String definitionName) {
buildDefinitionTitle(markupDocBuilder, crossReference(markupDocBuilder, definitionDocumentResolverDefault.apply(definitionName), definitionName, definitionName), "ref-" + definitionName);
}
/**
* Builds definition title
*
* @param markupDocBuilder the markupDocBuilder do use for output
* @param title definition title
* @param anchor optional anchor (null => auto-generate from title)
*/
private void buildDefinitionTitle(MarkupDocBuilder markupDocBuilder, String title, String anchor) {
markupDocBuilder.sectionTitleWithAnchorLevel2(title, anchor);
}
public static class Parameters {
private final Map<String, Model> definitions;
public Parameters(Map<String, Model> definitions) {
this.definitions = definitions;
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import java.nio.charset.Charset;
import java.nio.file.OpenOption;
import java.nio.file.Path;
public class MarkupDocument {
private MarkupDocBuilder markupDocBuilder;
public MarkupDocument(MarkupDocBuilder markupDocBuilder) {
this.markupDocBuilder = markupDocBuilder;
}
/**
* Returns a string representation of the document.
*/
public String toString() {
return markupDocBuilder.toString();
}
/**
* Writes the content of the builder to a file.<br>
* An extension identifying the markup language will be automatically added to file name.
*
* @param file the generated file
* @param charset the the charset to use for encoding
* @param options the file open options
*/
public void writeToFile(Path file, Charset charset, OpenOption... options) {
markupDocBuilder.writeToFile(file, charset, options);
}
/**
* Writes the content of the builder to a file.
*
* @param file the generated file
* @param charset the the charset to use for encoding
* @param options the file open options
*/
public void writeToFileWithoutExtension(Path file, Charset charset, OpenOption... options) {
markupDocBuilder.writeToFileWithoutExtension(file, charset, options);
}
}

View File

@@ -1,167 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.component.*;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.*;
import org.apache.commons.lang3.Validate;
import java.util.List;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.markupDescription;
import static io.github.swagger2markup.spi.OverviewDocumentExtension.Context;
import static io.github.swagger2markup.spi.OverviewDocumentExtension.Position;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class OverviewDocument extends MarkupComponent<OverviewDocument.Parameters> {
public static final int SECTION_TITLE_LEVEL = 2;
private static final String OVERVIEW_ANCHOR = "overview";
private final VersionInfoComponent versionInfoComponent;
private final ContactInfoComponent contactInfoComponent;
private final LicenseInfoComponent licenseInfoComponent;
private final UriSchemeComponent uriSchemeComponent;
private final TagsComponent tagsComponent;
private final ProducesComponent producesComponent;
private final ConsumesComponent consumesComponent;
private final ExternalDocsComponent externalDocsComponent;
public OverviewDocument(Swagger2MarkupConverter.Context context) {
super(context);
versionInfoComponent = new VersionInfoComponent(context);
contactInfoComponent = new ContactInfoComponent(context);
licenseInfoComponent = new LicenseInfoComponent(context);
uriSchemeComponent = new UriSchemeComponent(context);
tagsComponent = new TagsComponent(context);
producesComponent = new ProducesComponent(context);
consumesComponent = new ConsumesComponent(context);
externalDocsComponent = new ExternalDocsComponent((context));
}
public static OverviewDocument.Parameters parameters(Swagger swagger) {
return new OverviewDocument.Parameters(swagger);
}
/**
* Builds the overview MarkupDocument.
*
* @return the overview MarkupDocument
*/
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, OverviewDocument.Parameters params) {
Swagger swagger = params.swagger;
Info info = swagger.getInfo();
buildDocumentTitle(markupDocBuilder, info.getTitle());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEFORE, markupDocBuilder));
buildOverviewTitle(markupDocBuilder, labels.getLabel(Labels.OVERVIEW));
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEGIN, markupDocBuilder));
buildDescriptionParagraph(markupDocBuilder, info.getDescription());
buildVersionInfoSection(markupDocBuilder, info);
buildContactInfoSection(markupDocBuilder, info.getContact());
buildLicenseInfoSection(markupDocBuilder, info);
buildUriSchemeSection(markupDocBuilder, swagger);
buildTagsSection(markupDocBuilder, swagger.getTags());
buildConsumesSection(markupDocBuilder, swagger.getConsumes());
buildProducesSection(markupDocBuilder, swagger.getProduces());
buildExternalDocsSection(markupDocBuilder, swagger.getExternalDocs());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_END, markupDocBuilder));
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_AFTER, markupDocBuilder));
return markupDocBuilder;
}
private void buildDocumentTitle(MarkupDocBuilder markupDocBuilder, String title) {
markupDocBuilder.documentTitle(title);
}
private void buildOverviewTitle(MarkupDocBuilder markupDocBuilder, String title) {
markupDocBuilder.sectionTitleWithAnchorLevel1(title, OVERVIEW_ANCHOR);
}
void buildDescriptionParagraph(MarkupDocBuilder markupDocBuilder, String description) {
if (isNotBlank(description)) {
markupDocBuilder.paragraph(markupDescription(config.getSwaggerMarkupLanguage(), markupDocBuilder, description));
}
}
private void buildVersionInfoSection(MarkupDocBuilder markupDocBuilder, Info info) {
if (info != null) {
versionInfoComponent.apply(markupDocBuilder, VersionInfoComponent.parameters(info, SECTION_TITLE_LEVEL));
}
}
private void buildContactInfoSection(MarkupDocBuilder markupDocBuilder, Contact contact) {
if (contact != null) {
contactInfoComponent.apply(markupDocBuilder, ContactInfoComponent.parameters(contact, SECTION_TITLE_LEVEL));
}
}
private void buildLicenseInfoSection(MarkupDocBuilder markupDocBuilder, Info info) {
if (info != null) {
licenseInfoComponent.apply(markupDocBuilder, LicenseInfoComponent.parameters(info, SECTION_TITLE_LEVEL));
}
}
private void buildUriSchemeSection(MarkupDocBuilder markupDocBuilder, Swagger swagger) {
uriSchemeComponent.apply(markupDocBuilder, UriSchemeComponent.parameters(swagger, SECTION_TITLE_LEVEL));
}
private void buildTagsSection(MarkupDocBuilder markupDocBuilder, List<Tag> tags) {
if (isNotEmpty(tags)) {
tagsComponent.apply(markupDocBuilder, TagsComponent.parameters(tags, SECTION_TITLE_LEVEL));
}
}
private void buildConsumesSection(MarkupDocBuilder markupDocBuilder, List<String> consumes) {
if (isNotEmpty(consumes)) {
consumesComponent.apply(markupDocBuilder, ConsumesComponent.parameters(consumes, SECTION_TITLE_LEVEL));
}
}
private void buildProducesSection(MarkupDocBuilder markupDocBuilder, List<String> produces) {
if (isNotEmpty(produces)) {
producesComponent.apply(markupDocBuilder, ProducesComponent.parameters(produces, SECTION_TITLE_LEVEL));
}
}
private void buildExternalDocsSection(MarkupDocBuilder markupDocBuilder, ExternalDocs externalDocs) {
if (externalDocs != null) {
externalDocsComponent.apply(markupDocBuilder, ExternalDocsComponent.parameters(externalDocs, SECTION_TITLE_LEVEL));
}
}
/**
* Apply extension context to all OverviewContentExtension
*
* @param context context
*/
private void applyOverviewDocumentExtension(Context context) {
extensionRegistry.getOverviewDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final Swagger swagger;
public Parameters(Swagger swagger) {
this.swagger = Validate.notNull(swagger, "Swagger must not be null");
}
}
}

View File

@@ -1,258 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document;
import com.google.common.collect.Multimap;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.component.PathOperationComponent;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverFromOperation;
import io.github.swagger2markup.internal.resolver.OperationDocumentNameResolver;
import io.github.swagger2markup.internal.resolver.OperationDocumentResolverDefault;
import io.github.swagger2markup.internal.resolver.SecurityDocumentResolver;
import io.github.swagger2markup.internal.utils.PathUtils;
import io.github.swagger2markup.internal.utils.RegexUtils;
import io.github.swagger2markup.internal.utils.TagUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.Path;
import io.swagger.models.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.copyMarkupDocBuilder;
import static io.github.swagger2markup.internal.utils.MarkupDocBuilderUtils.crossReference;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Context;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Position;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
/**
* @author Robert Winkler
*/
public class PathsDocument extends MarkupComponent<PathsDocument.Parameters> {
private static final String PATHS_ANCHOR = "paths";
private final PathOperationComponent pathOperationComponent;
private final OperationDocumentNameResolver operationDocumentNameResolver;
private final OperationDocumentResolverDefault operationDocumentResolverDefault;
public PathsDocument(Swagger2MarkupConverter.Context context) {
super(context);
this.pathOperationComponent = new PathOperationComponent(context,
new DefinitionDocumentResolverFromOperation(context),
new SecurityDocumentResolver(context));
this.operationDocumentNameResolver = new OperationDocumentNameResolver(context);
this.operationDocumentResolverDefault = new OperationDocumentResolverDefault(context);
if (logger.isDebugEnabled()) {
if (config.isGeneratedExamplesEnabled()) {
logger.debug("Generate examples is enabled.");
} else {
logger.debug("Generate examples is disabled.");
}
if (config.isSeparatedOperationsEnabled()) {
logger.debug("Create separated operation files is enabled.");
} else {
logger.debug("Create separated operation files is disabled.");
}
}
}
public static PathsDocument.Parameters parameters(Map<String, Path> paths) {
return new PathsDocument.Parameters(paths);
}
/**
* Builds the paths MarkupDocument.
*
* @return the paths MarkupDocument
*/
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, PathsDocument.Parameters params) {
Map<String, Path> paths = params.paths;
if (MapUtils.isNotEmpty(paths)) {
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, markupDocBuilder));
buildPathsTitle(markupDocBuilder);
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, markupDocBuilder));
buildsPathsSection(markupDocBuilder, paths);
applyPathsDocumentExtension(new Context(Position.DOCUMENT_END, markupDocBuilder));
applyPathsDocumentExtension(new Context(Position.DOCUMENT_AFTER, markupDocBuilder));
}
return markupDocBuilder;
}
/**
* Builds the paths section. Groups the paths either as-is, by tags or using regex.
*
* @param paths the Swagger paths
*/
private void buildsPathsSection(MarkupDocBuilder markupDocBuilder, Map<String, Path> paths) {
List<PathOperation> pathOperations = PathUtils.toPathOperationsList(paths, getBasePath(), config.getOperationOrdering());
if (CollectionUtils.isNotEmpty(pathOperations)) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
pathOperations.forEach(operation -> buildOperation(markupDocBuilder, operation, config));
} else if (config.getPathsGroupedBy() == GroupBy.TAGS) {
Validate.notEmpty(context.getSwagger().getTags(), "Tags must not be empty, when operations are grouped by tags");
// Group operations by tag
Multimap<String, PathOperation> operationsGroupedByTag = TagUtils.groupOperationsByTag(pathOperations, config.getOperationOrdering());
Map<String, Tag> tagsMap = TagUtils.toSortedMap(context.getSwagger().getTags(), config.getTagOrdering());
tagsMap.forEach((String tagName, Tag tag) -> {
markupDocBuilder.sectionTitleWithAnchorLevel2(WordUtils.capitalize(tagName), tagName + "_resource");
String description = tag.getDescription();
if (StringUtils.isNotBlank(description)) {
markupDocBuilder.paragraph(description);
}
operationsGroupedByTag.get(tagName).forEach(operation -> buildOperation(markupDocBuilder, operation, config));
});
} else if (config.getPathsGroupedBy() == GroupBy.REGEX) {
Validate.notNull(config.getHeaderPattern(), "Header regex pattern must not be empty when operations are grouped using regex");
Pattern headerPattern = config.getHeaderPattern();
Multimap<String, PathOperation> operationsGroupedByRegex = RegexUtils.groupOperationsByRegex(pathOperations, headerPattern);
Set<String> keys = operationsGroupedByRegex.keySet();
String[] sortedHeaders = RegexUtils.toSortedArray(keys);
for (String header : sortedHeaders) {
markupDocBuilder.sectionTitleWithAnchorLevel2(WordUtils.capitalize(header), header + "_resource");
operationsGroupedByRegex.get(header).forEach(operation -> buildOperation(markupDocBuilder, operation, config));
}
}
}
}
/**
* Builds the path title depending on the operationsGroupedBy configuration setting.
*/
private void buildPathsTitle(MarkupDocBuilder markupDocBuilder) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
buildPathsTitle(markupDocBuilder, labels.getLabel(Labels.PATHS));
} else if (config.getPathsGroupedBy() == GroupBy.REGEX) {
buildPathsTitle(markupDocBuilder, labels.getLabel(Labels.OPERATIONS));
} else {
buildPathsTitle(markupDocBuilder, labels.getLabel(Labels.RESOURCES));
}
}
/**
* Returns the basePath which should be prepended to the relative path
*
* @return either the relative or the full path
*/
private String getBasePath() {
if (config.isBasePathPrefixEnabled()) {
return StringUtils.defaultString(context.getSwagger().getBasePath());
}
return "";
}
private void buildPathsTitle(MarkupDocBuilder markupDocBuilder, String title) {
markupDocBuilder.sectionTitleWithAnchorLevel1(title, PATHS_ANCHOR);
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(Context context) {
extensionRegistry.getPathsDocumentExtensions().forEach(extension -> extension.apply(context));
}
/**
* Builds a path operation depending on generation mode.
*
* @param operation operation
*/
private void buildOperation(MarkupDocBuilder markupDocBuilder, PathOperation operation, Swagger2MarkupConfig config) {
if (config.isSeparatedOperationsEnabled()) {
MarkupDocBuilder pathDocBuilder = copyMarkupDocBuilder(markupDocBuilder);
applyPathOperationComponent(pathDocBuilder, operation);
java.nio.file.Path operationFile = context.getOutputPath().resolve(operationDocumentNameResolver.apply(operation));
pathDocBuilder.writeToFileWithoutExtension(operationFile, StandardCharsets.UTF_8);
if (logger.isDebugEnabled()) {
logger.debug("Separate operation file produced : '{}'", operationFile);
}
buildOperationRef(markupDocBuilder, operation);
} else {
applyPathOperationComponent(markupDocBuilder, operation);
}
if (logger.isDebugEnabled()) {
logger.debug("Operation processed : '{}' (normalized id = '{}')", operation, normalizeName(operation.getId()));
}
}
/**
* Builds a path operation.
*
* @param markupDocBuilder the docbuilder do use for output
* @param operation the Swagger Operation
*/
private void applyPathOperationComponent(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
if (operation != null) {
pathOperationComponent.apply(markupDocBuilder, PathOperationComponent.parameters(operation));
}
}
/**
* Builds a cross-reference to a separated operation file
*
* @param markupDocBuilder the markupDocBuilder do use for output
* @param operation the Swagger Operation
*/
private void buildOperationRef(MarkupDocBuilder markupDocBuilder, PathOperation operation) {
buildOperationTitle(markupDocBuilder, crossReference(markupDocBuilder, operationDocumentResolverDefault.apply(operation), operation.getId(), operation.getTitle()), "ref-" + operation.getId());
}
/**
* Adds a operation title to the document.
*
* @param title the operation title
* @param anchor optional anchor (null => auto-generate from title)
*/
private void buildOperationTitle(MarkupDocBuilder markupDocBuilder, String title, String anchor) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
markupDocBuilder.sectionTitleWithAnchorLevel2(title, anchor);
} else {
markupDocBuilder.sectionTitleWithAnchorLevel3(title, anchor);
}
}
public static class Parameters {
private final Map<String, Path> paths;
public Parameters(Map<String, Path> paths) {
this.paths = paths;
}
}
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.component.SecuritySchemeDefinitionComponent;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.MarkupComponent;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.collections4.MapUtils;
import java.util.Map;
import static io.github.swagger2markup.Labels.SECURITY;
import static io.github.swagger2markup.internal.utils.MapUtils.toSortedMap;
import static io.github.swagger2markup.spi.SecurityDocumentExtension.Context;
import static io.github.swagger2markup.spi.SecurityDocumentExtension.Position;
/**
* @author Robert Winkler
*/
public class SecurityDocument extends MarkupComponent<SecurityDocument.Parameters> {
private static final String SECURITY_ANCHOR = "securityScheme";
private final SecuritySchemeDefinitionComponent securitySchemeDefinitionComponent;
public SecurityDocument(Swagger2MarkupConverter.Context context) {
super(context);
this.securitySchemeDefinitionComponent = new SecuritySchemeDefinitionComponent(context);
}
public static SecurityDocument.Parameters parameters(Map<String, SecuritySchemeDefinition> securitySchemeDefinitions) {
return new SecurityDocument.Parameters(securitySchemeDefinitions);
}
/**
* Builds the security MarkupDocument.
*
* @return the security MarkupDocument
*/
@Override
public MarkupDocBuilder apply(MarkupDocBuilder markupDocBuilder, SecurityDocument.Parameters params) {
Map<String, SecuritySchemeDefinition> definitions = params.securitySchemeDefinitions;
if (MapUtils.isNotEmpty(definitions)) {
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEFORE, markupDocBuilder));
buildSecurityTitle(markupDocBuilder, labels.getLabel(SECURITY));
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEGIN, markupDocBuilder));
buildSecuritySchemeDefinitionsSection(markupDocBuilder, definitions);
applySecurityDocumentExtension(new Context(Position.DOCUMENT_END, markupDocBuilder));
applySecurityDocumentExtension(new Context(Position.DOCUMENT_AFTER, markupDocBuilder));
}
return markupDocBuilder;
}
private void buildSecurityTitle(MarkupDocBuilder markupDocBuilder, String title) {
markupDocBuilder.sectionTitleWithAnchorLevel1(title, SECURITY_ANCHOR);
}
private void buildSecuritySchemeDefinitionsSection(MarkupDocBuilder markupDocBuilder, Map<String, SecuritySchemeDefinition> securitySchemes) {
Map<String, SecuritySchemeDefinition> securitySchemeNames = toSortedMap(securitySchemes, null); // TODO : provide a dedicated ordering configuration for security schemes
securitySchemeNames.forEach((String securitySchemeName, SecuritySchemeDefinition securityScheme) ->
securitySchemeDefinitionComponent.apply(markupDocBuilder, SecuritySchemeDefinitionComponent.parameters(
securitySchemeName, securityScheme, 2
)));
}
/**
* Apply extension context to all SecurityContentExtension
*
* @param context context
*/
private void applySecurityDocumentExtension(Context context) {
extensionRegistry.getSecurityDocumentExtensions().forEach(extension -> extension.apply(context));
}
public static class Parameters {
private final Map<String, SecuritySchemeDefinition> securitySchemeDefinitions;
public Parameters(Map<String, SecuritySchemeDefinition> securitySchemeDefinitions) {
this.securitySchemeDefinitions = securitySchemeDefinitions;
}
}
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document.builder;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.internal.document.MarkupDocument;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.ObjectTypePolymorphism;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.internal.utils.ModelUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.DefinitionsDocumentExtension;
import io.swagger.models.Model;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import static io.github.swagger2markup.internal.utils.MapUtils.toKeySet;
import static io.github.swagger2markup.spi.DefinitionsDocumentExtension.Context;
import static io.github.swagger2markup.spi.DefinitionsDocumentExtension.Position;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class DefinitionsDocumentBuilder extends MarkupDocumentBuilder {
/* Discriminator is only displayed for inheriting definitions */
private static final boolean ALWAYS_DISPLAY_DISCRIMINATOR = false;
private static final String DEFINITIONS_ANCHOR = "definitions";
private final String DEFINITIONS;
private final String DISCRIMINATOR_COLUMN;
private final String POLYMORPHISM_COLUMN;
private final Map<ObjectTypePolymorphism.Nature, String> POLYMORPHISM_NATURE;
private final String TYPE_COLUMN;
private static final List<String> IGNORED_DEFINITIONS = Collections.singletonList("Void");
public DefinitionsDocumentBuilder(Swagger2MarkupConverter.Context context, Swagger2MarkupExtensionRegistry extensionRegistry, Path outputPath) {
super(context, extensionRegistry, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
DEFINITIONS = labels.getString("definitions");
POLYMORPHISM_COLUMN = labels.getString("polymorphism.column");
DISCRIMINATOR_COLUMN = labels.getString("polymorphism.discriminator");
POLYMORPHISM_NATURE = new HashMap<ObjectTypePolymorphism.Nature, String>() {{
put(ObjectTypePolymorphism.Nature.COMPOSITION, labels.getString("polymorphism.nature.COMPOSITION"));
put(ObjectTypePolymorphism.Nature.INHERITANCE, labels.getString("polymorphism.nature.INHERITANCE"));
}};
TYPE_COLUMN = labels.getString("type_column");
if (config.isSeparatedDefinitionsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is enabled.");
}
Validate.notNull(outputPath, "Output directory is required for separated definition files!");
} else {
if (logger.isDebugEnabled()) {
logger.debug("Create separated definition files is disabled.");
}
}
}
/**
* Builds the definitions MarkupDocument.
*
* @return the definitions MarkupDocument
*/
@Override
public MarkupDocument build() {
if (MapUtils.isNotEmpty(globalContext.getSwagger().getDefinitions())) {
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildDefinitionsTitle(DEFINITIONS);
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildDefinitionsSection();
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
applyDefinitionsDocumentExtension(new Context(Position.DOCUMENT_AFTER, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildDefinitionsSection() {
Set<String> definitionNames = toKeySet(globalContext.getSwagger().getDefinitions(), config.getDefinitionOrdering());
for (String definitionName : definitionNames) {
Model model = globalContext.getSwagger().getDefinitions().get(definitionName);
if (isNotBlank(definitionName)) {
if (checkThatDefinitionIsNotInIgnoreList(definitionName)) {
buildDefinition(definitionName, model);
if (logger.isInfoEnabled()) {
logger.info("Definition processed : '{}'", definitionName);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Definition was ignored : '{}'", definitionName);
}
}
}
}
}
private void buildDefinitionsTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, DEFINITIONS_ANCHOR);
}
/**
* Apply extension context to all DefinitionsContentExtension
*
* @param context context
*/
private void applyDefinitionsDocumentExtension(Context context) {
for (DefinitionsDocumentExtension extension : extensionRegistry.getDefinitionsDocumentExtensions()) {
extension.apply(context);
}
}
/**
* Create the definition filename depending on the generation mode
*
* @param definitionName definition name
* @return definition filename
*/
private String resolveDefinitionDocument(String definitionName) {
if (config.isSeparatedDefinitionsEnabled())
return new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(normalizeName(definitionName))).getPath();
else
return markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
}
/**
* Generate definition files depending on the generation mode
*
* @param definitionName definition name to process
* @param model definition model to process
*/
private void buildDefinition(String definitionName, Model model) {
if (config.isSeparatedDefinitionsEnabled()) {
MarkupDocBuilder defDocBuilder = copyMarkupDocBuilder();
buildDefinition(definitionName, model, defDocBuilder);
Path definitionFile = outputPath.resolve(resolveDefinitionDocument(definitionName));
defDocBuilder.writeToFileWithoutExtension(definitionFile, StandardCharsets.UTF_8);
if (logger.isInfoEnabled()) {
logger.info("Separate definition file produced : '{}'", definitionFile);
}
definitionRef(definitionName, this.markupDocBuilder);
} else {
buildDefinition(definitionName, model, this.markupDocBuilder);
}
}
/**
* Checks that the definition is not in the list of ignored definitions.
*
* @param definitionName the name of the definition
* @return true if the definition can be processed
*/
private boolean checkThatDefinitionIsNotInIgnoreList(String definitionName) {
return !IGNORED_DEFINITIONS.contains(definitionName);
}
/**
* Builds a concrete definition
*
* @param definitionName the name of the definition
* @param model the Swagger Model of the definition
* @param docBuilder the docbuilder do use for output
*/
private void buildDefinition(String definitionName, Model model, MarkupDocBuilder docBuilder) {
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_BEFORE, docBuilder, definitionName, model));
buildDefinitionTitle(definitionName, definitionName, docBuilder);
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_BEGIN, docBuilder, definitionName, model));
buildDescriptionParagraph(model, docBuilder);
inlineDefinitions(typeSection(definitionName, model, docBuilder), definitionName, docBuilder);
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_END, docBuilder, definitionName, model));
applyDefinitionsDocumentExtension(new Context(Position.DEFINITION_AFTER, docBuilder, definitionName, model));
}
/**
* Builds a cross-reference to a separated definition file.
*
* @param definitionName definition name to target
* @param docBuilder the docbuilder do use for output
*/
private void definitionRef(String definitionName, MarkupDocBuilder docBuilder) {
buildDefinitionTitle(copyMarkupDocBuilder().crossReference(new DefinitionDocumentResolverDefault().apply(definitionName), definitionName, definitionName).toString(), "ref-" + definitionName, docBuilder);
}
/**
* Builds definition title
*
* @param title definition title
* @param anchor optional anchor (null => auto-generate from title)
* @param docBuilder the docbuilder do use for output
*/
private void buildDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
}
/**
* Builds the type informations of a definition
*
* @param definitionName name of the definition to display
* @param model model of the definition to display
* @param docBuilder the docbuilder do use for output
* @return a list of inlined types.
*/
private List<ObjectType> typeSection(String definitionName, Model model, MarkupDocBuilder docBuilder) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
Type modelType = ModelUtils.resolveRefType(ModelUtils.getType(model, globalContext.getSwagger().getDefinitions(), new DefinitionDocumentResolverFromDefinition()));
if (!(modelType instanceof ObjectType)) {
modelType = createInlineType(modelType, definitionName, definitionName + " " + "inline", inlineDefinitions);
}
if (modelType instanceof ObjectType) {
ObjectType objectType = (ObjectType) modelType;
MarkupDocBuilder typeInfos = copyMarkupDocBuilder();
switch (objectType.getPolymorphism().getNature()) {
case COMPOSITION:
typeInfos.italicText(POLYMORPHISM_COLUMN).textLine(COLON + POLYMORPHISM_NATURE.get(objectType.getPolymorphism().getNature()));
break;
case INHERITANCE:
typeInfos.italicText(POLYMORPHISM_COLUMN).textLine(COLON + POLYMORPHISM_NATURE.get(objectType.getPolymorphism().getNature()));
typeInfos.italicText(DISCRIMINATOR_COLUMN).textLine(COLON + objectType.getPolymorphism().getDiscriminator());
break;
case NONE:
if (ALWAYS_DISPLAY_DISCRIMINATOR) {
if (StringUtils.isNotBlank(objectType.getPolymorphism().getDiscriminator()))
typeInfos.italicText(DISCRIMINATOR_COLUMN).textLine(COLON + objectType.getPolymorphism().getDiscriminator());
}
default: break;
}
String typeInfosString = typeInfos.toString();
if (StringUtils.isNotBlank(typeInfosString))
docBuilder.paragraph(typeInfosString, true);
inlineDefinitions.addAll(buildPropertiesTable(((ObjectType) modelType).getProperties(), definitionName, new DefinitionDocumentResolverFromDefinition(), docBuilder));
} else if (modelType != null) {
MarkupDocBuilder typeInfos = copyMarkupDocBuilder();
typeInfos.italicText(TYPE_COLUMN).textLine(COLON + modelType.displaySchema(docBuilder));
docBuilder.paragraph(typeInfos.toString());
}
return inlineDefinitions;
}
private void buildDescriptionParagraph(Model model, MarkupDocBuilder docBuilder) {
modelDescription(model, docBuilder);
}
private void modelDescription(Model model, MarkupDocBuilder docBuilder) {
String description = model.getDescription();
if (isNotBlank(description)) {
buildDescriptionParagraph(description, docBuilder);
}
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
* @param docBuilder the docbuilder do use for output
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor, null);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param docBuilder the docbuilder do use for output
*/
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, MarkupDocBuilder docBuilder) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<ObjectType> localDefinitions = buildPropertiesTable(definition.getProperties(), uniquePrefix, new DefinitionDocumentResolverFromDefinition(), docBuilder);
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(Collections.singletonList(localDefinition), localDefinition.getUniqueName(), docBuilder);
}
}
}
/**
* Overrides definition document resolver functor for inter-document cross-references from definitions files.
* This implementation simplify the path between two definitions because all definitions are in the same path.
*/
class DefinitionDocumentResolverFromDefinition extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromDefinition() {
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedDefinitionsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(normalizeName(definitionName));
else
return defaultResolver;
}
}
}

View File

@@ -0,0 +1,282 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document.builder;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.internal.document.MarkupDocument;
import io.github.swagger2markup.internal.type.*;
import io.github.swagger2markup.internal.utils.PropertyUtils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.markup.builder.MarkupDocBuilders;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.markup.builder.MarkupTableColumn;
import io.github.swagger2markup.utils.IOUtils;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Path;
import java.util.*;
import static io.github.swagger2markup.internal.utils.MapUtils.toKeySet;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public abstract class MarkupDocumentBuilder {
protected static final String COLON = " : ";
protected final String DEFAULT_COLUMN;
protected final String EXAMPLE_COLUMN;
protected final String SCHEMA_COLUMN;
protected final String NAME_COLUMN;
protected final String DESCRIPTION_COLUMN;
protected final String SCOPES_COLUMN;
protected final String DESCRIPTION;
protected final String PRODUCES;
protected final String CONSUMES;
protected final String TAGS;
protected final String NO_CONTENT;
protected final String FLAGS_COLUMN;
protected final String FLAGS_REQUIRED;
protected final String FLAGS_OPTIONAL;
protected final String FLAGS_READ_ONLY;
protected Logger logger = LoggerFactory.getLogger(getClass());
protected Swagger2MarkupConverter.Context globalContext;
protected Swagger2MarkupExtensionRegistry extensionRegistry;
protected Swagger2MarkupConfig config;
protected MarkupDocBuilder markupDocBuilder;
protected Path outputPath;
MarkupDocumentBuilder(Swagger2MarkupConverter.Context globalContext, Swagger2MarkupExtensionRegistry extensionRegistry, Path outputPath) {
this.globalContext = globalContext;
this.extensionRegistry = extensionRegistry;
this.config = globalContext.getConfig();
this.outputPath = outputPath;
this.markupDocBuilder = MarkupDocBuilders.documentBuilder(config.getMarkupLanguage(), config.getLineSeparator()).withAnchorPrefix(config.getAnchorPrefix());
ResourceBundle labels = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
DEFAULT_COLUMN = labels.getString("default_column");
EXAMPLE_COLUMN = labels.getString("example_column");
FLAGS_COLUMN = labels.getString("flags.column");
FLAGS_REQUIRED = labels.getString("flags.required");
FLAGS_OPTIONAL = labels.getString("flags.optional");
FLAGS_READ_ONLY = labels.getString("flags.read_only");
SCHEMA_COLUMN = labels.getString("schema_column");
NAME_COLUMN = labels.getString("name_column");
DESCRIPTION_COLUMN = labels.getString("description_column");
SCOPES_COLUMN = labels.getString("scopes_column");
DESCRIPTION = DESCRIPTION_COLUMN;
PRODUCES = labels.getString("produces");
CONSUMES = labels.getString("consumes");
TAGS = labels.getString("tags");
NO_CONTENT = labels.getString("no_content");
}
/**
* Builds the MarkupDocument.
*
* @return the built MarkupDocument
* @throws IOException if the files to include are not readable
*/
public abstract MarkupDocument build() throws IOException;
/**
* Returns a RefType to a new inlined type named with {@code name} and {@code uniqueName}.<br>
* The returned RefType point to the new inlined type which is added to the {@code inlineDefinitions} collection.<br>
* The function is recursive and support collections (ArrayType and MapType).<br>
* The function is transparent : {@code type} is returned as-is if type is not inlinable or if !config.isInlineSchemaEnabled().<br>
*
* @param type type to inline
* @param name name of the created inline ObjectType
* @param uniqueName unique name of the created inline ObjectType
* @param inlineDefinitions a non null collection of inline ObjectType
* @return the type referencing the newly created inline ObjectType. Can be a RefType, an ArrayType or a MapType
*/
protected Type createInlineType(Type type, String name, String uniqueName, List<ObjectType> inlineDefinitions) {
if (!config.isInlineSchemaEnabled())
return type;
if (type instanceof ObjectType) {
return createInlineObjectType(type, name, uniqueName, inlineDefinitions);
} else if (type instanceof ArrayType) {
ArrayType arrayType = (ArrayType)type;
arrayType.setOfType(createInlineType(arrayType.getOfType(), name, uniqueName, inlineDefinitions));
return arrayType;
} else if (type instanceof MapType) {
MapType mapType = (MapType)type;
if (mapType.getValueType() instanceof ObjectType)
mapType.setValueType(createInlineType(mapType.getValueType(), name, uniqueName, inlineDefinitions));
return mapType;
} else {
return type;
}
}
protected Type createInlineObjectType(Type type, String name, String uniqueName, List<ObjectType> inlineDefinitions) {
if (type instanceof ObjectType) {
ObjectType objectType = (ObjectType)type;
if (MapUtils.isNotEmpty(objectType.getProperties())) {
if (objectType.getName() == null) {
objectType.setName(name);
objectType.setUniqueName(uniqueName);
}
inlineDefinitions.add(objectType);
return new RefType(objectType);
} else
return type;
} else
return type;
}
/**
* Build a generic property table
*
* @param properties properties to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param definitionDocumentResolver definition document resolver to apply to property type cross-reference
* @param docBuilder the docbuilder do use for output
* @return a list of inline schemas referenced by some properties, for later display
*/
protected List<ObjectType> buildPropertiesTable(Map<String, Property> properties, String uniquePrefix, DefinitionDocumentResolver definitionDocumentResolver, MarkupDocBuilder docBuilder) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(NAME_COLUMN).withWidthRatio(3).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(11).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^11"),
new MarkupTableColumn(SCHEMA_COLUMN).withWidthRatio(4).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^4"));
if (MapUtils.isNotEmpty(properties)) {
Set<String> propertyNames = toKeySet(properties, config.getPropertyOrdering());
for (String propertyName : propertyNames) {
Property property = properties.get(propertyName);
Type propertyType = PropertyUtils.getType(property, definitionDocumentResolver);
propertyType = createInlineType(propertyType, propertyName, uniquePrefix + " " + propertyName, inlineDefinitions);
Object example = PropertyUtils.getExample(config.isGeneratedExamplesEnabled(), property, markupDocBuilder);
Object defaultValue = PropertyUtils.getDefaultValue(property);
MarkupDocBuilder propertyNameContent = copyMarkupDocBuilder();
propertyNameContent.boldTextLine(propertyName, true);
if (BooleanUtils.isTrue(property.getRequired()))
propertyNameContent.italicText(FLAGS_REQUIRED.toLowerCase());
else
propertyNameContent.italicText(FLAGS_OPTIONAL.toLowerCase());
if (BooleanUtils.isTrue(property.getReadOnly())) {
propertyNameContent.newLine(true);
propertyNameContent.italicText(FLAGS_READ_ONLY.toLowerCase());
}
MarkupDocBuilder descriptionContent = copyMarkupDocBuilder();
String description = defaultString(swaggerMarkupDescription(property.getDescription()));
if (isNotBlank(description))
descriptionContent.text(description);
if(defaultValue != null){
if (isNotBlank(description))
descriptionContent.newLine(true);
descriptionContent.boldText(DEFAULT_COLUMN).text(COLON).literalText(Json.pretty(defaultValue));
}
if (example != null) {
if (isNotBlank(description) || defaultValue != null)
descriptionContent.newLine(true);
descriptionContent.boldText(EXAMPLE_COLUMN).text(COLON).literalText(Json.pretty(example));
}
List<String> content = Arrays.asList(
propertyNameContent.toString(),
descriptionContent.toString(),
propertyType.displaySchema(docBuilder)
);
cells.add(content);
}
docBuilder.tableWithColumnSpecs(cols, cells);
} else {
docBuilder.textLine(NO_CONTENT);
}
return inlineDefinitions;
}
protected MarkupDocBuilder copyMarkupDocBuilder() {
return markupDocBuilder.copy(false);
}
protected String boldText(String text) {
return copyMarkupDocBuilder().boldText(text).toString();
}
protected String italicText(String text) {
return copyMarkupDocBuilder().italicText(text).toString();
}
protected String literalText(String text) {
return copyMarkupDocBuilder().literalText(text).toString();
}
/**
* Returns converted markup text from Swagger.
*
* @param markupText text to convert, or null
* @return converted markup text, or null if {@code markupText} == null
*/
protected String swaggerMarkupDescription(String markupText) {
if (markupText == null)
return null;
return copyMarkupDocBuilder().importMarkup(new StringReader(markupText), globalContext.getConfig().getSwaggerMarkupLanguage()).toString().trim();
}
protected void buildDescriptionParagraph(String description, MarkupDocBuilder docBuilder) {
if (isNotBlank(description)) {
docBuilder.paragraph(swaggerMarkupDescription(description));
}
}
/**
* Default {@code DefinitionDocumentResolver} functor
*/
class DefinitionDocumentResolverDefault implements DefinitionDocumentResolver {
public DefinitionDocumentResolverDefault() {
}
public String apply(String definitionName) {
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
return null;
else if (config.isSeparatedDefinitionsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(IOUtils.normalizeName(definitionName))).getPath();
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
}
}
}

View File

@@ -0,0 +1,224 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document.builder;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.internal.document.MarkupDocument;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.spi.OverviewDocumentExtension;
import io.swagger.models.*;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import static io.github.swagger2markup.spi.OverviewDocumentExtension.Context;
import static io.github.swagger2markup.spi.OverviewDocumentExtension.Position;
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.*;
public class OverviewDocumentBuilder extends MarkupDocumentBuilder {
private static final String OVERVIEW_ANCHOR = "overview";
private final String OVERVIEW;
private final String CURRENT_VERSION;
private final String VERSION;
private final String CONTACT_INFORMATION;
private final String CONTACT_NAME;
private final String CONTACT_EMAIL;
private final String LICENSE_INFORMATION;
private final String LICENSE;
private final String LICENSE_URL;
private final String TERMS_OF_SERVICE;
private final String URI_SCHEME;
private final String HOST;
private final String BASE_PATH;
private final String SCHEMES;
public OverviewDocumentBuilder(Swagger2MarkupConverter.Context context, Swagger2MarkupExtensionRegistry extensionRegistry, Path outputPath){
super(context, extensionRegistry, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
OVERVIEW = labels.getString("overview");
CURRENT_VERSION = labels.getString("current_version");
VERSION = labels.getString("version");
CONTACT_INFORMATION = labels.getString("contact_information");
CONTACT_NAME = labels.getString("contact_name");
CONTACT_EMAIL = labels.getString("contact_email");
LICENSE_INFORMATION = labels.getString("license_information");
LICENSE = labels.getString("license");
LICENSE_URL = labels.getString("license_url");
TERMS_OF_SERVICE = labels.getString("terms_of_service");
URI_SCHEME = labels.getString("uri_scheme");
HOST = labels.getString("host");
BASE_PATH = labels.getString("base_path");
SCHEMES = labels.getString("schemes");
}
/**
* Builds the overview MarkupDocument.
*
* @return the overview MarkupDocument
*/
@Override
public MarkupDocument build(){
Swagger swagger = globalContext.getSwagger();
Info info = swagger.getInfo();
buildDocumentTitle(info.getTitle());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildOverviewTitle(OVERVIEW);
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildDescriptionParagraph(info.getDescription(), this.markupDocBuilder);
buildVersionInfoSection(info.getVersion());
buildContactInfoSection(info.getContact());
buildLicenseInfoSection(info.getLicense(), info.getTermsOfService());
buildUriSchemeSection(swagger);
buildTagsSection(swagger.getTags());
buildConsumesSection(swagger.getConsumes());
buildProducesSection(swagger.getProduces());
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
applyOverviewDocumentExtension(new Context(Position.DOCUMENT_AFTER, this.markupDocBuilder));
return new MarkupDocument(markupDocBuilder);
}
private void buildDocumentTitle(String title) {
this.markupDocBuilder.documentTitle(title);
}
private void buildOverviewTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, OVERVIEW_ANCHOR);
}
private void buildVersionInfoSection(String version) {
if(isNotBlank(version)){
this.markupDocBuilder.sectionTitleLevel2(CURRENT_VERSION);
MarkupDocBuilder paragraph = copyMarkupDocBuilder();
paragraph.italicText(VERSION).textLine(COLON + version);
this.markupDocBuilder.paragraph(paragraph.toString(), true);
}
}
private void buildContactInfoSection(Contact contact) {
if(contact != null){
this.markupDocBuilder.sectionTitleLevel2(CONTACT_INFORMATION);
MarkupDocBuilder paragraph = copyMarkupDocBuilder();
if(isNotBlank(contact.getName())){
paragraph.italicText(CONTACT_NAME).textLine(COLON + contact.getName());
}
if(isNotBlank(contact.getEmail())){
paragraph.italicText(CONTACT_EMAIL).textLine(COLON + contact.getEmail());
}
this.markupDocBuilder.paragraph(paragraph.toString(), true);
}
}
private void buildLicenseInfoSection(License license, String termOfService) {
if (
(license != null && (isNotBlank(license.getName()) || isNotBlank(license.getUrl()))) ||
(isNotBlank(termOfService))
) {
this.markupDocBuilder.sectionTitleLevel2(LICENSE_INFORMATION);
MarkupDocBuilder paragraph = copyMarkupDocBuilder();
if (license != null && isNotBlank(license.getName())) {
paragraph.italicText(LICENSE).textLine(COLON + license.getName());
}
if (license != null && isNotBlank(license.getUrl())) {
paragraph.italicText(LICENSE_URL).textLine(COLON + license.getUrl());
}
if(isNotBlank(termOfService)){
paragraph.italicText(TERMS_OF_SERVICE).textLine(COLON + termOfService);
}
this.markupDocBuilder.paragraph(paragraph.toString(), true);
}
}
private void buildUriSchemeSection(Swagger swagger) {
if(isNotBlank(swagger.getHost()) || isNotBlank(swagger.getBasePath()) || isNotEmpty(swagger.getSchemes())) {
this.markupDocBuilder.sectionTitleLevel2(URI_SCHEME);
MarkupDocBuilder paragraph = copyMarkupDocBuilder();
if (isNotBlank(swagger.getHost())) {
paragraph.italicText(HOST).textLine(COLON + swagger.getHost());
}
if (isNotBlank(swagger.getBasePath())) {
paragraph.italicText(BASE_PATH).textLine(COLON + swagger.getBasePath());
}
if (isNotEmpty(swagger.getSchemes())) {
List<String> schemes = new ArrayList<>();
for (Scheme scheme : swagger.getSchemes()) {
schemes.add(scheme.toString());
}
paragraph.italicText(SCHEMES).textLine(COLON + join(schemes, ", "));
}
this.markupDocBuilder.paragraph(paragraph.toString(), true);
}
}
private void buildTagsSection(List<Tag> tags) {
if(isNotEmpty(tags)){
this.markupDocBuilder.sectionTitleLevel2(TAGS);
List<String> tagsList = new ArrayList<>();
for(Tag tag : tags){
String name = tag.getName();
String description = tag.getDescription();
if(isNoneBlank(description)){
tagsList.add(name + COLON + description);
}else{
tagsList.add(name);
}
}
this.markupDocBuilder.unorderedList(tagsList);
}
}
private void buildConsumesSection(List<String> consumes) {
if (isNotEmpty(consumes)) {
this.markupDocBuilder.sectionTitleLevel2(CONSUMES);
this.markupDocBuilder.newLine();
for (String consume : consumes) {
this.markupDocBuilder.unorderedListItem(literalText(consume));
}
this.markupDocBuilder.newLine();
}
}
private void buildProducesSection(List<String> produces) {
if (isNotEmpty(produces)) {
this.markupDocBuilder.sectionTitleLevel2(PRODUCES);
this.markupDocBuilder.newLine();
for (String produce : produces) {
this.markupDocBuilder.unorderedListItem(literalText(produce));
}
this.markupDocBuilder.newLine();
}
}
/**
* Apply extension context to all OverviewContentExtension
*
* @param context context
*/
private void applyOverviewDocumentExtension(Context context) {
for (OverviewDocumentExtension extension : extensionRegistry.getOverviewDocumentExtensions()) {
extension.apply(context);
}
}
}

View File

@@ -0,0 +1,770 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document.builder;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.internal.document.MarkupDocument;
import io.github.swagger2markup.internal.type.ObjectType;
import io.github.swagger2markup.internal.type.Type;
import io.github.swagger2markup.internal.utils.ExamplesUtil;
import io.github.swagger2markup.internal.utils.ParameterUtils;
import io.github.swagger2markup.internal.utils.PropertyUtils;
import io.github.swagger2markup.internal.utils.TagUtils;
import io.github.swagger2markup.markup.builder.*;
import io.github.swagger2markup.model.PathOperation;
import io.github.swagger2markup.spi.PathsDocumentExtension;
import io.swagger.models.*;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static io.github.swagger2markup.internal.utils.ListUtils.toSet;
import static io.github.swagger2markup.internal.utils.MapUtils.toKeySet;
import static io.github.swagger2markup.internal.utils.TagUtils.convertTagsListToMap;
import static io.github.swagger2markup.internal.utils.TagUtils.getTagDescription;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Context;
import static io.github.swagger2markup.spi.PathsDocumentExtension.Position;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class PathsDocumentBuilder extends MarkupDocumentBuilder {
private final String RESPONSE;
private final String REQUEST;
private final String PATHS;
private final String RESOURCES;
private final String PARAMETERS;
private final String BODY_PARAMETER;
private final String RESPONSES;
private final String HEADERS_COLUMN;
private final String EXAMPLE_REQUEST;
private final String EXAMPLE_RESPONSE;
private final String SECURITY;
private final String TYPE_COLUMN;
private final String HTTP_CODE_COLUMN;
private final String DEPRECATED_OPERATION;
private final String UNKNOWN;
private static final String PATHS_ANCHOR = "paths";
public PathsDocumentBuilder(Swagger2MarkupConverter.Context globalContext, Swagger2MarkupExtensionRegistry extensionRegistry, java.nio.file.Path outputPath) {
super(globalContext, extensionRegistry, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
RESPONSE = labels.getString("response");
REQUEST = labels.getString("request");
PATHS = labels.getString("paths");
RESOURCES = labels.getString("resources");
PARAMETERS = labels.getString("parameters");
BODY_PARAMETER = labels.getString("body_parameter");
RESPONSES = labels.getString("responses");
HEADERS_COLUMN = labels.getString("headers_column");
EXAMPLE_REQUEST = labels.getString("example_request");
EXAMPLE_RESPONSE = labels.getString("example_response");
SECURITY = labels.getString("security");
TYPE_COLUMN = labels.getString("type_column");
HTTP_CODE_COLUMN = labels.getString("http_code_column");
DEPRECATED_OPERATION = labels.getString("operation.deprecated");
UNKNOWN = labels.getString("unknown");
if (config.isGeneratedExamplesEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Include examples is enabled.");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Include examples is disabled.");
}
}
if (config.isSeparatedOperationsEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Create separated operation files is enabled.");
}
Validate.notNull(outputPath, "Output directory is required for separated operation files!");
} else {
if (logger.isDebugEnabled()) {
logger.debug("Create separated operation files is disabled.");
}
}
}
/**
* Builds the paths MarkupDocument.
*
* @return the paths MarkupDocument
*/
@Override
public MarkupDocument build() {
Map<String, Path> paths = globalContext.getSwagger().getPaths();
if (MapUtils.isNotEmpty(paths)) {
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildPathsTitle();
applyPathsDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildsPathsSection(paths);
applyPathsDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
applyPathsDocumentExtension(new Context(Position.DOCUMENT_AFTER, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildsPathsSection(Map<String, Path> paths) {
Set<PathOperation> pathOperations = toPathOperationsSet(paths);
if (CollectionUtils.isNotEmpty(pathOperations)) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
for (PathOperation operation : pathOperations) {
buildOperation(operation);
}
} else {
Multimap<String, PathOperation> operationsGroupedByTag = TagUtils.groupOperationsByTag(pathOperations, config.getTagOrdering(), config.getOperationOrdering());
Map<String, Tag> tagsMap = convertTagsListToMap(globalContext.getSwagger().getTags());
for (String tagName : operationsGroupedByTag.keySet()) {
this.markupDocBuilder.sectionTitleWithAnchorLevel2(WordUtils.capitalize(tagName), tagName + "_resource");
Optional<String> tagDescription = getTagDescription(tagsMap, tagName);
if (tagDescription.isPresent()) {
this.markupDocBuilder.paragraph(tagDescription.get());
}
for (PathOperation operation : operationsGroupedByTag.get(tagName)) {
buildOperation(operation);
}
}
}
}
}
/**
* Builds the path title depending on the operationsGroupedBy configuration setting.
*/
private void buildPathsTitle() {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
buildPathsTitle(PATHS);
} else {
buildPathsTitle(RESOURCES);
}
}
/**
* Converts the Swagger paths into a list PathOperations.
*
* @param paths the Swagger paths
* @return the path operations
*/
private Set<PathOperation> toPathOperationsSet(Map<String, Path> paths) {
Set<PathOperation> pathOperations;
if (config.getOperationOrdering() != null) {
pathOperations = new TreeSet<>(config.getOperationOrdering());
} else {
pathOperations = new LinkedHashSet<>();
}
for (Map.Entry<String, Path> path : paths.entrySet()) {
Map<HttpMethod, Operation> operations = path.getValue().getOperationMap(); // TODO AS_IS does not work because of https://github.com/swagger-api/swagger-core/issues/1696
if (MapUtils.isNotEmpty(operations)) {
for (Map.Entry<HttpMethod, Operation> operation : operations.entrySet()) {
pathOperations.add(new PathOperation(operation.getKey(), path.getKey(), operation.getValue()));
}
}
}
return pathOperations;
}
private void buildPathsTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, PATHS_ANCHOR);
}
/**
* Apply extension context to all OperationsContentExtension.
*
* @param context context
*/
private void applyPathsDocumentExtension(Context context) {
for (PathsDocumentExtension extension : extensionRegistry.getPathsDocumentExtensions()) {
extension.apply(context);
}
}
/**
* Create the operation filename depending on the generation mode
*
* @param operation operation
* @return operation filename
*/
private String resolveOperationDocument(PathOperation operation) {
if (config.isSeparatedOperationsEnabled())
return new File(config.getSeparatedOperationsFolder(), this.markupDocBuilder.addFileExtension(normalizeName(operation.getId()))).getPath();
else
return this.markupDocBuilder.addFileExtension(config.getPathsDocument());
}
/**
* Builds a path operation depending on generation mode.
*
* @param operation operation
*/
private void buildOperation(PathOperation operation) {
if (config.isSeparatedOperationsEnabled()) {
MarkupDocBuilder pathDocBuilder = copyMarkupDocBuilder();
buildOperation(operation, pathDocBuilder);
java.nio.file.Path operationFile = outputPath.resolve(resolveOperationDocument(operation));
pathDocBuilder.writeToFileWithoutExtension(operationFile, StandardCharsets.UTF_8);
if (logger.isInfoEnabled()) {
logger.info("Separate operation file produced : '{}'", operationFile);
}
buildOperationRef(operation, this.markupDocBuilder);
} else {
buildOperation(operation, this.markupDocBuilder);
}
if (logger.isInfoEnabled()) {
logger.info("Operation processed : '{}' (normalized id = '{}')", operation, normalizeName(operation.getId()));
}
}
/**
* Builds a path operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperation(PathOperation operation, MarkupDocBuilder docBuilder) {
if (operation != null) {
applyPathsDocumentExtension(new Context(Position.OPERATION_BEFORE, docBuilder, operation));
buildDeprecatedSection(operation, docBuilder);
buildOperationTitle(operation, docBuilder);
applyPathsDocumentExtension(new Context(Position.OPERATION_BEGIN, docBuilder, operation));
buildDescriptionSection(operation, docBuilder);
inlineDefinitions(buildParametersSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), docBuilder);
inlineDefinitions(buildBodyParameterSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), docBuilder);
inlineDefinitions(buildResponsesSection(operation, docBuilder), operation.getPath() + " " + operation.getMethod(), docBuilder);
buildConsumesSection(operation, docBuilder);
buildProducesSection(operation, docBuilder);
buildTagsSection(operation, docBuilder);
buildSecuritySchemeSection(operation, docBuilder);
buildExamplesSection(operation, docBuilder);
applyPathsDocumentExtension(new Context(Position.OPERATION_END, docBuilder, operation));
applyPathsDocumentExtension(new Context(Position.OPERATION_AFTER, docBuilder, operation));
}
}
/**
* Builds a cross-reference to a separated operation file
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperationRef(PathOperation operation, MarkupDocBuilder docBuilder) {
String document;
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
document = null;
else if (config.isSeparatedOperationsEnabled())
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
else
document = defaultString(config.getInterDocumentCrossReferencesPrefix()) + resolveOperationDocument(operation);
buildOperationTitle(copyMarkupDocBuilder().crossReference(document, operation.getId(), operation.getTitle()).toString(), "ref-" + operation.getId(), docBuilder);
}
/**
* Builds a warning if method is deprecated.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildDeprecatedSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Boolean deprecated = operation.getOperation().isDeprecated();
if (deprecated != null && deprecated) {
docBuilder.block(DEPRECATED_OPERATION, MarkupBlockStyle.EXAMPLE, null, MarkupAdmonition.CAUTION);
}
}
/**
* Adds the operation title to the document. If the operation has a summary, the title is the summary.
* Otherwise the title is the method of the operation and the URL of the operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildOperationTitle(PathOperation operation, MarkupDocBuilder docBuilder) {
buildOperationTitle(operation.getTitle(), operation.getId(), docBuilder);
if (operation.getTitle().equals(operation.getOperation().getSummary())) {
docBuilder.block(operation.getMethod() + " " + operation.getPath(), MarkupBlockStyle.LITERAL);
}
}
/**
* Adds a operation title to the document.
*
* @param title the operation title
* @param anchor optional anchor (null => auto-generate from title)
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildOperationTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleWithAnchorLevel2(title, anchor);
} else {
docBuilder.sectionTitleWithAnchorLevel3(title, anchor);
}
}
/**
* Adds a operation section title to the document.
*
* @param title the section title
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildSectionTitle(String title, MarkupDocBuilder docBuilder) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleLevel3(title);
} else {
docBuilder.sectionTitleLevel4(title);
}
}
/**
* Adds a example title to the document.
*
* @param title the section title
* @param docBuilder the MarkupDocBuilder to use
*/
private void buildExampleTitle(String title, MarkupDocBuilder docBuilder) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
docBuilder.sectionTitleLevel4(title);
} else {
docBuilder.sectionTitleLevel5(title);
}
}
/**
* Adds a operation description to the document.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildDescriptionSection(PathOperation operation, MarkupDocBuilder docBuilder) {
MarkupDocBuilder descriptionBuilder = copyMarkupDocBuilder();
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_BEGIN, descriptionBuilder, operation));
buildDescriptionParagraph(operation.getOperation().getDescription(), descriptionBuilder);
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_END, descriptionBuilder, operation));
String descriptionContent = descriptionBuilder.toString();
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_BEFORE, docBuilder, operation));
if (isNotBlank(descriptionContent)) {
buildSectionTitle(DESCRIPTION, docBuilder);
docBuilder.text(descriptionContent);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_AFTER, docBuilder, operation));
}
/**
* Filter parameters to display in parameters section
*
* @param parameter parameter to filter
* @return true if parameter can be displayed
*/
private boolean filterParameter(Parameter parameter) {
return (!config.isFlatBodyEnabled() || !StringUtils.equals(parameter.getIn(), "body"));
}
private List<ObjectType> buildParametersSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<Parameter> parameters = operation.getOperation().getParameters();
if (config.getParameterOrdering() != null)
Collections.sort(parameters, config.getParameterOrdering());
List<ObjectType> inlineDefinitions = new ArrayList<>();
boolean hasParameters = false;
if (CollectionUtils.isNotEmpty(parameters)) {
for (Parameter p : parameters) {
if (filterParameter(p)) {
hasParameters = true;
break;
}
}
}
MarkupDocBuilder parametersBuilder = copyMarkupDocBuilder();
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_BEGIN, parametersBuilder, operation));
if (hasParameters) {
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(TYPE_COLUMN).withWidthRatio(1).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(NAME_COLUMN).withWidthRatio(3).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(10).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^10"),
new MarkupTableColumn(SCHEMA_COLUMN).withWidthRatio(4).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^4"),
new MarkupTableColumn(DEFAULT_COLUMN).withWidthRatio(2).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^2"));
for (Parameter parameter : parameters) {
if (filterParameter(parameter)) {
Type type = ParameterUtils.getType(parameter, globalContext.getSwagger().getDefinitions(), new DefinitionDocumentResolverFromOperation());
type = createInlineType(type, parameter.getName(), operation.getId() + " " + parameter.getName(), inlineDefinitions);
String parameterType = WordUtils.capitalize(parameter.getIn());
MarkupDocBuilder parameterNameContent = copyMarkupDocBuilder();
parameterNameContent.boldTextLine(parameter.getName(), true);
if (parameter.getRequired())
parameterNameContent.italicText(FLAGS_REQUIRED.toLowerCase());
else
parameterNameContent.italicText(FLAGS_OPTIONAL.toLowerCase());
Object defaultValue = ParameterUtils.getDefaultValue(parameter);
List<String> content = Arrays.asList(
boldText(parameterType),
parameterNameContent.toString(),
defaultString(swaggerMarkupDescription(parameter.getDescription())),
type.displaySchema(markupDocBuilder),
defaultValue != null ? literalText(Json.pretty(defaultValue)) : "");
cells.add(content);
}
}
parametersBuilder.tableWithColumnSpecs(cols, cells);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_DESCRIPTION_END, parametersBuilder, operation));
String parametersContent = parametersBuilder.toString();
applyPathsDocumentExtension(new Context(Position.OPERATION_PARAMETERS_BEFORE, docBuilder, operation));
if (isNotBlank(parametersContent)) {
buildSectionTitle(PARAMETERS, docBuilder);
docBuilder.text(parametersContent);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_PARAMETERS_AFTER, docBuilder, operation));
return inlineDefinitions;
}
/**
* Builds the body parameter section, if {@code Swagger2MarkupConfig.isIsolatedBody()} is true
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
* @return a list of inlined types.
*/
private List<ObjectType> buildBodyParameterSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<ObjectType> inlineDefinitions = new ArrayList<>();
if (config.isFlatBodyEnabled()) {
List<Parameter> parameters = operation.getOperation().getParameters();
if (CollectionUtils.isNotEmpty(parameters)) {
for (Parameter parameter : parameters) {
if (StringUtils.equals(parameter.getIn(), "body")) {
Type type = ParameterUtils.getType(parameter, globalContext.getSwagger().getDefinitions(), new DefinitionDocumentResolverFromOperation());
if (!(type instanceof ObjectType)) {
type = createInlineType(type, parameter.getName(), operation.getId() + " " + parameter.getName(), inlineDefinitions);
}
buildSectionTitle(BODY_PARAMETER, docBuilder);
if (isNotBlank(parameter.getDescription())) {
buildDescriptionParagraph(parameter.getDescription(), docBuilder);
}
MarkupDocBuilder typeInfos = copyMarkupDocBuilder();
typeInfos.italicText(NAME_COLUMN).textLine(COLON + parameter.getName());
typeInfos.italicText(FLAGS_COLUMN).textLine(COLON + (BooleanUtils.isTrue(parameter.getRequired()) ? FLAGS_REQUIRED.toLowerCase() : FLAGS_OPTIONAL.toLowerCase()));
if (!(type instanceof ObjectType)) {
typeInfos.italicText(TYPE_COLUMN).textLine(COLON + type.displaySchema(docBuilder));
}
docBuilder.paragraph(typeInfos.toString(), true);
if (type instanceof ObjectType) {
inlineDefinitions.addAll(buildPropertiesTable(((ObjectType) type).getProperties(), operation.getId(), new DefinitionDocumentResolverFromOperation(), docBuilder));
}
}
}
}
}
return inlineDefinitions;
}
private void buildConsumesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<String> consumes = operation.getOperation().getConsumes();
if (CollectionUtils.isNotEmpty(consumes)) {
buildSectionTitle(CONSUMES, docBuilder);
docBuilder.newLine();
for (String consume : consumes) {
docBuilder.unorderedListItem(literalText(consume));
}
docBuilder.newLine();
}
}
private void buildProducesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<String> produces = operation.getOperation().getProduces();
if (CollectionUtils.isNotEmpty(produces)) {
buildSectionTitle(PRODUCES, docBuilder);
docBuilder.newLine();
for (String produce : produces) {
docBuilder.unorderedListItem(literalText(produce));
}
docBuilder.newLine();
}
}
private void buildTagsSection(PathOperation operation, MarkupDocBuilder docBuilder) {
if (config.getPathsGroupedBy() == GroupBy.AS_IS) {
List<String> tags = operation.getOperation().getTags();
if (CollectionUtils.isNotEmpty(tags)) {
buildSectionTitle(TAGS, docBuilder);
Set<String> tagsSet = toSet(tags, config.getTagOrdering());
docBuilder.unorderedList(new ArrayList<>(tagsSet));
}
}
}
/**
* Builds the example section of a Swagger Operation.
*
* @param operation the Swagger Operation
* @param docBuilder the docbuilder do use for output
*/
private void buildExamplesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, globalContext.getSwagger().getDefinitions(), markupDocBuilder);
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation.getOperation(), globalContext.getSwagger().getDefinitions(), markupDocBuilder);
exampleMap(generatedRequestExampleMap, EXAMPLE_REQUEST, REQUEST, docBuilder);
exampleMap(generatedResponseExampleMap, EXAMPLE_RESPONSE, RESPONSE, docBuilder);
}
private void exampleMap(Map<String, Object> exampleMap, String operationSectionTitle, String sectionTitle, MarkupDocBuilder docBuilder) {
if (exampleMap.size() > 0) {
buildSectionTitle(operationSectionTitle, docBuilder);
for (Map.Entry<String, Object> entry : exampleMap.entrySet()) {
buildExampleTitle(sectionTitle + " " + entry.getKey(), docBuilder);
docBuilder.listingBlock(Json.pretty(entry.getValue()), "json");
}
}
}
/**
* Builds the security section of a Swagger Operation.
*
* @param operation the Swagger Operation
* @param docBuilder the MarkupDocBuilder document builder
*/
private void buildSecuritySchemeSection(PathOperation operation, MarkupDocBuilder docBuilder) {
List<Map<String, List<String>>> securitySchemes = operation.getOperation().getSecurity();
MarkupDocBuilder securityBuilder = copyMarkupDocBuilder();
applyPathsDocumentExtension(new Context(Position.OPERATION_SECURITY_BEGIN, securityBuilder, operation));
if (CollectionUtils.isNotEmpty(securitySchemes)) {
Map<String, SecuritySchemeDefinition> securityDefinitions = globalContext.getSwagger().getSecurityDefinitions();
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(TYPE_COLUMN).withWidthRatio(3).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(NAME_COLUMN).withWidthRatio(4).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^4"),
new MarkupTableColumn(SCOPES_COLUMN).withWidthRatio(13).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^13"));
for (Map<String, List<String>> securityScheme : securitySchemes) {
for (Map.Entry<String, List<String>> securityEntry : securityScheme.entrySet()) {
String securityKey = securityEntry.getKey();
String type = UNKNOWN;
if (securityDefinitions != null && securityDefinitions.containsKey(securityKey)) {
type = securityDefinitions.get(securityKey).getType();
}
List<String> content = Arrays.asList(boldText(type), boldText(copyMarkupDocBuilder().crossReference(securityDocumentResolver(), securityKey, securityKey).toString()),
Joiner.on(",").join(securityEntry.getValue()));
cells.add(content);
}
}
securityBuilder.tableWithColumnSpecs(cols, cells);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_SECURITY_END, securityBuilder, operation));
String securityContent = securityBuilder.toString();
applyPathsDocumentExtension(new Context(Position.OPERATION_SECURITY_BEFORE, docBuilder, operation));
if (isNotBlank(securityContent)) {
buildSectionTitle(SECURITY, docBuilder);
docBuilder.text(securityContent);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_SECURITY_AFTER, docBuilder, operation));
}
/**
* Resolve Security document for use in cross-references.
*
* @return document or null if cross-reference is not inter-document
*/
private String securityDocumentResolver() {
if (!config.isInterDocumentCrossReferencesEnabled() || outputPath == null)
return null;
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(config.getSecurityDocument());
}
private List<ObjectType> buildResponsesSection(PathOperation operation, MarkupDocBuilder docBuilder) {
Map<String, Response> responses = operation.getOperation().getResponses();
List<ObjectType> inlineDefinitions = new ArrayList<>();
MarkupDocBuilder responsesBuilder = copyMarkupDocBuilder();
applyPathsDocumentExtension(new Context(Position.OPERATION_RESPONSES_BEGIN, responsesBuilder, operation));
if (MapUtils.isNotEmpty(responses)) {
List<MarkupTableColumn> responseCols = Arrays.asList(
new MarkupTableColumn(HTTP_CODE_COLUMN).withWidthRatio(1).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^1"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(15).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^15"),
new MarkupTableColumn(SCHEMA_COLUMN).withWidthRatio(4).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^4"));
List<List<String>> cells = new ArrayList<>();
Set<String> responseNames = toKeySet(responses, config.getResponseOrdering());
for (String responseName : responseNames) {
Response response = responses.get(responseName);
String schemaContent = NO_CONTENT;
if (response.getSchema() != null) {
Property property = response.getSchema();
Type type = PropertyUtils.getType(property, new DefinitionDocumentResolverFromOperation());
type = createInlineType(type, RESPONSE + " " + responseName, operation.getId() + " " + RESPONSE + " " + responseName, inlineDefinitions);
schemaContent = type.displaySchema(markupDocBuilder);
}
MarkupDocBuilder descriptionBuilder = copyMarkupDocBuilder();
descriptionBuilder.text(defaultString(swaggerMarkupDescription(response.getDescription())));
Map<String, Property> headers = response.getHeaders();
if (MapUtils.isNotEmpty(headers)) {
descriptionBuilder.newLine(true).boldText(HEADERS_COLUMN).text(COLON);
for (Map.Entry<String, Property> header : headers.entrySet()) {
descriptionBuilder.newLine(true);
Property headerProperty = header.getValue();
Type propertyType = PropertyUtils.getType(headerProperty, null);
String headerDescription = defaultString(swaggerMarkupDescription(headerProperty.getDescription()));
Object defaultValue = PropertyUtils.getDefaultValue(headerProperty);
descriptionBuilder
.literalText(header.getKey())
.text(String.format(" (%s)", propertyType.displaySchema(markupDocBuilder)));
if (isNotBlank(headerDescription) || defaultValue != null) {
descriptionBuilder.text(COLON);
if (isNotBlank(headerDescription) && !headerDescription.endsWith("."))
headerDescription += ".";
descriptionBuilder.text(headerDescription);
if (defaultValue != null) {
descriptionBuilder.text(" ").boldText(DEFAULT_COLUMN).text(COLON).literalText(Json.pretty(defaultValue));
}
}
}
}
cells.add(Arrays.asList(boldText(responseName), descriptionBuilder.toString(), schemaContent));
}
responsesBuilder.tableWithColumnSpecs(responseCols, cells);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_RESPONSES_END, responsesBuilder, operation));
String responsesContent = responsesBuilder.toString();
applyPathsDocumentExtension(new Context(Position.OPERATION_RESPONSES_BEFORE, docBuilder, operation));
if (isNotBlank(responsesContent)) {
buildSectionTitle(RESPONSES, docBuilder);
docBuilder.text(responsesContent);
}
applyPathsDocumentExtension(new Context(Position.OPERATION_RESPONSES_AFTER, docBuilder, operation));
return inlineDefinitions;
}
/**
* Builds the title of an inline schema.
* Inline definitions should never been referenced in TOC because they have no real existence, so they are just text.
*
* @param title inline schema title
* @param anchor inline schema anchor
* @param docBuilder the docbuilder do use for output
*/
private void addInlineDefinitionTitle(String title, String anchor, MarkupDocBuilder docBuilder) {
docBuilder.anchor(anchor);
docBuilder.newLine();
docBuilder.boldTextLine(title);
}
/**
* Builds inline schema definitions
*
* @param definitions all inline definitions to display
* @param uniquePrefix unique prefix to prepend to inline object names to enforce unicity
* @param docBuilder the docbuilder do use for output
*/
private void inlineDefinitions(List<ObjectType> definitions, String uniquePrefix, MarkupDocBuilder docBuilder) {
if (CollectionUtils.isNotEmpty(definitions)) {
for (ObjectType definition : definitions) {
addInlineDefinitionTitle(definition.getName(), definition.getUniqueName(), docBuilder);
List<ObjectType> localDefinitions = buildPropertiesTable(definition.getProperties(), uniquePrefix, new DefinitionDocumentResolverFromOperation(), docBuilder);
for (ObjectType localDefinition : localDefinitions)
inlineDefinitions(Collections.singletonList(localDefinition), localDefinition.getUniqueName(), docBuilder);
}
}
}
/**
* Overrides definition document resolver functor for inter-document cross-references from operations files.
* This implementation adapt the relative paths to definitions files
*/
class DefinitionDocumentResolverFromOperation extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromOperation() {
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedOperationsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File("..", defaultResolver).getPath();
else
return defaultResolver;
}
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.document.builder;
import com.google.common.collect.Ordering;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.internal.document.MarkupDocument;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.markup.builder.MarkupTableColumn;
import io.github.swagger2markup.spi.SecurityDocumentExtension;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import org.apache.commons.collections4.MapUtils;
import java.nio.file.Path;
import java.util.*;
import static io.github.swagger2markup.internal.utils.MapUtils.toKeySet;
import static io.github.swagger2markup.spi.SecurityDocumentExtension.Context;
import static io.github.swagger2markup.spi.SecurityDocumentExtension.Position;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author Robert Winkler
*/
public class SecurityDocumentBuilder extends MarkupDocumentBuilder {
private static final String SECURITY_ANCHOR = "securityScheme";
private final String SECURITY;
private final String TYPE;
private final String NAME;
private final String IN;
private final String FLOW;
private final String AUTHORIZATION_URL;
private final String TOKEN_URL;
public SecurityDocumentBuilder(Swagger2MarkupConverter.Context context, Swagger2MarkupExtensionRegistry extensionRegistry, Path outputPath) {
super(context, extensionRegistry, outputPath);
ResourceBundle labels = ResourceBundle.getBundle("io/github/swagger2markup/lang/labels", config.getOutputLanguage().toLocale());
SECURITY = labels.getString("security");
TYPE = labels.getString("security_type");
NAME = labels.getString("security_name");
IN = labels.getString("security_in");
FLOW = labels.getString("security_flow");
AUTHORIZATION_URL = labels.getString("security_authorizationUrl");
TOKEN_URL = labels.getString("security_tokenUrl");
}
/**
* Builds the security MarkupDocument.
*
* @return the security MarkupDocument
*/
@Override
public MarkupDocument build(){
Map<String, SecuritySchemeDefinition> definitions = globalContext.getSwagger().getSecurityDefinitions();
if (MapUtils.isNotEmpty(definitions)) {
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEFORE, this.markupDocBuilder));
buildSecurityTitle(SECURITY);
applySecurityDocumentExtension(new Context(Position.DOCUMENT_BEGIN, this.markupDocBuilder));
buildSecuritySchemeDefinitionsSection(definitions);
applySecurityDocumentExtension(new Context(Position.DOCUMENT_END, this.markupDocBuilder));
applySecurityDocumentExtension(new Context(Position.DOCUMENT_AFTER, this.markupDocBuilder));
}
return new MarkupDocument(markupDocBuilder);
}
private void buildSecurityTitle(String title) {
this.markupDocBuilder.sectionTitleWithAnchorLevel1(title, SECURITY_ANCHOR);
}
private void buildSecuritySchemeDefinitionsSection(Map<String, SecuritySchemeDefinition> securitySchemes) {
Set<String> securitySchemeNames = toKeySet(securitySchemes, Ordering.natural()); // TODO : provide a dedicated ordering configuration for security schemes
for (String securitySchemeName : securitySchemeNames) {
SecuritySchemeDefinition securityScheme = securitySchemes.get(securitySchemeName);
applySecurityDocumentExtension(new Context(Position.SECURITY_SCHEME_BEFORE, markupDocBuilder, securitySchemeName, securityScheme));
buildSecuritySchemeDefinitionTitle(securitySchemeName);
applySecurityDocumentExtension(new Context(Position.SECURITY_SCHEME_BEGIN, markupDocBuilder, securitySchemeName, securityScheme));
buildDescriptionParagraph(securityScheme.getDescription(), this.markupDocBuilder);
buildSecurityScheme(securityScheme);
applySecurityDocumentExtension(new Context(Position.SECURITY_SCHEME_END, markupDocBuilder, securitySchemeName, securityScheme));
applySecurityDocumentExtension(new Context(Position.SECURITY_SCHEME_AFTER, markupDocBuilder, securitySchemeName, securityScheme));
}
}
private MarkupDocBuilder buildSecuritySchemeDefinitionTitle(String securitySchemeName) {
return markupDocBuilder.sectionTitleWithAnchorLevel2(securitySchemeName);
}
private void buildSecurityScheme(SecuritySchemeDefinition securityScheme) {
String type = securityScheme.getType();
MarkupDocBuilder paragraph = copyMarkupDocBuilder();
paragraph.italicText(TYPE).textLine(COLON + type);
if (securityScheme instanceof ApiKeyAuthDefinition) {
paragraph.italicText(NAME).textLine(COLON + ((ApiKeyAuthDefinition) securityScheme).getName());
paragraph.italicText(IN).textLine(COLON + ((ApiKeyAuthDefinition) securityScheme).getIn());
markupDocBuilder.paragraph(paragraph.toString(), true);
} else if (securityScheme instanceof OAuth2Definition) {
OAuth2Definition oauth2Scheme = (OAuth2Definition) securityScheme;
String flow = oauth2Scheme.getFlow();
paragraph.italicText(FLOW).textLine(COLON + flow);
if (isNotBlank(oauth2Scheme.getAuthorizationUrl())) {
paragraph.italicText(AUTHORIZATION_URL).textLine(COLON + oauth2Scheme.getAuthorizationUrl());
}
if (isNotBlank(oauth2Scheme.getTokenUrl())) {
paragraph.italicText(TOKEN_URL).textLine(COLON + oauth2Scheme.getTokenUrl());
}
List<List<String>> cells = new ArrayList<>();
List<MarkupTableColumn> cols = Arrays.asList(
new MarkupTableColumn(NAME_COLUMN).withWidthRatio(3).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(17).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^17"));
for (Map.Entry<String, String> scope : oauth2Scheme.getScopes().entrySet()) {
List<String> content = Arrays.asList(scope.getKey(), scope.getValue());
cells.add(content);
}
markupDocBuilder.paragraph(paragraph.toString(), true);
markupDocBuilder.tableWithColumnSpecs(cols, cells);
} else {
markupDocBuilder.paragraph(paragraph.toString(), true);
}
}
/**
* Apply extension context to all SecurityContentExtension
*
* @param context context
*/
private void applySecurityDocumentExtension(Context context) {
for (SecurityDocumentExtension extension : extensionRegistry.getSecurityDocumentExtensions()) {
extension.apply(context);
}
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import java.io.File;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
public class DefinitionDocumentNameResolver extends DocumentResolver {
public DefinitionDocumentNameResolver(Swagger2MarkupConverter.Context context) {
super(context);
}
public String apply(String definitionName) {
if (config.isSeparatedDefinitionsEnabled())
return new File(config.getSeparatedDefinitionsFolder(), markupDocBuilder.addFileExtension(normalizeName(definitionName))).getPath();
else
return markupDocBuilder.addFileExtension(config.getDefinitionsDocument());
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* Default {@code DocumentResolver} functor
*/
public class DefinitionDocumentResolverDefault extends DocumentResolver {
private final DefinitionDocumentNameResolver definitionDocumentNameResolver;
public DefinitionDocumentResolverDefault(Swagger2MarkupConverter.Context context) {
super(context);
this.definitionDocumentNameResolver = new DefinitionDocumentNameResolver(context);
}
public String apply(String definitionName) {
if (!config.isInterDocumentCrossReferencesEnabled() || context.getOutputPath() == null)
return null;
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + definitionDocumentNameResolver.apply(definitionName);
}
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* Overrides definition document resolver functor for inter-document cross-references from definitions files.
* This implementation simplifies the path between two definitions because all definitions are in the same path.
*/
public class DefinitionDocumentResolverFromDefinition extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromDefinition(Swagger2MarkupConverter.Context context) {
super(context);
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedDefinitionsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(normalizeName(definitionName));
else
return defaultResolver;
}
}

View File

@@ -1,27 +0,0 @@
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import java.io.File;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* Overrides definition document resolver functor for inter-document cross-references from operations files.
* This implementation adapt the relative paths to definitions files
*/
public class DefinitionDocumentResolverFromOperation extends DefinitionDocumentResolverDefault {
public DefinitionDocumentResolverFromOperation(Swagger2MarkupConverter.Context context) {
super(context);
}
public String apply(String definitionName) {
String defaultResolver = super.apply(definitionName);
if (defaultResolver != null && config.isSeparatedOperationsEnabled())
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + new File("..", defaultResolver).getPath();
else
return defaultResolver;
}
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import javaslang.Function1;
/**
* A functor to return the document part of an inter-document cross-references, depending on the context.
*/
public abstract class DocumentResolver implements Function1<String, String> {
Swagger2MarkupConverter.Context context;
MarkupDocBuilder markupDocBuilder;
Swagger2MarkupConfig config;
public DocumentResolver(Swagger2MarkupConverter.Context context) {
this.context = context;
this.markupDocBuilder = context.createMarkupDocBuilder();
this.config = context.getConfig();
}
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.model.PathOperation;
import java.io.File;
import static io.github.swagger2markup.utils.IOUtils.normalizeName;
public class OperationDocumentNameResolver extends OperationDocumentResolver {
public OperationDocumentNameResolver(Swagger2MarkupConverter.Context context) {
super(context);
}
public String apply(PathOperation operation) {
if (config.isSeparatedOperationsEnabled())
return new File(config.getSeparatedOperationsFolder(), markupDocBuilder.addFileExtension(normalizeName(operation.getId()))).getPath();
else
return markupDocBuilder.addFileExtension(config.getPathsDocument());
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import javaslang.Function1;
/**
* A functor to return the document part of an inter-document cross-references, depending on the context.
*/
public abstract class OperationDocumentResolver implements Function1<PathOperation, String> {
Swagger2MarkupConverter.Context context;
MarkupDocBuilder markupDocBuilder;
Swagger2MarkupConfig config;
public OperationDocumentResolver(Swagger2MarkupConverter.Context context) {
this.context = context;
this.markupDocBuilder = context.createMarkupDocBuilder();
this.config = context.getConfig();
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.model.PathOperation;
import static org.apache.commons.lang3.StringUtils.defaultString;
/**
* Default {@code DocumentResolver} functor
*/
public class OperationDocumentResolverDefault extends OperationDocumentResolver {
private final OperationDocumentNameResolver operationDocumentNameResolver;
public OperationDocumentResolverDefault(Swagger2MarkupConverter.Context context) {
super(context);
this.operationDocumentNameResolver = new OperationDocumentNameResolver(context);
}
public String apply(PathOperation operation) {
if (!config.isInterDocumentCrossReferencesEnabled() || context.getOutputPath() == null)
return null;
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + operationDocumentNameResolver.apply(operation);
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.resolver;
import io.github.swagger2markup.Swagger2MarkupConverter;
import static org.apache.commons.lang3.StringUtils.defaultString;
public class SecurityDocumentResolver extends DocumentResolver {
public SecurityDocumentResolver(Swagger2MarkupConverter.Context context) {
super(context);
}
public String apply(String definitionName) {
if (!config.isInterDocumentCrossReferencesEnabled() || context.getOutputPath() == null)
return null;
else
return defaultString(config.getInterDocumentCrossReferencesPrefix()) + markupDocBuilder.addFileExtension(config.getSecurityDocument());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/
public class ArrayType extends Type {
private String collectionFormat;
private Type ofType;
protected String collectionFormat;
protected Type ofType;
public ArrayType(String name, Type ofType) {
this(name, ofType, null);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ public class BasicType extends Type {
public BasicType(String type, String name, String format) {
super(name);
Validate.notBlank(type, "Type of parameter '%s' must not be blank", name);
Validate.notBlank(type);
this.type = type;
this.format = format;
}
@@ -46,7 +46,7 @@ public class BasicType extends Type {
@Override
public String displaySchema(MarkupDocBuilder docBuilder) {
if (isNotBlank(this.format))
return String.format("%s (%s)", this.type, this.format);
return String.format("%s(%s)", this.type, this.format);
else
return this.type;
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.type;
import com.google.common.base.Function;
/**
* A functor to return the document part of an inter-document cross-references, depending on the globalContext.
*/
public interface DefinitionDocumentResolver extends Function<String, String> {}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,9 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
*/
public class MapType extends Type {
private Type keyType = new BasicType("string", null);
private Type valueType;
protected Type keyType = new BasicType("string", null);
protected Type valueType;
public MapType(String name, Type valueType) {
super(name);
this.valueType = valueType;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +25,9 @@ import java.util.Map;
* Complex object abstraction
*/
public class ObjectType extends Type {
private Map<String, Property> properties;
private ObjectTypePolymorphism polymorphism;
protected Map<String, Property> properties;
protected ObjectTypePolymorphism polymorphism;
public ObjectType(String name, ObjectTypePolymorphism polymorphism, Map<String, Property> properties) {
super(name);
@@ -43,7 +43,7 @@ public class ObjectType extends Type {
public String displaySchema(MarkupDocBuilder docBuilder) {
return "object";
}
public ObjectTypePolymorphism getPolymorphism() {
return polymorphism;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,12 @@
package io.github.swagger2markup.internal.type;
public class ObjectTypePolymorphism {
public enum Nature {
NONE,
COMPOSITION,
INHERITANCE
}
public Nature nature = Nature.NONE;
public String discriminator;
@@ -42,10 +48,4 @@ public class ObjectTypePolymorphism {
this.discriminator = discriminator;
}
public enum Nature {
NONE,
COMPOSITION,
INHERITANCE
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
public abstract class Type {
protected String name;
private String uniqueName;
protected String uniqueName;
public Type(String name, String uniqueName) {
this.name = name;
@@ -35,14 +35,14 @@ public abstract class Type {
this(name, name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getUniqueName() {
return uniqueName;
}

View File

@@ -1,25 +0,0 @@
package io.github.swagger2markup.internal.utils;
import io.github.swagger2markup.ExampleType;
/**
* swagger2markup (c) Duco Hosting
* Created by cas on 02-Oct-17.
*/
public class Example {
private ExampleType type;
private Object example;
public Example(ExampleType type, Object example) {
this.type = type;
this.example = example;
}
public ExampleType getType() {
return type;
}
public Object getExample() {
return example;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
package io.github.swagger2markup.internal.utils;
import io.github.swagger2markup.internal.adapter.ParameterAdapter;
import io.github.swagger2markup.internal.adapter.PropertyAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.ObjectType;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.*;
@@ -28,28 +28,30 @@ import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ExamplesUtil {
private static final Integer MAX_RECURSION_TO_DISPLAY = 2;
private static Logger logger = LoggerFactory.getLogger(ExamplesUtil.class);
/**
* Generates a Map of response examples
* Generates a map of response examples from the given {@code operation}
*
* @param generateMissingExamples specifies the missing examples should be generated
* @param operation the Swagger Operation
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @param operation the Swagger Operation
* @param definitions the map of all available definitions
* @param markupDocBuilder the markup builder
* @return map containing response examples.
*/
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, PathOperation operation, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder) {
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, Operation operation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Map<String, Object> examples = new LinkedHashMap<>();
Map<String, Response> responses = operation.getOperation().getResponses();
Map<String, Response> responses = operation.getResponses();
if (responses != null)
for (Map.Entry<String, Response> responseEntry : responses.entrySet()) {
Response response = responseEntry.getValue();
@@ -61,13 +63,10 @@ public class ExamplesUtil {
if (example == null && schema instanceof RefProperty) {
String simpleRef = ((RefProperty) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
}
if (example == null && schema instanceof ArrayProperty && generateMissingExamples) {
example = generateExampleForArrayProperty((ArrayProperty) schema, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
}
if (example == null && generateMissingExamples) {
example = PropertyAdapter.generateExample(schema, markupDocBuilder);
example = PropertyUtils.generateExample(schema, markupDocBuilder);
}
}
}
@@ -81,15 +80,15 @@ public class ExamplesUtil {
}
/**
* Generates examples for request
* Generates a map of request examples from the given {@code operation}
*
* @param generateMissingExamples specifies the missing examples should be generated
* @param pathOperation the Swagger Operation
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @return an Optional with the example content
* @param pathOperation the Swagger Operation
* @param definitions the map of all available definitions
* @param markupDocBuilder the markup builder
* @return map containing request examples
*/
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder) {
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Operation operation = pathOperation.getOperation();
List<Parameter> parameters = operation.getParameters();
Map<String, Object> examples = new LinkedHashMap<>();
@@ -100,14 +99,63 @@ public class ExamplesUtil {
for (Parameter parameter : parameters) {
Object example = null;
if (parameter instanceof BodyParameter) {
example = generateBodyParameterExample(parameter, generateMissingExamples, definitions, definitionDocumentResolver, markupDocBuilder);
example = ((BodyParameter) parameter).getExamples();
if (example == null) {
Model schema = ((BodyParameter) parameter).getSchema();
if (schema instanceof RefModel) {
String simpleRef = ((RefModel) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
} else if (generateMissingExamples) {
if (schema instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel(
(ComposedModel) schema, definitions), definitions, markupDocBuilder);
} else if (schema instanceof ArrayModel) {
example = generateExampleForArrayModel((ArrayModel) schema, definitions, markupDocBuilder);
} else {
example = schema.getExample();
if (example == null) {
example = exampleMapForProperties(schema.getProperties(), definitions, markupDocBuilder);
}
}
}
}
} else if (parameter instanceof AbstractSerializableParameter) {
if (generateMissingExamples) {
example = generateAbstractSerializableParameterExample(parameter, examples, markupDocBuilder);
Object abstractSerializableParameterExample;
abstractSerializableParameterExample = ((AbstractSerializableParameter) parameter).getExample();
if (abstractSerializableParameterExample == null) {
Property item = ((AbstractSerializableParameter) parameter).getItems();
if (item != null) {
abstractSerializableParameterExample = item.getExample();
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyUtils.generateExample(item, markupDocBuilder);
}
}
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = ParameterUtils.generateExample((AbstractSerializableParameter)parameter);
}
}
if (parameter instanceof PathParameter) {
String pathExample = (String) examples.get("path");
pathExample = pathExample.replace('{' + parameter.getName() + '}', String.valueOf(abstractSerializableParameterExample));
example = pathExample;
} else {
example = abstractSerializableParameterExample;
}
if (parameter instanceof QueryParameter) {
//noinspection unchecked
@SuppressWarnings("unchecked")
Map<String, Object> queryExampleMap = (Map<String, Object>) examples.get("query");
if (queryExampleMap == null) {
queryExampleMap = new LinkedHashMap<>();
}
queryExampleMap.put(parameter.getName(), abstractSerializableParameterExample);
example = queryExampleMap;
}
}
} else if (parameter instanceof RefParameter) {
String simpleRef = ((RefParameter) parameter).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
}
if (example != null)
@@ -117,120 +165,41 @@ public class ExamplesUtil {
return examples;
}
/**
* Generates example for a body parameter
*
* @param parameter Body paramteter to generate example for
* @param generateMissingExamples Should an example be generated if none is defined
* @param definitions the map of definitions
* @param definitionDocumentResolver definitions document resolver
* @param markupDocBuilder the markup builder
* @return Object containing example
*/
private static Object generateBodyParameterExample(Parameter parameter, Boolean generateMissingExamples, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder) {
Object example = ((BodyParameter) parameter).getExamples();
if (example == null) {
Model schema = ((BodyParameter) parameter).getSchema();
if (schema instanceof RefModel) {
String simpleRef = ((RefModel) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else if (generateMissingExamples) {
if (schema instanceof ComposedModel) {
//FIXME: getProperties() may throw NullPointerException
example = exampleMapForProperties(((ObjectType) ModelUtils.getType(schema, definitions, definitionDocumentResolver)).getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else if (schema instanceof ArrayModel) {
example = generateExampleForArrayModel((ArrayModel) schema, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else {
example = schema.getExample();
if (example == null) {
example = exampleMapForProperties(schema.getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
}
}
}
}
return example;
}
private static Object generateAbstractSerializableParameterExample(Parameter parameter, Map<String, Object> examples, MarkupDocBuilder markupDocBuilder) {
Object abstractSerializableParameterExample;
Object example;
abstractSerializableParameterExample = ((AbstractSerializableParameter) parameter).getExample();
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = parameter.getVendorExtensions().get("x-example");
}
if (abstractSerializableParameterExample == null) {
Property item = ((AbstractSerializableParameter) parameter).getItems();
if (item != null) {
abstractSerializableParameterExample = item.getExample();
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyAdapter.generateExample(item, markupDocBuilder);
}
}
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = ParameterAdapter.generateExample((AbstractSerializableParameter) parameter);
}
}
if (parameter instanceof PathParameter) {
String pathExample = (String) examples.get("path");
pathExample = pathExample.replace('{' + parameter.getName() + '}', String.valueOf(abstractSerializableParameterExample));
example = pathExample;
} else {
example = abstractSerializableParameterExample;
}
if (parameter instanceof QueryParameter) {
//TODO: #264 query parameters seem to be collected here
//noinspection unchecked
@SuppressWarnings("unchecked")
Map<String, Object> queryExampleMap = (Map<String, Object>) examples.get("query");
if (queryExampleMap == null) {
queryExampleMap = new LinkedHashMap<>();
}
queryExampleMap.put(parameter.getName(), abstractSerializableParameterExample);
example = queryExampleMap;
}
return example;
}
/**
* Generates an example object from a simple reference
*
* @param generateMissingExamples specifies the missing examples should be generated
* @param simpleRef the simple reference string
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @param refStack map to detect cyclic references
* @param simpleRef the simple reference string
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @return returns an Object or Map of examples
*/
private static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
public static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Model model = definitions.get(simpleRef);
Object example = null;
if (model != null) {
example = model.getExample();
// Workaround for https://github.com/swagger-api/swagger-parser/issues/255 returning a string
if (model instanceof ArrayModel && example instanceof String) {
ObjectMapper mapper = new ObjectMapper();
try {
example = mapper.readTree((String) example);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (example == null && generateMissingExamples) {
if (!refStack.containsKey(simpleRef)) {
refStack.put(simpleRef, 1);
if (model instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel((ComposedModel) model, definitions), definitions, markupDocBuilder);
} else {
refStack.put(simpleRef, refStack.get(simpleRef) + 1);
example = exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder);
}
if (refStack.get(simpleRef) <= MAX_RECURSION_TO_DISPLAY) {
if (model instanceof ComposedModel) {
//FIXME: getProperties() may throw NullPointerException
example = exampleMapForProperties(((ObjectType) ModelUtils.getType(model, definitions, definitionDocumentResolver)).getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else {
example = exampleMapForProperties(model.getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, refStack);
}
} else {
return "...";
}
refStack.put(simpleRef, refStack.get(simpleRef) - 1);
}
}
return example;
}
private static Map<String, Property> getPropertiesForComposedModel(ComposedModel model, Map<String, Model> definitions) {
//TODO: Unused method, make sure this is never used and then remove it.
Map<String, Property> combinedProperties;
if (model.getParent() instanceof RefModel) {
Map<String, Property> parentProperties = definitions.get(((RefModel) model.getParent()).getSimpleRef()).getProperties();
@@ -259,28 +228,28 @@ public class ExamplesUtil {
* Generates a map of examples from a map of properties. If defined examples are found, those are used. Otherwise,
* examples are generated from the type.
*
* @param properties the map of properties
* @param definitions the map of definitions
* @param properties the map of properties
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @param refStack map to detect cyclic references
*
* @return a Map of examples
*/
private static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
public static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Map<String, Object> exampleMap = new LinkedHashMap<>();
if (properties != null) {
for (Map.Entry<String, Property> property : properties.entrySet()) {
Object exampleObject = property.getValue().getExample();
if (exampleObject == null) {
if (property.getValue() instanceof RefProperty) {
exampleObject = generateExampleForRefModel(true, ((RefProperty) property.getValue()).getSimpleRef(), definitions, definitionDocumentResolver, markupDocBuilder, refStack);
exampleObject = generateExampleForRefModel(true, ((RefProperty) property.getValue()).getSimpleRef(), definitions, markupDocBuilder);
} else if (property.getValue() instanceof ArrayProperty) {
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, definitionDocumentResolver, markupDocBuilder, refStack);
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, markupDocBuilder);
} else if (property.getValue() instanceof MapProperty) {
exampleObject = generateExampleForMapProperty((MapProperty) property.getValue(), markupDocBuilder);
}
if (exampleObject == null) {
Property valueProperty = property.getValue();
exampleObject = PropertyAdapter.generateExample(valueProperty, markupDocBuilder);
exampleObject = PropertyUtils.generateExample(valueProperty, markupDocBuilder);
}
}
exampleMap.put(property.getKey(), exampleObject);
@@ -289,7 +258,7 @@ public class ExamplesUtil {
return exampleMap;
}
private static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
public static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
if (property.getExample() != null) {
return property.getExample();
}
@@ -298,62 +267,48 @@ public class ExamplesUtil {
if (valueProperty.getExample() != null) {
return valueProperty.getExample();
}
exampleMap.put("string", PropertyAdapter.generateExample(valueProperty, markupDocBuilder));
exampleMap.put("string", PropertyUtils.generateExample(valueProperty, markupDocBuilder));
return exampleMap;
}
private static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
public static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
if (model.getExample() != null) {
return model.getExample();
} else if (model.getProperties() != null) {
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder)};
} else {
Property itemProperty = model.getItems();
return getExample(itemProperty, definitions, definitionDocumentResolver, markupDocBuilder, refStack);
if (itemProperty.getExample() != null) {
return new Object[]{itemProperty.getExample()};
} else if (itemProperty instanceof ArrayProperty) {
return new Object[]{generateExampleForArrayProperty((ArrayProperty) itemProperty, definitions, markupDocBuilder)};
} else if (itemProperty instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) itemProperty).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyUtils.generateExample(itemProperty, markupDocBuilder)};
}
}
}
/**
* Generates examples from an ArrayProperty
*
* @param value ArrayProperty
* @param definitions map of definitions
* @param value ArrayProperty
* @param definitions map of definitions
* @param markupDocBuilder the markup builder
* @return array of Object
*/
private static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
public static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
Property property = value.getItems();
return getExample(property, definitions, definitionDocumentResolver, markupDocBuilder, refStack);
}
/**
* Get example from a property
*
* @param property Property
* @param definitions map of definitions
* @param definitionDocumentResolver DocumentResolver
* @param markupDocBuilder the markup builder
* @param refStack reference stack
* @return array of Object
*/
private static Object[] getExample(
Property property,
Map<String, Model> definitions,
DocumentResolver definitionDocumentResolver,
MarkupDocBuilder markupDocBuilder,
Map<String, Integer> refStack) {
if (property.getExample() != null) {
return new Object[]{property.getExample()};
} else if (property instanceof ArrayProperty) {
return new Object[]{generateExampleForArrayProperty((ArrayProperty) property, definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
return new Object[]{generateExampleForArrayProperty((ArrayProperty) property, definitions, markupDocBuilder)};
} else if (property instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyAdapter.generateExample(property, markupDocBuilder)};
return new Object[]{PropertyUtils.generateExample(property, markupDocBuilder)};
}
}
//TODO: Unused method, make sure this is never used and then remove it.
//FIXME: getProperties() may throw NullPointerException
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import io.github.swagger2markup.internal.type.*;
import java.util.List;
import static org.apache.commons.collections4.MapUtils.isNotEmpty;
public class InlineSchemaUtils {
/**
* Returns a RefType to a new inlined type named with {@code name} and {@code uniqueName}.<br>
* The returned RefType point to the new inlined type which is added to the {@code inlineDefinitions} collection.<br>
* The function is recursive and support collections (ArrayType and MapType).<br>
* The function is transparent : {@code type} is returned as-is if type is not inlinable or if !config.isInlineSchemaEnabled().<br>
*
* @param type type to inline
* @param name name of the created inline ObjectType
* @param uniqueName unique name of the created inline ObjectType
* @param inlineDefinitions a non null collection of inline ObjectType
* @return the type referencing the newly created inline ObjectType. Can be a RefType, an ArrayType or a MapType
*/
public static Type createInlineType(Type type, String name, String uniqueName, List<ObjectType> inlineDefinitions) {
if (type instanceof ObjectType) {
return createInlineObjectType(type, name, uniqueName, inlineDefinitions);
} else if (type instanceof ArrayType) {
ArrayType arrayType = (ArrayType) type;
arrayType.setOfType(createInlineType(arrayType.getOfType(), name, uniqueName, inlineDefinitions));
return arrayType;
} else if (type instanceof MapType) {
MapType mapType = (MapType) type;
if (mapType.getValueType() instanceof ObjectType)
mapType.setValueType(createInlineType(mapType.getValueType(), name, uniqueName, inlineDefinitions));
return mapType;
} else {
return type;
}
}
private static Type createInlineObjectType(Type type, String name, String uniqueName, List<ObjectType> inlineDefinitions) {
if (type instanceof ObjectType) {
ObjectType objectType = (ObjectType) type;
if (isNotEmpty(objectType.getProperties())) {
if (objectType.getName() == null) {
objectType.setName(name);
objectType.setUniqueName(uniqueName);
}
inlineDefinitions.add(objectType);
return new RefType(objectType);
} else
return type;
} else
return type;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import java.util.*;
public class ListUtils {
/**
* Returns the List as an Set either ordered or as-is, if the comparator is null.
*
* @param list the List
* @param comparator the comparator to use.
* @return the Set
*/
public static Set<String> toSet(List<String> list, Comparator<String> comparator){
Set<String> set;
if (comparator == null)
set = new LinkedHashSet<>();
else
set = new TreeSet<>(comparator);
set.addAll(list);
return set;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,27 +15,24 @@
*/
package io.github.swagger2markup.internal.utils;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;
public class MapUtils {
/**
* Returns the the Map either ordered or as-is, if the comparator is null.
* Returns the keys of the Map either ordered or as-is, if the comparator is null.
*
* @param map the Map
* @param map the Map
* @param comparator the comparator to use.
* @return the keySet of the Map
*/
public static <K, V> Map<K, V> toSortedMap(Map<K, V> map, Comparator<? super K> comparator) {
Map<K, V> sortedMap;
public static Set<String> toKeySet(Map<String, ?> map, Comparator<String> comparator){
Set<String> keys;
if (comparator == null)
sortedMap = new LinkedHashMap<>();
keys = new LinkedHashSet<>();
else
sortedMap = new TreeMap<>(comparator);
sortedMap.putAll(map);
return sortedMap;
keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());
return keys;
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.apache.commons.lang3.StringUtils;
import java.io.StringReader;
public class MarkupDocBuilderUtils {
public static MarkupDocBuilder copyMarkupDocBuilder(MarkupDocBuilder markupDocBuilder) {
return markupDocBuilder.copy(false);
}
public static String literalText(MarkupDocBuilder markupDocBuilder, String text) {
if (StringUtils.isBlank(text)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).literalText(escapeText(text)).toString();
}
private static String escapeText(String text) {
if(text.startsWith("*")){
text = "\\" + text;
}
return text;
}
public static String boldText(MarkupDocBuilder markupDocBuilder, String text) {
if (StringUtils.isBlank(text)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).boldText(escapeText(text)).toString();
}
public static String italicText(MarkupDocBuilder markupDocBuilder, String text) {
if (StringUtils.isBlank(text)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).italicText(escapeText(text)).toString();
}
public static String crossReference(MarkupDocBuilder markupDocBuilder, String document, String anchor, String text) {
return copyMarkupDocBuilder(markupDocBuilder)
.crossReference(document, anchor, text).toString();
}
public static String markupDescription(MarkupLanguage swaggerMarkupLanguage, MarkupDocBuilder markupDocBuilder, String markupText) {
if (StringUtils.isBlank(markupText)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).importMarkup(new StringReader(markupText), swaggerMarkupLanguage).toString().trim();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,25 +15,22 @@
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import io.github.swagger2markup.internal.adapter.PropertyAdapter;
import io.github.swagger2markup.internal.resolver.DocumentResolver;
import io.github.swagger2markup.internal.type.*;
import io.swagger.models.*;
import io.swagger.models.properties.Property;
import io.swagger.models.refs.RefFormat;
import org.apache.commons.lang3.Validate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class ModelUtils {
/**
* Recursively resolve referenced type if {@code type} is of type RefType
*
* @param type type to resolve
* @return referenced type
*/
@@ -54,13 +51,13 @@ public final class ModelUtils {
* @param definitionDocumentResolver the definition document resolver
* @return the type of the model, or otherwise null
*/
public static Type getType(Model model, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver) {
public static Type getType(Model model, Map<String, Model> definitions, Function<String, String> definitionDocumentResolver) {
Validate.notNull(model, "model must not be null!");
if (model instanceof ModelImpl) {
ModelImpl modelImpl = (ModelImpl) model;
if (modelImpl.getAdditionalProperties() != null)
return new MapType(modelImpl.getTitle(), new PropertyAdapter(modelImpl.getAdditionalProperties()).getType(definitionDocumentResolver));
return new MapType(modelImpl.getTitle(), PropertyUtils.getType(modelImpl.getAdditionalProperties(), definitionDocumentResolver));
else if (modelImpl.getEnum() != null)
return new EnumType(modelImpl.getTitle(), modelImpl.getEnum());
else if (modelImpl.getProperties() != null) {
@@ -69,9 +66,7 @@ public final class ModelUtils {
objectType.getPolymorphism().setDiscriminator(modelImpl.getDiscriminator());
return objectType;
} else if (isNotBlank(modelImpl.getFormat()))
return new BasicType(modelImpl.getType(), modelImpl.getTitle(), modelImpl.getFormat());
else
} else
return new BasicType(modelImpl.getType(), modelImpl.getTitle());
} else if (model instanceof ComposedModel) {
ComposedModel composedModel = (ComposedModel) model;
@@ -100,7 +95,7 @@ public final class ModelUtils {
}
}
}
return new ObjectType(name, polymorphism, allProperties);
} else if (model instanceof RefModel) {
RefModel refModel = (RefModel) model;
@@ -117,7 +112,7 @@ public final class ModelUtils {
} else if (model instanceof ArrayModel) {
ArrayModel arrayModel = ((ArrayModel) model);
return new ArrayType(null, new PropertyAdapter(arrayModel.getItems()).getType(definitionDocumentResolver));
return new ArrayType(null, PropertyUtils.getType(arrayModel.getItems(), definitionDocumentResolver));
}
return null;

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.base.Function;
import io.github.swagger2markup.internal.type.*;
import io.swagger.models.Model;
import io.swagger.models.parameters.AbstractSerializableParameter;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.RefParameter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.List;
import java.util.Map;
public final class ParameterUtils {
/**
* Retrieves the type of a parameter, or otherwise null
*
* @param parameter the parameter
* @param definitionDocumentResolver the defintion document resolver
* @return the type of the parameter, or otherwise null
*/
public static Type getType(Parameter parameter, Map<String, Model> definitions, Function<String, String> definitionDocumentResolver){
Validate.notNull(parameter, "parameter must not be null!");
Type type = null;
if(parameter instanceof BodyParameter){
BodyParameter bodyParameter = (BodyParameter)parameter;
Model model = bodyParameter.getSchema();
if(model != null){
type = ModelUtils.getType(model, definitions, definitionDocumentResolver);
}else{
type = new BasicType("string", null);
}
}
else if(parameter instanceof AbstractSerializableParameter){
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
@SuppressWarnings("unchecked")
List<String> enums = serializableParameter.getEnum();
if(CollectionUtils.isNotEmpty(enums)){
type = new EnumType(null, enums);
}else{
type = new BasicType(serializableParameter.getType(), null, serializableParameter.getFormat());
}
if(serializableParameter.getType().equals("array")){
String collectionFormat = serializableParameter.getCollectionFormat();
type = new ArrayType(null, PropertyUtils.getType(serializableParameter.getItems(), definitionDocumentResolver), collectionFormat);
}
}
else if(parameter instanceof RefParameter){
String refName = ((RefParameter)parameter).getSimpleRef();
type = new RefType(definitionDocumentResolver.apply(refName), new ObjectType(refName, null /* FIXME, not used for now */));
}
return type;
}
/**
* Retrieves the default value of a parameter, or otherwise returns null
*
* @param parameter the parameter
* @return the default value of the parameter, or otherwise null
*/
public static Object getDefaultValue(Parameter parameter){
Validate.notNull(parameter, "parameter must not be null!");
Object defaultValue = null;
if(parameter instanceof AbstractSerializableParameter){
AbstractSerializableParameter serializableParameter = (AbstractSerializableParameter)parameter;
defaultValue = serializableParameter.getDefaultValue();
}
return defaultValue;
}
/**
* Generate a default example value for parameter.
*
* @param parameter parameter
* @return a generated example for the parameter
*/
public static Object generateExample(AbstractSerializableParameter parameter) {
switch (parameter.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
default:
return parameter.getType();
}
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.HttpMethod;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import java.util.*;
public class PathUtils {
/**
* Returns the operations of a path as a map which preserves the insertion order.
*
* @param path the path
* @return the operations of a path as a map
*/
private static Map<HttpMethod, Operation> getOperationMap(Path path) {
Map<HttpMethod, Operation> result = new LinkedHashMap<>();
if (path.getGet() != null) {
result.put(HttpMethod.GET, path.getGet());
}
if (path.getPut() != null) {
result.put(HttpMethod.PUT, path.getPut());
}
if (path.getPost() != null) {
result.put(HttpMethod.POST, path.getPost());
}
if (path.getDelete() != null) {
result.put(HttpMethod.DELETE, path.getDelete());
}
if (path.getPatch() != null) {
result.put(HttpMethod.PATCH, path.getPatch());
}
if (path.getHead() != null) {
result.put(HttpMethod.HEAD, path.getHead());
}
if (path.getOptions() != null) {
result.put(HttpMethod.OPTIONS, path.getOptions());
}
return result;
}
/**
* Converts the Swagger paths into a list of PathOperations.
*
* @param paths the Swagger paths
* @param basePath the basePath of all paths
* @param comparator the comparator to use.
* @return the path operations
*/
public static List<PathOperation> toPathOperationsList(Map<String, Path> paths,
String basePath,
Comparator<PathOperation> comparator) {
List<PathOperation> pathOperations = new ArrayList<>();
paths.forEach((relativePath, path) ->
pathOperations.addAll(toPathOperationsList(basePath + relativePath, path)));
if (comparator != null) {
pathOperations.sort(comparator);
}
return pathOperations;
}
/**
* Converts a Swagger path into a PathOperation.
*
* @param path the path
* @param pathModel the Swagger Path model
* @return the path operations
*/
public static List<PathOperation> toPathOperationsList(String path, Path pathModel) {
List<PathOperation> pathOperations = new ArrayList<>();
getOperationMap(pathModel).forEach((httpMethod, operation) ->
pathOperations.add(new PathOperation(httpMethod, path, operation)));
return pathOperations;
}
}

View File

@@ -0,0 +1,210 @@
/*
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.base.Function;
import io.github.swagger2markup.internal.type.*;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.swagger.models.properties.*;
import io.swagger.models.refs.RefFormat;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.Validate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class PropertyUtils {
/**
* Retrieves the type and format of a property.
*
* @param property the property
* @param definitionDocumentResolver the definition document resolver
* @return the type of the property
*/
public static Type getType(Property property, Function<String, String> definitionDocumentResolver) {
Validate.notNull(property, "property must not be null");
Type type;
if (property instanceof RefProperty) {
RefProperty refProperty = (RefProperty) property;
if (refProperty.getRefFormat() == RefFormat.RELATIVE)
type = new ObjectType(refProperty.getTitle(), null); // FIXME : Workaround for https://github.com/swagger-api/swagger-parser/issues/177
else
type = new RefType(definitionDocumentResolver.apply(refProperty.getSimpleRef()), new ObjectType(refProperty.getSimpleRef(), null /* FIXME, not used for now */));
} else if (property instanceof ArrayProperty) {
ArrayProperty arrayProperty = (ArrayProperty) property;
Property items = arrayProperty.getItems();
if (items == null)
type = new ArrayType(arrayProperty.getTitle(), new ObjectType(null, null)); // FIXME : Workaround for Swagger parser issue with composed models (https://github.com/Swagger2Markup/swagger2markup/issues/150)
else
type = new ArrayType(arrayProperty.getTitle(), getType(items, definitionDocumentResolver));
} else if (property instanceof MapProperty) {
MapProperty mapProperty = (MapProperty) property;
Property additionalProperties = mapProperty.getAdditionalProperties();
if (additionalProperties == null)
type = new MapType(mapProperty.getTitle(), new ObjectType(null, null)); // FIXME : Workaround for Swagger parser issue with composed models (https://github.com/Swagger2Markup/swagger2markup/issues/150)
else
type = new MapType(mapProperty.getTitle(), getType(additionalProperties, definitionDocumentResolver));
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
List<String> enums = stringProperty.getEnum();
if (CollectionUtils.isNotEmpty(enums)) {
type = new EnumType(stringProperty.getTitle(), enums);
} else {
type = new BasicType(stringProperty.getType(), stringProperty.getTitle());
}
} else if (property instanceof ObjectProperty) {
type = new ObjectType(property.getTitle(), ((ObjectProperty) property).getProperties());
} else {
if (isNotBlank(property.getFormat())) {
type = new BasicType(property.getType(), property.getTitle(), property.getFormat());
} else {
type = new BasicType(property.getType(), property.getTitle());
}
}
return type;
}
/**
* Retrieves the default value of a property, or otherwise returns null.
*
* @param property the property
* @return the default value of the property, or otherwise null
*/
public static Object getDefaultValue(Property property) {
Validate.notNull(property, "property must not be null");
Object defaultValue = null;
if (property instanceof BooleanProperty) {
BooleanProperty booleanProperty = (BooleanProperty) property;
defaultValue = booleanProperty.getDefault();
} else if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
defaultValue = stringProperty.getDefault();
} else if (property instanceof DoubleProperty) {
DoubleProperty doubleProperty = (DoubleProperty) property;
defaultValue = doubleProperty.getDefault();
} else if (property instanceof FloatProperty) {
FloatProperty floatProperty = (FloatProperty) property;
defaultValue = floatProperty.getDefault();
} else if (property instanceof IntegerProperty) {
IntegerProperty integerProperty = (IntegerProperty) property;
defaultValue = integerProperty.getDefault();
} else if (property instanceof LongProperty) {
LongProperty longProperty = (LongProperty) property;
defaultValue = longProperty.getDefault();
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
defaultValue = uuidProperty.getDefault();
}
return defaultValue;
}
/**
* Return example display string for the given {@code property}.
*
* @param generateMissingExamples specifies if missing examples should be generated
* @param property property
* @param markupDocBuilder doc builder
* @return property example display string
*/
public static Object getExample(boolean generateMissingExamples, Property property, MarkupDocBuilder markupDocBuilder) {
Validate.notNull(property, "property must not be null");
Object examplesValue = null;
if (property.getExample() != null) {
examplesValue = property.getExample();
} else if (property instanceof MapProperty) {
Property additionalProperty = ((MapProperty) property).getAdditionalProperties();
if (additionalProperty.getExample() != null) {
examplesValue = additionalProperty.getExample();
} else if (generateMissingExamples) {
Map<String, Object> exampleMap = new HashMap<>();
exampleMap.put("string", generateExample(additionalProperty, markupDocBuilder));
examplesValue = exampleMap;
}
} else if (property instanceof ArrayProperty) {
if (generateMissingExamples) {
Property itemProperty = ((ArrayProperty) property).getItems();
List<Object> exampleArray = new ArrayList<>();
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
examplesValue = exampleArray;
}
} else if (generateMissingExamples) {
examplesValue = generateExample(property, markupDocBuilder);
}
return examplesValue;
}
/**
* Generate a default example value for property.
*
* @param property property
* @param markupDocBuilder doc builder
* @return a generated example for the property
*/
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
switch (property.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
case "ref":
if (property instanceof RefProperty) {
return markupDocBuilder.copy(false).crossReference(((RefProperty) property).getSimpleRef()).toString();
}
default:
return property.getType();
}
}
/**
* Convert a string {@code value} to specified {@code type}.
*
* @param value value to convert
* @param type target conversion type
* @return converted value as object
*/
public static Object convertExample(String value, String type) {
if (value == null) {
return null;
}
try {
switch (type) {
case "integer":
return Integer.valueOf(value);
case "number":
return Float.valueOf(value);
case "boolean":
return Boolean.valueOf(value);
case "string":
return value;
default:
return value;
}
} catch (NumberFormatException e) {
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
}
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2016 Cas Eliëns
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import io.github.swagger2markup.model.PathOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexUtils {
private static Logger logger = LoggerFactory.getLogger(TagUtils.class);
/**
* Alphabetically sort the list of groups
*
* @param groups List of available groups
* @return String[] of sorted groups
*/
public static String[] toSortedArray(Set<String> groups) {
//TODO: sort in another way than just alphabetically
String[] sortedArray = groups.toArray(new String[groups.size()]);
Arrays.sort(sortedArray);
return sortedArray;
}
/**
* Groups the operations by regex group. The key of the Multimap is the group name.
* The value of the Multimap is a PathOperation
*
* @param allOperations all operations
* @param headerPattern regex pattern used for determining headers
* @return Operations grouped by regex
*/
public static Multimap<String, PathOperation> groupOperationsByRegex(List<PathOperation> allOperations, Pattern headerPattern) {
Multimap<String, PathOperation> operationsGroupedByRegex = LinkedHashMultimap.create();
for (PathOperation operation : allOperations) {
String path = operation.getPath();
Matcher m = headerPattern.matcher(path);
if (m.matches() && m.group(1) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Added path operation '{}' to header '{}'", operation, m.group(1));
}
operationsGroupedByRegex.put(m.group(1), operation);
} else {
if(logger.isWarnEnabled()) {
logger.warn("Operation '{}' does not match regex '{}' and will not be included in output", operation, headerPattern.toString());
}
}
}
return operationsGroupedByRegex;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,10 @@
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.base.Optional;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Ordering;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.Tag;
import org.apache.commons.lang3.Validate;
@@ -28,49 +29,68 @@ import java.util.*;
public class TagUtils {
private static Logger logger = LoggerFactory.getLogger(TagUtils.class);
private static Logger LOG = LoggerFactory.getLogger(TagUtils.class);
/**
* Converts the global Tag list into a Map where the tag name is the key and the Tag the value.
* Either ordered or as-is, if the comparator is null.
*
* @param tags the List of tags
* @param comparator the comparator to use.
* @return the Map of tags. Either ordered or as-is, if the comparator is null.
* @param tags the List of tags
* @return the Map of tags
*/
public static Map<String, Tag> toSortedMap(List<Tag> tags, Comparator<String> comparator) {
Map<String, Tag> sortedMap;
if (comparator == null)
sortedMap = new LinkedHashMap<>();
else
sortedMap = new TreeMap<>(comparator);
tags.forEach(tag -> sortedMap.put(tag.getName(), tag));
return sortedMap;
public static Map<String, Tag> convertTagsListToMap(List<Tag> tags) {
if (tags == null) {
tags = new ArrayList<>();
}
Map<String, Tag> tagsMap = new HashMap<>();
for (Tag tag : tags) tagsMap.put(tag.getName(), tag);
return tagsMap;
}
/**
* Retrieves the optional description of a tag.
*
* @param tagsMap the Map of tags
* @param tagName the name of the tag
* @return the optional description of the tag
*/
public static Optional<String> getTagDescription(Map<String, Tag> tagsMap, String tagName) {
Tag tag = tagsMap.get(tagName);
if(tag != null){
return Optional.fromNullable(tag.getDescription());
}
return Optional.absent();
}
/**
* Groups the operations by tag. The key of the Multimap is the tag name.
* The value of the Multimap is a PathOperation
*
* @param allOperations all operations
* @param allOperations all operations
* @param tagOrdering comparator for tags
* @param operationOrdering comparator for operations, for a given tag
* @return Operations grouped by Tag
*/
public static Multimap<String, PathOperation> groupOperationsByTag(List<PathOperation> allOperations, Comparator<PathOperation> operationOrdering) {
public static Multimap<String, PathOperation> groupOperationsByTag(Set<PathOperation> allOperations, Comparator<String> tagOrdering, Comparator<PathOperation> operationOrdering) {
MultimapBuilder.MultimapBuilderWithKeys<String> multimapBuilderWithKeys;
if (tagOrdering == null)
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(Ordering.<String>natural()); // FIXME as-is sorting not supported because of limitations in MultiMap::hashkeys(). Replaced with Ordering.natural()
else
multimapBuilderWithKeys = MultimapBuilder.SortedSetMultimapBuilder.treeKeys(tagOrdering);
Multimap<String, PathOperation> operationsGroupedByTag;
if (operationOrdering == null) {
operationsGroupedByTag = LinkedHashMultimap.create();
} else {
operationsGroupedByTag = MultimapBuilder.linkedHashKeys().treeSetValues(operationOrdering).build();
}
if (operationOrdering == null)
operationsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
else
operationsGroupedByTag = multimapBuilderWithKeys.treeSetValues(operationOrdering).build();
for (PathOperation operation : allOperations) {
List<String> tags = operation.getOperation().getTags();
Validate.notEmpty(tags, "Can't GroupBy.TAGS. Operation '%s' has no tags", operation);
Validate.notEmpty(tags, "Can't GroupBy.TAGS > Operation '%s' has not tags", operation);
for (String tag : tags) {
if (logger.isDebugEnabled()) {
logger.debug("Added path operation '{}' to tag '{}'", operation, tag);
if (LOG.isInfoEnabled()) {
LOG.info("Added path operation '{}' to tag '{}'", operation, tag);
}
operationsGroupedByTag.put(tag, operation);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
public class PathOperation {
private HttpMethod method;
private String path;
private Operation operation;
protected HttpMethod method;
protected String path;
protected Operation operation;
public PathOperation(HttpMethod method, String path, Operation operation) {
this.method = method;
@@ -43,7 +43,6 @@ public class PathOperation {
/**
* Returns the display title for an operation
*
* @return the operation title
*/
public String getTitle() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,51 +16,16 @@
package io.github.swagger2markup.spi;
import com.google.common.base.Optional;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.swagger.models.Model;
import org.apache.commons.lang3.Validate;
import java.util.Optional;
/**
* DefinitionsDocumentExtension extension point can be used to extend the definitions document content.
*/
public abstract class DefinitionsDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
*
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) throws RuntimeException {
//TODO: Unused method, make sure this is never used and then remove it.
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case DEFINITION_BEFORE:
case DEFINITION_AFTER:
levelOffset = 1;
break;
case DEFINITION_BEGIN:
case DEFINITION_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
@@ -85,7 +50,7 @@ public abstract class DefinitionsDocumentExtension extends AbstractExtension {
private Model model;
/**
* @param position the current position
* @param position the current position
* @param docBuilder the MarkupDocBuilder
*/
public Context(Position position, MarkupDocBuilder docBuilder) {
@@ -95,10 +60,10 @@ public abstract class DefinitionsDocumentExtension extends AbstractExtension {
}
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param definitionName the name of the current definition
* @param model the current Model of the definition
* @param model the current Model of the definition
*/
public Context(Position position, MarkupDocBuilder docBuilder, String definitionName, Model model) {
super(docBuilder);
@@ -115,11 +80,45 @@ public abstract class DefinitionsDocumentExtension extends AbstractExtension {
}
public Optional<String> getDefinitionName() {
return Optional.ofNullable(definitionName);
return Optional.fromNullable(definitionName);
}
public Optional<Model> getModel() {
return Optional.ofNullable(model);
return Optional.fromNullable(model);
}
}
public DefinitionsDocumentExtension() {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case DEFINITION_BEFORE:
case DEFINITION_AFTER:
levelOffset = 1;
break;
case DEFINITION_BEGIN:
case DEFINITION_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2017 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.spi;
import io.github.swagger2markup.Labels;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import javaslang.Function2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class MarkupComponent<T> implements Function2<MarkupDocBuilder, T, MarkupDocBuilder> {
protected static final String COLON = " : ";
protected Logger logger = LoggerFactory.getLogger(getClass());
protected Swagger2MarkupConverter.Context context;
protected Labels labels;
protected Swagger2MarkupConfig config;
protected Swagger2MarkupExtensionRegistry extensionRegistry;
public MarkupComponent(Swagger2MarkupConverter.Context context) {
this.context = context;
this.config = context.getConfig();
this.extensionRegistry = context.getExtensionRegistry();
this.labels = context.getLabels();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,17 +23,41 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
*/
public abstract class OverviewDocumentExtension extends AbstractExtension {
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_AFTER,
DOCUMENT_BEGIN,
DOCUMENT_END
}
public static class Context extends ContentContext {
private Position position;
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
*/
public Context(Position position, MarkupDocBuilder docBuilder) {
super(docBuilder);
this.position = position;
}
public Position getPosition() {
return position;
}
}
public OverviewDocumentExtension() {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
*
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
//TODO: Unused method, make sure this is never used and then remove it.
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
@@ -51,28 +75,4 @@ public abstract class OverviewDocumentExtension extends AbstractExtension {
return levelOffset;
}
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_AFTER,
DOCUMENT_BEGIN,
DOCUMENT_END
}
public static class Context extends ContentContext {
private Position position;
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
*/
public Context(Position position, MarkupDocBuilder docBuilder) {
super(docBuilder);
this.position = position;
}
public Position getPosition() {
return position;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,68 +27,6 @@ import org.apache.commons.lang3.Validate;
*/
public abstract class PathsDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
*
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
//TODO: Unused method, make sure this is never used and then remove it.
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case OPERATION_BEFORE:
case OPERATION_AFTER:
levelOffset = 1;
break;
case OPERATION_BEGIN:
case OPERATION_END:
levelOffset = increaseLevelOffset(2);
break;
case OPERATION_DESCRIPTION_BEFORE:
case OPERATION_DESCRIPTION_AFTER:
case OPERATION_PARAMETERS_BEFORE:
case OPERATION_PARAMETERS_AFTER:
case OPERATION_RESPONSES_BEFORE:
case OPERATION_RESPONSES_AFTER:
case OPERATION_SECURITY_BEFORE:
case OPERATION_SECURITY_AFTER:
levelOffset = increaseLevelOffset(2);
break;
case OPERATION_DESCRIPTION_BEGIN:
case OPERATION_DESCRIPTION_END:
case OPERATION_PARAMETERS_BEGIN:
case OPERATION_PARAMETERS_END:
case OPERATION_RESPONSES_BEGIN:
case OPERATION_RESPONSES_END:
case OPERATION_SECURITY_BEGIN:
case OPERATION_SECURITY_END:
levelOffset = 3;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
private int increaseLevelOffset(int levelOffset) {
//TODO: This method always receives levelOffset=2. Perhaps the parameter could be removed
if (globalContext.getConfig().getPathsGroupedBy() == GroupBy.TAGS) {
return ++levelOffset;
} else {
return levelOffset;
}
}
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
@@ -137,7 +75,6 @@ public abstract class PathsDocumentExtension extends AbstractExtension {
/**
* Context for all other positions
*
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param operation the current path operation
@@ -158,4 +95,66 @@ public abstract class PathsDocumentExtension extends AbstractExtension {
return Optional.fromNullable(operation);
}
}
public PathsDocumentExtension() {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
*
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case OPERATION_BEFORE:
case OPERATION_AFTER:
levelOffset = 1;
break;
case OPERATION_BEGIN:
case OPERATION_END:
levelOffset = increaseLevelOffset(2);
break;
case OPERATION_DESCRIPTION_BEFORE:
case OPERATION_DESCRIPTION_AFTER:
case OPERATION_PARAMETERS_BEFORE:
case OPERATION_PARAMETERS_AFTER:
case OPERATION_RESPONSES_BEFORE:
case OPERATION_RESPONSES_AFTER:
case OPERATION_SECURITY_BEFORE:
case OPERATION_SECURITY_AFTER:
levelOffset = increaseLevelOffset(2);
break;
case OPERATION_DESCRIPTION_BEGIN:
case OPERATION_DESCRIPTION_END:
case OPERATION_PARAMETERS_BEGIN:
case OPERATION_PARAMETERS_END:
case OPERATION_RESPONSES_BEGIN:
case OPERATION_RESPONSES_END:
case OPERATION_SECURITY_BEGIN:
case OPERATION_SECURITY_END:
levelOffset = 3;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
private int increaseLevelOffset(int levelOffset) {
if (globalContext.getConfig().getPathsGroupedBy() == GroupBy.TAGS) {
return ++levelOffset;
}else {
return levelOffset;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,40 +26,6 @@ import org.apache.commons.lang3.Validate;
*/
public abstract class SecurityDocumentExtension extends AbstractExtension {
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
*
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
//TODO: Unused method, make sure this is never used and then remove it.
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case SECURITY_SCHEME_BEFORE:
case SECURITY_SCHEME_AFTER:
levelOffset = 1;
break;
case SECURITY_SCHEME_BEGIN:
case SECURITY_SCHEME_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_BEGIN,
@@ -83,7 +49,7 @@ public abstract class SecurityDocumentExtension extends AbstractExtension {
private SecuritySchemeDefinition securityScheme;
/**
* @param position the current position
* @param position the current position
* @param docBuilder the MarkupDocBuilder
*/
public Context(Position position, MarkupDocBuilder docBuilder) {
@@ -93,10 +59,10 @@ public abstract class SecurityDocumentExtension extends AbstractExtension {
}
/**
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param position the current position
* @param docBuilder the MarkupDocBuilder
* @param securitySchemeName the name of the current securityScheme
* @param securityScheme the current security scheme securityScheme
* @param securityScheme the current security scheme securityScheme
*/
public Context(Position position, MarkupDocBuilder docBuilder, String securitySchemeName, SecuritySchemeDefinition securityScheme) {
super(docBuilder);
@@ -121,4 +87,38 @@ public abstract class SecurityDocumentExtension extends AbstractExtension {
}
}
public SecurityDocumentExtension() {
}
public abstract void apply(Context context);
/**
* Returns title level offset from 1 to apply to content
* @param context context
* @return title level offset
*/
protected int levelOffset(Context context) {
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
case SECURITY_SCHEME_BEFORE:
case SECURITY_SCHEME_AFTER:
levelOffset = 1;
break;
case SECURITY_SCHEME_BEGIN:
case SECURITY_SCHEME_END:
levelOffset = 2;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,9 @@ import io.swagger.models.Swagger;
*/
public abstract class SwaggerModelExtension extends AbstractExtension {
public SwaggerModelExtension() {
}
public abstract void apply(Swagger swagger);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017 Robert Winkler
* Copyright 2016 Robert Winkler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More