Compare commits

...

77 Commits

Author SHA1 Message Date
Robert Winkler
81edab38f3 The notBlank validation of the type should tell which parameter is not valid. 2017-01-03 15:58:43 +01:00
Robert Winkler
039607a294 Updated version to 1.2.0-SNAPSHOT 2017-01-03 15:27:32 +01:00
Cas Eliëns
2f33522e6d Issue #214 Added support for page breaks (#226)
* Added support for page breaks
* Added documentation and config file support for page breaks and regex
2017-01-03 11:21:31 +01:00
Cas Eliëns
76c54a713a use raw JSON object instead of converting to string 2017-01-02 13:47:02 +01:00
Cas Eliëns
dcebed2d42 split reused code into methods 2017-01-02 13:47:02 +01:00
Cas Eliëns
dbf9afa8da Remove unused import 2017-01-02 13:47:02 +01:00
Cas Eliëns
f7f397b5f2 Improve printing for different ways of defining examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
44f852ad42 Improve example printing for $ref'd examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
e1be2f2130 Great Expectations 2017-01-02 13:47:02 +01:00
Cas Eliëns
8468607703 Improve example rendering for hardcoded examples 2017-01-02 13:47:02 +01:00
Cas Eliëns
f981318142 Example responses now display correctly 2017-01-02 13:47:02 +01:00
Cas Eliëns
e1d0d7b293 Add FIXME comment 2017-01-02 13:47:02 +01:00
Cas Eliëns
d118a0cf74 Further work on Swagger2Markup/swagger2markup#223 2017-01-02 13:47:02 +01:00
Cas Eliëns
7cb1095465 Begin work on Swagger2Markup/swagger2markup#223 2017-01-02 13:47:02 +01:00
Cas Eliëns
595b885b9a Close Swagger2Markup/swagger2markup#220 2016-12-20 14:07:27 +01:00
Cas Eliëns
b1c219bc1b Remove unused code, optimize imports, fix Codacy issues
* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Work on implementing regex sorting

* Add regex ordering translations and unit test

* Improve Regex grouping

* Make regex sorting test more like a real-world example

* Remove unused imports

* Improve code style consistency

* Improve code style consistency

* Remove empty statement

* Resolve some Codacy issues

* Remove empty constructors

* Remove unused fields

* Merge nested IF statements

* Improve method scopes

* Remove unused classes

* Remove unused imports

* Remove fixed TODO comment

* Fix codacy issues

* Fix codacy issues (reverted from commit 43f27e7fc6)

* Improve code style consistency

* Resolve some Codacy issues

* Remove empty constructors

* Remove unused fields

* Merge nested IF statements

* Improve method scopes

* Remove unused classes

* Remove unused imports

* Remove fixed TODO comment

* Fix codacy issues
2016-12-19 16:04:17 +01:00
Cas Eliëns
852b2ac3b4 PR#218 Improve code style consistency
Improved code style consistency
2016-12-13 10:44:31 +01:00
Cas Eliëns
937cded2aa Issue #215: Path grouping via a RegEx pattern
* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Begin working on Swagger2Markup/swagger2markup#215

* Begin looking for methods that need to be modified for Swagger2Markup/swagger2markup#215

* Work on implementing regex sorting

* Add regex ordering translations and unit test

* Improve Regex grouping

* Make regex sorting test more like a real-world example

* Remove unused imports
2016-12-13 09:58:12 +01:00
Robert Winkler
022d2453d2 Issee #216: Replace slash with system file separator in unit tests. 2016-12-09 09:17:55 +01:00
Robert Winkler
e5a187cc24 Updated version to 1.1.2-SNAPSHOT 2016-11-30 09:18:22 +01:00
Robert Winkler
83bb63321a Updated markup-document-builder from 1.0.0 to 1.1.0 2016-11-30 08:20:04 +01:00
Robert Winkler
cd5b5c9240 Refactored ParameterAdapter and created MarkupDocBuilderUtils. 2016-11-18 12:36:39 +01:00
Robert Winkler
2096ec0d5d Refactored ParameterAdapter and moved ParameterAdapter and PropertyAdapter into a new package. 2016-11-16 12:54:32 +01:00
Robert Winkler
25d4311237 Added a modularized Swagger spec test 2016-11-16 12:54:03 +01:00
Robert Winkler
7e07c2fc81 Fixed method name in DefinitionsDocument 2016-11-15 14:50:45 +01:00
Robert Winkler
5a8a618e6b Refactored document resolver and added tests. 2016-11-15 14:47:11 +01:00
Robert Winkler
f072fc99b9 Refactored Documents. Documents are also components now and can be composed of components. 2016-11-15 11:12:17 +01:00
Robert Winkler
54e881fc58 Fixed wrong import in SecuritySchemeComponent 2016-11-14 16:14:16 +01:00
Robert Winkler
cd6a3ed724 Refactored Components to be more functional. 2016-11-14 16:08:24 +01:00
Robert Winkler
5a00dde912 Refactored Components to be more functional. 2016-11-14 16:02:49 +01:00
Robert Winkler
876d7b2f7b Moved code into BodyParameterComponent 2016-11-11 14:21:43 +01:00
Robert Winkler
4b74ec0e54 Moved code into PathOperationComponent 2016-11-11 13:30:04 +01:00
Robert Winkler
a719e33332 Moved code into SecuritySchemeComponent 2016-11-11 10:29:51 +01:00
Robert Winkler
86a727f097 Refactored DocumentBuilder into components. 2016-11-10 15:48:03 +01:00
Robert Winkler
2670780076 Enhancement #206 Updated to markup-document-builder v1.1.0 which renders bold text as **text** and italic text as __text__. 2016-11-10 12:42:52 +01:00
Robert Winkler
ebf9912269 Bug #205: Fix ordering of operations when grouped by tags. 2016-11-10 12:41:26 +01:00
Robert Winkler
11549ab64e Bug #205: Fix ordering of operations when grouped by tags. 2016-11-10 10:43:12 +01:00
Robert Winkler
d128146952 Added a component API to split a document into components and improve component testability 2016-11-09 16:30:02 +01:00
Robert Winkler
686abd8842 Added a component API to split a document into components and improve component testability 2016-11-09 15:02:28 +01:00
Robert Winkler
551aeed835 Removed ListUtils and changed MapUtils.toKeySet to MapUtils.toSortedMap 2016-11-08 12:28:27 +01:00
Robert Winkler
5b1a1a2bcf Migrated some collections to Javaslang 2016-11-08 10:18:07 +01:00
Robert Winkler
09d2474a9a Added javaslang and paleo-core to improve Table rendering 2016-11-04 15:32:17 +01:00
Robert Winkler
5c00e5493c Removed ExternalLocation model from inlineSchema test. 2016-11-04 15:32:17 +01:00
Robert Winkler
c343af8f5a Updated Gradle to v3.1 2016-11-04 15:32:17 +01:00
yewton
4af7eb5b89 Add support for Japanese 2016-11-02 08:45:42 +01:00
Robert Winkler
aa9a340144 Added a config parameter which allows to prepend the basePath to all paths. 2016-11-01 14:42:46 +01:00
Robert Winkler
35ae68ceee Fixed german and spanish language files 2016-11-01 08:55:04 +01:00
Robert Winkler
560fb4ece6 Added language file for Portuguese (Brazilian) 2016-11-01 08:30:28 +01:00
Cleydson Júnior
8eb494cd5b Converting special characters to ASCII escape codes 2016-11-01 07:05:19 +01:00
Cleydson Júnior
0766336a56 Adding support for Brazilian Portuguese 2016-11-01 07:05:19 +01:00
TzeKai Lee
24352f4d1c Add format tests on request param in query and body 2016-10-28 09:07:56 +02:00
TzeKei Lee
adb0fee973 Added displaying format for string type and definitions only contains string or integer type. 2016-10-28 09:07:56 +02:00
Robert Winkler
13a7113aa7 Fixes #197 Converted ZH-language file from UTF-8 to latin1 using native2asciidoc 2016-10-25 15:25:27 +02:00
Robert Winkler
e882975726 Updated README 2016-10-18 15:27:06 +02:00
Robert Winkler
12209fe923 Updated version to 1.1.0 2016-10-18 15:14:05 +02:00
Robert Winkler
8a63744198 Updated releases notes 2016-10-18 15:11:52 +02:00
James Bassett
5871f0c9b0 Added support for exclusiveMin and exclusiveMax 2016-10-14 07:12:53 +02:00
James Bassett
908f524c64 Updated min/max value to format correctly based on the data type 2016-10-12 08:47:54 +02:00
Francisco José Bermejo Herrera
9fa0ee3def Add support for Spanish language 2016-10-03 13:46:12 +02:00
Robert Winkler
35e9450f74 Updated docker documentation 2016-09-23 10:29:46 +02:00
Robert Winkler
6033ea5a98 Updated docker documentation 2016-09-23 10:21:02 +02:00
Robert Winkler
6f24c3cb39 Merge remote-tracking branch 'origin/master' 2016-09-23 08:54:37 +02:00
Robert Winkler
e975e49d3e Added docker documentation 2016-09-23 08:54:18 +02:00
Robert Winkler
c5cfe10fa6 Merge pull request #187 from KristinaGen/master
update labels_ru
2016-09-14 09:55:56 +02:00
KristinaGen
7c988460f0 update labels_ru 2016-09-13 16:20:57 +02:00
Robert Winkler
21f1892de0 Added chinese language 2016-09-12 10:02:02 +02:00
Robert Winkler
b97344849d Merge pull request #186 from mingkaili/patch-1
labels_zh.properties
2016-09-12 09:49:43 +02:00
Mingkai Lee
935d48d4cc labels_zh.properties
Add chinese labels.properties. Add chinese language.
2016-09-12 10:26:16 +08:00
Robert Winkler
73ba233f9e Merge pull request #181 from iwannayoyo/Remove_empty_columns
eliminate empty columns in tables
2016-08-31 10:20:25 +02:00
Chris Hartman
ff955d392b eliminate empty columns in tables 2016-08-25 16:43:17 -04:00
Robert Winkler
19fde31f67 Merge pull request #177 from mhswisscom/Fix_without_reformat
recursive examples patch without reformatting
2016-08-25 13:49:45 +02:00
Marc Habegger
b3f368ac37 recursive examples patch without reformatting 2016-08-25 13:33:27 +02:00
Robert Winkler
c5efb401b4 Added releaseVersion to build.gradle and documentation.gradle scripts so that the AsciiDoc documentation always refers to the release version and not to the SNAPSHOT version. 2016-08-04 12:10:08 +02:00
Robert Winkler
f386e6ed91 Updated version to 1.0.2-SNAPSHOT 2016-08-04 10:28:30 +02:00
Robert Winkler
55b323c063 Merge pull request #171 from zerok/fix/emptycontact
Allow empty contact objects
2016-08-04 10:25:14 +02:00
Robert Winkler
6f286b52d8 Prepare release v1.0.1 2016-08-04 10:03:08 +02:00
Horst Gutmann
4850673b96 Allow empty contact objects
According to the spec the contact object can be empty (it doesn't have
any required properties). Previously, the markup generation failed in
that situation due to an empty paragraph being generated. This change
fixes that.
2016-08-04 10:00:33 +02:00
261 changed files with 16967 additions and 8913 deletions

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.0.1/[Reference Documentation]
- http://swagger2markup.github.io/swagger2markup/1.1.1/[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]

View File

@@ -95,3 +95,31 @@
=== 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.1.2
* 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-SNAPSHOT

View File

@@ -13,7 +13,8 @@ buildscript {
}
}
description = 'swagger2markup Build'
version = '1.0.1'
version = '1.2.0-SNAPSHOT'
ext.releaseVersion = '1.1.1'
group = 'io.github.swagger2markup'
apply plugin: 'java'
@@ -40,15 +41,17 @@ repositories {
}
dependencies {
compile 'io.github.swagger2markup:markup-document-builder:1.0.0'
compile 'io.swagger:swagger-compat-spec-parser:1.0.18'
compile 'org.apache.commons:commons-configuration2:2.0'
compile 'io.github.swagger2markup:markup-document-builder:1.1.1-SNAPSHOT'
compile 'io.swagger:swagger-compat-spec-parser:1.0.23'
compile 'org.apache.commons:commons-configuration2:2.1'
compile 'commons-beanutils:commons-beanutils:1.9.2'
compile 'org.apache.commons:commons-collections4:4.1'
compile 'io.javaslang:javaslang:2.0.4'
compile 'ch.netzwerg:paleo-core:0.10.1'
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.4.0'
testCompile 'org.assertj:assertj-core:3.5.2'
testCompile 'io.github.robwin:assertj-diff:0.1.1'
}
@@ -63,5 +66,5 @@ test {
task wrapper(type: Wrapper) {
gradleVersion = '2.12'
gradleVersion = '3.1'
}

View File

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

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Thu Mar 31 16:29:35 CEST 2016
#Thu Nov 03 09:37:13 CET 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip

2
gradlew.bat vendored
View File

@@ -46,7 +46,7 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

View File

@@ -0,0 +1,13 @@
== 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

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

View File

@@ -136,13 +136,15 @@ 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 | AS_IS
|swagger2markup.pathsGroupedBy| Specifies how the paths should be grouped | AS_IS, TAGS, REGEX | 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 |
|===
[options="header"]
@@ -192,6 +194,13 @@ 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

@@ -17,5 +17,6 @@ package io.github.swagger2markup;
public enum GroupBy {
AS_IS,
TAGS
TAGS,
REGEX
}

View File

@@ -0,0 +1,110 @@
/*
* 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;
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";
//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

@@ -22,11 +22,15 @@ import java.util.Locale;
* @author Maksim Myshkin
*/
public enum Language {
EN(new Locale("en")),
EN(Locale.ENGLISH),
RU(new Locale("ru")),
FR(new Locale("fr")),
DE(new Locale("de")),
TR(new Locale("tr"));
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);
private final Locale lang;

View File

@@ -0,0 +1,37 @@
/*
* 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;
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

@@ -21,6 +21,8 @@ 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.
@@ -43,6 +45,11 @@ 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.
*/
@@ -73,6 +80,11 @@ public interface Swagger2MarkupConfig {
*/
OrderBy getTagOrderBy();
/**
* Specifies the regex pattern used for header matching
*/
Pattern getHeaderPattern();
/**
* Specifies a custom comparator function to order tags.
*/
@@ -208,4 +220,11 @@ public interface Swagger2MarkupConfig {
* @return the extension properties
*/
Swagger2MarkupProperties getExtensionsProperties();
/**
* Returns the list of page break locations
*
* @return List of PageBreakLocations
*/
List<PageBreakLocations> getPageBreakLocations();
}

View File

@@ -17,11 +17,12 @@ package io.github.swagger2markup;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.builder.Swagger2MarkupExtensionRegistryBuilder;
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.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.utils.URIUtils;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
@@ -47,22 +48,18 @@ import java.nio.file.StandardOpenOption;
*/
public class Swagger2MarkupConverter {
private Context context;
private final Context context;
private final OverviewDocument overviewDocument;
private final PathsDocument pathsDocument;
private final DefinitionsDocument definitionsDocument;
private final SecurityDocument securityDocument;
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;
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);
}
/**
@@ -74,17 +71,15 @@ 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));
}
}
@@ -95,7 +90,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);
}
@@ -108,11 +103,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) {
@@ -163,18 +158,57 @@ 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");
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);
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()));
}
/**
@@ -202,10 +236,10 @@ public class Swagger2MarkupConverter {
public void toFile(Path outputFile) {
Validate.notNull(outputFile, "outputFile must not be null");
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);
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);
}
/**
@@ -213,13 +247,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");
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);
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);
}
/**
@@ -230,10 +264,10 @@ public class Swagger2MarkupConverter {
public String toString() {
StringBuilder sb = new StringBuilder();
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());
sb.append(applyOverviewDocument().toString());
sb.append(applyPathsDocument().toString());
sb.append(applyDefinitionsDocument().toString());
sb.append(applySecurityDocument().toString());
return sb.toString();
}
@@ -283,7 +317,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");
@@ -310,48 +344,45 @@ public class Swagger2MarkupConverter {
if (extensionRegistry == null)
extensionRegistry = new Swagger2MarkupExtensionRegistryBuilder().build();
Context context = new Context(config, swagger, swaggerLocation);
Context context = new Context(config, extensionRegistry, swagger, swaggerLocation);
initExtensions(context);
applySwaggerExtensions(context);
return new Swagger2MarkupConverter(context, extensionRegistry);
return new Swagger2MarkupConverter(context);
}
private void initExtensions(Context 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);
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));
}
private void applySwaggerExtensions(Context context) {
for (SwaggerModelExtension swaggerModelExtension : extensionRegistry.getSwaggerModelExtensions()) {
swaggerModelExtension.apply(context.getSwagger());
}
extensionRegistry.getSwaggerModelExtensions().forEach(extension -> extension.apply(context.getSwagger()));
}
}
public static class Context {
private Swagger2MarkupConfig config;
private Swagger swagger;
private URI swaggerLocation;
private final Swagger2MarkupConfig config;
private final Swagger swagger;
private final URI swaggerLocation;
private final Swagger2MarkupExtensionRegistry extensionRegistry;
private final Labels labels;
private Path outputPath;
Context(Swagger2MarkupConfig config, Swagger swagger, URI swaggerLocation) {
public Context(Swagger2MarkupConfig config,
Swagger2MarkupExtensionRegistry extensionRegistry,
Swagger swagger,
URI swaggerLocation) {
this.config = config;
this.extensionRegistry = extensionRegistry;
this.swagger = swagger;
this.swaggerLocation = swaggerLocation;
this.labels = new Labels(config);
}
public Swagger2MarkupConfig getConfig() {
@@ -365,6 +396,27 @@ 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

@@ -25,30 +25,35 @@ 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

@@ -25,10 +25,8 @@ import org.apache.commons.configuration2.MapConfiguration;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
import java.util.regex.Pattern;
public class Swagger2MarkupProperties {
@@ -40,9 +38,11 @@ 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";
@@ -63,6 +63,7 @@ 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
@@ -79,63 +80,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
*
* @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 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 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
*
* @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));
@@ -143,15 +144,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));
}
}
@@ -159,43 +160,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 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
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @param key the property name to resolve
* @return The URI property
* @throws IllegalStateException if the value cannot be mapped to the enum
*/
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));
}
}
@@ -203,31 +204,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
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @param key the property name to resolve
* @return The Path property
* @throws IllegalStateException if the value cannot be mapped to the enum
*/
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 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));
}
}
@@ -235,75 +236,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
*
* @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
*
* @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
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @param key the property name to resolve
* @return The GroupBy property
* @throws IllegalStateException if the value cannot be mapped to the enum
*/
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
* @throws IllegalStateException if the value cannot be mapped to the enum
*
* @param key the property name to resolve
* @return The OrderBy property
* @throws IllegalStateException if the value cannot be mapped to the enum
*/
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));
}
}
@@ -313,7 +314,7 @@ public class Swagger2MarkupProperties {
*
* @return the list of keys.
*/
public List<String> getKeys(){
public List<String> getKeys() {
return IteratorUtils.toList(configuration.getKeys());
}
@@ -330,10 +331,25 @@ 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 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,5 +1,6 @@
/*
* Copyright 2016 Robert Winkler
* Modified December 12 2016 by 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.
@@ -15,9 +16,9 @@
*/
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.Swagger2MarkupProperties;
import io.github.swagger2markup.markup.builder.LineSeparator;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import io.github.swagger2markup.model.PathOperation;
@@ -28,54 +29,28 @@ import org.apache.commons.configuration2.builder.fluent.Configurations;
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.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static io.github.swagger2markup.Swagger2MarkupProperties.*;
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(new Function<PathOperation, HttpMethod>() {
public HttpMethod apply(PathOperation operation) {
return operation.getMethod();
}
});
.onResultOf(PathOperation::getMethod);
static final Ordering<PathOperation> OPERATION_PATH_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(new Function<PathOperation, String>() {
public String apply(PathOperation operation) {
return operation.getPath();
}
});
.onResultOf(PathOperation::getPath);
static final Ordering<Parameter> PARAMETER_IN_NATURAL_ORDERING = Ordering
.explicit("header", "path", "query", "formData", "body")
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getIn();
}
});
.onResultOf(Parameter::getIn);
static final Ordering<Parameter> PARAMETER_NAME_NATURAL_ORDERING = Ordering
.natural()
.onResultOf(new Function<Parameter, String>() {
public String apply(Parameter parameter) {
return parameter.getName();
}
});
.onResultOf(Parameter::getName);
private static final String PROPERTIES_DEFAULT = "io/github/swagger2markup/config/default.properties";
DefaultSwagger2MarkupConfig config = new DefaultSwagger2MarkupConfig();
public Swagger2MarkupConfigBuilder() {
@@ -101,6 +76,7 @@ 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);
@@ -124,10 +100,16 @@ 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);
Configuration swagger2markupConfiguration = compositeConfiguration.subset(PROPERTIES_PREFIX);
Configuration extensionsConfiguration = swagger2markupConfiguration.subset(EXTENSION_PREFIX);
config.extensionsProperties = new Swagger2MarkupProperties(extensionsConfiguration);
@@ -241,6 +223,19 @@ 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.
*
@@ -477,6 +472,16 @@ public class Swagger2MarkupConfigBuilder {
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.
*
@@ -484,11 +489,23 @@ public class Swagger2MarkupConfigBuilder {
* @return this builder
*/
public Swagger2MarkupConfigBuilder withAnchorPrefix(String anchorPrefix) {
Validate.notNull(anchorPrefix, "%s must no be null", "anchorPrefix");
Validate.notNull(anchorPrefix, "%s must not 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.
*
@@ -501,11 +518,12 @@ 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;
@@ -537,6 +555,10 @@ public class Swagger2MarkupConfigBuilder {
private String separatedOperationsFolder;
private String separatedDefinitionsFolder;
private List<PageBreakLocations> pageBreakLocations;
private Pattern headerPattern;
private Swagger2MarkupProperties extensionsProperties;
@Override
@@ -584,6 +606,11 @@ public class Swagger2MarkupConfigBuilder {
return tagOrderBy;
}
@Override
public Pattern getHeaderPattern() {
return headerPattern;
}
@Override
public Comparator<String> getTagOrdering() {
return tagOrdering;
@@ -703,5 +730,15 @@ public class Swagger2MarkupConfigBuilder {
public Swagger2MarkupProperties getExtensionsProperties() {
return extensionsProperties;
}
@Override
public boolean isBasePathPrefixEnabled() {
return basePathPrefixEnabled;
}
@Override
public List<PageBreakLocations> getPageBreakLocations() {
return pageBreakLocations;
}
}
}

View File

@@ -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

@@ -0,0 +1,205 @@
/*
* 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.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<String> 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

@@ -13,258 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.swagger2markup.internal.utils;
package io.github.swagger2markup.internal.adapter;
import com.google.common.base.Function;
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class PropertyUtils {
public final class PropertyAdapter {
/**
* 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) {
private final Property property;
private static Logger logger = LoggerFactory.getLogger(PropertyAdapter.class);
public PropertyAdapter(Property property) {
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;
}
/**
* Retrieves the minLength of a property, or otherwise returns null.
*
* @param property the property
* @return the minLength of the property, or otherwise null
*/
public static Integer getMinlength(Property property) {
Validate.notNull(property, "property must not be null");
Integer minLength = null;
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
minLength = stringProperty.getMinLength();
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
minLength = uuidProperty.getMinLength();
}
return minLength;
}
/**
* Retrieves the maxLength of a property, or otherwise returns null.
*
* @param property the property
* @return the maxLength of the property, or otherwise null
*/
public static Integer getMaxlength(Property property) {
Validate.notNull(property, "property must not be null");
Integer maxLength = null;
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
maxLength = stringProperty.getMaxLength();
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
maxLength = uuidProperty.getMaxLength();
}
return maxLength;
}
/**
* Retrieves the pattern of a property, or otherwise returns null.
*
* @param property the property
* @return the pattern of the property, or otherwise null
*/
public static String getPattern(Property property) {
Validate.notNull(property, "property must not be null");
String pattern = null;
if (property instanceof StringProperty) {
StringProperty stringProperty = (StringProperty) property;
pattern = stringProperty.getPattern();
} else if (property instanceof UUIDProperty) {
UUIDProperty uuidProperty = (UUIDProperty) property;
pattern = uuidProperty.getPattern();
}
return pattern;
}
/**
* Retrieves the minimum value of a property, or otherwise returns null.
*
* @param property the property
* @return the minimum value of the property, or otherwise null
*/
public static Double getMin(Property property) {
Validate.notNull(property, "property must not be null");
Double min = null;
if (property instanceof DoubleProperty) {
DoubleProperty doubleProperty = (DoubleProperty) property;
min = doubleProperty.getMinimum();
} else if (property instanceof FloatProperty) {
FloatProperty floatProperty = (FloatProperty) property;
min = floatProperty.getMinimum();
} else if (property instanceof IntegerProperty) {
IntegerProperty integerProperty = (IntegerProperty) property;
min = integerProperty.getMinimum();
} else if (property instanceof LongProperty) {
LongProperty longProperty = (LongProperty) property;
min = longProperty.getMinimum();
}
return min;
}
/**
* Retrieves the minimum value of a property, or otherwise returns null.
*
* @param property the property
* @return the minimum value of the property, or otherwise null
*/
public static Double getMax(Property property) {
Validate.notNull(property, "property must not be null");
Double max = null;
if (property instanceof DoubleProperty) {
DoubleProperty doubleProperty = (DoubleProperty) property;
max = doubleProperty.getMaximum();
} else if (property instanceof FloatProperty) {
FloatProperty floatProperty = (FloatProperty) property;
max = floatProperty.getMaximum();
} else if (property instanceof IntegerProperty) {
IntegerProperty integerProperty = (IntegerProperty) property;
max = integerProperty.getMaximum();
} else if (property instanceof LongProperty) {
LongProperty longProperty = (LongProperty) property;
max = longProperty.getMaximum();
}
return max;
}
/**
* 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;
this.property = property;
}
/**
@@ -275,6 +48,7 @@ public final class PropertyUtils {
* @return a generated example for the property
*/
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
switch (property.getType()) {
case "integer":
return 0;
@@ -286,7 +60,10 @@ public final class PropertyUtils {
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");
}
default:
return property.getType();
@@ -322,4 +99,233 @@ public final class PropertyUtils {
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<Number> getMin() {
if (property instanceof BaseIntegerProperty) {
BaseIntegerProperty integerProperty = (BaseIntegerProperty) property;
return Optional.ofNullable(integerProperty.getMinimum() != null ? integerProperty.getMinimum().longValue() : 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<Number> getMax() {
if (property instanceof BaseIntegerProperty) {
BaseIntegerProperty integerProperty = (BaseIntegerProperty) property;
return Optional.ofNullable(integerProperty.getMaximum() != null ? integerProperty.getMaximum().longValue() : 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

@@ -0,0 +1,127 @@
/*
* 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.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

@@ -0,0 +1,59 @@
/*
* 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.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

@@ -0,0 +1,69 @@
/*
* 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.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

@@ -0,0 +1,199 @@
/*
* 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.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

@@ -0,0 +1,75 @@
/*
* 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.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

@@ -0,0 +1,166 @@
/*
* 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.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_DESCRIPTION_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_DESCRIPTION_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

@@ -0,0 +1,475 @@
/*
* 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.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) {
Map<String, Object> generatedRequestExampleMap = ExamplesUtil.generateRequestExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
Map<String, Object> generatedResponseExampleMap = ExamplesUtil.generateResponseExampleMap(config.isGeneratedExamplesEnabled(), operation, definitions, definitionDocumentResolver, markupDocBuilder);
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);
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()) {
// workaround for "array" example
//TODO: print $ref'd examples correctly instead of just "array"
String example = stripExampleQuotes(Json.pretty(entry.getValue()));
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 {
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

@@ -0,0 +1,59 @@
/*
* 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.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

@@ -0,0 +1,213 @@
/*
* 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.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.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.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<Number> optionalMinValue = propertyAdapter.getMin();
boolean exclusiveMin = propertyAdapter.getExclusiveMin();
Optional<Number> 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()));
}
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(optionalMinValue.get().toString());
}
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(optionalMaxValue.get().toString());
}
if (optionalExample.isPresent()) {
if (isNotBlank(description) || optionalDefaultValue.isPresent()) {
descriptionContent.newLine(true);
}
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()));
}
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

@@ -0,0 +1,173 @@
/*
* 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.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(null);
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

@@ -0,0 +1,123 @@
/*
* 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.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

@@ -0,0 +1,135 @@
/*
* 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.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

@@ -0,0 +1,76 @@
/*
* 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.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

@@ -0,0 +1,79 @@
/*
* 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.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

@@ -0,0 +1,83 @@
/*
* 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.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

@@ -0,0 +1,64 @@
/*
* 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.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

@@ -0,0 +1,194 @@
/*
* 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.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

@@ -1,61 +0,0 @@
/*
* 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

@@ -0,0 +1,161 @@
/*
* 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.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.Contact;
import io.swagger.models.Info;
import io.swagger.models.Swagger;
import io.swagger.models.Tag;
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;
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);
}
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());
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));
}
}
/**
* 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

@@ -0,0 +1,258 @@
/*
* 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 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

@@ -0,0 +1,96 @@
/*
* 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.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

@@ -1,336 +0,0 @@
/*
* 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);
final 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

@@ -1,357 +0,0 @@
/*
* 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 MAXLENGTH_COLUMN;
protected final String MINLENGTH_COLUMN;
protected final String LENGTH_COLUMN;
protected final String PATTERN_COLUMN;
protected final String MINVALUE_COLUMN;
protected final String MAXVALUE_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");
MINLENGTH_COLUMN = labels.getString("minlength_column");
MAXLENGTH_COLUMN = labels.getString("maxlength_column");
LENGTH_COLUMN = labels.getString("length_column");
PATTERN_COLUMN = labels.getString("pattern_column");
MINVALUE_COLUMN = labels.getString("minvalue_column");
MAXVALUE_COLUMN = labels.getString("maxvalue_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);
Integer maxlength = PropertyUtils.getMaxlength(property);
Integer minlength = PropertyUtils.getMinlength(property);
String pattern = PropertyUtils.getPattern(property);
Double minValue = PropertyUtils.getMin(property);
Double maxValue = PropertyUtils.getMax(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.toString()))
descriptionContent.text(description);
if(defaultValue != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(DEFAULT_COLUMN).text(COLON).literalText(Json.pretty(defaultValue));
}
if (minlength != null && maxlength != null) {
// combination of minlength/maxlength
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
String lengthRange = minlength + " - " + maxlength;
if (minlength.equals(maxlength)) {
lengthRange = minlength.toString();
}
descriptionContent.boldText(LENGTH_COLUMN).text(COLON).literalText(lengthRange);
} else {
if(minlength != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(MINLENGTH_COLUMN).text(COLON).literalText(minlength.toString());
}
if(maxlength != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(MAXLENGTH_COLUMN).text(COLON).literalText(maxlength.toString());
}
}
if(pattern != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(PATTERN_COLUMN).text(COLON).literalText(Json.pretty(pattern));
}
if(minValue != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(MINVALUE_COLUMN).text(COLON).literalText(minValue.toString());
}
if(maxValue != null){
if (isNotBlank(descriptionContent.toString()))
descriptionContent.newLine(true);
descriptionContent.boldText(MAXVALUE_COLUMN).text(COLON).literalText(maxValue.toString());
}
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

@@ -1,224 +0,0 @@
/*
* 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

@@ -1,771 +0,0 @@
/*
* 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);
if (config.isPathSecuritySectionEnabled()) {
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(2).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^2"),
new MarkupTableColumn(NAME_COLUMN).withWidthRatio(3).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^3"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(9).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^9"),
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(2).withHeaderColumn(false).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^2"),
new MarkupTableColumn(DESCRIPTION_COLUMN).withWidthRatio(14).withMarkupSpecifiers(MarkupLanguage.ASCIIDOC, ".^14"),
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

@@ -1,155 +0,0 @@
/*
* 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, null); // 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

@@ -0,0 +1,37 @@
/*
* 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.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

@@ -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.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

@@ -0,0 +1,42 @@
/*
* 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.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

@@ -0,0 +1,27 @@
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

@@ -0,0 +1,38 @@
/*
* 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.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

@@ -0,0 +1,38 @@
/*
* 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.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

@@ -0,0 +1,39 @@
/*
* 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.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

@@ -0,0 +1,41 @@
/*
* 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.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

@@ -0,0 +1,34 @@
/*
* 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.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

@@ -25,8 +25,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/
public class ArrayType extends Type {
protected String collectionFormat;
protected Type ofType;
private String collectionFormat;
private Type ofType;
public ArrayType(String name, Type ofType) {
this(name, ofType, null);

View File

@@ -38,7 +38,7 @@ public class BasicType extends Type {
public BasicType(String type, String name, String format) {
super(name);
Validate.notBlank(type);
Validate.notBlank(type, "Type of parameter '%s' must not be blank", name);
this.type = type;
this.format = format;
}

View File

@@ -1,24 +0,0 @@
/*
* 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

@@ -23,8 +23,8 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
*/
public class MapType extends Type {
protected Type keyType = new BasicType("string", null);
protected Type valueType;
private Type keyType = new BasicType("string", null);
private Type valueType;
public MapType(String name, Type valueType) {
super(name);

View File

@@ -26,8 +26,8 @@ import java.util.Map;
*/
public class ObjectType extends Type {
protected Map<String, Property> properties;
protected ObjectTypePolymorphism polymorphism;
private Map<String, Property> properties;
private ObjectTypePolymorphism polymorphism;
public ObjectType(String name, ObjectTypePolymorphism polymorphism, Map<String, Property> properties) {
super(name);

View File

@@ -18,12 +18,6 @@ package io.github.swagger2markup.internal.type;
public class ObjectTypePolymorphism {
public enum Nature {
NONE,
COMPOSITION,
INHERITANCE
}
public Nature nature = Nature.NONE;
public String discriminator;
@@ -48,4 +42,10 @@ public class ObjectTypePolymorphism {
this.discriminator = discriminator;
}
public enum Nature {
NONE,
COMPOSITION,
INHERITANCE
}
}

View File

@@ -24,7 +24,7 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
public abstract class Type {
protected String name;
protected String uniqueName;
private String uniqueName;
public Type(String name, String uniqueName) {
this.name = name;
@@ -35,14 +35,14 @@ public abstract class Type {
this(name, name);
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUniqueName() {
return uniqueName;
}

View File

@@ -16,6 +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 io.github.swagger2markup.markup.builder.MarkupDocBuilder;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.*;
@@ -24,16 +28,15 @@ 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.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ExamplesUtil {
private static Logger logger = LoggerFactory.getLogger(ExamplesUtil.class);
private static final Integer MAX_RECURSION_TO_DISPLAY = 2;
/**
* Generates a Map of response examples
@@ -44,9 +47,9 @@ public class ExamplesUtil {
* @param markupDocBuilder the markup builder
* @return map containing response examples.
*/
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, Operation operation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
public static Map<String, Object> generateResponseExampleMap(boolean generateMissingExamples, PathOperation operation, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder) {
Map<String, Object> examples = new LinkedHashMap<>();
Map<String, Response> responses = operation.getResponses();
Map<String, Response> responses = operation.getOperation().getResponses();
if (responses != null)
for (Map.Entry<String, Response> responseEntry : responses.entrySet()) {
Response response = responseEntry.getValue();
@@ -58,10 +61,10 @@ public class ExamplesUtil {
if (example == null && schema instanceof RefProperty) {
String simpleRef = ((RefProperty) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
}
if (example == null && generateMissingExamples) {
example = PropertyUtils.generateExample(schema, markupDocBuilder);
example = PropertyAdapter.generateExample(schema, markupDocBuilder);
}
}
}
@@ -83,7 +86,7 @@ public class ExamplesUtil {
* @param markupDocBuilder the markup builder
* @return an Optional with the example content
*/
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
public static Map<String, Object> generateRequestExampleMap(boolean generateMissingExamples, PathOperation pathOperation, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder) {
Operation operation = pathOperation.getOperation();
List<Parameter> parameters = operation.getParameters();
Map<String, Object> examples = new LinkedHashMap<>();
@@ -99,17 +102,17 @@ public class ExamplesUtil {
Model schema = ((BodyParameter) parameter).getSchema();
if (schema instanceof RefModel) {
String simpleRef = ((RefModel) schema).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else if (generateMissingExamples) {
if (schema instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel(
(ComposedModel) schema, definitions), definitions, markupDocBuilder);
//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, markupDocBuilder);
example = generateExampleForArrayModel((ArrayModel) schema, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
} else {
example = schema.getExample();
if (example == null) {
example = exampleMapForProperties(schema.getProperties(), definitions, markupDocBuilder);
example = exampleMapForProperties(schema.getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
}
}
}
@@ -123,11 +126,11 @@ public class ExamplesUtil {
if (item != null) {
abstractSerializableParameterExample = item.getExample();
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyUtils.generateExample(item, markupDocBuilder);
abstractSerializableParameterExample = PropertyAdapter.generateExample(item, markupDocBuilder);
}
}
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = ParameterUtils.generateExample((AbstractSerializableParameter)parameter);
abstractSerializableParameterExample = ParameterAdapter.generateExample((AbstractSerializableParameter) parameter);
}
}
if (parameter instanceof PathParameter) {
@@ -150,7 +153,7 @@ public class ExamplesUtil {
}
} else if (parameter instanceof RefParameter) {
String simpleRef = ((RefParameter) parameter).getSimpleRef();
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, definitionDocumentResolver, markupDocBuilder, new HashMap<>());
}
if (example != null)
@@ -167,25 +170,38 @@ public class ExamplesUtil {
* @param simpleRef the simple reference string
* @param definitions the map of definitions
* @param markupDocBuilder the markup builder
* @param refStack map to detect cyclic references
* @return returns an Object or Map of examples
*/
public static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
private static Object generateExampleForRefModel(boolean generateMissingExamples, String simpleRef, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
Model model = definitions.get(simpleRef);
Object example = null;
if (model != null) {
example = model.getExample();
if (example == null && generateMissingExamples) {
if (model instanceof ComposedModel) {
example = exampleMapForProperties(getPropertiesForComposedModel((ComposedModel) model, definitions), definitions, markupDocBuilder);
if (!refStack.containsKey(simpleRef)) {
refStack.put(simpleRef, 1);
} else {
example = exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder);
refStack.put(simpleRef, refStack.get(simpleRef) + 1);
}
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();
@@ -217,25 +233,25 @@ public class ExamplesUtil {
* @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
*/
public static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
private static Map<String, Object> exampleMapForProperties(Map<String, Property> properties, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
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, markupDocBuilder);
exampleObject = generateExampleForRefModel(true, ((RefProperty) property.getValue()).getSimpleRef(), definitions, definitionDocumentResolver, markupDocBuilder, refStack);
} else if (property.getValue() instanceof ArrayProperty) {
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, markupDocBuilder);
exampleObject = generateExampleForArrayProperty((ArrayProperty) property.getValue(), definitions, definitionDocumentResolver, markupDocBuilder, refStack);
} else if (property.getValue() instanceof MapProperty) {
exampleObject = generateExampleForMapProperty((MapProperty) property.getValue(), markupDocBuilder);
}
if (exampleObject == null) {
Property valueProperty = property.getValue();
exampleObject = PropertyUtils.generateExample(valueProperty, markupDocBuilder);
exampleObject = PropertyAdapter.generateExample(valueProperty, markupDocBuilder);
}
}
exampleMap.put(property.getKey(), exampleObject);
@@ -244,7 +260,7 @@ public class ExamplesUtil {
return exampleMap;
}
public static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
private static Object generateExampleForMapProperty(MapProperty property, MarkupDocBuilder markupDocBuilder) {
if (property.getExample() != null) {
return property.getExample();
}
@@ -253,26 +269,18 @@ public class ExamplesUtil {
if (valueProperty.getExample() != null) {
return valueProperty.getExample();
}
exampleMap.put("string", PropertyUtils.generateExample(valueProperty, markupDocBuilder));
exampleMap.put("string", PropertyAdapter.generateExample(valueProperty, markupDocBuilder));
return exampleMap;
}
public static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
private static Object generateExampleForArrayModel(ArrayModel model, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
if (model.getExample() != null) {
return model.getExample();
} else if (model.getProperties() != null) {
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, markupDocBuilder)};
return new Object[]{exampleMapForProperties(model.getProperties(), definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
} else {
Property itemProperty = model.getItems();
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)};
}
return getExample(itemProperty, definitions, definitionDocumentResolver, markupDocBuilder, refStack);
}
}
@@ -284,17 +292,39 @@ public class ExamplesUtil {
* @param markupDocBuilder the markup builder
* @return array of Object
*/
public static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, MarkupDocBuilder markupDocBuilder) {
private static Object[] generateExampleForArrayProperty(ArrayProperty value, Map<String, Model> definitions, DocumentResolver definitionDocumentResolver, MarkupDocBuilder markupDocBuilder, Map<String, Integer> refStack) {
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, markupDocBuilder)};
return new Object[]{generateExampleForArrayProperty((ArrayProperty) property, definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
} else if (property instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, markupDocBuilder)};
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, definitionDocumentResolver, markupDocBuilder, refStack)};
} else {
return new Object[]{PropertyUtils.generateExample(property, markupDocBuilder)};
return new Object[]{PropertyAdapter.generateExample(property, markupDocBuilder)};
}
}
//TODO: Unused method, make sure this is never used and then remove it.
//FIXME: getProperties() may throw NullPointerException
}

View File

@@ -0,0 +1,72 @@
/*
* 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 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

@@ -1,40 +0,0 @@
/*
* 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

@@ -15,24 +15,27 @@
*/
package io.github.swagger2markup.internal.utils;
import java.util.*;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapUtils {
/**
* Returns the keys of the Map either ordered or as-is, if the comparator is null.
* Returns the the Map either ordered or as-is, if the comparator is null.
*
* @param map the Map
* @param comparator the comparator to use.
* @return the keySet of the Map
*/
public static Set<String> toKeySet(Map<String, ?> map, Comparator<String> comparator){
Set<String> keys;
public static <K, V> Map<K, V> toSortedMap(Map<K, V> map, Comparator<? super K> comparator) {
Map<K, V> sortedMap;
if (comparator == null)
keys = new LinkedHashSet<>();
sortedMap = new LinkedHashMap<>();
else
keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());
return keys;
sortedMap = new TreeMap<>(comparator);
sortedMap.putAll(map);
return sortedMap;
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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 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(text).toString();
}
public static String boldText(MarkupDocBuilder markupDocBuilder, String text) {
if (StringUtils.isBlank(text)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).boldText(text).toString();
}
public static String italicText(MarkupDocBuilder markupDocBuilder, String text) {
if (StringUtils.isBlank(text)) {
return StringUtils.EMPTY;
}
return copyMarkupDocBuilder(markupDocBuilder).italicText(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

@@ -15,22 +15,25 @@
*/
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
*/
@@ -51,13 +54,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, Function<String, String> definitionDocumentResolver) {
public static Type getType(Model model, Map<String, Model> definitions, DocumentResolver 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(), PropertyUtils.getType(modelImpl.getAdditionalProperties(), definitionDocumentResolver));
return new MapType(modelImpl.getTitle(), new PropertyAdapter(modelImpl.getAdditionalProperties()).getType(definitionDocumentResolver));
else if (modelImpl.getEnum() != null)
return new EnumType(modelImpl.getTitle(), modelImpl.getEnum());
else if (modelImpl.getProperties() != null) {
@@ -66,7 +69,9 @@ public final class ModelUtils {
objectType.getPolymorphism().setDiscriminator(modelImpl.getDiscriminator());
return objectType;
} else
} else if (isNotBlank(modelImpl.getFormat()))
return new BasicType(modelImpl.getType(), modelImpl.getTitle(), modelImpl.getFormat());
else
return new BasicType(modelImpl.getType(), modelImpl.getTitle());
} else if (model instanceof ComposedModel) {
ComposedModel composedModel = (ComposedModel) model;
@@ -112,7 +117,7 @@ public final class ModelUtils {
} else if (model instanceof ArrayModel) {
ArrayModel arrayModel = ((ArrayModel) model);
return new ArrayType(null, PropertyUtils.getType(arrayModel.getItems(), definitionDocumentResolver));
return new ArrayType(null, new PropertyAdapter(arrayModel.getItems()).getType(definitionDocumentResolver));
}
return null;

View File

@@ -1,117 +0,0 @@
/*
* 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

@@ -0,0 +1,95 @@
/*
* 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 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 paths 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) {
Collections.sort(pathOperations, 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,81 @@
/*
* 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

@@ -15,10 +15,9 @@
*/
package io.github.swagger2markup.internal.utils;
import com.google.common.base.Optional;
import com.google.common.collect.LinkedHashMultimap;
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;
@@ -29,37 +28,24 @@ import java.util.*;
public class TagUtils {
private static Logger LOG = LoggerFactory.getLogger(TagUtils.class);
private static Logger logger = 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
* @return the Map of tags
* @param comparator the comparator to use.
* @return the Map of tags. Either ordered or as-is, if the comparator is null.
*/
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();
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;
}
/**
@@ -67,30 +53,24 @@ public class TagUtils {
* The value of the Multimap is a PathOperation
*
* @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(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);
public static Multimap<String, PathOperation> groupOperationsByTag(List<PathOperation> allOperations, Comparator<PathOperation> operationOrdering) {
Multimap<String, PathOperation> operationsGroupedByTag;
if (operationOrdering == null)
operationsGroupedByTag = multimapBuilderWithKeys.hashSetValues().build();
else
operationsGroupedByTag = multimapBuilderWithKeys.treeSetValues(operationOrdering).build();
if (operationOrdering == null) {
operationsGroupedByTag = LinkedHashMultimap.create();
} else {
operationsGroupedByTag = MultimapBuilder.linkedHashKeys().treeSetValues(operationOrdering).build();
}
for (PathOperation operation : allOperations) {
List<String> tags = operation.getOperation().getTags();
Validate.notEmpty(tags, "Can't GroupBy.TAGS > Operation '%s' has not tags", operation);
Validate.notEmpty(tags, "Can't GroupBy.TAGS. Operation '%s' has no tags", operation);
for (String tag : tags) {
if (LOG.isInfoEnabled()) {
LOG.info("Added path operation '{}' to tag '{}'", operation, tag);
if (logger.isDebugEnabled()) {
logger.debug("Added path operation '{}' to tag '{}'", operation, tag);
}
operationsGroupedByTag.put(tag, operation);
}

View File

@@ -23,9 +23,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
public class PathOperation {
protected HttpMethod method;
protected String path;
protected Operation operation;
private HttpMethod method;
private String path;
private Operation operation;
public PathOperation(HttpMethod method, String path, Operation operation) {
this.method = method;
@@ -43,6 +43,7 @@ public class PathOperation {
/**
* Returns the display title for an operation
*
* @return the operation title
*/
public String getTitle() {

View File

@@ -16,16 +16,51 @@
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,
@@ -80,45 +115,11 @@ public abstract class DefinitionsDocumentExtension extends AbstractExtension {
}
public Optional<String> getDefinitionName() {
return Optional.fromNullable(definitionName);
return Optional.ofNullable(definitionName);
}
public Optional<Model> getModel() {
return Optional.fromNullable(model);
return Optional.ofNullable(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

@@ -0,0 +1,43 @@
/*
* 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.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

@@ -23,6 +23,34 @@ import io.github.swagger2markup.markup.builder.MarkupDocBuilder;
*/
public abstract class OverviewDocumentExtension 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:
levelOffset = 1;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
public enum Position {
DOCUMENT_BEFORE,
DOCUMENT_AFTER,
@@ -47,32 +75,4 @@ public abstract class OverviewDocumentExtension extends AbstractExtension {
}
}
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) {
int levelOffset;
switch (context.position) {
case DOCUMENT_BEFORE:
case DOCUMENT_AFTER:
levelOffset = 0;
break;
case DOCUMENT_BEGIN:
case DOCUMENT_END:
levelOffset = 1;
break;
default:
throw new RuntimeException(String.format("Unknown position '%s'", context.position));
}
return levelOffset;
}
}

View File

@@ -27,6 +27,68 @@ 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,
@@ -75,6 +137,7 @@ 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
@@ -95,66 +158,4 @@ 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

@@ -26,6 +26,40 @@ 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,
@@ -87,38 +121,4 @@ 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

@@ -23,9 +23,6 @@ import io.swagger.models.Swagger;
*/
public abstract class SwaggerModelExtension extends AbstractExtension {
public SwaggerModelExtension() {
}
public abstract void apply(Swagger swagger);
}

View File

@@ -23,6 +23,7 @@ import java.nio.file.Paths;
public class URIUtils {
/**
* Return URI parent
*
* @param uri source URI
* @return URI parent
*/
@@ -36,7 +37,7 @@ public class URIUtils {
* @param uri the source URI
* @return the converted URI
*/
public static URI convertUriWithoutSchemeToFileScheme(URI uri){
public static URI convertUriWithoutSchemeToFileScheme(URI uri) {
if (uri.getScheme() == null) {
return Paths.get(uri.getPath()).toUri();
}
@@ -49,10 +50,10 @@ public class URIUtils {
* @param input String representation of a URI or a Path.
* @return the URI
*/
public static URI create(String input){
if(isFile(input) || isURL(input)){
public static URI create(String input) {
if (isFile(input) || isURL(input)) {
return URI.create(input);
}else{
} else {
return Paths.get(input).toUri();
}
}

View File

@@ -1,6 +1,7 @@
swagger2markup.markupLanguage=ASCIIDOC
swagger2markup.swaggerMarkupLanguage=MARKDOWN
swagger2markup.generatedExamplesEnabled=false
swagger2markup.basePathPrefixEnabled=false
swagger2markup.operationExtensionsEnabled=false
swagger2markup.definitionExtensionsEnabled=false
swagger2markup.separatedDefinitionsEnabled=false

View File

@@ -1,14 +1,14 @@
definitions=Definitionen
default_column=Standard
# validators
minlength_column=Mindestl<EFBFBD>nge
maxlength_column=Maximale L<EFBFBD>nge
length_column=L<EFBFBD>nge
minlength_column=Mindestl\u00E4nge
maxlength_column=Maximale L\u00E4nge
length_column=L\u00E4nge
pattern_column=Pattern
minvalue_column=Mindestwert
minvalue_exclusive_column=Mindestwert (exklusiv)
maxvalue_column=Maximalwert
maxvalue_exclusive_column=Maximalwert (exklusiv)
example_column=Beispiel
flags.column=Flags
flags.required=verpflichtend
@@ -23,7 +23,7 @@ scopes_column=Scopes
produces=Erzeugt
consumes=Verarbeitet
tags=Tags
overview=<EFBFBD>bersicht
overview=\u00DCbersicht
current_version=Aktuelle Version
version=Version
contact_information=Kontaktinformationen
@@ -37,7 +37,7 @@ uri_scheme=URI Schema
host=Host
base_path=Basis-Pfad
schemes=Schemata
security_name=
security_name=Name
security_type=Typ
security_in=In
security_flow=Flow
@@ -45,6 +45,7 @@ security_authorizationUrl=Token URL
security_tokenUrl=Token URL
paths=Pfade
resources=Ressourcen
operations=Betrieb
security=Sicherheit
body_parameter=Body Parameter
parameters=Parameter

View File

@@ -1,15 +1,14 @@
definitions=Definitions
default_column=Default
# validators
minlength_column=Minimum length
maxlength_column=Maximal length
length_column=Length
pattern_column=Pattern
minvalue_column=Minimum value
minvalue_exclusive_column=Minimum value (exclusive)
maxvalue_column=Maximum value
maxvalue_exclusive_column=Maximum value (exclusive)
example_column=Example
flags.column=Flags
flags.required=Required
@@ -24,7 +23,6 @@ scopes_column=Scopes
produces=Produces
consumes=Consumes
tags=Tags
overview=Overview
current_version=Version information
version=Version
@@ -45,9 +43,9 @@ security_in=In
security_flow=Flow
security_authorizationUrl=Token URL
security_tokenUrl=Token URL
paths=Paths
resources=Resources
operations=Operations
security=Security
parameters=Parameters
body_parameter=Body parameter
@@ -59,7 +57,6 @@ example_response=Example HTTP response
type_column=Type
http_code_column=HTTP Code
parameter=Parameter
unknown=Unknown
no_content=No Content
operation.deprecated=This operation is deprecated.

View File

@@ -0,0 +1,66 @@
definitions=Definiciones
default_column=Valor por defecto
# validators
minlength_column=Longitud m\u00EDnima
maxlength_column=Longitud m\u00E1xima
length_column=Longitud
pattern_column=Patr\u00F3n
minvalue_column=Valor m\u00EDnimo
minvalue_exclusive_column=Valor m\u00EDnimo (exclusivo)
maxvalue_column=Valor m\u00E1ximo
maxvalue_exclusive_column=Valor m\u00E1ximo (exclusivo)
example_column=Ejemplo
flags.column=Flags
flags.required=Obligatorio
flags.optional=Opcional
flags.read_only=S\u00F3lo lectura
flags.read_write=Lectura-escritura
schema_column=Esquema
name_column=Nombre
description_column=Descripci\u00F3n
headers_column=Cabeceras
scopes_column=Scopes
produces=Produce
consumes=Consume
tags=Etiquetas
overview=Resumen
current_version=Informaci\u00F3n de versi\u00F3n
version=Versi\u00F3n
contact_information=Informaci\u00F3n de contacto
contact_name=Contacto
contact_email=Email de contacto
license_information=Informaci\u00F3n de licencia
license=Licencia
license_url=URL de licencia
terms_of_service=T\u00E9rminos de servicio
uri_scheme=Esquema URI
host=Servidor
base_path=Ruta base
schemes=Esquemas
security_type=Tipo
security_name=Nombre
security_in=En
security_flow=Flujo
security_authorizationUrl=URL de autorizaci\u00F3n
security_tokenUrl=URL del token
paths=Rutas
resources=Recursos
operations=Operaciones
security=Seguridad
parameters=Par\u00E1metros
body_parameter=Par\u00E1metro de cuerpo
responses=Respuestas
response=Respuesta
request=Solicitud
example_request=Ejemplo de solicitud HTTP
example_response=Ejemplo de respuesta HTTP
type_column=Tipo
http_code_column=C\u00F3digo HTTP
parameter=Par\u00E1metro
unknown=Desconocido
no_content=Sin contenido
operation.deprecated=Operaci\u00F3n obsoleta
polymorphism.column=Polimorfismo
polymorphism.discriminator=Discriminador
polymorphism.nature.INHERITANCE=Herencia
polymorphism.nature.COMPOSITION=Composici\u00F3n

View File

@@ -1,15 +1,14 @@
definitions=D\u00E9finitions
default_column=D\u00E9faut
# validators
minlength_column=Longueur minimale
maxlength_column=Longueur maximale
length_column=Longueur
pattern_column=Mod\u00E8le
minvalue_column=Valeur minimale
minvalue_exclusive_column=Valeur minimale (exclusif)
maxvalue_column=Valeur maximale
maxvalue_exclusive_column=Valeur maximale (exclusif)
example_column=Exemple
flags.column=Modificateurs
flags.required=Requis
@@ -24,7 +23,6 @@ scopes_column=P\u00E9rim\u00E8tre
produces=Produit
consumes=Consomme
tags=Tags
overview=Vue g\u00E9n\u00E9rale
current_version=Information de version
version=Version
@@ -45,9 +43,9 @@ security_in=Position
security_flow=Flux
security_authorizationUrl=URL d'autorisation
security_tokenUrl=URL de jeton
paths=Op\u00E9rations
resources=Ressources
operations=Op\u00E9rations
security=S\u00E9curit\u00E9
parameters=Param\u00E8tres
body_parameter=Contenu
@@ -59,7 +57,6 @@ example_response=Exemple de r\u00E9ponse HTTP
type_column=Type
http_code_column=Code HTTP
parameter=Param\u00E8tre
unknown=Inconnu
no_content=Pas de contenu
operation.deprecated=Cette op\u00E9ration est obsol\u00E8te.

View File

@@ -0,0 +1,66 @@
definitions=\u30e2\u30c7\u30eb\u5b9a\u7fa9
default_column=\u30c7\u30d5\u30a9\u30eb\u30c8
# validators
minlength_column=\u6700\u4f4e\u9577
maxlength_column=\u6700\u5927\u9577
length_column=\u9577\u3055
pattern_column=\u30d1\u30bf\u30fc\u30f3
minvalue_column=\u6700\u5c0f\u5024
minvalue_exclusive_column=\u6700\u5c0f\u5024(\u5883\u754c\u5024\u9664\u5916)
maxvalue_column=\u6700\u5927\u5024
maxvalue_exclusive_column=\u6700\u5927\u5024(\u5883\u754c\u5024\u9664\u5916)
example_column=\u4f8b
flags.column=\u30d5\u30e9\u30b0
flags.required=\u5fc5\u9808
flags.optional=\u30aa\u30d7\u30b7\u30e7\u30f3
flags.read_only=Read-only
flags.read_write=Read-write
schema_column=\u30b9\u30ad\u30fc\u30de
name_column=\u540d\u524d
description_column=\u8aac\u660e
headers_column=\u30d8\u30c3\u30c0\u30fc
scopes_column=\u30b9\u30b3\u30fc\u30d7
produces=\u51fa\u529b\u5f62\u5f0f
consumes=\u5165\u529b\u5f62\u5f0f
tags=\u30bf\u30b0
overview=\u6982\u8981
current_version=\u30d0\u30fc\u30b8\u30e7\u30f3\u60c5\u5831
version=\u30d0\u30fc\u30b8\u30e7\u30f3
contact_information=\u9023\u7d61\u5148\u60c5\u5831
contact_name=\u540d\u524d
contact_email=\u30e1\u30fc\u30eb
license_information=\u30e9\u30a4\u30bb\u30f3\u30b9\u60c5\u5831
license=\u30e9\u30a4\u30bb\u30f3\u30b9
license_url=\u30e9\u30a4\u30bb\u30f3\u30b9 URL
terms_of_service=\u5229\u7528\u898f\u7d04
uri_scheme=URI \u30b9\u30ad\u30fc\u30e0
host=\u30db\u30b9\u30c8
base_path=\u30d9\u30fc\u30b9\u30d1\u30b9
schemes=\u30b9\u30ad\u30fc\u30e0
security_type=\u30bf\u30a4\u30d7
security_name=\u540d\u524d
security_in=\u6307\u5b9a\u7b87\u6240
security_flow=\u30d5\u30ed\u30fc
security_authorizationUrl=\u30c8\u30fc\u30af\u30f3 URL
security_tokenUrl=\u30c8\u30fc\u30af\u30f3 URL
paths=\u30d1\u30b9
resources=\u30ea\u30bd\u30fc\u30b9
operations=\u30AA\u30DA\u30EC\u30FC\u30B7\u30E7\u30F3
security=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3
parameters=\u30d1\u30e9\u30e1\u30fc\u30bf
body_parameter=\u30dc\u30c7\u30a3\u30d1\u30e9\u30e1\u30fc\u30bf
responses=\u30ec\u30b9\u30dd\u30f3\u30b9
response=\u30ec\u30b9\u30dd\u30f3\u30b9
request=\u30ea\u30af\u30a8\u30b9\u30c8
example_request=HTTP \u30ea\u30af\u30a8\u30b9\u30c8\u4f8b
example_response=HTTP \u30ec\u30b9\u30dd\u30f3\u30b9\u4f8b
type_column=\u30bf\u30a4\u30d7
http_code_column=HTTP \u30b3\u30fc\u30c9
parameter=\u30d1\u30e9\u30e1\u30fc\u30bf
unknown=\u4e0d\u660e
no_content=No Content
operation.deprecated=\u3053\u306e\u64cd\u4f5c\u306f\u975e\u63a8\u5968\u3067\u3059\u3002
polymorphism.column=\u30dd\u30ea\u30e2\u30fc\u30d5\u30a3\u30ba\u30e0
polymorphism.discriminator=Discriminator
polymorphism.nature.INHERITANCE=\u7d99\u627f
polymorphism.nature.COMPOSITION=\u5305\u542b

View File

@@ -0,0 +1,66 @@
definitions=Definitions
default_column=Padr\u00e3o
# validators
minlength_column=Tamanho m\u00ednimo
maxlength_column=Tamanho M\u00e1ximo
length_column=Tamanho
pattern_column=Padr\u00e3o
minvalue_column=Valor m\u00ednimo
minvalue_exclusive_column=Valor m\u00ednimo (exclusivo)
maxvalue_column=Valor m\u00e1ximo
maxvalue_exclusive_column=Valor m\u00e1ximo (exclusivo)
example_column=Exemplo
flags.column=Flags
flags.required=Obrigat\u00f3rio
flags.optional=Opcional
flags.read_only=Apenas-Leitura
flags.read_write=Leitura-Escrita
schema_column=Esquema
name_column=Nome
description_column=Descri\u00e7\u00e3o
headers_column=Cabe\u00e7alhos
scopes_column=Escopos
produces=Produz
consumes=Consome
tags=Tags
overview=Vis\u00e3o Geral
current_version=Informa\u00e7\u00f5es da Vers\u00e3o
version=Vers\u00e3o
contact_information=Informa\u00e7\u00f5es de contato
contact_name=Contato
contact_email=Email de contato
license_information=Informa\u00e7\u00f5es da Licen\u00e7a
license=Licen\u00e7a
license_url=URL da Licen\u00e7a
terms_of_service=Termos de servi\u00e7o
uri_scheme=Esquema URI
host=Host
base_path=BasePath
schemes=Schemes
security_type=Tipo
security_name=Nome
security_in=No
security_flow=Fluxo
security_authorizationUrl=URL do Token
security_tokenUrl=URL do Token
paths=Paths
resources=Recursos
operations=Opera\u00E7\u00F5es
security=Seguran\u00e7a
parameters=Par\u00e2metros
body_parameter=Par\u00e2metro de corpo
responses=Respostas
response=Resposta
request=Requisi\u00e7\u00e3o
example_request=Exemplo de requisi\u00e7\u00e3o HTTP
example_response=Exemplo de resposta HTTP
type_column=Tipo
http_code_column=C\u00f3digo de status HTTP
parameter=Par\u00e2metro
unknown=Desconhecido
no_content=Nenhum conte\u00fado
operation.deprecated=Essa opera\u00e7\u00e3o est\u00e1 obsoleta.
polymorphism.column=Polimorfismo
polymorphism.discriminator=Discriminador
polymorphism.nature.INHERITANCE=Heran\u00e7a
polymorphism.nature.COMPOSITION=Composi\u00e7\u00e3o

View File

@@ -1,15 +1,14 @@
definitions=\u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F
default_column=\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E
# validators
minlength_column=Minimum length
maxlength_column=Maximal length
length_column=Length
pattern_column=Pattern
minvalue_column=Minimum value
minvalue_exclusive_column=Minimum value (exclusive)
maxvalue_column=Maximum value
maxvalue_exclusive_column=Maximum value (exclusive)
flags.column=Flags
flags.required=\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E
flags.optional=Optional
@@ -24,7 +23,6 @@ scopes_column=\u041E\u0431\u043B\u0430\u0441\u0442\u0438 \u043F\u0440\u0438\u043
produces=\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442
consumes=\u041F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442
tags=\u0422\u044D\u0433\u0438
overview=\u041E\u0431\u0437\u043E\u0440
current_version=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0432\u0435\u0440\u0441\u0438\u0438
version=\u0412\u0435\u0440\u0441\u0438\u044F
@@ -45,9 +43,9 @@ security_in=\u0421\u043E\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044F \u0432
security_flow=\u041F\u043E\u0442\u043E\u043A
security_authorizationUrl=URL \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0438
security_tokenUrl=URL \u0442\u043E\u043A\u0435\u043D\u0430
paths=\u041F\u0443\u0442\u0438
resources=\u041E\u0442\u0432\u0435\u0442\u044B
resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044B
operations=\u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438
security=\u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C
response=\u041E\u0442\u0432\u0435\u0442
request=\u0417\u0430\u043F\u0440\u043E\u0441
@@ -59,7 +57,6 @@ example_response=\u041F\u0440\u0438\u043C\u0435\u0440 HTTP \u0437\u0430\u043F\u0
type_column=\u0422\u0438\u043F
http_code_column=HTTP \u043A\u043E\u0434
parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440
unknown=Unknown
no_content=\u0411\u0435\u0437 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043E
operation.deprecated=\u042D\u0442\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0430.

View File

@@ -1,15 +1,14 @@
definitions=Tan\u0131mlar
default_column=Varsay\u0131lan
# validators
minlength_column=Minimum length
maxlength_column=Maximal length
length_column=Length
pattern_column=Pattern
minvalue_column=Minimum value
minvalue_exclusive_column=Minimum value (exclusive)
maxvalue_column=Maximum value
maxvalue_exclusive_column=Maximum value (exclusive)
example_column=\u00D6rnek
flags.column=Bayraklar
flags.required=Gerekli
@@ -24,7 +23,6 @@ scopes_column=Kapsamlar
produces=\u00DCretilenler
consumes=Kullan\u0131lanlar
tags=Etiketler
overview=Genel Bak\u0131\u015F
current_version=Versiyon bilgisi
version=Versiyon
@@ -45,9 +43,9 @@ security_in=Yer
security_flow=Ak\u0131\u015F
security_authorizationUrl=Yetkilendirme adresi
security_tokenUrl=Token adresi
paths=Dizinler
resources=Kaynaklar
operations=Operasyonlar
security=G\u00FCvenlik
parameters=Parametreler
body_parameter=G\u00F6vde parametresi
@@ -59,7 +57,6 @@ example_response=\u00D6rnek HTTP cevab\u0131
type_column=Tip
http_code_column=HTTP Kodu
parameter=Parametre
unknown=Bilinmeyen
no_content=\u0130\u00E7erik yok
operation.deprecated=Bu i\u015Flem \u00F6nerilmemektedir.

View File

@@ -0,0 +1,66 @@
definitions=\u5b9a\u4e49
default_column=\u9ed8\u8ba4\u5217
# validators
minlength_column=\u6700\u5c0f\u957f\u5ea6
maxlength_column=\u6700\u5927\u957f\u5ea6
length_column=\u957f\u5ea6
pattern_column=\u6a21\u5f0f
minvalue_column=\u6700\u5c0f\u503c
minvalue_exclusive_column=\u6700\u5c0f\u503c(\u4e0d\u5305\u62ec)
maxvalue_column=\u6700\u5927\u503c
maxvalue_exclusive_column=\u6700\u5927\u503c(\u4e0d\u5305\u62ec)
example_column=\u4f8b\u5b50
flags.column=\u6807\u5fd7
flags.required=\u5fc5\u586b
flags.optional=\u53ef\u9009
flags.read_only=\u53ea\u8bfb
flags.read_write=\u8bfb\u5199
schema_column=\u67b6\u6784
name_column=\u540d\u79f0
description_column=\u8bf4\u660e
headers_column=\u5934
scopes_column=\u4f5c\u7528\u57df
produces=\u751f\u6210
consumes=\u6d88\u8017
tags=\u6807\u7b7e
overview=\u6982\u89c2
current_version=\u7248\u672c\u4fe1\u606f
version=\u7248\u672c
contact_information=\u8054\u7cfb\u65b9\u5f0f
contact_name=\u540d\u5b57
contact_email=\u90ae\u7bb1
license_information=\u8bb8\u53ef\u4fe1\u606f
license=\u8bb8\u53ef\u8bc1
license_url=\u8bb8\u53ef\u7f51\u5740
terms_of_service=\u670d\u52a1\u6761\u6b3e
uri_scheme=URI scheme
host=\u57df\u540d
base_path=\u57fa\u7840\u8def\u5f84
schemes=\u65b9\u6848
security_type=\u7c7b\u578b
security_name=\u540d\u79f0
security_in=\u5728
security_flow=\u6d41
security_authorizationUrl=\u6388\u6743\u7f51\u5740
security_tokenUrl=\u4ee4\u724c\u7f51\u5740
paths=\u8def\u5f84
resources=\u8d44\u6e90
operations=\u64CD\u4F5C
security=\u5b89\u5168
parameters=\u53c2\u6570
body_parameter=Body\u53c2\u6570
responses=\u54cd\u5e94
response=\u54cd\u5e94
request=\u8bf7\u6c42
example_request=HTTP\u8bf7\u6c42\u793a\u4f8b
example_response=HTTP\u54cd\u5e94\u793a\u4f8b
type_column=\u7c7b\u578b
http_code_column=HTTP\u4ee3\u7801
parameter=\u53c2\u6570
unknown=\u672a\u77e5
no_content=\u65e0\u5185\u5bb9
operation.deprecated=\u8be5\u64cd\u4f5c\u5df2\u5f03\u7528
polymorphism.column=\u591a\u6001\u6027
polymorphism.discriminator=\u9274\u522b
polymorphism.nature.INHERITANCE=\u7ee7\u627f
polymorphism.nature.COMPOSITION=\u6210\u5206

View File

@@ -21,8 +21,6 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -39,17 +37,16 @@ import static org.assertj.core.api.BDDAssertions.assertThat;
public class AsciidocConverterTest {
private static final Logger LOG = LoggerFactory.getLogger(AsciidocConverterTest.class);
private static final String[] EXPECTED_FILES = new String[]{"definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"};
private List<String> expectedFiles;
@Before
public void setUp(){
public void setUp() {
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
}
@Test
public void testSwagger2AsciiDocConversionAsString() throws IOException, URISyntaxException {
public void testToString() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
@@ -60,12 +57,11 @@ public class AsciidocConverterTest {
assertThat(asciiDocAsString).isNotEmpty();
}
@Test
public void testSwagger2AsciiDocConversion() throws IOException, URISyntaxException {
public void testToFolder() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/default");
Path outputDirectory = Paths.get("build/test/asciidoc/to_folder");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
@@ -76,19 +72,136 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/default").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversion.html");
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_folder").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testToFolder.html");
}
@Test
public void testSwagger2AsciiDocConversionInstagram() throws IOException, URISyntaxException {
public void testToFileWithoutExtension() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputFile = Paths.get("build/test/asciidoc/to_file/swagger.adoc");
//When
Swagger2MarkupConverter.from(file)
.build()
.toFileWithoutExtension(outputFile);
//Then
Path expectedFile = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_file/swagger.adoc").toURI());
DiffUtils.assertThatFileIsEqual(expectedFile, outputFile, "testToFileWithoutExtension.html");
}
@Test(expected = NullPointerException.class)
// Not working atm. See https://github.com/Swagger2Markup/swagger2markup/issues/212
public void testModularizedSwaggerSpec() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/modules/swagger_petstore.yaml").toURI());
Path outputFile = Paths.get("build/test/asciidoc/modularized_swagger/swagger.adoc");
//When
Swagger2MarkupConverter.from(file)
.build()
.toFileWithoutExtension(outputFile);
//Then
Path expectedFile = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_file/swagger.adoc").toURI());
DiffUtils.assertThatFileIsEqual(expectedFile, outputFile, "testModularizedSwaggerSpec.html");
}
@Test
public void testOrderByAsIs() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_ordering.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/ordering_asis");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withTagOrdering(OrderBy.AS_IS)
.withParameterOrdering(OrderBy.AS_IS)
.withOperationOrdering(OrderBy.AS_IS)
.withDefinitionOrdering(OrderBy.AS_IS)
.withPathsGroupedBy(GroupBy.TAGS)
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/ordering_asis").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testOrderingAsIs.html");
}
@Test
public void testOrderByNatural() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_ordering.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/ordering_natural");
FileUtils.deleteQuietly(outputDirectory.toFile());
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withTagOrdering(OrderBy.NATURAL)
.withParameterOrdering(OrderBy.NATURAL)
.withOperationOrdering(OrderBy.NATURAL)
.withPathsGroupedBy(GroupBy.TAGS)
.build();
//When
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/ordering_natural").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testOrderingNatural.html");
}
@Test
public void testOrderByRegex() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_ordering_regex.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/ordering_regex");
FileUtils.deleteQuietly(outputDirectory.toFile());
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withTagOrdering(OrderBy.NATURAL)
.withParameterOrdering(OrderBy.NATURAL)
.withOperationOrdering(OrderBy.NATURAL)
.withPathsGroupedBy(GroupBy.REGEX)
.withHeaderRegex("\\/(\\w+)(\\/|\\w)*$")
.build();
//When
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/ordering_regex").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testOrderingRegex.html");
}
@Test
public void testMarkupRenderingInInstagram() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_instagram.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/instagram");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConverter.from(file).build()
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withTagOrdering(OrderBy.AS_IS)
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
@@ -96,11 +209,11 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/instagram").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionInstagram.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testMarkupRenderingInInstagram.html");
}
@Test
public void testSwagger2AsciiDocConversionWithInterDocumentCrossReferences() throws IOException, URISyntaxException {
public void testInterDocumentCrossReferences() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/idxref");
@@ -119,14 +232,38 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/idxref").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithInterDocumentCrossReferences.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testInterDocumentCrossReferences.html");
}
@Test
public void testWithBasePathPrefix() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_examples.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/basepathprefix");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withBasePathPrefix()
.withGeneratedExamples()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/basepathprefix").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithBasePathPrefix.html");
}
@Test
public void testSwagger2AsciiDocConversionFromString() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
Path outputDirectory = Paths.get("build/test/asciidoc/default");
Path outputDirectory = Paths.get("build/test/asciidoc/to_folder");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
@@ -137,12 +274,12 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/default").toURI());
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/to_folder").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversion.html");
}
@Test
public void testSwagger2AsciiDocConversionWithExamples() throws IOException, URISyntaxException {
public void testWithExamples() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/test/asciidoc/examples");
@@ -162,11 +299,11 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/examples").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithExamples.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithExamples.html");
}
@Test
public void testSwagger2AsciiDocConversionWithGeneratedExamples() throws IOException, URISyntaxException {
public void testWithGeneratedExamples() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/test/asciidoc/generated_examples");
@@ -187,11 +324,30 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/generated_examples").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithGeneratedExamples.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithGeneratedExamples.html");
}
@Test
public void testSwagger2AsciiDocWithInlineSchema() throws IOException, URISyntaxException {
public void testWithGeneratedRecursiveExamples() throws IOException, URISyntaxException {
// Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_recursion.json"));
Path outputDirectory = Paths.get("build/test/asciidoc/generated_recursion_examples");
FileUtils.deleteQuietly(outputDirectory.toFile());
// When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder().withoutInlineSchema().withGeneratedExamples().build();
Swagger2MarkupConverter.from(swaggerJsonString).withConfig(config).build().toFolder(outputDirectory);
// Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/generated_recursion_examples").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithGeneratedRecursiveExamples.html");
}
@Test
public void testWithInlineSchema() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/inline_schema");
@@ -209,11 +365,11 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/inline_schema").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocWithInlineSchema.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithInlineSchema.html");
}
@Test
public void testSwagger2AsciiDocWithInlineSchemaAndFlatBody() throws IOException, URISyntaxException {
public void testWithInlineSchemaAndFlatBody() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/inline_schema_flat_body");
@@ -232,11 +388,11 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/inline_schema_flat_body").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocWithInlineSchemaAndFlatBody.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithInlineSchemaAndFlatBody.html");
}
@Test
public void testSwagger2AsciiDocGroupedByTags() throws IOException, URISyntaxException {
public void testGroupedByTags() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/group_by_tags");
@@ -254,11 +410,11 @@ public class AsciidocConverterTest {
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/group_by_tags").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocGroupedByTags.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testGroupedByTags.html");
}
@Test
public void testSwagger2AsciiDocGroupedByTagsWithMissingTag() throws IOException, URISyntaxException {
public void testByTagsWithMissingTag() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_missing_tag.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
@@ -276,12 +432,12 @@ public class AsciidocConverterTest {
// If NullPointerException was not thrown, test would fail the specified message
failBecauseExceptionWasNotThrown(NullPointerException.class);
} catch (Exception e) {
assertThat(e).hasMessage("Can't GroupBy.TAGS > Operation 'updatePet' has not tags");
assertThat(e).hasMessage("Can't GroupBy.TAGS. Operation 'updatePet' has no tags");
}
}
@Test
public void testSwagger2AsciiDocConversionDoesNotContainUriScheme() throws IOException, URISyntaxException {
public void tesDoesNotContainUriScheme() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_not_contain_uri_scheme.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
@@ -300,7 +456,7 @@ public class AsciidocConverterTest {
}
@Test
public void testSwagger2AsciiDocConversionContainsUriScheme() throws IOException, URISyntaxException {
public void testContainsUriScheme() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_should_contain_uri_scheme.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
@@ -320,7 +476,7 @@ public class AsciidocConverterTest {
@Test
public void testSwagger2AsciiDocConversionWithSeparatedDefinitions() throws IOException, URISyntaxException {
public void testWithSeparatedDefinitions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
@@ -345,7 +501,7 @@ public class AsciidocConverterTest {
}
@Test
public void testSwagger2AsciiDocConversionWithSeparatedOperations() throws IOException, URISyntaxException {
public void testWithSeparatedOperations() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
@@ -369,15 +525,44 @@ public class AsciidocConverterTest {
}
@Test
public void testSwagger2AsciiDocConversionWithRussianOutputLanguage() throws IOException, URISyntaxException {
public void testWithRussianOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.RU, "definitions.adoc", "== Определения");
}
@Test
public void testWithFrenchOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.FR, "overview.adoc", "== Sch\u00E9ma d'URI");
}
@Test
public void testWithGermanOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.DE, "definitions.adoc", "Beschreibung");
}
@Test
public void testWithSpanishOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.ES, "definitions.adoc", "Descripción");
}
@Test
public void testWithJapaneseOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.JA, "definitions.adoc", "説明");
}
@Test
public void testWithChineseOutputLanguage() throws IOException, URISyntaxException {
testWithOutputLanguage(Language.ZH, "definitions.adoc", "说明");
}
private void testWithOutputLanguage(Language language, String outputFilename, String expected) throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
Path outputDirectory = Paths.get("build/test/asciidoc/language");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withOutputLanguage(Language.RU)
.withOutputLanguage(language)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
@@ -385,33 +570,12 @@ public class AsciidocConverterTest {
.toFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")), Charset.forName("UTF-8")))
.contains("== Определения");
assertThat(new String(Files.readAllBytes(outputDirectory.resolve(outputFilename)), Charset.forName("UTF-8")))
.contains(expected);
}
@Test
public void testSwagger2AsciiDocConversionWithFrenchOutputLanguage() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withOutputLanguage(Language.FR)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
assertThat(new String(Files.readAllBytes(outputDirectory.resolve("overview.adoc")), Charset.forName("UTF-8")))
.contains("== Sch\u00E9ma d'URI");
}
@Test
public void testSwagger2AsciiDocConversionWithMaps() throws IOException, URISyntaxException {
public void testWithMaps() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_maps.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/maps");
@@ -419,6 +583,7 @@ public class AsciidocConverterTest {
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withTagOrdering(OrderBy.AS_IS)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
@@ -430,11 +595,11 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/maps").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithMaps.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithMaps.html");
}
@Test
public void testSwagger2AsciiDocConversionWithEnums() throws IOException, URISyntaxException {
public void testWithEnums() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_enums.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/enums");
@@ -453,12 +618,12 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/enums").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithEnums.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithEnums.html");
}
@Test
public void testSwagger2AsciiDocConversionWithValidators() throws IOException, URISyntaxException {
public void testWithValidators() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_validators.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/validators");
@@ -477,11 +642,11 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/validators").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithValidators.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithValidators.html");
}
@Test
public void testSwagger2AsciiDocConversionWithPolymorphism() throws IOException, URISyntaxException {
public void testWithPolymorphism() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_polymorphism.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/polymorphism");
@@ -500,11 +665,11 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/polymorphism").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithPolymorphism.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithPolymorphism.html");
}
@Test
public void testSwagger2AsciiDocConversionWithPolymorphismAsIsOrdering() throws IOException, URISyntaxException {
public void testWithPolymorphismAsIsOrdering() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_polymorphism.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/polymorphismAsIsOrdering");
@@ -524,11 +689,11 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/polymorphismAsIsOrdering").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithPolymorphismAsIsOrdering.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithPolymorphismAsIsOrdering.html");
}
@Test
public void testSwagger2AsciiDocConversionWithResponseHeaders() throws IOException, URISyntaxException {
public void testWithResponseHeaders() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_response_headers.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/response_headers");
@@ -547,6 +712,77 @@ public class AsciidocConverterTest {
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/response_headers").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2AsciiDocConversionWithResponseHeaders.html");
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithResponseHeaders.html");
}
@Test
public void testWithEmptyContactUsingJSON() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/json/swagger_emptycontact.json").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/emptycontact");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/emptycontact").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithEmptyContactUsingJSON.html");
}
@Test
public void testWithFormat() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_format.yaml").toURI());
Path outputDirectory = Paths.get("build/test/asciidoc/format");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/format").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithFormat.html");
}
@Test
public void testWithPageBreaks() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_examples.json"));
Path outputDirectory = Paths.get("build/test/asciidoc/page_breaks");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withoutInlineSchema()
.withPageBreaks(new ArrayList<>(asList(PageBreakLocations.BEFORE_OPERATION, PageBreakLocations.BEFORE_OPERATION_EXAMPLE_REQUEST)))
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/page_breaks").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithPageBreaks.html");
}
}

View File

@@ -80,7 +80,7 @@ public class DocumentationTest {
// end::convertIntoString[]
}
public void swagger2MarkupConfigBuilder(){
public void swagger2MarkupConfigBuilder() {
Path localSwaggerFile = Paths.get("/path/to/swagger.yaml");
// tag::swagger2MarkupConfigBuilder[]

View File

@@ -15,10 +15,7 @@
*/
package io.github.swagger2markup;
import io.github.swagger2markup.assertions.DiffUtils;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
@@ -40,31 +37,10 @@ public class GeneralConverterTest {
private List<String> expectedFiles;
@Before
public void setUp(){
public void setUp() {
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
}
@Test
public void testToFileWithoutExtension() throws IOException, URISyntaxException {
//Given
String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/yaml/swagger_petstore.yaml"));
Path outputFile = Paths.get("build/test/asciidoc/toFile/outputFile.adoc");
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withGeneratedExamples()
.build();
Swagger2MarkupConverter.from(swaggerJsonString)
.withConfig(config)
.build()
.toFileWithoutExtension(outputFile);
//Then
Path expectedFile = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/toFile/outputFile.adoc").toURI());
DiffUtils.assertThatFileIsEqual(expectedFile, outputFile, "testOutputFile.html");
}
@Test
public void testFromHttpURI() throws IOException, URISyntaxException {
//Given

View File

@@ -48,144 +48,6 @@ public class MarkdownConverterTest {
private static final String[] EXPECTED_FILES = new String[]{"definitions.md", "overview.md", "paths.md", "security.md"};
private List<String> expectedFiles;
@Before
public void setUp(){
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
}
@Test
public void testSwagger2MarkdownConversion() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/default");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/default").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2MarkdownConversion.html");
}
@Test
public void testSwagger2MarkdownConversionWithInterDocumentCrossReferences() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/idxref");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withInterDocumentCrossReferences()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/idxref").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2MarkdownConversionWithInterDocumentCrossReferences.html");
}
@Test
public void testSwagger2MarkdownConversionWithSeparatedDefinitions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withSeparatedDefinitions()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("definitions");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path definitionsDirectory = outputDirectory.resolve("definitions");
String[] definitions = definitionsDirectory.toFile().list();
assertThat(definitions).hasSize(5).containsAll(
asList("Category.md", "Order.md", "Pet.md", "Tag.md", "User.md"));
}
@Test
public void testSwagger2MarkdownConversionWithResponseHeaders() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_response_headers.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/response_headers");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/response_headers").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testSwagger2MarkdownConversionWithResponseHeaders.html");
}
@Test
public void testSwagger2MarkdownConversionHandlesComposition() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withSeparatedDefinitions()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
// Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("definitions");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path definitionsDirectory = outputDirectory.resolve("definitions");
verifyMarkdownContainsFieldsInTables(
definitionsDirectory.resolve("User.md").toFile(),
ImmutableMap.<String, Set<String>>builder()
.put("User", ImmutableSet.of("id", "username", "firstName",
"lastName", "email", "password", "phone", "userStatus"))
.build()
);
}
/**
* Given a markdown document to search, this checks to see if the specified tables
* have all of the expected fields listed.
@@ -197,6 +59,7 @@ public class MarkdownConverterTest {
* @throws IOException if the markdown document could not be read
*/
private static void verifyMarkdownContainsFieldsInTables(File doc, Map<String, Set<String>> fieldsByTable) throws IOException {
//TODO: This method is too complex, split it up in smaller methods to increase readability
final List<String> lines = Files.readAllLines(doc.toPath(), Charset.defaultCharset());
final Map<String, Set<String>> fieldsLeftByTable = Maps.newHashMap();
for (Map.Entry<String, Set<String>> entry : fieldsByTable.entrySet()) {
@@ -250,4 +113,141 @@ public class MarkdownConverterTest {
? line.replace("###", "").trim()
: null;
}
@Before
public void setUp() {
expectedFiles = new ArrayList<>(asList(EXPECTED_FILES));
}
@Test
public void testToFolder() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/to_folder");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/to_folder").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testToFolder.html");
}
@Test
public void testWithInterDocumentCrossReferences() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/idxref");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.withInterDocumentCrossReferences()
.build();
Swagger2MarkupConverter.from(file).withConfig(config).build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/idxref").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithInterDocumentCrossReferences.html");
}
@Test
public void testWithSeparatedDefinitions() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withSeparatedDefinitions()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("definitions");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path definitionsDirectory = outputDirectory.resolve("definitions");
String[] definitions = definitionsDirectory.toFile().list();
assertThat(definitions).hasSize(5).containsAll(
asList("Category.md", "Order.md", "Pet.md", "Tag.md", "User.md"));
}
@Test
public void testWithResponseHeaders() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(AsciidocConverterTest.class.getResource("/yaml/swagger_response_headers.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/response_headers");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
//Then
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(expectedFiles);
Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/markdown/response_headers").toURI());
DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithResponseHeaders.html");
}
@Test
public void testHandlesComposition() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(MarkdownConverterTest.class.getResource("/yaml/swagger_petstore.yaml").toURI());
Path outputDirectory = Paths.get("build/test/markdown/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withSeparatedDefinitions()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(file)
.withConfig(config)
.build()
.toFolder(outputDirectory);
// Then
String[] files = outputDirectory.toFile().list();
expectedFiles.add("definitions");
assertThat(files).hasSize(5).containsAll(expectedFiles);
Path definitionsDirectory = outputDirectory.resolve("definitions");
verifyMarkdownContainsFieldsInTables(
definitionsDirectory.resolve("User.md").toFile(),
ImmutableMap.<String, Set<String>>builder()
.put("User", ImmutableSet.of("id", "username", "firstName",
"lastName", "email", "password", "phone", "userStatus"))
.build()
);
}
}

View File

@@ -46,7 +46,7 @@ public class MyExtension extends DefinitionsDocumentExtension {
String definitionName = context.getDefinitionName().get();
Model definitionModel = context.getModel().get();
if(position.equals(Position.DEFINITION_END)) {
if (position.equals(Position.DEFINITION_END)) {
markupBuilder.sectionTitleLevel1(definitionName) //<4>
.paragraph(definitionModel.getDescription())
.importMarkup(new StringReader("*Markup*"), MarkupLanguage.ASCIIDOC);

View File

@@ -0,0 +1,42 @@
/*
* 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.helper;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.Swagger2MarkupExtensionRegistry;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.builder.Swagger2MarkupExtensionRegistryBuilder;
import io.swagger.models.Swagger;
public class ContextUtils {
public static Swagger2MarkupConverter.Context createContext() {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder().build();
Swagger2MarkupExtensionRegistry extensionRegistry = new Swagger2MarkupExtensionRegistryBuilder().build();
return new Swagger2MarkupConverter.Context(config, extensionRegistry, null, null);
}
public static Swagger2MarkupConverter.Context createContext(Swagger2MarkupConfig config) {
Swagger2MarkupExtensionRegistry extensionRegistry = new Swagger2MarkupExtensionRegistryBuilder().build();
return new Swagger2MarkupConverter.Context(config, extensionRegistry, null, null);
}
public static Swagger2MarkupConverter.Context createContext(Swagger2MarkupConfig config, Swagger swagger) {
Swagger2MarkupExtensionRegistry extensionRegistry = new Swagger2MarkupExtensionRegistryBuilder().build();
return new Swagger2MarkupConverter.Context(config, extensionRegistry, swagger, null);
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.adapter;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.internal.resolver.DefinitionDocumentResolverFromOperation;
import io.github.swagger2markup.internal.type.BasicType;
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.internal.utils.PathUtils;
import io.github.swagger2markup.model.PathOperation;
import io.swagger.models.Swagger;
import io.swagger.models.parameters.Parameter;
import org.junit.Test;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class ParameterAdapterTest {
@Test
public void testParameterWrapper() throws URISyntaxException {
//Given
Path file = Paths.get(ParameterAdapterTest.class.getResource("/yaml/swagger_inlineSchema.yaml").toURI());
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(file).build();
Swagger2MarkupConverter.Context context = converter.getContext();
Swagger swagger = context.getSwagger();
io.swagger.models.Path path = swagger.getPaths().get("/LaunchCommand");
List<PathOperation> pathOperations = PathUtils.toPathOperationsList("/LaunchCommand", path);
PathOperation operation = pathOperations.get(0);
List<Parameter> parameters = operation.getOperation().getParameters();
DefinitionDocumentResolverFromOperation resolverFromOperation = new DefinitionDocumentResolverFromOperation(context);
//Test Query Parameter
Parameter queryParamter = parameters.get(0);
ParameterAdapter queryParameterAdapter = new ParameterAdapter(
context,
operation,
queryParamter,
resolverFromOperation);
Type type = queryParameterAdapter.getType();
assertThat(queryParameterAdapter.getIn()).isEqualTo("Query");
assertThat(type).isInstanceOf(BasicType.class);
assertThat(type.getName()).isEqualTo("Version");
assertThat(type.getUniqueName()).isEqualTo("Version");
assertThat(((BasicType) type).getType()).isEqualTo("string");
//Test Body Parameter
Parameter bodyParameter = parameters.get(2);
ParameterAdapter bodyParameterAdapter = new ParameterAdapter(
context,
operation,
bodyParameter,
resolverFromOperation);
type = bodyParameterAdapter.getType();
assertThat(bodyParameterAdapter.getIn()).isEqualTo("Body");
assertThat(type).isInstanceOf(RefType.class);
Type refType = ((RefType) type).getRefType();
assertThat(refType).isInstanceOf(ObjectType.class);
ObjectType objectType = (ObjectType) refType;
assertThat(objectType.getProperties()).hasSize(3);
//Inline Schema
assertThat(bodyParameterAdapter.getInlineDefinitions()).hasSize(1);
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.component;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
abstract class AbstractComponentTest {
Path getOutputFile(String componentName) {
return Paths.get("build/test/component/" + componentName + ".adoc");
}
Path getExpectedFile(String componentName) throws URISyntaxException {
return Paths.get(AbstractComponentTest.class.getResource("/component/" + componentName + ".adoc").toURI());
}
String getReportName(String componentName) {
return "/component/" + componentName + ".html";
}
}

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