diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..13566b81
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/aws.xml b/.idea/aws.xml
new file mode 100644
index 00000000..b63b642c
--- /dev/null
+++ b/.idea/aws.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..6d2383c2
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..fdafdfdb
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..76bdc048
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 1baa047f..374892db 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,33 @@
# openapi-to-plantuml
+

[](https://codecov.io/gh/davidmoten/openapi-to-plantuml)
[](https://maven-badges.herokuapp.com/maven-central/com.github.davidmoten/openapi-to-plantuml)
-Java library to generate a [PlantUML](https://plantuml.com) Class Diagram (supplemented with path information) from an OpenAPI 3.0 definition (YAML or JSON). Try it online [here](https://openapi-to-puml.davidmoten.org/prod/site/index.html).
+Java library to generate a [PlantUML](https://plantuml.com) Class Diagram (supplemented with path information) from an
+OpenAPI 3.0 definition (YAML or JSON). Try it online [here](https://openapi-to-puml.davidmoten.org/prod/site/index.html)
+.
**Features**
Supports all features of OpenAPI 3.0 including
-* Mixed types (*oneOf*, *anyOf*, *allOf*)
-* Multiple levels of indirection (`$ref` -> `$ref` for example)
+* Mixed types (*oneOf*, *anyOf*, *allOf*)
+* Multiple levels of indirection (`$ref` -> `$ref` for example)
* Multiple response content types
-**Status:** Released to Maven Central
+**Status:** Released to Maven Central
**Limitations**
* Only handles internal references ("#/*"), that is the yaml file should be self-contained
**TODO**
+
* Model *Callbacks*
* Model *additionalProperties*
-[openapi-example.yml](src/test/resources/openapi-example.yml):
+[openapi-example.yml](src/test/resources/openapi-example.yml):
@@ -35,31 +39,83 @@ mvn clean install
## How to quickly convert your OpenAPI definition
-The easiest thing to do is to use the [online converter](https://openapi-to-puml.davidmoten.org/prod/site/index.html). If your definition is large then PlantText may refuse to render it (the Plant UML text is encoded and added to the PlantText url which can get too long). In that case just add your yaml file to `src/test/resources/demo/` directory and run `mvn test`. The generated image will be saved in `target/demos`.
+The easiest thing to do is to use the [online converter](https://openapi-to-puml.davidmoten.org/prod/site/index.html).
+If your definition is large then PlantText may refuse to render it (the Plant UML text is encoded and added to the
+PlantText url which can get too long). In that case just add your yaml file to `src/test/resources/demo/` directory and
+run `mvn test`. The generated image will be saved in `target/demos`.
## Getting started
+
Add this dependency to your pom.xml:
```xml
com.github.davidmoten
openapi-to-plantuml
- VERSION_HERE
+ 2022-01-01-SNAPSHOT
```
-Or use the standalone *jar-with-dependencies* artifact from [Maven Central](https://search.maven.org/search?q=g:com.github.davidmoten%20AND%20a:openapi-to-plantuml) (or from the `target` directory if you have built the project locally):
+Or use the standalone *jar-with-dependencies* artifact
+from [Maven Central](https://search.maven.org/search?q=g:com.github.davidmoten%20AND%20a:openapi-to-plantuml) (or from
+the `target` directory if you have built the project locally):
+
+## Usage
+
+Read com.github.davidmoten.oas3.puml.ConverterMainTest for more examples
+
+```bash
+Usage:
+java -jar openapi-to-plantuml-all.jar |<[FILE_FORMAT1, FILE_FORMAT1...]>
+ file or Directory containing *.yml or *.yaml files
+ output Directory
+ optional file format default PUML and SVG only
+ or<[FILE_FORMAT1, FILE_FORMAT1...]> optional several file formats
+surrounded by [delimited by comma and space ', ')] i.e. supported formats are:
+[ATXT, BRAILLE_PNG, DEBUG, EPS, EPS_TEXT, LATEX, LATEX_NO_PREAMBLE, PNG, SVG, UTXT, VDX]
+ATXT *.atxt text/plain
+BRAILLE_PNG *.braille.png image/png
+DEBUG *.debug text/plain
+EPS *.eps application/postscript
+EPS_TEXT *.eps.text.eps application/postscript
+LATEX *.latex application/x-latex
+LATEX_NO_PREAMBLE *.latex.no.preamble.latex application/x-latex
+PNG *.png image/png
+SVG *.svg image/svg+xml
+UTXT *.utxt text/plain;charset=UTF-8
+VDX *.vdx application/vnd.visio.xml
+```
+
+all demo files at src/test/resources/demo to target/converted-puml as PUML & SVG by default
+
+```bash
+java -jar target/openapi-to-plantuml-2022-01-01-SNAPSHOT-jar-with-dependencies.jar src/test/resources/demo target/converted-puml
+```
+
+all demo files at src/test/resources/demo to target/converted-puml as PUML, SVG & PNG
```bash
-java -jar openapi-to-plantuml-VERSION_HERE-jar-with-dependencies.jar openapi.yaml PNG openapi.png
+java -jar target/openapi-to-plantuml-2022-01-01-SNAPSHOT-jar-with-dependencies.jar src/test/resources/demo target/converted-puml "[SVG, PNG]"
```
## Usage
+Read com.github.davidmoten.oas3.puml.DemoJavaTest for more examples All supported formats
+
```java
import com.github.davidmoten.oas3.puml.Converter;
+Converter.writeOpenApiDirectoryFileToPumlAndTo(OPEN_API_DIRECTORY_FILE,
+ OUTPUT_DIRECTORY_FILE,
+ Converter.SUPPORTED_FORMATS);
+```
-String puml = Converter.openApiToPuml(openapi);
+PUML, SVG & PNG
+
+```java
+Converter.writeOpenApiDirectoryFileToPumlAndTo(OPEN_API_DIRECTORY_FILE,
+ OUTPUT_DIRECTORY_FILE,
+ FileFormat.SVG,
+ FileFormat.PNG);
```
## Examples
diff --git a/openapi-to-plantuml.eml b/openapi-to-plantuml.eml
new file mode 100644
index 00000000..dafd0912
--- /dev/null
+++ b/openapi-to-plantuml.eml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c036ed70..86294fb6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,24 +1,20 @@
-
-
+
4.0.0
com.github.davidmoten
openapi-to-plantuml
- 0.1.6-SNAPSHOT
+ 2022-01-23-SNAPSHOT
${project.artifactId}
Generates PlantUML file from an OpenAPI 3.0 Definition
jar
-
http://github.com/davidmoten/openapi-to-plantuml
UTF-8
UTF-8
- 1.8
-
- 1.7.33
+ 11
3.1.2
src/main/checkstyle/checkstyle.xml
src/main/checkstyle/suppressions.xml
@@ -36,10 +32,8 @@
${project.build.directory}/target/coverage-reports
0.80
0.40
-
- 1.7.30
+ 1.7.33
2.17.1
-
@@ -61,7 +55,7 @@
https://github.com/davidmoten/openapi-to-plantuml/issues
- 2021
+ 2022
dave
@@ -73,6 +67,16 @@
+10
+
+ VRDate
+ Tomer Bar-Shlomo
+ https://github.com/VRDate/
+
+ architect
+ developer
+
+ +2
+
@@ -252,7 +256,7 @@
${checkstyle.version}
true
- ${checkstyle.xml}
+ src/main/checkstyle/checkstyle.xml
UTF-8
true
true
@@ -392,7 +396,7 @@
maven-javadoc-plugin
${javadoc.version}
- true
+
ErrorModeltimestamp : timestamp {O}status : integererror : string {O}message : stringpath : string {O}GenericLinkhref : stringtemplated : boolean {O}PsuContextLinksAccountLinksBalancesLinksTransactionsLinksEndUserIdentityLinksPaymentRequestLinksPaymentCoverageReportLinksPaymentRequestResourceCreationLinksAppliedAuthenticationApproachvalue : stringGenericIdentificationidentification : stringschemeName : stringissuer : string {O}AccountIdentificationiban : string {O}CurrencyCodevalue : stringAmountTypeamount : stringClearingSystemMemberIdentificationclearingSystemId : string {O}memberId : string {O}FinancialInstitutionIdentificationbicFi : stringname : string {O}PostalAddresscountry : stringaddressLine : string[]PartyIdentificationname : stringResourceIdvalue : stringPaymentIdentificationinstructionId : stringendToEndId : string {O}PriorityCodevalue : stringCategoryPurposeCodevalue : stringServiceLevelCodevalue : stringLocalInstrumentCodevalue : stringPaymentTypeInformationPurposeCodevalue : stringChargeBearerCodevalue : stringUnstructuredRemittanceInformationUnstructuredRemittanceInformation.1value : stringPaymentInformationStatusCodevalue : stringTransactionIndividualStatusCodevalue : stringStatusReasonInformationvalue : stringRegulatoryReportingCodevalue : stringRegulatoryReportingCodesRequestedExecutionDatevalue : timestampEndDatevalue : timestampExecutionRulevalue : stringFrequencyCodevalue : stringCreditTransferTransactionBeneficiaryid : string {O}isTrusted : boolean {O}SupplementaryDataacceptedAuthenticationApproach : string[] {O}scaHint : string {O}successfulReportUrl : string {O}unsuccessfulReportUrl : string {O}BalanceStatusvalue : stringTransactionStatusvalue : stringCreditDebitIndicatorvalue : stringTransactionentryReference : string {O}bookingDate : datevalueDate : date {O}transactionDate : date {O}AccountResourcebicFi : string {O}name : stringdetails : string {O}linkedAccount : string {O}usage : string {O}cashAccountType : stringproduct : string {O}psuStatus : string {O}BalanceResourcename : stringlastChangeDateTime : timestamp {O}referenceDate : date {O}lastCommittedTransaction : string {O}PaymentInformationIdvalue : stringCreationDateTimevalue : timestampFundsAvailabilityInformationvalue : booleanBookingInformationvalue : booleanPaymentRequestResourcenumberOfTransactions : integerrequestedExecutionDate : timestamp {O}PaymentCoverageRequestResourcepaymentCoverageRequestId : stringpayee : string {O}HalAccountsHalBalancesHalTransactionsGetPaymentRequestHalPaymentRequestHalPaymentRequestCreationHalPaymentCoverageReportresult : booleanHalEndUserIdentityconnectedPsu : stringHalBeneficiariesAccessibleAccountsAccesstrustedBeneficiaries : booleanpsuIdentity : booleanConfirmationResourcepsuAuthenticationFactor : string {O}Noncevalue : string«Parameter»AccountResourceIdentificationvalue : string«Parameter»PaymentRequestResourceIdentificationvalue : string«Parameter»ToImputationDatevalue : timestamp«Parameter»FromImputationDatevalue : timestamp«Parameter»AuthorizationParametervalue : string«Parameter»PsuIpAddressHeadervalue : string«Parameter»PsuIpPortHeadervalue : string«Parameter»PsuHttpMethodHeadervalue : string«Parameter»PsuDateHeadervalue : string«Parameter»PsuGeoLocationvalue : string«Parameter»PsuUserAgentHeadervalue : string«Parameter»PsuRefererHeadervalue : string«Parameter»PsuAcceptHeadervalue : string«Parameter»PsuAcceptCharsetHeadervalue : string«Parameter»PsuAcceptEncodingHeadervalue : string«Parameter»PsuAcceptLanguageHeadervalue : string«Parameter»PsuDeviceIdvalue : string«Parameter»DigestHeadervalue : string«Parameter»SignatureHeadervalue : string«Parameter»Correlationvalue : string«Parameter»QueryParameterPagevalue : integer400401403404405406408409429500501503«Method»GET /openbanking-test/v1/accountsGET /openbanking-test/v1/accounts 204 Response«Method»GET /openbanking-test/v1/accounts/{accountResourceId}/balancesGET /openbanking-test/v1/accounts/{accountResourceId}/balances 204 Response«Method»GET /openbanking-test/v1/accounts/{accountResourceId}/transactionsGET /openbanking-test/v1/accounts/{accountResourceId}/transactions 204 Response«Method»POST /openbanking-test/v1/accounts/funds-confirmations«Method»PUT /openbanking-test/v1/consentsPUT /openbanking-test/v1/consents 201 Response«Method»GET /openbanking-test/v1/end_user_identityGET /openbanking-test/v1/end_user_identity 204 Response«Method»GET /openbanking-test/v1/trusted-beneficiariesGET /openbanking-test/v1/trusted-beneficiaries 204 Response«Method»POST /openbanking-test/v1/payment-requests«Method»GET /openbanking-test/v1/payment-requests/{paymentRequestResourceId}«Method»PUT /openbanking-test/v1/payment-requests/{paymentRequestResourceId}paymentRequestResourceId : stringPSU-IP-Address : string {O}PSU-IP-Port : string {O}PSU-HTTP-Method : string {O}PSU-Date : string {O}PSU-GEO-Location : string {O}PSU-User-Agent : string {O}PSU-Referer : string {O}PSU-Accept : string {O}PSU-Accept-Charset : string {O}PSU-Accept-Encoding : string {O}PSU-Accept-Language : string {O}PSU-Device-ID : string {O}Digest : string {O}Signature : string {O}X-Request-ID : string {O}«Method»POST /openbanking-test/v1/payment-requests/{paymentRequestResourceId}/confirmationpaymentRequestResourceId : stringPSU-IP-Address : string {O}PSU-IP-Port : string {O}PSU-HTTP-Method : string {O}PSU-Date : string {O}PSU-GEO-Location : string {O}PSU-User-Agent : string {O}PSU-Referer : string {O}PSU-Accept : string {O}PSU-Accept-Charset : string {O}PSU-Accept-Encoding : string {O}PSU-Accept-Language : string {O}PSU-Device-ID : string {O}Digest : string {O}Signature : string {O}X-Request-ID : string {O}self1endUserIdentity0..1beneficiaries0..1first0..1last0..1next0..1prev0..1balances0..1transactions0..1self1parent-list0..1transactions0..1self1parent-list0..1balances0..1first0..1last0..1next0..1prev0..1self1parent-list0..1request0..1confirmation0..1self1consentApproval0..1other0..1currency0..1currency1clearingSystemMemberId0..1postalAddress0..1postalAddress0..1organisationId0..1privateId0..1resourceId0..1instructionPriority0..1serviceLevel0..1localInstrument0..1categoryPurpose0..1**paymentId1beneficiary0..1requestedExecutionDate0..1endDate0..1executionRule0..1frequency0..1instructedAmount1ultimateCreditor0..1regulatoryReportingCodes0..1remittanceInformation0..1transactionStatus0..1statusReasonInformation0..1appliedAuthenticationApproach0..1resourceId0..1transactionAmount1creditDebitIndicator1status1remittanceInformation0..1resourceId0..1accountId0..1balances*_links1balanceAmount1balanceType1resourceId0..1paymentInformationId1creationDateTime1initiatingParty1debtor0..1ultimateCreditor0..1paymentTypeInformation1debtorAccount0..1debtorAgent0..1purpose0..1chargeBearer0..1paymentInformationStatus0..1statusReasonInformation0..1fundsAvailability0..1booking0..1creditTransferTransaction*supplementaryData1instructedAmount1accountId1accounts*_links1balances*_links1transactions*_links1paymentRequest1_links1paymentRequest1_links1appliedAuthenticationApproach0..1_links0..1request1_links1creditorAgent0..1creditor1creditorAccount0..1_links1beneficiaries**balances1transactions1nonce0..11111111111111200204401403404405406408429500503parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151parameter161200204400401403404405406408429500503parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151parameter161200204400401403404405406408429500503parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151parameter161parameter171parameter181parameter191200400401403405406408429500503«Request Body»parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151201400401403405406408429500501503«Request Body»parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151200204401403404405406429500parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151200204401403404405406429500501parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151201400401403405406408429500503«Request Body»parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151200400401403404405406408429500503200400401403404405406408409429500503«Request Body»parameter11parameter21parameter31parameter41parameter51parameter61parameter71parameter81parameter91parameter101parameter111parameter121parameter131parameter141parameter151parameter161200400401403405406408409429500503«Request Body»
+
+
+
+ ErrorModel
+
+
+ timestamp : timestamp {O}
+
+ status : integer
+
+ error : string {O}
+
+ message : string
+
+ path : string {O}
+
+
+
+
+
+ GenericLink
+
+
+ href : string
+
+ templated : boolean {O}
+
+
+
+
+
+ PsuContextLinks
+
+
+
+
+
+
+ AccountLinks
+
+
+
+
+
+
+ BalancesLinks
+
+
+
+
+
+
+ TransactionsLinks
+
+
+
+
+
+
+ EndUserIdentityLinks
+
+
+
+
+
+
+ PaymentRequestLinks
+
+
+
+
+
+
+ PaymentCoverageReportLinks
+
+
+
+
+
+
+ PaymentRequestResourceCreationLinks
+
+
+
+
+
+
+ AppliedAuthenticationApproach
+
+
+ value : string
+
+
+
+
+
+ GenericIdentification
+
+
+ identification : string
+
+ schemeName : string
+
+ issuer : string {O}
+
+
+
+
+
+ AccountIdentification
+
+
+ iban : string {O}
+
+
+
+
+
+ CurrencyCode
+
+
+ value : string
+
+
+
+
+
+ AmountType
+
+
+ amount : string
+
+
+
+
+
+ ClearingSystemMemberIdentification
+
+
+ clearingSystemId : string {O}
+
+ memberId : string {O}
+
+
+
+
+
+ FinancialInstitutionIdentification
+
+
+ bicFi : string
+
+ name : string {O}
+
+
+
+
+
+ PostalAddress
+
+
+ country : string
+
+ addressLine : string[]
+
+
+
+
+
+ PartyIdentification
+
+
+ name : string
+
+
+
+
+
+ ResourceId
+
+
+ value : string
+
+
+
+
+
+ PaymentIdentification
+
+
+ instructionId : string
+
+ endToEndId : string {O}
+
+
+
+
+
+ PriorityCode
+
+
+ value : string
+
+
+
+
+
+ CategoryPurposeCode
+
+
+ value : string
+
+
+
+
+
+ ServiceLevelCode
+
+
+ value : string
+
+
+
+
+
+ LocalInstrumentCode
+
+
+ value : string
+
+
+
+
+
+ PaymentTypeInformation
+
+
+
+
+
+
+ PurposeCode
+
+
+ value : string
+
+
+
+
+
+ ChargeBearerCode
+
+
+ value : string
+
+
+
+
+
+ UnstructuredRemittanceInformation
+
+
+
+
+
+
+ UnstructuredRemittanceInformation.1
+
+
+ value : string
+
+
+
+
+
+ PaymentInformationStatusCode
+
+
+ value : string
+
+
+
+
+
+ TransactionIndividualStatusCode
+
+
+ value : string
+
+
+
+
+
+ StatusReasonInformation
+
+
+ value : string
+
+
+
+
+
+ RegulatoryReportingCode
+
+
+ value : string
+
+
+
+
+
+ RegulatoryReportingCodes
+
+
+
+
+
+
+ RequestedExecutionDate
+
+
+ value : timestamp
+
+
+
+
+
+ EndDate
+
+
+ value : timestamp
+
+
+
+
+
+ ExecutionRule
+
+
+ value : string
+
+
+
+
+
+ FrequencyCode
+
+
+ value : string
+
+
+
+
+
+ CreditTransferTransaction
+
+
+
+
+
+
+ Beneficiary
+
+
+ id : string {O}
+
+ isTrusted : boolean {O}
+
+
+
+
+
+ SupplementaryData
+
+
+ acceptedAuthenticationApproach : string[] {O}
+
+ scaHint : string {O}
+
+ successfulReportUrl : string {O}
+
+ unsuccessfulReportUrl : string {O}
+
+
+
+
+
+ BalanceStatus
+
+
+ value : string
+
+
+
+
+
+ TransactionStatus
+
+
+ value : string
+
+
+
+
+
+ CreditDebitIndicator
+
+
+ value : string
+
+
+
+
+
+ Transaction
+
+
+ entryReference : string {O}
+
+ bookingDate : date
+
+ valueDate : date {O}
+
+ transactionDate : date {O}
+
+
+
+
+
+ AccountResource
+
+
+ bicFi : string {O}
+
+ name : string
+
+ details : string {O}
+
+ linkedAccount : string {O}
+
+ usage : string {O}
+
+ cashAccountType : string
+
+ product : string {O}
+
+ psuStatus : string {O}
+
+
+
+
+
+ BalanceResource
+
+
+ name : string
+
+ lastChangeDateTime : timestamp {O}
+
+ referenceDate : date {O}
+
+ lastCommittedTransaction : string {O}
+
+
+
+
+
+ PaymentInformationId
+
+
+ value : string
+
+
+
+
+
+ CreationDateTime
+
+
+ value : timestamp
+
+
+
+
+
+ FundsAvailabilityInformation
+
+
+ value : boolean
+
+
+
+
+
+ BookingInformation
+
+
+ value : boolean
+
+
+
+
+
+ PaymentRequestResource
+
+
+ numberOfTransactions : integer
+
+ requestedExecutionDate : timestamp {O}
+
+
+
+
+
+ PaymentCoverageRequestResource
+
+
+ paymentCoverageRequestId : string
+
+ payee : string {O}
+
+
+
+
+
+ HalAccounts
+
+
+
+
+
+
+ HalBalances
+
+
+
+
+
+
+ HalTransactions
+
+
+
+
+
+
+ GetPaymentRequest
+
+
+
+
+
+
+ HalPaymentRequest
+
+
+
+
+
+
+ HalPaymentRequestCreation
+
+
+
+
+
+
+ HalPaymentCoverageReport
+
+
+ result : boolean
+
+
+
+
+
+ HalEndUserIdentity
+
+
+ connectedPsu : string
+
+
+
+
+
+ HalBeneficiaries
+
+
+
+
+
+
+ AccessibleAccounts
+
+
+
+
+
+
+ Access
+
+
+ trustedBeneficiaries : boolean
+
+ psuIdentity : boolean
+
+
+
+
+
+ ConfirmationResource
+
+
+ psuAuthenticationFactor : string {O}
+
+
+
+
+
+ Nonce
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ AccountResourceIdentification
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PaymentRequestResourceIdentification
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ ToImputationDate
+
+
+ value : timestamp
+
+
+
+
+
+ «Parameter»
+
+ FromImputationDate
+
+
+ value : timestamp
+
+
+
+
+
+ «Parameter»
+
+ AuthorizationParameter
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuIpAddressHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuIpPortHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuHttpMethodHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuDateHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuGeoLocation
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuUserAgentHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuRefererHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuAcceptHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuAcceptCharsetHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuAcceptEncodingHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuAcceptLanguageHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ PsuDeviceId
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ DigestHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ SignatureHeader
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ Correlation
+
+
+ value : string
+
+
+
+
+
+ «Parameter»
+
+ QueryParameterPage
+
+
+ value : integer
+
+
+
+
+
+ 400
+
+
+
+
+
+
+ 401
+
+
+
+
+
+
+ 403
+
+
+
+
+
+
+ 404
+
+
+
+
+
+
+ 405
+
+
+
+
+
+
+ 406
+
+
+
+
+
+
+ 408
+
+
+
+
+
+
+ 409
+
+
+
+
+
+
+ 429
+
+
+
+
+
+
+ 500
+
+
+
+
+
+
+ 501
+
+
+
+
+
+
+ 503
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/accounts
+
+
+
+
+
+
+ GET /openbanking-test/v1/accounts 204 Response
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/accounts/{accountResourceId}/balances
+
+
+
+
+
+
+ GET /openbanking-test/v1/accounts/{accountResourceId}/balances 204 Response
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/accounts/{accountResourceId}/transactions
+
+
+
+
+
+
+ GET /openbanking-test/v1/accounts/{accountResourceId}/transactions 204 Response
+
+
+
+
+ «Method»
+
+ POST /openbanking-test/v1/accounts/funds-confirmations
+
+
+
+
+ «Method»
+
+ PUT /openbanking-test/v1/consents
+
+
+
+
+
+
+ PUT /openbanking-test/v1/consents 201 Response
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/end_user_identity
+
+
+
+
+
+
+ GET /openbanking-test/v1/end_user_identity 204 Response
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/trusted-beneficiaries
+
+
+
+
+
+
+ GET /openbanking-test/v1/trusted-beneficiaries 204 Response
+
+
+
+
+ «Method»
+
+ POST /openbanking-test/v1/payment-requests
+
+
+
+
+ «Method»
+
+ GET /openbanking-test/v1/payment-requests/{paymentRequestResourceId}
+
+
+
+
+ «Method»
+
+ PUT /openbanking-test/v1/payment-requests/{paymentRequestResourceId}
+
+
+ paymentRequestResourceId : string
+
+ PSU-IP-Address : string {O}
+
+ PSU-IP-Port : string {O}
+
+ PSU-HTTP-Method : string {O}
+
+ PSU-Date : string {O}
+
+ PSU-GEO-Location : string {O}
+
+ PSU-User-Agent : string {O}
+
+ PSU-Referer : string {O}
+
+ PSU-Accept : string {O}
+
+ PSU-Accept-Charset : string {O}
+
+ PSU-Accept-Encoding : string {O}
+
+ PSU-Accept-Language : string {O}
+
+ PSU-Device-ID : string {O}
+
+ Digest : string {O}
+
+ Signature : string {O}
+
+ X-Request-ID : string {O}
+
+
+
+ «Method»
+
+ POST /openbanking-test/v1/payment-requests/{paymentRequestResourceId}/confirmation
+
+
+ paymentRequestResourceId : string
+
+ PSU-IP-Address : string {O}
+
+ PSU-IP-Port : string {O}
+
+ PSU-HTTP-Method : string {O}
+
+ PSU-Date : string {O}
+
+ PSU-GEO-Location : string {O}
+
+ PSU-User-Agent : string {O}
+
+ PSU-Referer : string {O}
+
+ PSU-Accept : string {O}
+
+ PSU-Accept-Charset : string {O}
+
+ PSU-Accept-Encoding : string {O}
+
+ PSU-Accept-Language : string {O}
+
+ PSU-Device-ID : string {O}
+
+ Digest : string {O}
+
+ Signature : string {O}
+
+ X-Request-ID : string {O}
+
+
+
+
+ self
+
+ 1
+
+
+
+ endUserIdentity
+
+ 0..1
+
+
+
+ beneficiaries
+
+ 0..1
+
+
+
+ first
+
+ 0..1
+
+
+
+ last
+
+ 0..1
+
+
+
+ next
+
+ 0..1
+
+
+
+ prev
+
+ 0..1
+
+
+
+ balances
+
+ 0..1
+
+
+
+ transactions
+
+ 0..1
+
+
+
+ self
+
+ 1
+
+
+
+ parent-list
+
+ 0..1
+
+
+
+ transactions
+
+ 0..1
+
+
+
+ self
+
+ 1
+
+
+
+ parent-list
+
+ 0..1
+
+
+
+ balances
+
+ 0..1
+
+
+
+ first
+
+ 0..1
+
+
+
+ last
+
+ 0..1
+
+
+
+ next
+
+ 0..1
+
+
+
+ prev
+
+ 0..1
+
+
+
+ self
+
+ 1
+
+
+
+ parent-list
+
+ 0..1
+
+
+
+ request
+
+ 0..1
+
+
+
+ confirmation
+
+ 0..1
+
+
+
+ self
+
+ 1
+
+
+
+ consentApproval
+
+ 0..1
+
+
+
+ other
+
+ 0..1
+
+
+
+ currency
+
+ 0..1
+
+
+
+ currency
+
+ 1
+
+
+
+ clearingSystemMemberId
+
+ 0..1
+
+
+
+ postalAddress
+
+ 0..1
+
+
+
+ postalAddress
+
+ 0..1
+
+
+
+ organisationId
+
+ 0..1
+
+
+
+ privateId
+
+ 0..1
+
+
+
+ resourceId
+
+ 0..1
+
+
+
+ instructionPriority
+
+ 0..1
+
+
+
+ serviceLevel
+
+ 0..1
+
+
+
+ localInstrument
+
+ 0..1
+
+
+
+ categoryPurpose
+
+ 0..1
+
+
+
+ *
+
+
+
+ *
+
+
+
+ paymentId
+
+ 1
+
+
+
+ beneficiary
+
+ 0..1
+
+
+
+ requestedExecutionDate
+
+ 0..1
+
+
+
+ endDate
+
+ 0..1
+
+
+
+ executionRule
+
+ 0..1
+
+
+
+ frequency
+
+ 0..1
+
+
+
+ instructedAmount
+
+ 1
+
+
+
+ ultimateCreditor
+
+ 0..1
+
+
+
+ regulatoryReportingCodes
+
+ 0..1
+
+
+
+ remittanceInformation
+
+ 0..1
+
+
+
+ transactionStatus
+
+ 0..1
+
+
+
+ statusReasonInformation
+
+ 0..1
+
+
+
+ appliedAuthenticationApproach
+
+ 0..1
+
+
+
+ resourceId
+
+ 0..1
+
+
+
+ transactionAmount
+
+ 1
+
+
+
+ creditDebitIndicator
+
+ 1
+
+
+
+ status
+
+ 1
+
+
+
+ remittanceInformation
+
+ 0..1
+
+
+
+ resourceId
+
+ 0..1
+
+
+
+ accountId
+
+ 0..1
+
+
+
+ balances
+
+ *
+
+
+
+ _links
+
+ 1
+
+
+
+ balanceAmount
+
+ 1
+
+
+
+ balanceType
+
+ 1
+
+
+
+ resourceId
+
+ 0..1
+
+
+
+ paymentInformationId
+
+ 1
+
+
+
+ creationDateTime
+
+ 1
+
+
+
+ initiatingParty
+
+ 1
+
+
+
+ debtor
+
+ 0..1
+
+
+
+ ultimateCreditor
+
+ 0..1
+
+
+
+ paymentTypeInformation
+
+ 1
+
+
+
+ debtorAccount
+
+ 0..1
+
+
+
+ debtorAgent
+
+ 0..1
+
+
+
+ purpose
+
+ 0..1
+
+
+
+ chargeBearer
+
+ 0..1
+
+
+
+ paymentInformationStatus
+
+ 0..1
+
+
+
+ statusReasonInformation
+
+ 0..1
+
+
+
+ fundsAvailability
+
+ 0..1
+
+
+
+ booking
+
+ 0..1
+
+
+
+ creditTransferTransaction
+
+ *
+
+
+
+ supplementaryData
+
+ 1
+
+
+
+ instructedAmount
+
+ 1
+
+
+
+ accountId
+
+ 1
+
+
+
+ accounts
+
+ *
+
+
+
+ _links
+
+ 1
+
+
+
+ balances
+
+ *
+
+
+
+ _links
+
+ 1
+
+
+
+ transactions
+
+ *
+
+
+
+ _links
+
+ 1
+
+
+
+ paymentRequest
+
+ 1
+
+
+
+ _links
+
+ 1
+
+
+
+ paymentRequest
+
+ 1
+
+
+
+ _links
+
+ 1
+
+
+
+ appliedAuthenticationApproach
+
+ 0..1
+
+
+
+ _links
+
+ 0..1
+
+
+
+ request
+
+ 1
+
+
+
+ _links
+
+ 1
+
+
+
+ creditorAgent
+
+ 0..1
+
+
+
+ creditor
+
+ 1
+
+
+
+ creditorAccount
+
+ 0..1
+
+
+
+ _links
+
+ 1
+
+
+
+ beneficiaries
+
+ *
+
+
+
+ *
+
+
+
+ balances
+
+ 1
+
+
+
+ transactions
+
+ 1
+
+
+
+ nonce
+
+ 0..1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 1
+
+
+
+ 200
+
+
+
+ 204
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ parameter16
+
+ 1
+
+
+
+ 200
+
+
+
+ 204
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ parameter16
+
+ 1
+
+
+
+ 200
+
+
+
+ 204
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ parameter16
+
+ 1
+
+
+
+ parameter17
+
+ 1
+
+
+
+ parameter18
+
+ 1
+
+
+
+ parameter19
+
+ 1
+
+
+
+ 200
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ «Request Body»
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ 201
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 501
+
+
+
+ 503
+
+
+
+ «Request Body»
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ 200
+
+
+
+ 204
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ 200
+
+
+
+ 204
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 501
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ 201
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ «Request Body»
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ 200
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ 200
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 404
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 409
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ «Request Body»
+
+
+
+ parameter1
+
+ 1
+
+
+
+ parameter2
+
+ 1
+
+
+
+ parameter3
+
+ 1
+
+
+
+ parameter4
+
+ 1
+
+
+
+ parameter5
+
+ 1
+
+
+
+ parameter6
+
+ 1
+
+
+
+ parameter7
+
+ 1
+
+
+
+ parameter8
+
+ 1
+
+
+
+ parameter9
+
+ 1
+
+
+
+ parameter10
+
+ 1
+
+
+
+ parameter11
+
+ 1
+
+
+
+ parameter12
+
+ 1
+
+
+
+ parameter13
+
+ 1
+
+
+
+ parameter14
+
+ 1
+
+
+
+ parameter15
+
+ 1
+
+
+
+ parameter16
+
+ 1
+
+
+
+ 200
+
+
+
+ 400
+
+
+
+ 401
+
+
+
+ 403
+
+
+
+ 405
+
+
+
+ 406
+
+
+
+ 408
+
+
+
+ 409
+
+
+
+ 429
+
+
+
+ 500
+
+
+
+ 503
+
+
+
+ «Request Body»
+
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/bookstore.svg b/src/docs/demos/bookstore.svg
index 03c3264d..432680c5 100644
--- a/src/docs/demos/bookstore.svg
+++ b/src/docs/demos/bookstore.svg
@@ -1,32 +1,371 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/ebay.svg b/src/docs/demos/ebay.svg
index 0cfd7056..c86b78ad 100644
--- a/src/docs/demos/ebay.svg
+++ b/src/docs/demos/ebay.svg
@@ -1,294 +1,4373 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/ecommerce.svg b/src/docs/demos/ecommerce.svg
index ac90b429..6052e383 100644
--- a/src/docs/demos/ecommerce.svg
+++ b/src/docs/demos/ecommerce.svg
@@ -1,113 +1,1341 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/news.svg b/src/docs/demos/news.svg
index 08256979..54f2ca6d 100644
--- a/src/docs/demos/news.svg
+++ b/src/docs/demos/news.svg
@@ -1,102 +1,1166 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/strava.svg b/src/docs/demos/strava.svg
index 0fd3681a..4e4c6336 100644
--- a/src/docs/demos/strava.svg
+++ b/src/docs/demos/strava.svg
@@ -1,328 +1,4616 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/demos/twitter.svg b/src/docs/demos/twitter.svg
index 2a354804..103e8adc 100644
--- a/src/docs/demos/twitter.svg
+++ b/src/docs/demos/twitter.svg
@@ -1,566 +1,6888 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/examples.md b/src/docs/examples.md
index 95cdb54b..9321c86b 100644
--- a/src/docs/examples.md
+++ b/src/docs/examples.md
@@ -1,142 +1,141 @@
## openapi-to-plantuml examples
+* [all-of-class-level.yml](../../src/test/resources/inputs/all-of-class-level.yml)
+
+
* [all-of-property-level.yml](../../src/test/resources/inputs/all-of-property-level.yml)
-* [request-body.yml](../../src/test/resources/inputs/request-body.yml)
-
-
-
-* [path-returns-ref-ref.yml](../../src/test/resources/inputs/path-returns-ref-ref.yml)
-
-
-
-* [path-returns-ref-ref2.yml](../../src/test/resources/inputs/path-returns-ref-ref2.yml)
+* [anon-nested-class-level.yml](../../src/test/resources/inputs/anon-nested-class-level.yml)
-
+
-* [request-body-ref-ref.yml](../../src/test/resources/inputs/request-body-ref-ref.yml)
+* [anon-property-not-required.yml](../../src/test/resources/inputs/anon-property-not-required.yml)
-
+
-* [parameter-anon-empty-object.yml](../../src/test/resources/inputs/parameter-anon-empty-object.yml)
+* [anon-property-required.yml](../../src/test/resources/inputs/anon-property-required.yml)
-
+
-* [anon-nested-class-level.yml](../../src/test/resources/inputs/anon-nested-class-level.yml)
+* [any-of-anon-class-level.yml](../../src/test/resources/inputs/any-of-anon-class-level.yml)
-
+
* [any-of-anon-property-level.yml](../../src/test/resources/inputs/any-of-anon-property-level.yml)
-* [simple-types-and-arrays.yml](../../src/test/resources/inputs/simple-types-and-arrays.yml)
-
-
-
-* [array-anon-class-level.yml](../../src/test/resources/inputs/array-anon-class-level.yml)
-
-
-
-* [parameter-ref-ref.yml](../../src/test/resources/inputs/parameter-ref-ref.yml)
+* [any-of-class-level.yml](../../src/test/resources/inputs/any-of-class-level.yml)
-
+
-* [simple-has-refs.yml](../../src/test/resources/inputs/simple-has-refs.yml)
+* [any-of-property-level.yml](../../src/test/resources/inputs/any-of-property-level.yml)
-
+
-* [array-property-level.yml](../../src/test/resources/inputs/array-property-level.yml)
+* [array-anon-class-level.yml](../../src/test/resources/inputs/array-anon-class-level.yml)
-
+
-* [petstore.yml](../../src/test/resources/inputs/petstore.yml)
+* [array-anon-property-level.yml](../../src/test/resources/inputs/array-anon-property-level.yml)
-
+
* [array-class-level.yml](../../src/test/resources/inputs/array-class-level.yml)
-* [anon-property-required.yml](../../src/test/resources/inputs/anon-property-required.yml)
-
-
-
-* [ref-class-level.yml](../../src/test/resources/inputs/ref-class-level.yml)
+* [array-property-level.yml](../../src/test/resources/inputs/array-property-level.yml)
-
+
-* [any-of-anon-class-level.yml](../../src/test/resources/inputs/any-of-anon-class-level.yml)
+* [empty.yml](../../src/test/resources/inputs/empty.yml)
-
+
* [one-of-class-level-empty.yml](../../src/test/resources/inputs/one-of-class-level-empty.yml)
+* [one-of-class-level.yml](../../src/test/resources/inputs/one-of-class-level.yml)
+
+
+
* [one-of-property-level-required.yml](../../src/test/resources/inputs/one-of-property-level-required.yml)
-* [all-of-class-level.yml](../../src/test/resources/inputs/all-of-class-level.yml)
+* [one-of-property-level.yml](../../src/test/resources/inputs/one-of-property-level.yml)
-
+
-* [any-of-class-level.yml](../../src/test/resources/inputs/any-of-class-level.yml)
+* [parameter-anon-empty-object.yml](../../src/test/resources/inputs/parameter-anon-empty-object.yml)
-
+
-* [petstore-expanded.yml](../../src/test/resources/inputs/petstore-expanded.yml)
+* [parameter-anon.yml](../../src/test/resources/inputs/parameter-anon.yml)
-
+
* [parameter-ref-complex.yml](../../src/test/resources/inputs/parameter-ref-complex.yml)
-* [empty.yml](../../src/test/resources/inputs/empty.yml)
+* [parameter-ref-ref.yml](../../src/test/resources/inputs/parameter-ref-ref.yml)
-
+
+
+* [parameter-ref.yml](../../src/test/resources/inputs/parameter-ref.yml)
+
+
* [path-returns-non-ref.yml](../../src/test/resources/inputs/path-returns-non-ref.yml)
-* [one-of-class-level.yml](../../src/test/resources/inputs/one-of-class-level.yml)
+* [path-returns-ref-ref.yml](../../src/test/resources/inputs/path-returns-ref-ref.yml)
-
+
-* [one-of-property-level.yml](../../src/test/resources/inputs/one-of-property-level.yml)
+* [path-returns-ref-ref2.yml](../../src/test/resources/inputs/path-returns-ref-ref2.yml)
-
+
* [path-returns-ref.yml](../../src/test/resources/inputs/path-returns-ref.yml)
-* [parameter-ref.yml](../../src/test/resources/inputs/parameter-ref.yml)
+* [petstore-expanded.yml](../../src/test/resources/inputs/petstore-expanded.yml)
-
+
-* [parameter-anon.yml](../../src/test/resources/inputs/parameter-anon.yml)
+* [petstore.yml](../../src/test/resources/inputs/petstore.yml)
-
+
-* [anon-property-not-required.yml](../../src/test/resources/inputs/anon-property-not-required.yml)
+* [ref-class-level.yml](../../src/test/resources/inputs/ref-class-level.yml)
-
+
-* [any-of-property-level.yml](../../src/test/resources/inputs/any-of-property-level.yml)
+* [request-body-ref-ref.yml](../../src/test/resources/inputs/request-body-ref-ref.yml)
-
+
* [request-body-ref.yml](../../src/test/resources/inputs/request-body-ref.yml)
-* [array-anon-property-level.yml](../../src/test/resources/inputs/array-anon-property-level.yml)
+* [request-body.yml](../../src/test/resources/inputs/request-body.yml)
+
+
+
+* [simple-has-refs.yml](../../src/test/resources/inputs/simple-has-refs.yml)
+
+
+
+* [simple-types-and-arrays.yml](../../src/test/resources/inputs/simple-types-and-arrays.yml)
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/docs/openapi-example.svg b/src/docs/openapi-example.svg
index 6fd41378..3ef87300 100644
--- a/src/docs/openapi-example.svg
+++ b/src/docs/openapi-example.svg
@@ -1,51 +1,714 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/all-of-class-level.puml.svg b/src/docs/tests/all-of-class-level.puml.svg
index 23d477c8..d5055289 100644
--- a/src/docs/tests/all-of-class-level.puml.svg
+++ b/src/docs/tests/all-of-class-level.puml.svg
@@ -1,9 +1,68 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/all-of-property-level.puml.svg b/src/docs/tests/all-of-property-level.puml.svg
index a96902cc..7cec2bd5 100644
--- a/src/docs/tests/all-of-property-level.puml.svg
+++ b/src/docs/tests/all-of-property-level.puml.svg
@@ -1,9 +1,74 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/amazon-s3.puml.svg b/src/docs/tests/amazon-s3.puml.svg
index 40289ecf..ae337b99 100644
--- a/src/docs/tests/amazon-s3.puml.svg
+++ b/src/docs/tests/amazon-s3.puml.svg
@@ -1,1343 +1,15015 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/anon-nested-class-level.puml.svg b/src/docs/tests/anon-nested-class-level.puml.svg
index 0767c721..f9a30f01 100644
--- a/src/docs/tests/anon-nested-class-level.puml.svg
+++ b/src/docs/tests/anon-nested-class-level.puml.svg
@@ -1,9 +1,81 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/anon-parameters.puml.svg b/src/docs/tests/anon-parameters.puml.svg
index 3dc73768..dde871c4 100644
--- a/src/docs/tests/anon-parameters.puml.svg
+++ b/src/docs/tests/anon-parameters.puml.svg
@@ -1,10 +1,97 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/anon-property-not-required.puml.svg b/src/docs/tests/anon-property-not-required.puml.svg
index 28a147eb..abd26526 100644
--- a/src/docs/tests/anon-property-not-required.puml.svg
+++ b/src/docs/tests/anon-property-not-required.puml.svg
@@ -1,7 +1,57 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/anon-property-required.puml.svg b/src/docs/tests/anon-property-required.puml.svg
index 23301fd0..dcbe9ad6 100644
--- a/src/docs/tests/anon-property-required.puml.svg
+++ b/src/docs/tests/anon-property-required.puml.svg
@@ -1,7 +1,57 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/any-of-anon-class-level.puml.svg b/src/docs/tests/any-of-anon-class-level.puml.svg
index 06f4e858..a8c96a9b 100644
--- a/src/docs/tests/any-of-anon-class-level.puml.svg
+++ b/src/docs/tests/any-of-anon-class-level.puml.svg
@@ -1,9 +1,68 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/any-of-anon-property-level.puml.svg b/src/docs/tests/any-of-anon-property-level.puml.svg
index 696fa53d..b404e8a6 100644
--- a/src/docs/tests/any-of-anon-property-level.puml.svg
+++ b/src/docs/tests/any-of-anon-property-level.puml.svg
@@ -1,10 +1,81 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/any-of-class-level.puml.svg b/src/docs/tests/any-of-class-level.puml.svg
index e5d63609..d03b9187 100644
--- a/src/docs/tests/any-of-class-level.puml.svg
+++ b/src/docs/tests/any-of-class-level.puml.svg
@@ -1,9 +1,62 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/any-of-property-level.puml.svg b/src/docs/tests/any-of-property-level.puml.svg
index 13c2778a..5c3e8c66 100644
--- a/src/docs/tests/any-of-property-level.puml.svg
+++ b/src/docs/tests/any-of-property-level.puml.svg
@@ -1,10 +1,75 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/array-anon-class-level.puml.svg b/src/docs/tests/array-anon-class-level.puml.svg
index 2b2f4f7d..863dc208 100644
--- a/src/docs/tests/array-anon-class-level.puml.svg
+++ b/src/docs/tests/array-anon-class-level.puml.svg
@@ -1,7 +1,50 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/array-anon-property-level.puml.svg b/src/docs/tests/array-anon-property-level.puml.svg
index 40e56d7e..a53b93c5 100644
--- a/src/docs/tests/array-anon-property-level.puml.svg
+++ b/src/docs/tests/array-anon-property-level.puml.svg
@@ -1,7 +1,53 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/array-class-level.puml.svg b/src/docs/tests/array-class-level.puml.svg
index a3712949..91009c36 100644
--- a/src/docs/tests/array-class-level.puml.svg
+++ b/src/docs/tests/array-class-level.puml.svg
@@ -1,7 +1,50 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/array-property-level.puml.svg b/src/docs/tests/array-property-level.puml.svg
index 87280e82..ffa0498f 100644
--- a/src/docs/tests/array-property-level.puml.svg
+++ b/src/docs/tests/array-property-level.puml.svg
@@ -1,7 +1,53 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/banking.puml.svg b/src/docs/tests/banking.puml.svg
index 24f9a908..a0664e33 100644
--- a/src/docs/tests/banking.puml.svg
+++ b/src/docs/tests/banking.puml.svg
@@ -1,217 +1,3329 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/bookstore.puml.svg b/src/docs/tests/bookstore.puml.svg
index 9d3333ec..4dd83ed3 100644
--- a/src/docs/tests/bookstore.puml.svg
+++ b/src/docs/tests/bookstore.puml.svg
@@ -1,22 +1,260 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/components-parameter-complex.puml.svg b/src/docs/tests/components-parameter-complex.puml.svg
index 71b0f531..ef7c233a 100644
--- a/src/docs/tests/components-parameter-complex.puml.svg
+++ b/src/docs/tests/components-parameter-complex.puml.svg
@@ -1,11 +1,105 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/components-parameter.puml.svg b/src/docs/tests/components-parameter.puml.svg
index e1b39f7d..a353e7f8 100644
--- a/src/docs/tests/components-parameter.puml.svg
+++ b/src/docs/tests/components-parameter.puml.svg
@@ -1,11 +1,102 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/ecommerce.puml.svg b/src/docs/tests/ecommerce.puml.svg
index 23f58f29..aedb28bf 100644
--- a/src/docs/tests/ecommerce.puml.svg
+++ b/src/docs/tests/ecommerce.puml.svg
@@ -1,89 +1,1053 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/empty.puml.svg b/src/docs/tests/empty.puml.svg
index 87103672..b24d1e86 100644
--- a/src/docs/tests/empty.puml.svg
+++ b/src/docs/tests/empty.puml.svg
@@ -1,13 +1,18 @@
-
\ No newline at end of file
+-->
+
\ No newline at end of file
diff --git a/src/docs/tests/one-of-class-level-empty.puml.svg b/src/docs/tests/one-of-class-level-empty.puml.svg
index 17fb93e9..7416942f 100644
--- a/src/docs/tests/one-of-class-level-empty.puml.svg
+++ b/src/docs/tests/one-of-class-level-empty.puml.svg
@@ -1,5 +1,26 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/one-of-class-level.puml.svg b/src/docs/tests/one-of-class-level.puml.svg
index e5d63609..d03b9187 100644
--- a/src/docs/tests/one-of-class-level.puml.svg
+++ b/src/docs/tests/one-of-class-level.puml.svg
@@ -1,9 +1,62 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/one-of-property-level-required.puml.svg b/src/docs/tests/one-of-property-level-required.puml.svg
index dc32b3ef..5a3ab57b 100644
--- a/src/docs/tests/one-of-property-level-required.puml.svg
+++ b/src/docs/tests/one-of-property-level-required.puml.svg
@@ -1,10 +1,75 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/one-of-property-level.puml.svg b/src/docs/tests/one-of-property-level.puml.svg
index 13c2778a..5c3e8c66 100644
--- a/src/docs/tests/one-of-property-level.puml.svg
+++ b/src/docs/tests/one-of-property-level.puml.svg
@@ -1,10 +1,75 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-all-of-class-level.puml.svg b/src/docs/tests/openapi-all-of-class-level.puml.svg
index 0ad05212..43828e09 100644
--- a/src/docs/tests/openapi-all-of-class-level.puml.svg
+++ b/src/docs/tests/openapi-all-of-class-level.puml.svg
@@ -1,9 +1,72 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-any-of-class-level.puml.svg b/src/docs/tests/openapi-any-of-class-level.puml.svg
index b1b856ea..405d931f 100644
--- a/src/docs/tests/openapi-any-of-class-level.puml.svg
+++ b/src/docs/tests/openapi-any-of-class-level.puml.svg
@@ -1,9 +1,66 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-any-of-property-level.puml.svg b/src/docs/tests/openapi-any-of-property-level.puml.svg
index a8e051df..44cacaf4 100644
--- a/src/docs/tests/openapi-any-of-property-level.puml.svg
+++ b/src/docs/tests/openapi-any-of-property-level.puml.svg
@@ -1,10 +1,79 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-one-of-class-level.puml.svg b/src/docs/tests/openapi-one-of-class-level.puml.svg
index b1b856ea..405d931f 100644
--- a/src/docs/tests/openapi-one-of-class-level.puml.svg
+++ b/src/docs/tests/openapi-one-of-class-level.puml.svg
@@ -1,9 +1,66 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-one-of-property-level.puml.svg b/src/docs/tests/openapi-one-of-property-level.puml.svg
index a8e051df..44cacaf4 100644
--- a/src/docs/tests/openapi-one-of-property-level.puml.svg
+++ b/src/docs/tests/openapi-one-of-property-level.puml.svg
@@ -1,10 +1,79 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/openapi-path-returns-non-ref.puml.svg b/src/docs/tests/openapi-path-returns-non-ref.puml.svg
index 81b0df61..64697fa7 100644
--- a/src/docs/tests/openapi-path-returns-non-ref.puml.svg
+++ b/src/docs/tests/openapi-path-returns-non-ref.puml.svg
@@ -1,9 +1,97 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: Java(TM) SE Runtime Environment
+JVM: Java HotSpot(TM) 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: US
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/parameter-anon-empty-object.puml.svg b/src/docs/tests/parameter-anon-empty-object.puml.svg
index ab928912..b7d6d92b 100644
--- a/src/docs/tests/parameter-anon-empty-object.puml.svg
+++ b/src/docs/tests/parameter-anon-empty-object.puml.svg
@@ -1,13 +1,113 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/parameter-anon.puml.svg b/src/docs/tests/parameter-anon.puml.svg
index 248182e5..c3ed274c 100644
--- a/src/docs/tests/parameter-anon.puml.svg
+++ b/src/docs/tests/parameter-anon.puml.svg
@@ -1,13 +1,127 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/parameter-ref-complex.puml.svg b/src/docs/tests/parameter-ref-complex.puml.svg
index 0252720c..a88958cf 100644
--- a/src/docs/tests/parameter-ref-complex.puml.svg
+++ b/src/docs/tests/parameter-ref-complex.puml.svg
@@ -1,11 +1,99 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/parameter-ref-ref.puml.svg b/src/docs/tests/parameter-ref-ref.puml.svg
index d9f98ecc..eed5058a 100644
--- a/src/docs/tests/parameter-ref-ref.puml.svg
+++ b/src/docs/tests/parameter-ref-ref.puml.svg
@@ -1,13 +1,113 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/parameter-ref.puml.svg b/src/docs/tests/parameter-ref.puml.svg
index 7edb6981..125888b6 100644
--- a/src/docs/tests/parameter-ref.puml.svg
+++ b/src/docs/tests/parameter-ref.puml.svg
@@ -1,11 +1,97 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/path-returns-non-ref.puml.svg b/src/docs/tests/path-returns-non-ref.puml.svg
index 4391d1c2..5d6f6f16 100644
--- a/src/docs/tests/path-returns-non-ref.puml.svg
+++ b/src/docs/tests/path-returns-non-ref.puml.svg
@@ -1,9 +1,95 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/path-returns-ref-ref.puml.svg b/src/docs/tests/path-returns-ref-ref.puml.svg
index 6e829abb..ea1dc8d7 100644
--- a/src/docs/tests/path-returns-ref-ref.puml.svg
+++ b/src/docs/tests/path-returns-ref-ref.puml.svg
@@ -1,11 +1,113 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/path-returns-ref-ref2.puml.svg b/src/docs/tests/path-returns-ref-ref2.puml.svg
index 25ba8f5d..eda62783 100644
--- a/src/docs/tests/path-returns-ref-ref2.puml.svg
+++ b/src/docs/tests/path-returns-ref-ref2.puml.svg
@@ -1,11 +1,112 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/path-returns-ref.puml.svg b/src/docs/tests/path-returns-ref.puml.svg
index 6bbbb286..ea5d641d 100644
--- a/src/docs/tests/path-returns-ref.puml.svg
+++ b/src/docs/tests/path-returns-ref.puml.svg
@@ -1,9 +1,95 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/petstore-expanded.puml.svg b/src/docs/tests/petstore-expanded.puml.svg
index 377300f6..878131cc 100644
--- a/src/docs/tests/petstore-expanded.puml.svg
+++ b/src/docs/tests/petstore-expanded.puml.svg
@@ -1,26 +1,274 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/petstore.puml.svg b/src/docs/tests/petstore.puml.svg
index 0cb4febc..cecbdf84 100644
--- a/src/docs/tests/petstore.puml.svg
+++ b/src/docs/tests/petstore.puml.svg
@@ -1,18 +1,186 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/ref-class-level.puml.svg b/src/docs/tests/ref-class-level.puml.svg
index d8c90e9d..0921299f 100644
--- a/src/docs/tests/ref-class-level.puml.svg
+++ b/src/docs/tests/ref-class-level.puml.svg
@@ -1,7 +1,50 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/request-body-empty.puml.svg b/src/docs/tests/request-body-empty.puml.svg
index 4396aee4..5beff964 100644
--- a/src/docs/tests/request-body-empty.puml.svg
+++ b/src/docs/tests/request-body-empty.puml.svg
@@ -1,5 +1,26 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/request-body-ref-ref.puml.svg b/src/docs/tests/request-body-ref-ref.puml.svg
index 642ac0ce..9643ce64 100644
--- a/src/docs/tests/request-body-ref-ref.puml.svg
+++ b/src/docs/tests/request-body-ref-ref.puml.svg
@@ -1,13 +1,140 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/request-body-ref.puml.svg b/src/docs/tests/request-body-ref.puml.svg
index 999a051e..7bae92b0 100644
--- a/src/docs/tests/request-body-ref.puml.svg
+++ b/src/docs/tests/request-body-ref.puml.svg
@@ -1,11 +1,120 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/request-body.puml.svg b/src/docs/tests/request-body.puml.svg
index 9c749f68..ac05ef4e 100644
--- a/src/docs/tests/request-body.puml.svg
+++ b/src/docs/tests/request-body.puml.svg
@@ -1,11 +1,120 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/simple-has-refs.puml.svg b/src/docs/tests/simple-has-refs.puml.svg
index 948995d6..6beeb684 100644
--- a/src/docs/tests/simple-has-refs.puml.svg
+++ b/src/docs/tests/simple-has-refs.puml.svg
@@ -1,9 +1,82 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/docs/tests/simple-types-and-arrays.puml.svg b/src/docs/tests/simple-types-and-arrays.puml.svg
index 9e34e565..954e2d78 100644
--- a/src/docs/tests/simple-types-and-arrays.puml.svg
+++ b/src/docs/tests/simple-types-and-arrays.puml.svg
@@ -1,5 +1,72 @@
-
\ No newline at end of file
+
+PlantUML version 1.2021.2(Sun Mar 07 22:10:27 AEDT 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: en
+Country: AU
+-->
+
+
\ No newline at end of file
diff --git a/src/main/checkstyle/checkstyle.xml b/src/main/checkstyle/checkstyle.xml
index 1e21cd02..48e8cee9 100644
--- a/src/main/checkstyle/checkstyle.xml
+++ b/src/main/checkstyle/checkstyle.xml
@@ -1,7 +1,7 @@
+ "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+ "https://checkstyle.org/dtds/configuration_1_3.dtd">
+ default="checkstyle-suppressions.xml"/>
@@ -62,7 +62,7 @@
-
+
@@ -72,21 +72,21 @@
-
-
+
+
-
+
-
-
-
-
+
+
+
+
@@ -103,9 +103,9 @@
-
+
-
+
@@ -121,7 +121,7 @@
-
+
@@ -130,8 +130,8 @@
-
-
+
+
@@ -143,8 +143,8 @@
-
-
+
+
@@ -163,10 +163,10 @@
-
+
-
+
@@ -183,14 +183,14 @@
-
+
+ default="checkstyle-xpath-suppressions.xml"/>
diff --git a/src/main/checkstyle/suppressions.xml b/src/main/checkstyle/suppressions.xml
index edd94863..aba78149 100644
--- a/src/main/checkstyle/suppressions.xml
+++ b/src/main/checkstyle/suppressions.xml
@@ -1,12 +1,12 @@
+ "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+ "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+ files="src[\\/]test[\\/]java[\\/]"/>
+ files="src[\\/]test[\\/]java[\\/]"/>
\ No newline at end of file
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/Common.java b/src/main/java/com/github/davidmoten/oas3/internal/Common.java
index fc925962..36ef0ae3 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/Common.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/Common.java
@@ -1,324 +1,429 @@
package com.github.davidmoten.oas3.internal;
-import static java.util.Collections.emptyList;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
import com.github.davidmoten.guavamini.Preconditions;
-import com.github.davidmoten.oas3.internal.model.Association;
-import com.github.davidmoten.oas3.internal.model.AssociationType;
import com.github.davidmoten.oas3.internal.model.Class;
-import com.github.davidmoten.oas3.internal.model.ClassType;
-import com.github.davidmoten.oas3.internal.model.Field;
-import com.github.davidmoten.oas3.internal.model.Inheritance;
-import com.github.davidmoten.oas3.internal.model.Model;
-import com.github.davidmoten.oas3.internal.model.Relationship;
-import com.github.davidmoten.oas3.internal.model.SimpleType;
+import com.github.davidmoten.oas3.internal.model.*;
+import io.swagger.v3.oas.models.media.*;
-import io.swagger.v3.oas.models.media.ArraySchema;
-import io.swagger.v3.oas.models.media.BinarySchema;
-import io.swagger.v3.oas.models.media.BooleanSchema;
-import io.swagger.v3.oas.models.media.ByteArraySchema;
-import io.swagger.v3.oas.models.media.ComposedSchema;
-import io.swagger.v3.oas.models.media.DateSchema;
-import io.swagger.v3.oas.models.media.DateTimeSchema;
-import io.swagger.v3.oas.models.media.EmailSchema;
-import io.swagger.v3.oas.models.media.FileSchema;
-import io.swagger.v3.oas.models.media.IntegerSchema;
-import io.swagger.v3.oas.models.media.MapSchema;
-import io.swagger.v3.oas.models.media.NumberSchema;
-import io.swagger.v3.oas.models.media.ObjectSchema;
-import io.swagger.v3.oas.models.media.PasswordSchema;
-import io.swagger.v3.oas.models.media.Schema;
-import io.swagger.v3.oas.models.media.StringSchema;
-import io.swagger.v3.oas.models.media.UUIDSchema;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static java.util.Collections.emptyList;
final class Common {
- private Common() {
- // prevent instantiation
- }
+ private static final Set SIMPLE_TYPES_WITHOUT_BRACKETS = Arrays.stream(SimpleType.values()) //
+ .map(x -> x.toString()
+ .replace("[]",
+ "")) //
+ .collect(Collectors.toSet());
- private static final Set SIMPLE_TYPES_WITHOUT_BRACKETS = Arrays
- .stream(SimpleType.values()) //
- .map(x -> x.toString().replace("[]", "")) //
- .collect(Collectors.toSet());
+ private Common() {
+ // prevent instantiation
+ }
- static Model toModelClass(String name, Schema> schema, Names names, ClassType classType) {
- List fields = new ArrayList<>();
+ static Model toModelClass(String name,
+ Schema> schema,
+ Names names,
+ ClassType classType) {
+ List fields = new ArrayList<>();
- List relationships = new ArrayList<>();
- List classes = new ArrayList<>();
- if (schema.get$ref() != null) {
- // this is an alias case for a schema
- String otherClassName = names.refToClassName(schema.get$ref());
- relationships.add(Association.from(name).to(otherClassName).one().build());
- } else if (schema instanceof ComposedSchema) {
- ComposedSchema s = (ComposedSchema) schema;
- if (s.getOneOf() != null) {
- addInheritance(classes, relationships, name, s.getOneOf(), names);
- } else if (s.getAnyOf() != null) {
- addInheritance(classes, relationships, name, s.getAnyOf(), names);
- } else if (s.getAllOf() != null) {
- addMixedTypeAll(classes, relationships, name, s.getAllOf(), null, names);
- } else {
- throw new RuntimeException("unexpected");
- }
- } else if (schema.getProperties() != null) {
- final Set required;
- if (schema.getRequired() != null) {
- required = new HashSet<>(schema.getRequired());
- } else {
- required = Collections.emptySet();
- }
- schema.getProperties().entrySet().forEach(entry -> {
- String property = entry.getKey();
- Schema> sch = entry.getValue();
- if (sch instanceof ComposedSchema) {
- ComposedSchema s = (ComposedSchema) sch;
- @SuppressWarnings("rawtypes")
- final List list;
- final AssociationType associationType;
- boolean req = required.contains(property);
- boolean isAll = false;
- if (s.getOneOf() != null) {
- list = s.getOneOf();
- associationType = req ? AssociationType.ONE : AssociationType.ZERO_ONE;
- } else if (s.getAnyOf() != null) {
- list = s.getAnyOf();
- associationType = req ? AssociationType.ONE : AssociationType.ZERO_ONE;
- } else if (s.getAllOf() != null) {
- list = s.getAllOf();
- isAll = true;
- associationType = null;
- } else {
- // don't expect this path but be defensive
- list = emptyList();
- associationType = null;
- }
- if (!list.isEmpty()) {
- if (isAll) {
- addMixedTypeAll(classes, relationships, name, list, property, names);
- } else {
- addInheritanceForProperty(classes, relationships, name, list, property,
- associationType, names);
- }
- }
- } else if (sch.get$ref() != null) {
- String ref = sch.get$ref();
- String otherClassName = names.refToClassName(ref);
- addToOne(relationships, name, otherClassName, property,
- required.contains(entry.getKey()));
- } else {
- Optional t = getUmlTypeName(sch, names);
- if (t.isPresent()) {
- String type = t.get();
- if (isComplexArrayType(type)) {
- addArray(name, classes, relationships, property, (ArraySchema) sch,
- names);
- } else if (type.equals("object")) {
- // create anon class
- String otherClassName = names.nextClassName(name + "." + property);
- Model m = toModelClass(otherClassName, sch, names, classType);
- classes.addAll(m.classes());
- relationships.addAll(m.relationships());
- addToOne(relationships, name, otherClassName, property,
- required.contains(property));
- } else {
- fields.add(new Field(entry.getKey(), type, type.endsWith("]"),
- required.contains(entry.getKey())));
- }
- }
- }
- });
- } else if (schema instanceof ArraySchema) {
- ArraySchema a = (ArraySchema) schema;
- Schema> items = a.getItems();
- String ref = items.get$ref();
- String otherClassName;
- if (ref != null) {
- otherClassName = names.refToClassName(ref);
- } else {
- // create anon class
- otherClassName = names.nextClassName(name);
- Model m = toModelClass(otherClassName, items, names, classType);
- classes.addAll(m.classes());
- relationships.addAll(m.relationships());
- }
- addToMany(relationships, name, otherClassName);
- } else if (!(schema instanceof ObjectSchema)) {
- // has no properties so ignore ObjectSchema
- Optional t = getUmlTypeName(schema, names);
- if (t.isPresent()) {
- String type = t.get();
- fields.add(new Field("value", type, type.endsWith("]"), true));
- }
- }
- classes.add(new Class(name, classType, fields));
- return new Model(classes, relationships);
- }
+ List relationships = new ArrayList<>();
+ List classes = new ArrayList<>();
+ if (schema.get$ref() != null) {
+ // this is an alias case for a schema
+ String otherClassName = names.refToClassName(schema.get$ref());
+ relationships.add(Association.from(name)
+ .to(otherClassName)
+ .one()
+ .build());
+ } else if (schema instanceof ComposedSchema) {
+ ComposedSchema s = (ComposedSchema) schema;
+ if (s.getOneOf() != null) {
+ addInheritance(classes,
+ relationships,
+ name,
+ s.getOneOf(),
+ names);
+ } else if (s.getAnyOf() != null) {
+ addInheritance(classes,
+ relationships,
+ name,
+ s.getAnyOf(),
+ names);
+ } else if (s.getAllOf() != null) {
+ addMixedTypeAll(classes,
+ relationships,
+ name,
+ s.getAllOf(),
+ null,
+ names);
+ } else {
+ throw new RuntimeException("unexpected");
+ }
+ } else if (schema.getProperties() != null) {
+ final Set required;
+ if (schema.getRequired() != null) {
+ required = new HashSet<>(schema.getRequired());
+ } else {
+ required = Collections.emptySet();
+ }
+ schema.getProperties()
+ .entrySet()
+ .forEach(entry -> {
+ String property = entry.getKey();
+ Schema> sch = entry.getValue();
+ if (sch instanceof ComposedSchema) {
+ ComposedSchema s = (ComposedSchema) sch;
+ @SuppressWarnings("rawtypes") final List list;
+ final AssociationType associationType;
+ boolean req = required.contains(property);
+ boolean isAll = false;
+ if (s.getOneOf() != null) {
+ list = s.getOneOf();
+ associationType = req
+ ? AssociationType.ONE
+ : AssociationType.ZERO_ONE;
+ } else if (s.getAnyOf() != null) {
+ list = s.getAnyOf();
+ associationType = req
+ ? AssociationType.ONE
+ : AssociationType.ZERO_ONE;
+ } else if (s.getAllOf() != null) {
+ list = s.getAllOf();
+ isAll = true;
+ associationType = null;
+ } else {
+ // don't expect this path but be defensive
+ list = emptyList();
+ associationType = null;
+ }
+ if (!list.isEmpty()) {
+ if (isAll) {
+ addMixedTypeAll(classes,
+ relationships,
+ name,
+ list,
+ property,
+ names);
+ } else {
+ addInheritanceForProperty(classes,
+ relationships,
+ name,
+ list,
+ property,
+ associationType,
+ names);
+ }
+ }
+ } else if (sch.get$ref() != null) {
+ String ref = sch.get$ref();
+ String otherClassName = names.refToClassName(ref);
+ addToOne(relationships,
+ name,
+ otherClassName,
+ property,
+ required.contains(entry.getKey()));
+ } else {
+ Optional t = getUmlTypeName(sch,
+ names);
+ if (t.isPresent()) {
+ String type = t.get();
+ if (isComplexArrayType(type)) {
+ addArray(name,
+ classes,
+ relationships,
+ property,
+ (ArraySchema) sch,
+ names);
+ } else if (type.equals("object")) {
+ // create anon class
+ String otherClassName = names.nextClassName(name + "." + property);
+ Model m = toModelClass(otherClassName,
+ sch,
+ names,
+ classType);
+ classes.addAll(m.classes());
+ relationships.addAll(m.relationships());
+ addToOne(relationships,
+ name,
+ otherClassName,
+ property,
+ required.contains(property));
+ } else {
+ fields.add(new Field(entry.getKey(),
+ type,
+ type.endsWith("]"),
+ required.contains(entry.getKey())));
+ }
+ }
+ }
+ });
+ } else if (schema instanceof ArraySchema) {
+ ArraySchema a = (ArraySchema) schema;
+ Schema> items = a.getItems();
+ String ref = items.get$ref();
+ String otherClassName;
+ if (ref != null) {
+ otherClassName = names.refToClassName(ref);
+ } else {
+ // create anon class
+ otherClassName = names.nextClassName(name);
+ Model m = toModelClass(otherClassName,
+ items,
+ names,
+ classType);
+ classes.addAll(m.classes());
+ relationships.addAll(m.relationships());
+ }
+ addToMany(relationships,
+ name,
+ otherClassName);
+ } else if (!(schema instanceof ObjectSchema)) {
+ // has no properties so ignore ObjectSchema
+ Optional t = getUmlTypeName(schema,
+ names);
+ if (t.isPresent()) {
+ String type = t.get();
+ fields.add(new Field("value",
+ type,
+ type.endsWith("]"),
+ true));
+ }
+ }
+ classes.add(new Class(name,
+ classType,
+ fields));
+ return new Model(classes,
+ relationships);
+ }
- private static boolean isComplexArrayType(String type) {
- return type.endsWith("[]") && !isSimpleType(type);
- }
+ private static boolean isComplexArrayType(String type) {
+ return type.endsWith("[]") && !isSimpleType(type);
+ }
- static boolean isSimpleType(String s) {
- return SIMPLE_TYPES_WITHOUT_BRACKETS.contains(s.replace("[", "").replace("]", ""));
- }
+ static boolean isSimpleType(String s) {
+ return SIMPLE_TYPES_WITHOUT_BRACKETS.contains(s.replace("[",
+ "")
+ .replace("]",
+ ""));
+ }
- private static void addArray(String name, List classes, List relationships,
- String property, ArraySchema a, Names names) {
- Preconditions.checkNotNull(property);
- // is array of items
- Schema> items = a.getItems();
- String ref = items.get$ref();
- final String otherClassName;
- if (ref != null) {
- otherClassName = names.refToClassName(ref);
- } else {
- // create anon class
- otherClassName = names.nextClassName(name + "." + property);
- Model m = toModelClass(otherClassName, items, names, ClassType.SCHEMA);
- classes.addAll(m.classes());
- relationships.addAll(m.relationships());
- }
- addToMany(relationships, name, otherClassName, property);
- }
+ private static void addArray(String name,
+ List classes,
+ List relationships,
+ String property,
+ ArraySchema a,
+ Names names) {
+ Preconditions.checkNotNull(property);
+ // is array of items
+ Schema> items = a.getItems();
+ String ref = items.get$ref();
+ final String otherClassName;
+ if (ref != null) {
+ otherClassName = names.refToClassName(ref);
+ } else {
+ // create anon class
+ otherClassName = names.nextClassName(name + "." + property);
+ Model m = toModelClass(otherClassName,
+ items,
+ names,
+ ClassType.SCHEMA);
+ classes.addAll(m.classes());
+ relationships.addAll(m.relationships());
+ }
+ addToMany(relationships,
+ name,
+ otherClassName,
+ property);
+ }
- private static void addMixedTypeAll(List classes, List relationships,
- String name, @SuppressWarnings("rawtypes") List schemas, String propertyName,
- Names names) {
- List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
- relationships, name, schemas, names, propertyName);
- for (String otherClassName : otherClassNames) {
- addToOne(relationships, name, otherClassName, propertyName, true);
- }
- }
+ private static void addMixedTypeAll(List classes,
+ List relationships,
+ String name,
+ @SuppressWarnings("rawtypes") List schemas,
+ String propertyName,
+ Names names) {
+ List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
+ relationships,
+ name,
+ schemas,
+ names,
+ propertyName);
+ for (String otherClassName : otherClassNames) {
+ addToOne(relationships,
+ name,
+ otherClassName,
+ propertyName,
+ true);
+ }
+ }
- private static void addInheritanceForProperty(List classes,
- List relationships, String name,
- @SuppressWarnings("rawtypes") List schemas, String propertyName,
- AssociationType associationType, Names names) {
- List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
- relationships, name, schemas, names, propertyName);
- Inheritance inheritance = new Inheritance(name, otherClassNames, associationType,
- Optional.of(propertyName));
- relationships.add(inheritance);
- }
+ private static void addInheritanceForProperty(List classes,
+ List relationships,
+ String name,
+ @SuppressWarnings("rawtypes") List schemas,
+ String propertyName,
+ AssociationType associationType,
+ Names names) {
+ List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
+ relationships,
+ name,
+ schemas,
+ names,
+ propertyName);
+ Inheritance inheritance = new Inheritance(name,
+ otherClassNames,
+ associationType,
+ Optional.of(propertyName));
+ relationships.add(inheritance);
+ }
- private static void addInheritance(List classes, List relationships,
- String name, @SuppressWarnings("rawtypes") List schemas, Names names) {
- List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
- relationships, name, schemas, names, null);
- relationships
- .add(new Inheritance(name, otherClassNames, AssociationType.ONE, Optional.empty()));
- }
+ private static void addInheritance(List classes,
+ List relationships,
+ String name,
+ @SuppressWarnings("rawtypes") List schemas,
+ Names names) {
+ List otherClassNames = addAnonymousClassesAndReturnOtherClassNames(classes,
+ relationships,
+ name,
+ schemas,
+ names,
+ null);
+ relationships.add(new Inheritance(name,
+ otherClassNames,
+ AssociationType.ONE,
+ Optional.empty()));
+ }
- private static List addAnonymousClassesAndReturnOtherClassNames(List classes,
- List relationships, String name,
- @SuppressWarnings("rawtypes") List schemas, Names names, String property) {
- List otherClassNames = schemas.stream() //
- .map(s -> {
- if (s.get$ref() != null) {
- return names.refToClassName(s.get$ref());
- } else {
- String className = names
- .nextClassName(name + (property == null ? "" : "." + property));
- Model m = toModelClass(className, s, names, ClassType.SCHEMA);
- classes.addAll(m.classes());
- relationships.addAll(m.relationships());
- return className;
- }
- }).collect(Collectors.toList());
- return otherClassNames;
- }
+ private static List addAnonymousClassesAndReturnOtherClassNames(List classes,
+ List relationships,
+ String name,
+ @SuppressWarnings("rawtypes")
+ List schemas,
+ Names names,
+ String property) {
+ List otherClassNames = schemas.stream() //
+ .map(s -> {
+ if (s.get$ref() != null) {
+ return names.refToClassName(s.get$ref());
+ } else {
+ String className = names.nextClassName(name + (property == null
+ ? ""
+ : "." + property));
+ Model m = toModelClass(className,
+ s,
+ names,
+ ClassType.SCHEMA);
+ classes.addAll(m.classes());
+ relationships.addAll(m.relationships());
+ return className;
+ }
+ })
+ .collect(Collectors.toList());
+ return otherClassNames;
+ }
- private static void addToMany(List relationships, String name,
- String otherClassName) {
- addToMany(relationships, name, otherClassName, null);
- }
+ private static void addToMany(List relationships,
+ String name,
+ String otherClassName) {
+ addToMany(relationships,
+ name,
+ otherClassName,
+ null);
+ }
- private static void addToMany(List relationships, String name,
- String otherClassName, String property) {
- relationships.add(Association.from(name).to(otherClassName).many()
- .propertyOrParameterName(Optional.ofNullable(property)).build());
- }
+ private static void addToMany(List relationships,
+ String name,
+ String otherClassName,
+ String property) {
+ relationships.add(Association.from(name)
+ .to(otherClassName)
+ .many()
+ .propertyOrParameterName(Optional.ofNullable(property))
+ .build());
+ }
- private static void addToOne(List relationships, String name,
- String otherClassName, String property, boolean isToOne) {
- relationships.add(Association //
- .from(name) //
- .to(otherClassName) //
- .type(isToOne ? AssociationType.ONE : AssociationType.ZERO_ONE) //
- .propertyOrParameterName(//
- property == null || property.equals(otherClassName) ? Optional.empty()
- : Optional.of(property))
- .build());
- }
+ private static void addToOne(List relationships,
+ String name,
+ String otherClassName,
+ String property,
+ boolean isToOne) {
+ relationships.add(Association //
+ .from(name) //
+ .to(otherClassName) //
+ .type(isToOne
+ ? AssociationType.ONE
+ : AssociationType.ZERO_ONE) //
+ .propertyOrParameterName(//
+ property == null || property.equals(otherClassName)
+ ? Optional.empty()
+ : Optional.of(property))
+ .build());
+ }
- private static Optional getUmlTypeName(Schema> schema, Names names) {
- return getUmlTypeName(schema.get$ref(), schema, names);
- }
+ private static Optional getUmlTypeName(Schema> schema,
+ Names names) {
+ return getUmlTypeName(schema.get$ref(),
+ schema,
+ names);
+ }
- static Optional getUmlTypeName(String ref, Schema> schema, Names names) {
- final String type;
- if (ref != null) {
- type = names.refToClassName(ref);
- } else if (schema == null) {
- type = null;
- } else if (schema instanceof StringSchema) {
- type = "string";
- } else if (schema instanceof BooleanSchema) {
- type = "boolean";
- } else if (schema instanceof DateTimeSchema) {
- type = "timestamp";
- } else if (schema instanceof DateSchema) {
- type = "date";
- } else if (schema instanceof NumberSchema) {
- type = "decimal";
- } else if (schema instanceof IntegerSchema) {
- type = "integer";
- } else if (schema instanceof ArraySchema) {
- ArraySchema a = (ArraySchema) schema;
- type = getUmlTypeName(a.getItems(), names) //
- .orElseThrow(() -> new RuntimeException("unexpected")) + "[]";
- } else if (schema instanceof BinarySchema) {
- type = "byte[]";
- } else if (schema instanceof ByteArraySchema) {
- type = "byte[]";
- } else if (schema instanceof ObjectSchema) {
- type = "object";
- } else if (schema instanceof FileSchema) {
- type = "string";
- } else if (schema instanceof PasswordSchema) {
- type = "string";
- } else if (schema instanceof EmailSchema) {
- type = "string";
- } else if (schema instanceof UUIDSchema) {
- type = "string";
- } else if (schema instanceof MapSchema) {
- // TODO handle MapSchema
- type = "map";
- } else if (schema instanceof ComposedSchema) {
- // TODO handle ComposedSchema
- type = "string";
- } else if ("string".equals(schema.getType())) {
- type = "string";
- } else if (schema.get$ref() != null) {
- type = names.refToClassName(schema.get$ref());
- } else if (schema.getType() == null) {
- type = null;
- } else {
- throw new RuntimeException("not expected" + schema);
- }
- return Optional.ofNullable(type);
- }
+ static Optional getUmlTypeName(String ref,
+ Schema> schema,
+ Names names) {
+ final String type;
+ if (ref != null) {
+ type = names.refToClassName(ref);
+ } else if (schema == null) {
+ type = null;
+ } else if (schema instanceof StringSchema) {
+ type = "string";
+ } else if (schema instanceof BooleanSchema) {
+ type = "boolean";
+ } else if (schema instanceof DateTimeSchema) {
+ type = "timestamp";
+ } else if (schema instanceof DateSchema) {
+ type = "date";
+ } else if (schema instanceof NumberSchema) {
+ type = "decimal";
+ } else if (schema instanceof IntegerSchema) {
+ type = "integer";
+ } else if (schema instanceof ArraySchema) {
+ ArraySchema a = (ArraySchema) schema;
+ type = getUmlTypeName(a.getItems(),
+ names) //
+ .orElseThrow(() -> new RuntimeException("unexpected")) + "[]";
+ } else if (schema instanceof BinarySchema) {
+ type = "byte[]";
+ } else if (schema instanceof ByteArraySchema) {
+ type = "byte[]";
+ } else if (schema instanceof ObjectSchema) {
+ type = "object";
+ } else if (schema instanceof FileSchema) {
+ type = "string";
+ } else if (schema instanceof PasswordSchema) {
+ type = "string";
+ } else if (schema instanceof EmailSchema) {
+ type = "string";
+ } else if (schema instanceof UUIDSchema) {
+ type = "string";
+ } else if (schema instanceof MapSchema) {
+ // TODO handle MapSchema
+ type = "map";
+ } else if (schema instanceof ComposedSchema) {
+ // TODO handle ComposedSchema
+ type = "string";
+ } else if ("string".equals(schema.getType())) {
+ type = "string";
+ } else if (schema.get$ref() != null) {
+ type = names.refToClassName(schema.get$ref());
+ } else if (schema.getType() == null) {
+ type = null;
+ } else {
+ throw new RuntimeException("not expected" + schema);
+ }
+ return Optional.ofNullable(type);
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/ComponentsHelper.java b/src/main/java/com/github/davidmoten/oas3/internal/ComponentsHelper.java
index f5a17b63..99dfe129 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/ComponentsHelper.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/ComponentsHelper.java
@@ -1,78 +1,127 @@
package com.github.davidmoten.oas3.internal;
-import static com.github.davidmoten.oas3.internal.Util.first;
-import static com.github.davidmoten.oas3.internal.Util.nullMapToEmpty;
-
import com.github.davidmoten.oas3.internal.model.Association;
import com.github.davidmoten.oas3.internal.model.Class;
import com.github.davidmoten.oas3.internal.model.ClassType;
import com.github.davidmoten.oas3.internal.model.Model;
-
+import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+
+import java.util.Map;
+
+import static com.github.davidmoten.oas3.internal.Util.first;
+import static com.github.davidmoten.oas3.internal.Util.nullMapToEmpty;
public final class ComponentsHelper {
- private ComponentsHelper() {
- // prevent instantiation
- }
+ private ComponentsHelper() {
+ // prevent instantiation
+ }
+
+ public static Model toModel(Names names) {
+ Model part1 = names.schemas() //
+ .entrySet() //
+ .stream() //
+ .map(entry -> Common.toModelClass(names.schemaClassName(entry.getKey()),
+ entry.getValue(),
+ names,
+ ClassType.SCHEMA)) //
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
+
+ Model part2 = names.requestBodies() //
+ .entrySet() //
+ .stream() //
+ .map(entry -> {
+ RequestBody b = entry.getValue();
+ String className = names.requestBodyClassName(b);
+ String ref = b.get$ref();
+ if (ref != null) {
+ String otherClassName = names.refToClassName(ref);
+ Class c = new Class(className,
+ ClassType.REQUEST_BODY);
+ Association a = Association.from(className)
+ .to(otherClassName)
+ .one()
+ .build();
+ return new Model(c,
+ a);
+ } else {
+ return Common.toModelClass(names.requestBodyClassName(entry.getKey()),
+ first(entry.getValue()
+ .getContent()).get()
+ .getValue()
+ .getSchema(),
+ names,
+ ClassType.REQUEST_BODY);
+ }
+ }) //
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
- public static Model toModel(Names names) {
- Model part1 = names.schemas() //
- .entrySet() //
- .stream() //
- .map(entry -> Common.toModelClass(names.schemaClassName(entry.getKey()), entry.getValue(), names,
- ClassType.SCHEMA)) //
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
+ Model part3 = names.parameters() //
+ .entrySet() //
+ .stream() //
+ .map(entry -> {
+ Parameter p = entry.getValue();
+ String className = names.parameterClassName(p);
+ String ref = p.get$ref();
+ if (ref != null) {
+ Class c = new Class(className,
+ ClassType.PARAMETER);
+ String otherClassName = names.refToClassName(ref);
+ Association a = Association.from(className)
+ .to(otherClassName)
+ .one()
+ .build();
+ return new Model(c,
+ a);
+ } else {
+ return Common.toModelClass(className,
+ p.getSchema(),
+ names,
+ ClassType.PARAMETER);
+ }
+ }) //
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
- Model part2 = names.requestBodies() //
- .entrySet() //
- .stream() //
- .map(entry -> {
- RequestBody b = entry.getValue();
- String className = names.requestBodyClassName(b);
- String ref = b.get$ref();
- if (ref != null) {
- String otherClassName = names.refToClassName(ref);
- Class c = new Class(className, ClassType.REQUEST_BODY);
- Association a = Association.from(className).to(otherClassName).one().build();
- return new Model(c, a);
- } else {
- return Common.toModelClass(names.requestBodyClassName(entry.getKey()),
- first(entry.getValue().getContent()).get().getValue().getSchema(), names,
- ClassType.REQUEST_BODY);
- }
- }) //
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
+ Model part4 = names.responses()
+ .entrySet()
+ .stream()
+ // TODO handle ref responses as per parameters and request bodies above
+ .map(entry -> first(nullMapToEmpty(entry.getValue()
+ .getContent())).map(x -> toModelClass(names,
+ entry,
+ x))
+ .orElse(toNewModelClass(names,
+ entry)))
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
+ return part1.add(part2)
+ .add(part3)
+ .add(part4);
+ }
- Model part3 = names.parameters() //
- .entrySet() //
- .stream() //
- .map(entry -> {
- Parameter p = entry.getValue();
- String className = names.parameterClassName(p);
- String ref = p.get$ref();
- if (ref != null) {
- Class c = new Class(className, ClassType.PARAMETER);
- String otherClassName = names.refToClassName(ref);
- Association a = Association.from(className).to(otherClassName).one().build();
- return new Model(c, a);
- } else {
- return Common.toModelClass(className, p.getSchema(), names, ClassType.PARAMETER);
- }
- }) //
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
+ private static Model toNewModelClass(Names names,
+ Map.Entry entry) {
+ Class responseClass = new Class(names.responseClassName(entry.getKey()),
+ ClassType.RESPONSE);
+ Model model = new Model(responseClass);
+ return model;
+ }
- Model part4 = names.responses() //
- .entrySet() //
- .stream() //
- // TODO handle ref responses as per parameters and request bodies above
- .map(entry -> first(nullMapToEmpty(entry.getValue().getContent())) //
- .map(x -> Common.toModelClass(names.responseClassName(entry.getKey()), x.getValue().getSchema(),
- names, ClassType.RESPONSE)) //
- .orElse(new Model(new Class(names.responseClassName(entry.getKey()), ClassType.RESPONSE)))) //
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
- return part1.add(part2).add(part3).add(part4);
- }
+ private static Model toModelClass(Names names,
+ Map.Entry entry,
+ Map.Entry x) {
+ Model model = Common.toModelClass(names.responseClassName(entry.getKey()),
+ x.getValue()
+ .getSchema(),
+ names,
+ ClassType.RESPONSE);
+ return model;
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/Names.java b/src/main/java/com/github/davidmoten/oas3/internal/Names.java
index 8175c1ef..b2ecd991 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/Names.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/Names.java
@@ -1,17 +1,7 @@
package com.github.davidmoten.oas3.internal;
-import static com.github.davidmoten.oas3.internal.Util.nullMapToEmpty;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import com.github.davidmoten.guavamini.Preconditions;
import com.github.davidmoten.guavamini.Sets;
-
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Paths;
@@ -20,148 +10,174 @@
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
+import java.util.*;
+
+import static com.github.davidmoten.oas3.internal.Util.nullMapToEmpty;
+
public final class Names {
- private static final String EMPTY_RESPONSE_CLASS_NAME = "Empty Response";
- private final Map refClassNames = new HashMap<>();
- private final Set classNames = Sets.newHashSet(EMPTY_RESPONSE_CLASS_NAME);
- private final OpenAPI openapi;
-
- public Names(OpenAPI a) {
- Components components = a.getComponents();
- this.openapi = a;
- if (components != null) {
- // resolve name clashes
- nullMapToEmpty(components.getSchemas()).keySet().forEach(name -> {
- String className = nextClassName(classNames, name);
- refClassNames.put("#/components/schemas/" + name, className);
- });
- nullMapToEmpty(components.getRequestBodies()).keySet().forEach(name -> {
- String className = nextClassName(classNames, name);
- refClassNames.put("#/components/requestBodies/" + name, className);
- });
- nullMapToEmpty(components.getParameters()).keySet().forEach(name -> {
- String className = nextClassName(classNames, name);
- refClassNames.put("#/components/parameters/" + name, className);
- });
- nullMapToEmpty(components.getResponses()).keySet().forEach(name -> {
- String className = nextClassName(classNames, name);
- refClassNames.put("#/components/responses/" + name, className);
- });
- }
- }
-
- String schemaClassName(String simpleName) {
- return refToClassName("#/components/schemas/" + simpleName);
- }
-
- String requestBodyClassName(String simpleName) {
- return refToClassName("#/components/requestBodies/" + simpleName);
- }
-
- String responseClassName(String simpleName) {
- return refToClassName("#/components/responses/" + simpleName);
- }
-
- private String parameterClassName(String simpleName) {
- return refToClassName("#/components/parameters/" + simpleName);
- }
-
- String requestBodyClassName(RequestBody b) {
- return nullMapToEmpty(components().getRequestBodies()) //
- .entrySet() //
- .stream() //
- .filter(entry -> entry.getValue() == b) //
- .map(entry -> requestBodyClassName(entry.getKey())) //
- .findFirst() //
- .orElseThrow(() -> new RuntimeException("cound not find " + b));
- }
-
- String parameterClassName(Parameter p) {
- return nullMapToEmpty(components().getParameters()) //
- .entrySet() //
- .stream() //
- .filter(entry -> entry.getValue() == p) //
- .map(entry -> parameterClassName(entry.getKey())) //
- .findFirst() //
- .orElseThrow(() -> new RuntimeException("cound not find " + p));
- }
-
- String refToClassName(String ref) {
- Preconditions.checkNotNull(ref);
- String className = refClassNames.get(ref);
- if (className == null) {
- throw new RuntimeException("could not find ref=" + ref);
- } else {
- return className;
- }
- }
-
- Components components() {
- return openapi.getComponents();
- }
-
- Paths paths() {
- return openapi.getPaths();
- }
-
- String nextClassName(String candidate) {
- return nextClassName(classNames, candidate);
- }
-
- private static String nextClassName(Set classNames, String... candidates) {
- return nextClassName(classNames, Arrays.asList(candidates));
- }
-
- private static String nextClassName(Set classNames, List candidates) {
- Preconditions.checkArgument(!candidates.isEmpty());
- for (String candidate : candidates) {
- if (!classNames.contains(candidate)) {
- classNames.add(candidate);
- return candidate;
- }
- }
- int i = 1;
- String lastCandidate = candidates.get(candidates.size() - 1);
- while (true) {
- String className = lastCandidate + "." + i;
- if (!classNames.contains(className)) {
- classNames.add(className);
- return className;
- }
- i++;
- }
- }
-
- @SuppressWarnings("rawtypes") Map schemas() {
- if (openapi.getComponents() == null) {
- return Collections.emptyMap();
- } else {
- return nullMapToEmpty(openapi.getComponents().getSchemas());
- }
- }
-
- Map requestBodies() {
- if (openapi.getComponents() == null) {
- return Collections.emptyMap();
- } else {
- return nullMapToEmpty(openapi.getComponents().getRequestBodies());
- }
- }
-
- Map parameters() {
- if (openapi.getComponents() == null) {
- return Collections.emptyMap();
- } else {
- return nullMapToEmpty(openapi.getComponents().getParameters());
- }
- }
-
- Map responses() {
- if (openapi.getComponents() == null) {
- return Collections.emptyMap();
- } else {
- return nullMapToEmpty(openapi.getComponents().getResponses());
- }
- }
+ private static final String EMPTY_RESPONSE_CLASS_NAME = "Empty Response";
+ private final Map refClassNames = new HashMap<>();
+ private final Set classNames = Sets.newHashSet(EMPTY_RESPONSE_CLASS_NAME);
+ private final OpenAPI openapi;
+
+ public Names(OpenAPI a) {
+ Components components = a.getComponents();
+ this.openapi = a;
+ if (components != null) {
+ // resolve name clashes
+ nullMapToEmpty(components.getSchemas()).keySet()
+ .forEach(name -> {
+ String className = nextClassName(classNames,
+ name);
+ refClassNames.put("#/components/schemas/" + name,
+ className);
+ });
+ nullMapToEmpty(components.getRequestBodies()).keySet()
+ .forEach(name -> {
+ String className = nextClassName(classNames,
+ name);
+ refClassNames.put("#/components/requestBodies/" + name,
+ className);
+ });
+ nullMapToEmpty(components.getParameters()).keySet()
+ .forEach(name -> {
+ String className = nextClassName(classNames,
+ name);
+ refClassNames.put("#/components/parameters/" + name,
+ className);
+ });
+ nullMapToEmpty(components.getResponses()).keySet()
+ .forEach(name -> {
+ String className = nextClassName(classNames,
+ name);
+ refClassNames.put("#/components/responses/" + name,
+ className);
+ });
+ }
+ }
+
+ private static String nextClassName(Set classNames,
+ String... candidates) {
+ return nextClassName(classNames,
+ Arrays.asList(candidates));
+ }
+
+ private static String nextClassName(Set classNames,
+ List candidates) {
+ Preconditions.checkArgument(!candidates.isEmpty());
+ for (String candidate : candidates) {
+ if (!classNames.contains(candidate)) {
+ classNames.add(candidate);
+ return candidate;
+ }
+ }
+ int i = 1;
+ String lastCandidate = candidates.get(candidates.size() - 1);
+ while (true) {
+ String className = lastCandidate + "." + i;
+ if (!classNames.contains(className)) {
+ classNames.add(className);
+ return className;
+ }
+ i++;
+ }
+ }
+
+ String schemaClassName(String simpleName) {
+ return refToClassName("#/components/schemas/" + simpleName);
+ }
+
+ String requestBodyClassName(String simpleName) {
+ return refToClassName("#/components/requestBodies/" + simpleName);
+ }
+
+ String responseClassName(String simpleName) {
+ return refToClassName("#/components/responses/" + simpleName);
+ }
+
+ private String parameterClassName(String simpleName) {
+ return refToClassName("#/components/parameters/" + simpleName);
+ }
+
+ String requestBodyClassName(RequestBody b) {
+ return nullMapToEmpty(components().getRequestBodies()) //
+ .entrySet() //
+ .stream() //
+ .filter(entry -> entry.getValue() == b) //
+ .map(entry -> requestBodyClassName(entry.getKey())) //
+ .findFirst() //
+ .orElseThrow(() -> new RuntimeException("cound not find "
+ + b));
+ }
+
+ String parameterClassName(Parameter p) {
+ return nullMapToEmpty(components().getParameters()) //
+ .entrySet() //
+ .stream() //
+ .filter(entry -> entry.getValue() == p) //
+ .map(entry -> parameterClassName(entry.getKey())) //
+ .findFirst() //
+ .orElseThrow(() -> new RuntimeException("cound not find " + p));
+ }
+
+ String refToClassName(String ref) {
+ Preconditions.checkNotNull(ref);
+ String className = refClassNames.get(ref);
+ if (className == null) {
+ throw new RuntimeException("could not find ref=" + ref);
+ } else {
+ return className;
+ }
+ }
+
+ Components components() {
+ return openapi.getComponents();
+ }
+
+ Paths paths() {
+ return openapi.getPaths();
+ }
+
+ String nextClassName(String candidate) {
+ return nextClassName(classNames,
+ candidate);
+ }
+
+ @SuppressWarnings("rawtypes")
+ Map schemas() {
+ if (openapi.getComponents() == null) {
+ return Collections.emptyMap();
+ } else {
+ return nullMapToEmpty(openapi.getComponents()
+ .getSchemas());
+ }
+ }
+
+ Map requestBodies() {
+ if (openapi.getComponents() == null) {
+ return Collections.emptyMap();
+ } else {
+ return nullMapToEmpty(openapi.getComponents()
+ .getRequestBodies());
+ }
+ }
+
+ Map parameters() {
+ if (openapi.getComponents() == null) {
+ return Collections.emptyMap();
+ } else {
+ return nullMapToEmpty(openapi.getComponents()
+ .getParameters());
+ }
+ }
+
+ Map responses() {
+ if (openapi.getComponents() == null) {
+ return Collections.emptyMap();
+ } else {
+ return nullMapToEmpty(openapi.getComponents()
+ .getResponses());
+ }
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/PathsHelper.java b/src/main/java/com/github/davidmoten/oas3/internal/PathsHelper.java
index 5da2f822..ad7a2cb2 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/PathsHelper.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/PathsHelper.java
@@ -1,22 +1,8 @@
package com.github.davidmoten.oas3.internal;
-import static com.github.davidmoten.oas3.internal.Util.first;
-import static com.github.davidmoten.oas3.internal.Util.nullListToEmpty;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Optional;
-
import com.github.davidmoten.guavamini.Preconditions;
-import com.github.davidmoten.oas3.internal.model.Association;
-import com.github.davidmoten.oas3.internal.model.AssociationType;
import com.github.davidmoten.oas3.internal.model.Class;
-import com.github.davidmoten.oas3.internal.model.ClassType;
-import com.github.davidmoten.oas3.internal.model.Field;
-import com.github.davidmoten.oas3.internal.model.Model;
-
+import com.github.davidmoten.oas3.internal.model.*;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
@@ -27,237 +13,313 @@
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+import static com.github.davidmoten.oas3.internal.Util.first;
+import static com.github.davidmoten.oas3.internal.Util.nullListToEmpty;
+
public final class PathsHelper {
- private PathsHelper() {
- // prevent instantiation
- }
+ private PathsHelper() {
+ // prevent instantiation
+ }
- public static Model toModel(Names names) {
- return paths(names);
- }
+ public static Model toModel(Names names) {
+ return paths(names);
+ }
- private static Model paths(Names names) {
- if (names.paths() == null) {
- return Model.EMPTY;
- } else {
- return names.paths() //
- .entrySet() //
- .stream() //
- .map(entry -> toModelPath(entry.getKey(), //
- entry.getValue(), names))
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
- }
- }
+ private static Model paths(Names names) {
+ if (names.paths() == null) {
+ return Model.EMPTY;
+ } else {
+ return names.paths() //
+ .entrySet() //
+ .stream() //
+ .map(entry -> toModelPath(entry.getKey(),
+ //
+ entry.getValue(),
+ names))
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
+ }
+ }
- private static Model toModelPath(String path, PathItem p, Names names) {
- // add method class blocks with HTTP verb and parameters
- // add response lines
- return p.readOperationsMap() //
- .entrySet() //
- .stream() //
- .map(entry -> {
- Operation operation = entry.getValue();
- String className = entry.getKey() + " " + path;
- FieldsWithModel f = toModelParameters(names, className,
- operation.getParameters());
- Model m = new Model(new Class(className, ClassType.METHOD, f.fields))
- .add(f.model);
- m = m.add(toModelResponses(names, operation, className));
- return m.add(toModelRequestBody(className, operation, names));
- }) //
- .reduce(Model.EMPTY, (a, b) -> a.add(b));
- }
+ private static Model toModelPath(String path,
+ PathItem p,
+ Names names) {
+ // add method class blocks with HTTP verb and parameters
+ // add response lines
+ return p.readOperationsMap() //
+ .entrySet() //
+ .stream() //
+ .map(entry -> {
+ Operation operation = entry.getValue();
+ String className = entry.getKey() + " " + path;
+ FieldsWithModel f = toModelParameters(names,
+ className,
+ operation.getParameters());
+ Model m = new Model(new Class(className,
+ ClassType.METHOD,
+ f.fields)).add(f.model);
+ m = m.add(toModelResponses(names,
+ operation,
+ className));
+ return m.add(toModelRequestBody(className,
+ operation,
+ names));
+ }) //
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
+ }
- private static FieldsWithModel toModelParameters(Names names, String className,
- List parameters) {
- return nullListToEmpty(parameters) //
- .stream()//
- .map(param -> toModelParameter(names, className, param)) //
- .reduce(FieldsWithModel.EMPTY, (a, b) -> a.add(b));
- }
+ private static FieldsWithModel toModelParameters(Names names,
+ String className,
+ List parameters) {
+ return nullListToEmpty(parameters) //
+ .stream()//
+ .map(param -> toModelParameter(names,
+ className,
+ param)) //
+ .reduce(FieldsWithModel.EMPTY,
+ (a, b) -> a.add(b));
+ }
- private static final class FieldsWithModel {
- private static final FieldsWithModel EMPTY = new FieldsWithModel(Collections.emptyList(),
- Model.EMPTY);
- private final List fields;
- private final Model model;
+ private static FieldsWithModel toModelParameter(Names names,
+ String className,
+ Parameter param) {
+ String ref = param.get$ref();
+ String parameterName = param.getName();
+ Boolean required = param.getRequired();
+ if (ref != null) {
+ // resolve the parameter ref chain so we can get the parameter `name` and
+ // `required` fields
+ Parameter p = param;
+ while (p.get$ref() != null) {
+ String r = p.get$ref();
+ p = getParameter(names.components(),
+ r);
+ }
+ // override name with name from last ref
+ parameterName = p.getName();
+ required = p.getRequired();
+ }
+ if (ref != null) {
+ Model model = new Model(Association //
+ .from(className) //
+ .to(names.refToClassName(ref)) //
+ .one() //
+ .propertyOrParameterName(parameterName) //
+ .build());
+ return new FieldsWithModel(Collections.emptyList(),
+ model);
+ } else {
+ Optional field = Optional.empty();
+ final Model model;
+ final Optional type = Common.getUmlTypeName(param.get$ref(),
+ param.getSchema(),
+ names);
+ if (type.isPresent() && Common.isSimpleType(type.get())) {
+ field = Optional.of(new Field(parameterName,
+ type.get(),
+ type.get()
+ .endsWith("]"),
+ required));
+ model = Model.EMPTY;
+ } else {
+ String anonClassName = names.nextClassName(className + "." + parameterName);
+ final Model m;
+ if (param.getSchema() != null) {
+ m = Common.toModelClass(anonClassName,
+ param.getSchema(),
+ names,
+ ClassType.PARAMETER);
+ } else {
+ m = new Model(new Class(anonClassName,
+ ClassType.PARAMETER));
+ }
+ model = m.add(Association.from(className)
+ .to(anonClassName)
+ .type(required
+ ? AssociationType.ONE
+ : AssociationType.ZERO_ONE)
+ .propertyOrParameterName(parameterName)
+ .build());
+ }
+ // TODO else get schema from content?
- FieldsWithModel(List fields, Model model) {
- this.fields = fields;
- this.model = model;
- }
+ return new FieldsWithModel(field.map(x -> Collections.singletonList(x))
+ .orElse(Collections.emptyList()),
+ model);
+ }
- FieldsWithModel add(FieldsWithModel f) {
- List list = new ArrayList<>(fields);
- list.addAll(f.fields);
- return new FieldsWithModel(list, model.add(f.model));
- }
- }
+ }
- private static FieldsWithModel toModelParameter(Names names, String className,
- Parameter param) {
- String ref = param.get$ref();
- String parameterName = param.getName();
- Boolean required = param.getRequired();
- if (ref != null) {
- // resolve the parameter ref chain so we can get the parameter `name` and
- // `required` fields
- Parameter p = param;
- while (p.get$ref() != null) {
- String r = p.get$ref();
- p = getParameter(names.components(), r);
- }
- // override name with name from last ref
- parameterName = p.getName();
- required = p.getRequired();
- }
- if (ref != null) {
- Model model = new Model(Association //
- .from(className) //
- .to(names.refToClassName(ref)) //
- .one() //
- .propertyOrParameterName(parameterName) //
- .build());
- return new FieldsWithModel(Collections.emptyList(), model);
- } else {
- Optional field = Optional.empty();
- final Model model;
- final Optional type = Common.getUmlTypeName(param.get$ref(), param.getSchema(),
- names);
- if (type.isPresent() && Common.isSimpleType(type.get())) {
- field = Optional.of(
- new Field(parameterName, type.get(), type.get().endsWith("]"), required));
- model = Model.EMPTY;
- } else {
- String anonClassName = names.nextClassName(className + "." + parameterName);
- final Model m;
- if (param.getSchema() != null) {
- m = Common.toModelClass(anonClassName, param.getSchema(), names,
- ClassType.PARAMETER);
- } else {
- m = new Model(new Class(anonClassName, ClassType.PARAMETER));
- }
- model = m.add(Association.from(className).to(anonClassName)
- .type(required ? AssociationType.ONE : AssociationType.ZERO_ONE)
- .propertyOrParameterName(parameterName).build());
- }
- // TODO else get schema from content?
+ private static Parameter getParameter(Components components,
+ String ref) {
+ Preconditions.checkNotNull(ref);
+ Reference r = new Reference(ref);
+ if ("#/components/parameters".equals(r.namespace)) {
+ return components.getParameters()
+ .get(r.simpleName);
+ } else {
+ throw new RuntimeException("unexpected");
+ }
+ }
- return new FieldsWithModel(
- field.map(x -> Collections.singletonList(x)).orElse(Collections.emptyList()),
- model);
- }
+ private static Model toModelRequestBody(String className,
+ Operation operation,
+ Names names) {
+ RequestBody body = operation.getRequestBody();
+ if (body != null) {
+ String ref = body.get$ref();
+ if (ref != null) {
+ return new Model(Association.from(className)
+ .to(names.refToClassName(ref))
+ .one()
+ .build());
+ }
+ Content content = body.getContent();
+ if (content != null) {
+ Entry mediaType = first(content).get();
+ // use the first content entry
+ final String requestBodyClassName;
+ final Model model;
+ Schema> sch = mediaType.getValue()
+ .getSchema();
+ // note that sch cannot be null because the parser sets the
+ // response body to null if schema is missing
+ if (sch.get$ref() != null) {
+ requestBodyClassName = names.refToClassName(sch.get$ref());
+ model = Model.EMPTY;
+ } else {
+ requestBodyClassName = className + " Request";
+ model = Common.toModelClass(requestBodyClassName,
+ sch,
+ names,
+ ClassType.REQUEST_BODY);
+ }
+ Association a = Association.from(className)
+ .to(requestBodyClassName)
+ .one()
+ .build();
+ return model.add(a);
+ }
+ }
+ return Model.EMPTY;
+ }
- }
+ private static Model toModelResponses(Names names,
+ Operation operation,
+ String className) {
+ return operation //
+ .getResponses() //
+ .entrySet() //
+ .stream() //
+ .map(ent -> {
+ String responseCode = ent.getKey();
+ // TODO only using the first content
+ ApiResponse r = ent.getValue();
+ final Model model;
+ if (r.get$ref() != null) {
+ String returnClassName = names.refToClassName(r.get$ref());
+ model = new Model(Association.from(className)
+ .to(returnClassName)
+ .one()
+ .responseCode(responseCode)
+ .build());
+ } else {
- private static Parameter getParameter(Components components, String ref) {
- Preconditions.checkNotNull(ref);
- Reference r = new Reference(ref);
- if ("#/components/parameters".equals(r.namespace)) {
- return components.getParameters().get(r.simpleName);
- } else {
- throw new RuntimeException("unexpected");
- }
- }
+ if (r.getContent() == null) {
+ final String newReturnClassName = className + " " + responseCode;
+ Model m = new Model(new Class(newReturnClassName,
+ ClassType.RESPONSE));
+ String returnClassName = newReturnClassName;
+ model = m.add(Association.from(className)
+ .to(returnClassName)
+ .one()
+ .responseCode(responseCode)
+ .build());
+ } else {
+ Model m = Model.EMPTY;
+ for (Entry contentEntry : r.getContent()
+ .entrySet()) {
+ String contentType = contentEntry.getKey();
+ final String newReturnClassName = className
+ + " "
+ + responseCode
+ + ("application/json".equals(contentType)
+ ? ""
+ : " " + contentType);
+ MediaType mediaType = contentEntry.getValue();
+ Schema> sch = mediaType.getSchema();
+ if (sch == null) {
+ // TODO
+ System.out.println("TODO handle null schema in response");
+ } else if (sch.get$ref() != null) {
+ String returnClassName = names.refToClassName(sch.get$ref());
+ m = m.add(Association.from(className)
+ .to(returnClassName)
+ .one()
+ .responseCode(responseCode)
+ .responseContentType(contentType)
+ .build());
+ } else {
+ String returnClassName = newReturnClassName;
+ m = m.add(Common.toModelClass(returnClassName,
+ sch,
+ names,
+ ClassType.RESPONSE));
+ m = m.add(Association.from(className)
+ .to(returnClassName)
+ .one()
+ .responseCode(responseCode)
+ .responseContentType(contentType)
+ .build());
+ }
- private static Model toModelRequestBody(String className, Operation operation, Names names) {
- RequestBody body = operation.getRequestBody();
- if (body != null) {
- String ref = body.get$ref();
- if (ref != null) {
- return new Model(
- Association.from(className).to(names.refToClassName(ref)).one().build());
- }
- Content content = body.getContent();
- if (content != null) {
- Entry mediaType = first(content).get();
- // use the first content entry
- final String requestBodyClassName;
- final Model model;
- Schema> sch = mediaType.getValue().getSchema();
- // note that sch cannot be null because the parser sets the
- // response body to null if schema is missing
- if (sch.get$ref() != null) {
- requestBodyClassName = names.refToClassName(sch.get$ref());
- model = Model.EMPTY;
- } else {
- requestBodyClassName = className + " Request";
- model = Common.toModelClass(requestBodyClassName, sch, names,
- ClassType.REQUEST_BODY);
- }
- Association a = Association.from(className).to(requestBodyClassName).one().build();
- return model.add(a);
- }
- }
- return Model.EMPTY;
- }
+ }
+ model = m;
+ }
+ }
+ return model;
+ })
+ .reduce(Model.EMPTY,
+ (a, b) -> a.add(b));
+ }
- private static Model toModelResponses(Names names, Operation operation, String className) {
- return operation //
- .getResponses() //
- .entrySet() //
- .stream() //
- .map(ent -> {
- String responseCode = ent.getKey();
- // TODO only using the first content
- ApiResponse r = ent.getValue();
- final Model model;
- if (r.get$ref() != null) {
- String returnClassName = names.refToClassName(r.get$ref());
- model = new Model(Association.from(className).to(returnClassName).one()
- .responseCode(responseCode).build());
- } else {
+ private static final class FieldsWithModel {
+ private static final FieldsWithModel EMPTY = new FieldsWithModel(Collections.emptyList(),
+ Model.EMPTY);
+ private final List fields;
+ private final Model model;
- if (r.getContent() == null) {
- final String newReturnClassName = className + " " + responseCode;
- Model m = new Model(new Class(newReturnClassName, ClassType.RESPONSE));
- String returnClassName = newReturnClassName;
- model = m.add(Association.from(className).to(returnClassName).one()
- .responseCode(responseCode).build());
- } else {
- Model m = Model.EMPTY;
- for (Entry contentEntry : r.getContent()
- .entrySet()) {
- String contentType = contentEntry.getKey();
- final String newReturnClassName = className + " " + responseCode
- + ("application/json".equals(contentType) ? ""
- : " " + contentType);
- MediaType mediaType = contentEntry.getValue();
- Schema> sch = mediaType.getSchema();
- if (sch == null) {
- // TODO
- System.out.println("TODO handle null schema in response");
- } else if (sch.get$ref() != null) {
- String returnClassName = names.refToClassName(sch.get$ref());
- m = m.add(Association.from(className).to(returnClassName).one()
- .responseCode(responseCode)
- .responseContentType(contentType).build());
- } else {
- String returnClassName = newReturnClassName;
- m = m.add(Common.toModelClass(returnClassName, sch, names,
- ClassType.RESPONSE));
- m = m.add(Association.from(className).to(returnClassName).one()
- .responseCode(responseCode)
- .responseContentType(contentType).build());
- }
+ FieldsWithModel(List fields,
+ Model model) {
+ this.fields = fields;
+ this.model = model;
+ }
- }
- model = m;
- }
- }
- return model;
- }).reduce(Model.EMPTY, (a, b) -> a.add(b));
- }
+ FieldsWithModel add(FieldsWithModel f) {
+ List list = new ArrayList<>(fields);
+ list.addAll(f.fields);
+ return new FieldsWithModel(list,
+ model.add(f.model));
+ }
+ }
- private static final class Reference {
- private final String namespace;
- private final String simpleName;
+ private static final class Reference {
+ private final String namespace;
+ private final String simpleName;
- private Reference(String ref) {
- this.namespace = ref.substring(0, ref.lastIndexOf("/"));
- this.simpleName = ref.substring(ref.lastIndexOf("/") + 1);
- }
- }
+ private Reference(String ref) {
+ this.namespace = ref.substring(0,
+ ref.lastIndexOf("/"));
+ this.simpleName = ref.substring(ref.lastIndexOf("/") + 1);
+ }
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/Util.java b/src/main/java/com/github/davidmoten/oas3/internal/Util.java
index 2d9405c7..11f7326a 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/Util.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/Util.java
@@ -8,32 +8,34 @@
public final class Util {
- private Util() {
- // prevent instantiation
- }
-
- public static Map nullMapToEmpty(Map map) {
- if (map == null) {
- return Collections.emptyMap();
- } else {
- return map;
- }
- }
-
- public static List nullListToEmpty(List list) {
- if (list == null) {
- return Collections.emptyList();
- } else {
- return list;
- }
- }
-
- public static Optional> first(Map map) {
- return map.entrySet().stream().findFirst();
- }
-
- public static String quote(String s) {
- return "\"" + s + "\"";
- }
+ private Util() {
+ // prevent instantiation
+ }
+
+ public static Map nullMapToEmpty(Map map) {
+ if (map == null) {
+ return Collections.emptyMap();
+ } else {
+ return map;
+ }
+ }
+
+ public static List nullListToEmpty(List list) {
+ if (list == null) {
+ return Collections.emptyList();
+ } else {
+ return list;
+ }
+ }
+
+ public static Optional> first(Map map) {
+ return map.entrySet()
+ .stream()
+ .findFirst();
+ }
+
+ public static String quote(String s) {
+ return "\"" + s + "\"";
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Association.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Association.java
index cbcfb7c4..cccc7c54 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/Association.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Association.java
@@ -2,153 +2,163 @@
import java.util.Optional;
-public final class Association implements Relationship {
- private final String from;
- private final String to;
- private final AssociationType type;
- private final Optional responseCode;
- private final Optional responseContentType;
- private final Optional propertyOrParameterName;
-
- private Association(String from, String to, AssociationType type, Optional responseCode,
- Optional responseContentType, Optional propertyOrParameterName) {
- this.from = from;
- this.to = to;
- this.type = type;
- this.responseCode = responseCode;
- this.responseContentType = responseContentType;
- this.propertyOrParameterName = propertyOrParameterName;
- }
-
- public String from() {
- return from;
- }
-
- public String to() {
- return to;
- }
-
- public AssociationType type() {
- return type;
- }
-
- public Optional responseCode() {
- return responseCode;
- }
-
- public Optional responseContentType() {
- return responseContentType;
- }
-
- public Optional propertyOrParameterName() {
- return propertyOrParameterName;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Association [from=");
- b.append(from);
- b.append(", to=");
- b.append(to);
- b.append(", type=");
- b.append(type);
- b.append(", responseCode=");
- b.append(str(responseCode));
- b.append(", responseContentType=");
- b.append(str(responseContentType));
- b.append(", propertyOrParameterName=");
- b.append(str(propertyOrParameterName));
- b.append("]");
- return b.toString();
- }
-
- private static String str(Optional> o) {
- return o.map(x -> x.toString()).orElse("");
- }
-
- public static Builder from(String from) {
- return new Builder(from);
- }
-
- public static final class Builder {
-
- private final String from;
- private String to;
- private AssociationType type;
- private Optional propertyOrParameterName = Optional.empty();
- private Optional responseCode = Optional.empty();
- private Optional responseContentType = Optional.empty();
-
- Builder(String from) {
- this.from = from;
- }
-
- public Builder2 to(String to) {
- this.to = to;
- return new Builder2(this);
- }
-
- }
-
- public static final class Builder2 {
-
- private final Builder b;
-
- Builder2(Builder b) {
- this.b = b;
- }
-
- public Builder3 one() {
- return type(AssociationType.ONE);
- }
-
- public Builder3 many() {
- return type(AssociationType.MANY);
- }
-
- public Builder3 zeroOne() {
- return type(AssociationType.ZERO_ONE);
- }
-
- public Builder3 type(AssociationType type) {
- b.type = type;
- return new Builder3(b);
- }
-
- }
-
- public static final class Builder3 {
-
- private final Builder b;
-
- Builder3(Builder b) {
- this.b = b;
- }
-
- public Association build() {
- return new Association(b.from, b.to, b.type, b.responseCode, b.responseContentType,
- b.propertyOrParameterName);
- }
-
- public Builder3 propertyOrParameterName(String label) {
- return propertyOrParameterName(Optional.of(label));
- }
-
- public Builder3 responseCode(String responseCode) {
- b.responseCode = Optional.of(responseCode);
- return this;
- }
-
- public Builder3 responseContentType(String responseContentType) {
- b.responseContentType = Optional.of(responseContentType);
- return this;
- }
-
- public Builder3 propertyOrParameterName(Optional propertyOrParameterName) {
- b.propertyOrParameterName = propertyOrParameterName;
- return this;
- }
- }
+public final class Association
+ implements Relationship {
+ private final String from;
+ private final String to;
+ private final AssociationType type;
+ private final Optional responseCode;
+ private final Optional responseContentType;
+ private final Optional propertyOrParameterName;
+
+ private Association(String from,
+ String to,
+ AssociationType type,
+ Optional responseCode,
+ Optional responseContentType,
+ Optional propertyOrParameterName) {
+ this.from = from;
+ this.to = to;
+ this.type = type;
+ this.responseCode = responseCode;
+ this.responseContentType = responseContentType;
+ this.propertyOrParameterName = propertyOrParameterName;
+ }
+
+ private static String str(Optional> o) {
+ return o.map(x -> x.toString())
+ .orElse("");
+ }
+
+ public static Builder from(String from) {
+ return new Builder(from);
+ }
+
+ public String from() {
+ return from;
+ }
+
+ public String to() {
+ return to;
+ }
+
+ public AssociationType type() {
+ return type;
+ }
+
+ public Optional responseCode() {
+ return responseCode;
+ }
+
+ public Optional responseContentType() {
+ return responseContentType;
+ }
+
+ public Optional propertyOrParameterName() {
+ return propertyOrParameterName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Association [from=");
+ b.append(from);
+ b.append(", to=");
+ b.append(to);
+ b.append(", type=");
+ b.append(type);
+ b.append(", responseCode=");
+ b.append(str(responseCode));
+ b.append(", responseContentType=");
+ b.append(str(responseContentType));
+ b.append(", propertyOrParameterName=");
+ b.append(str(propertyOrParameterName));
+ b.append("]");
+ return b.toString();
+ }
+
+ public static final class Builder {
+
+ private final String from;
+ private String to;
+ private AssociationType type;
+ private Optional propertyOrParameterName = Optional.empty();
+ private Optional responseCode = Optional.empty();
+ private Optional responseContentType = Optional.empty();
+
+ Builder(String from) {
+ this.from = from;
+ }
+
+ public Builder2 to(String to) {
+ this.to = to;
+ return new Builder2(this);
+ }
+
+ }
+
+ public static final class Builder2 {
+
+ private final Builder b;
+
+ Builder2(Builder b) {
+ this.b = b;
+ }
+
+ public Builder3 one() {
+ return type(AssociationType.ONE);
+ }
+
+ public Builder3 many() {
+ return type(AssociationType.MANY);
+ }
+
+ public Builder3 zeroOne() {
+ return type(AssociationType.ZERO_ONE);
+ }
+
+ public Builder3 type(AssociationType type) {
+ b.type = type;
+ return new Builder3(b);
+ }
+
+ }
+
+ public static final class Builder3 {
+
+ private final Builder b;
+
+ Builder3(Builder b) {
+ this.b = b;
+ }
+
+ public Association build() {
+ return new Association(b.from,
+ b.to,
+ b.type,
+ b.responseCode,
+ b.responseContentType,
+ b.propertyOrParameterName);
+ }
+
+ public Builder3 propertyOrParameterName(String label) {
+ return propertyOrParameterName(Optional.of(label));
+ }
+
+ public Builder3 responseCode(String responseCode) {
+ b.responseCode = Optional.of(responseCode);
+ return this;
+ }
+
+ public Builder3 responseContentType(String responseContentType) {
+ b.responseContentType = Optional.of(responseContentType);
+ return this;
+ }
+
+ public Builder3 propertyOrParameterName(Optional propertyOrParameterName) {
+ b.propertyOrParameterName = propertyOrParameterName;
+ return this;
+ }
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/AssociationType.java b/src/main/java/com/github/davidmoten/oas3/internal/model/AssociationType.java
index f2563992..b5a6ec85 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/AssociationType.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/AssociationType.java
@@ -1,5 +1,7 @@
package com.github.davidmoten.oas3.internal.model;
public enum AssociationType {
- ONE, ZERO_ONE, MANY;
+ ONE,
+ ZERO_ONE,
+ MANY
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Class.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Class.java
index c669aa9e..90db183f 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/Class.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Class.java
@@ -1,51 +1,56 @@
package com.github.davidmoten.oas3.internal.model;
+import com.google.common.base.Preconditions;
+
import java.util.Collections;
import java.util.List;
-import com.google.common.base.Preconditions;
-
public final class Class {
- private final String name;
- private final ClassType type;
- private final List fields;
-
- public Class(String name, ClassType type, List fields) {
- Preconditions.checkNotNull(name);
- Preconditions.checkNotNull(type);
- Preconditions.checkNotNull(fields);
- this.name = name;
- this.type = type;
- this.fields = fields;
- }
-
- public Class(String name, ClassType type) {
- this(name, type, Collections.emptyList());
- }
-
- public String name() {
- return name;
- }
-
- public ClassType type() {
- return type;
- }
-
- public List fields() {
- return fields;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Class [name=");
- b.append(name);
- b.append(", type=");
- b.append(type);
- b.append(", fields=");
- b.append(fields);
- b.append("]");
- return b.toString();
- }
+ private final String name;
+ private final ClassType type;
+ private final List fields;
+
+ public Class(String name,
+ ClassType type,
+ List fields) {
+ Preconditions.checkNotNull(name);
+ Preconditions.checkNotNull(type);
+ Preconditions.checkNotNull(fields);
+ this.name = name;
+ this.type = type;
+ this.fields = fields;
+ }
+
+ public Class(String name,
+ ClassType type) {
+ this(name,
+ type,
+ Collections.emptyList());
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public ClassType type() {
+ return type;
+ }
+
+ public List fields() {
+ return fields;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Class [name=");
+ b.append(name);
+ b.append(", type=");
+ b.append(type);
+ b.append(", fields=");
+ b.append(fields);
+ b.append("]");
+ return b.toString();
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/ClassType.java b/src/main/java/com/github/davidmoten/oas3/internal/model/ClassType.java
index 2497f178..aa49dc86 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/ClassType.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/ClassType.java
@@ -2,17 +2,21 @@
public enum ClassType {
- SCHEMA("Schema"), PARAMETER("Parameter"), REQUEST_BODY("RequestBody"), RESPONSE("Response"), METHOD("Method");
+ SCHEMA("Schema"),
+ PARAMETER("Parameter"),
+ REQUEST_BODY("RequestBody"),
+ RESPONSE("Response"),
+ METHOD("Method");
- private final String name;
+ private final String name;
- ClassType(String name) {
- this.name = name;
- }
+ ClassType(String name) {
+ this.name = name;
+ }
- @Override
- public String toString() {
- return name;
- }
+ @Override
+ public String toString() {
+ return name;
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Field.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Field.java
index 398c6c72..4a9e85a0 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/Field.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Field.java
@@ -2,48 +2,51 @@
public final class Field {
- private final String name;
- // TODO convert to simpleType
- private final String type;
- private final boolean isArray;
- private final boolean required;
-
- public Field(String name, String type, boolean isArray, boolean required) {
- this.name = name;
- this.type = type;
- this.isArray = isArray;
- this.required = required;
- }
-
- public String name() {
- return name;
- }
-
- public String type() {
- return type;
- }
-
- public boolean isArray() {
- return isArray;
- }
-
- public boolean isRequired() {
- return required;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Field [name=");
- b.append(name);
- b.append(", type=");
- b.append(type);
- b.append(", isArray=");
- b.append(isArray);
- b.append(", required=");
- b.append(required);
- b.append("]");
- return b.toString();
- }
+ private final String name;
+ // TODO convert to simpleType
+ private final String type;
+ private final boolean isArray;
+ private final boolean required;
+
+ public Field(String name,
+ String type,
+ boolean isArray,
+ boolean required) {
+ this.name = name;
+ this.type = type;
+ this.isArray = isArray;
+ this.required = required;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public String type() {
+ return type;
+ }
+
+ public boolean isArray() {
+ return isArray;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Field [name=");
+ b.append(name);
+ b.append(", type=");
+ b.append(type);
+ b.append(", isArray=");
+ b.append(isArray);
+ b.append(", required=");
+ b.append(required);
+ b.append("]");
+ return b.toString();
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Inheritance.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Inheritance.java
index 86df9830..f63dec60 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/Inheritance.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Inheritance.java
@@ -3,48 +3,52 @@
import java.util.List;
import java.util.Optional;
-public final class Inheritance implements Relationship {
- private final String from;
- private final List to;
- private final AssociationType type;
- private final Optional propertyName;
-
- public Inheritance(String from, List to, AssociationType type, Optional propertyName) {
- this.from = from;
- this.to = to;
- this.type = type;
- this.propertyName = propertyName;
- }
-
- public String from() {
- return from;
- }
-
- public List to() {
- return to;
- }
-
- public AssociationType type() {
- return type;
- }
-
- public Optional propertyName() {
- return propertyName;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Inheritance [from=");
- b.append(from);
- b.append(", to=");
- b.append(to);
- b.append(", type=");
- b.append(type);
- b.append(", propertyName=");
- b.append(propertyName);
- b.append("]");
- return b.toString();
- }
+public final class Inheritance
+ implements Relationship {
+ private final String from;
+ private final List to;
+ private final AssociationType type;
+ private final Optional propertyName;
+
+ public Inheritance(String from,
+ List to,
+ AssociationType type,
+ Optional propertyName) {
+ this.from = from;
+ this.to = to;
+ this.type = type;
+ this.propertyName = propertyName;
+ }
+
+ public String from() {
+ return from;
+ }
+
+ public List to() {
+ return to;
+ }
+
+ public AssociationType type() {
+ return type;
+ }
+
+ public Optional propertyName() {
+ return propertyName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Inheritance [from=");
+ b.append(from);
+ b.append(", to=");
+ b.append(to);
+ b.append(", type=");
+ b.append(type);
+ b.append(", propertyName=");
+ b.append(propertyName);
+ b.append("]");
+ return b.toString();
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Model.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Model.java
index 4cf0f5cf..28f81b98 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/Model.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Model.java
@@ -1,67 +1,79 @@
package com.github.davidmoten.oas3.internal.model;
-import static java.util.stream.Collectors.joining;
+import com.github.davidmoten.guavamini.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import com.github.davidmoten.guavamini.Lists;
+import static java.util.stream.Collectors.joining;
public final class Model {
- public static final Model EMPTY = new Model(Collections.emptyList(), Collections.emptyList());
-
- private final List classes;
- private final List relationships;
-
- public Model(List classes, List relationships) {
- this.classes = classes;
- this.relationships = relationships;
- }
-
- public Model(Class cls, Relationship r) {
- this(Collections.singletonList(cls), Collections.singletonList(r));
- }
-
- public Model(Class cls) {
- this(Collections.singletonList(cls), Collections.emptyList());
- }
-
- public Model(Relationship r) {
- this(Collections.emptyList(), Collections.singletonList(r));
- }
-
- public Model add(Model model) {
- List c = Lists.newArrayList(classes);
- List r = Lists.newArrayList(relationships);
- c.addAll(model.classes);
- r.addAll(model.relationships);
- return new Model(c, r);
- }
-
- public Model add(Relationship r) {
- List list = new ArrayList<>(relationships);
- list.add(r);
- return new Model(classes, list);
- }
-
- public List classes() {
- return classes;
- }
-
- public List relationships() {
- return relationships;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Model [");
- b.append(classes.stream().map(x -> "\n " + x).collect(joining(",")));
- b.append(relationships.stream().map(x -> "\n " + x).collect(joining(",")));
- b.append("\n]");
- return b.toString();
- }
+ public static final Model EMPTY = new Model(Collections.emptyList(),
+ Collections.emptyList());
+
+ private final List classes;
+ private final List relationships;
+
+ public Model(List classes,
+ List relationships) {
+ this.classes = classes;
+ this.relationships = relationships;
+ }
+
+ public Model(Class cls,
+ Relationship r) {
+ this(Collections.singletonList(cls),
+ Collections.singletonList(r));
+ }
+
+ public Model(Class cls) {
+ this(Collections.singletonList(cls),
+ Collections.emptyList());
+ }
+
+ public Model(Relationship r) {
+ this(Collections.emptyList(),
+ Collections.singletonList(r));
+ }
+
+ public Model add(Model model) {
+ List c = Lists.newArrayList(classes);
+ List r = Lists.newArrayList(relationships);
+ c.addAll(model.classes);
+ r.addAll(model.relationships);
+ return new Model(c,
+ r);
+ }
+
+ public Model add(Relationship r) {
+ List list = new ArrayList<>(relationships);
+ list.add(r);
+ return new Model(classes,
+ list);
+ }
+
+ public List classes() {
+ return classes;
+ }
+
+ public List relationships() {
+ return relationships;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Model [");
+ b.append(classes.stream()
+ .map(x -> "\n " + x)
+ .collect(joining(",")));
+ b.append(relationships.stream()
+ .map(x -> "\n " + x)
+ .collect(joining(",")));
+ b.append("\n]");
+ return b.toString();
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/SimpleType.java b/src/main/java/com/github/davidmoten/oas3/internal/model/SimpleType.java
index 5c312422..7f5c28b4 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/SimpleType.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/SimpleType.java
@@ -2,18 +2,23 @@
public enum SimpleType {
- STRING("string"), DECIMAL("decimal"), INTEGER("integer"), BYTE_ARRAY("byte[]"),
- BOOLEAN("boolean"), DATE("date"), TIMESTAMP("timestamp"), //
- MAP("map"); // TODO get rid of Map once we model `additionalProperties`
+ STRING("string"),
+ DECIMAL("decimal"),
+ INTEGER("integer"),
+ BYTE_ARRAY("byte[]"),
+ BOOLEAN("boolean"),
+ DATE("date"),
+ TIMESTAMP("timestamp"), //
+ MAP("map"); // TODO get rid of Map once we model `additionalProperties`
- private final String name;
+ private final String name;
- SimpleType(String name) {
- this.name = name;
- }
+ SimpleType(String name) {
+ this.name = name;
+ }
- @Override
- public String toString() {
- return name;
- }
+ @Override
+ public String toString() {
+ return name;
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/Throwables.java b/src/main/java/com/github/davidmoten/oas3/internal/model/Throwables.java
new file mode 100644
index 00000000..bd216064
--- /dev/null
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/Throwables.java
@@ -0,0 +1,44 @@
+package com.github.davidmoten.oas3.internal.model;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class Throwables
+ extends Throwable {
+ private final Set throwables = new LinkedHashSet<>();
+
+ public Throwables() {
+ super();
+ }
+
+ public Throwables(String message) {
+ super(message);
+ }
+
+ public Throwables(String message,
+ Throwable cause) {
+ super(message,
+ cause);
+ getThrowables().add(cause);
+ }
+
+ public Throwables(Throwable cause) {
+ super(cause);
+ getThrowables().add(cause);
+ }
+
+ public final Set getThrowables() {
+ return throwables;
+ }
+
+ @Override
+ public final String toString() {
+ String message = getMessage() == null
+ ? ""
+ : getMessage();
+ String string = String.format("%s%n%s%n",
+ message,
+ throwables);
+ return string;
+ }
+}
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/model/package-info.java b/src/main/java/com/github/davidmoten/oas3/internal/model/package-info.java
index 158c2844..20c971da 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/model/package-info.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/model/package-info.java
@@ -1,7 +1,7 @@
/**
* classes to support conversion of OpenAPI to Model.
*
- * @since 1.0
* @see java.awt
+ * @since 1.0
*/
package com.github.davidmoten.oas3.internal.model;
\ No newline at end of file
diff --git a/src/main/java/com/github/davidmoten/oas3/internal/package-info.java b/src/main/java/com/github/davidmoten/oas3/internal/package-info.java
index 602f7c62..31331219 100644
--- a/src/main/java/com/github/davidmoten/oas3/internal/package-info.java
+++ b/src/main/java/com/github/davidmoten/oas3/internal/package-info.java
@@ -1,7 +1,7 @@
/**
* classes to support conversion of OpenAPI to Model.
*
- * @since 1.0
* @see java.awt
+ * @since 1.0
*/
package com.github.davidmoten.oas3.internal;
\ No newline at end of file
diff --git a/src/main/java/com/github/davidmoten/oas3/puml/Converter.java b/src/main/java/com/github/davidmoten/oas3/puml/Converter.java
index 279e4cfc..8cf1f85e 100644
--- a/src/main/java/com/github/davidmoten/oas3/puml/Converter.java
+++ b/src/main/java/com/github/davidmoten/oas3/puml/Converter.java
@@ -1,162 +1,661 @@
package com.github.davidmoten.oas3.puml;
-import static com.github.davidmoten.oas3.internal.Util.quote;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Optional;
-
-import org.apache.commons.io.IOUtils;
-
import com.github.davidmoten.oas3.internal.ComponentsHelper;
import com.github.davidmoten.oas3.internal.Names;
import com.github.davidmoten.oas3.internal.PathsHelper;
import com.github.davidmoten.oas3.internal.Util;
-import com.github.davidmoten.oas3.internal.model.Association;
-import com.github.davidmoten.oas3.internal.model.AssociationType;
import com.github.davidmoten.oas3.internal.model.Class;
-import com.github.davidmoten.oas3.internal.model.ClassType;
-import com.github.davidmoten.oas3.internal.model.Inheritance;
-import com.github.davidmoten.oas3.internal.model.Model;
-import com.github.davidmoten.oas3.internal.model.Relationship;
-
+import com.github.davidmoten.oas3.internal.model.*;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
+import net.sourceforge.plantuml.FileFormat;
+import net.sourceforge.plantuml.FileFormatOption;
+import net.sourceforge.plantuml.SourceStringReader;
+import net.sourceforge.plantuml.core.DiagramDescription;
+import org.apache.commons.io.IOUtils;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.davidmoten.oas3.internal.Util.quote;
+
+@SuppressWarnings("UnnecessaryLocalVariable")
public final class Converter {
- private static final String COLON = " : ";
- private static final String SPACE = " ";
-
- private Converter() {
- // prevent instantiation
- }
-
- public static String openApiToPuml(InputStream in) throws IOException {
- return openApiToPuml(IOUtils.toString(in, StandardCharsets.UTF_8));
- }
-
- public static String openApiToPuml(File file) throws IOException {
- try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
- return openApiToPuml(in);
- }
- }
-
- public static String openApiToPuml(String openApi) {
- SwaggerParseResult result = new OpenAPIParser().readContents(openApi, null, null);
- if (result.getOpenAPI() == null) {
- throw new IllegalArgumentException("Not an OpenAPI definition");
- }
- return openApiToPuml(result.getOpenAPI());
- }
-
- private static String openApiToPuml(OpenAPI a) {
-
- Names names = new Names(a);
- Model model = ComponentsHelper //
- .toModel(names) //
- .add(PathsHelper.toModel(names));
-
- return "@startuml" //
- + "\nhide <<" + toStereotype(ClassType.METHOD).get() + ">> circle" //
- + "\nhide <<" + toStereotype(ClassType.RESPONSE).get() + ">> circle" //
- + "\nhide <<" + toStereotype(ClassType.PARAMETER).get() + ">> circle" //
- + "\nhide empty methods" //
- + "\nhide empty fields" //
- // make sure that periods in class names aren't interpreted as namespace
- // separators (which results in recursive boxing)
- + "\nset namespaceSeparator none" //
- + toPlantUml(model) //
- + "\n\n@enduml";
- }
-
- private static String toPlantUml(Model model) {
- int anonNumber = 0;
- StringBuilder b = new StringBuilder();
- for (Class cls : model.classes()) {
- b.append("\n\nclass " + Util.quote(cls.name())
- + toStereotype(cls.type()).map(x -> " <<" + x + ">>").orElse("") + " {");
- cls.fields().stream().forEach(f -> {
- b.append("\n {field} " + f.name() + COLON + f.type() + (f.isRequired() ? "" : " {O}"));
- });
- b.append("\n}");
- }
-
- for (Relationship r : model.relationships()) {
- if (r instanceof Association) {
- Association a = (Association) r;
-
- final String mult = toMultiplicity(a.type());
-
- final String label;
- final String arrow;
- if (a.responseCode().isPresent()) {
- arrow = "..>";
- label = a.responseCode().get() + a.responseContentType()
- .filter(x -> !"application/json".equalsIgnoreCase(x))
- .map(x -> SPACE + x).orElse("");
- } else {
- arrow = "-->";
- label = a.propertyOrParameterName().orElse("");
- }
- b.append("\n\n" + quote(a.from()) + SPACE + arrow + SPACE + quote(mult) + SPACE
- + quote(a.to())
- + (label.equals("") ? "" : SPACE + COLON + SPACE + quote(label)));
- } else {
- Inheritance a = (Inheritance) r;
- if (a.propertyName().isPresent() || a.type() != AssociationType.ONE) {
- String mult = toMultiplicity(a.type());
- anonNumber++;
- String diamond = "anon" + anonNumber;
- b.append("\n\ndiamond " + diamond);
- b.append("\n\n" + quote(a.from()) + SPACE + "-->" + quote(mult) + SPACE
- + quote(diamond) + a.propertyName().map(x -> COLON + quote(x)).orElse(""));
- for (String otherClassName : a.to()) {
- b.append("\n\n" + quote(otherClassName) + SPACE + "--|>" + SPACE
- + quote(diamond));
- }
- } else {
- for (String otherClassName : a.to()) {
- b.append("\n\n" + quote(otherClassName) + SPACE + "--|>" + SPACE
- + quote(a.from()));
- }
- }
- }
- }
- return b.toString();
- }
-
- private static String toMultiplicity(AssociationType type) {
- final String mult;
- if (type == AssociationType.ONE) {
- mult = "1";
- } else if (type == AssociationType.ZERO_ONE) {
- mult = "0..1";
- } else {
- mult = "*";
- }
- return mult;
- }
-
- private static Optional toStereotype(ClassType type) {
- final String result;
- if (type == ClassType.METHOD) {
- result = "Path";
- } else if (type == ClassType.PARAMETER) {
- result = "Parameter";
- } else if (type == ClassType.REQUEST_BODY) {
- result = "RequestBody";
- } else if (type == ClassType.RESPONSE) {
- result = "Response";
- } else {
- result = null;
- }
- return Optional.ofNullable(result);
- }
+ public static final String PUML = "PUML";
+
+ public static final Set UNSUPPORTED_FORMATS
+ = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(FileFormat.ANIMATED_GIF.name(),
+ FileFormat.BASE64.name(),
+ FileFormat.HTML.name(),
+ FileFormat.HTML5.name(),
+ FileFormat.MJPEG.name(),
+ FileFormat.PREPROC.name(),
+ FileFormat.PDF.name(),
+ PUML,
+ FileFormat.SCXML.name(),
+ FileFormat.XMI_ARGO.name(),
+ FileFormat.XMI_STANDARD.name(),
+ FileFormat.XMI_STAR.name())));
+
+ public static final Set SUPPORTED_FORMATS = Arrays.stream(FileFormat.values())
+ .sorted(Comparator.comparing(Object::toString))
+ .map(FileFormat::name)
+ .filter(fileFormat -> !UNSUPPORTED_FORMATS.contains(fileFormat))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+
+
+ private static final FileFormat[] SUPPORTED_FILE_FORMAT_ARRAY = Arrays.stream(FileFormat.values())
+ .sorted(Comparator.comparing(Object::toString))
+ .filter(Converter::isFileFormatSupported)
+ .collect(Collectors.toList())
+ .toArray(new FileFormat[]{});
+ public static final String SUPPORTED_FILE_FORMAT_ARRAY_STRING = Arrays.stream(SUPPORTED_FILE_FORMAT_ARRAY)
+ .map(Converter::toString)
+ .collect(Collectors.joining());
+ public static final String SUPPORTED_FORMATS_STRING = SUPPORTED_FORMATS.toString();
+ public static final String DELIMITER = ", ";
+ private static final String COLON = " : ";
+ private static final String SPACE = " ";
+
+ private Converter() {
+ // prevent instantiation
+ }
+
+ public static String toString(FileFormat fileFormat) {
+ StringBuilder stringBuilder = new StringBuilder();
+ String name = fileFormat.name();
+ String fileSuffix = getFileSuffix(fileFormat);
+ String mimeType = fileFormat.getMimeType();
+ stringBuilder.append(name)
+ .append("\t*")
+ .append(fileSuffix)
+ .append("\t")
+ .append(mimeType)
+ .append("\n");
+ return stringBuilder.toString();
+ }
+
+ public static void writeOpenApiToPumlAndTo(String openApiDirectoryFilePath,
+ String outputDirectoryPath,
+ String fileFormatsString)
+ throws
+ Throwables {
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFilePath);
+ File outputDirectory = toOutputDirectory(outputDirectoryPath);
+ Set fileFormats = toFileFormats(fileFormatsString);
+ Throwables throwables = writeOpenApiToPumlAndTo(openApiFiles,
+ outputDirectory,
+ fileFormats);
+ if (!throwables.getThrowables()
+ .isEmpty()) {
+ throw throwables;
+ }
+ }
+
+ private static File toOutputDirectory(String outputDirectoryPath) {
+ File outputDirectory = outputDirectoryPath == null || outputDirectoryPath.isEmpty()
+ ? null
+ : new File(outputDirectoryPath);
+ return outputDirectory;
+ }
+
+ public static void writeOpenApiToPumlAndTo(String openApiDirectoryFilePath,
+ String outputDirectoryPath,
+ Set fileFormats)
+ throws
+ Throwables {
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFilePath);
+ File outputDirectory = toOutputDirectory(outputDirectoryPath);
+ Throwables throwables = writeOpenApiToPumlAndTo(openApiFiles,
+ outputDirectory,
+ fileFormats);
+ if (!throwables.getThrowables()
+ .isEmpty()) {
+ throw throwables;
+ }
+ }
+
+ public static void writeOpenApiToPumlAndTo(String openApiDirectoryFilePath,
+ String outputDirectoryPath,
+ FileFormat... fileFormatsArray)
+ throws
+ Throwables {
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFilePath);
+ File outputDirectory = toOutputDirectory(outputDirectoryPath);
+ Set fileFormats = toFileFormats(fileFormatsArray);
+ Throwables throwables = writeOpenApiToPumlAndTo(openApiFiles,
+ outputDirectory,
+ fileFormats);
+ if (!throwables.getThrowables()
+ .isEmpty()) {
+ throw throwables;
+ }
+ }
+
+ public static void writeOpenApiDirectoryFileToPumlAndTo(File openApiDirectoryFile,
+ File outputDirectory,
+ Set fileFormats)
+ throws
+ Throwables {
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFile);
+ Throwables throwables = writeOpenApiToPumlAndTo(openApiFiles,
+ outputDirectory,
+ fileFormats);
+ if (!throwables.getThrowables()
+ .isEmpty()) {
+ throw throwables;
+ }
+ }
+
+ public static void writeOpenApiDirectoryFileToPumlAndTo(File openApiDirectoryFile,
+ File outputDirectory,
+ FileFormat... fileFormatsArray)
+ throws
+ Throwables {
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFile);
+ Set fileFormats = toFileFormats(fileFormatsArray);
+ Throwables throwables = writeOpenApiToPumlAndTo(openApiFiles,
+ outputDirectory,
+ fileFormats);
+ if (!throwables.getThrowables()
+ .isEmpty()) {
+ throw throwables;
+ }
+ }
+
+ private static Set toOpenApiFiles(String openApiDirectoryFilePath) {
+ File openApiDirectoryFile = new File(openApiDirectoryFilePath);
+ Set openApiFiles = toOpenApiFiles(openApiDirectoryFile);
+ return openApiFiles;
+ }
+
+
+ private static Set toOpenApiFiles(File openApiDirectoryFile) {
+ Set openApiFiles = null;
+ if (openApiDirectoryFile.isDirectory()) {
+ File[] openApiFileArray = openApiDirectoryFile.listFiles(Converter::acceptOpenApiYamlFileAtDirectory);
+ openApiFiles = toOpenApiFiles(openApiFileArray);
+ } else if (acceptOpenApiYamlFile(openApiDirectoryFile)) {
+ openApiFiles = new LinkedHashSet<>();
+ openApiFiles.add(openApiDirectoryFile);
+ }
+ return openApiFiles;
+ }
+
+ private static boolean acceptOpenApiYamlFile(File openApiFile) {
+ boolean acceptFile = acceptOpenApiYamlFileAtDirectory(openApiFile.getParentFile(),
+ openApiFile.getName());
+ return acceptFile;
+ }
+
+ private static boolean acceptOpenApiYamlFileAtDirectory(File dir,
+ String name) {
+ String nameToLowerCase = name.toLowerCase(Locale.ROOT);
+ boolean isYaml = nameToLowerCase.endsWith(".yml") || nameToLowerCase.endsWith(".yaml");
+ return isYaml;
+ }
+
+ private static Set toOpenApiFiles(File... openApiFileArray) {
+ Set openApiFilesSet = openApiFileArray == null
+ ? null
+ : Arrays.stream(openApiFileArray)
+ .sorted(Comparator.comparing(File::getName))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ return openApiFilesSet;
+ }
+
+ private static Set toFileFormats(String fileFormatsString) {
+ Set fileFormats = null;
+ if (fileFormatsString != null) {
+ String fileFormatsValuesString = fileFormatsString.contains("[") && fileFormatsString.contains("]")
+ ? fileFormatsString.substring(1,
+ fileFormatsString.length() - 1)
+ : fileFormatsString;
+ fileFormats = Arrays.stream(fileFormatsValuesString.split(DELIMITER))
+ .collect(Collectors.toSet());
+ }
+ return fileFormats;
+ }
+
+ private static Set toFileFormats(FileFormat... fileFormatsArray) {
+
+ Set fileFormats = null;
+ if (fileFormatsArray != null && fileFormatsArray.length > 0) {
+ fileFormats = Arrays.stream(fileFormatsArray)
+ .map(Enum::name)
+ .collect(Collectors.toSet());
+ }
+ return fileFormats;
+ }
+
+ private static Throwables writeOpenApiToPumlAndTo(Set openApiFiles,
+ File outputDirectory,
+ Set fileFormat) {
+ Throwables throwables = new Throwables();
+ Set openApiFilesThrowables = throwables.getThrowables();
+ if (openApiFiles == null || openApiFiles.isEmpty()) {
+ throw new IllegalArgumentException("Open Api Files are null or empty or contains no *.yml or *.yaml files");
+ }
+ for (File openApiFile : openApiFiles) {
+ Throwables openApiFileThrowables = writeOpenApiToPumlAndTo(openApiFile,
+ outputDirectory,
+ fileFormat);
+ if (!openApiFileThrowables.getThrowables()
+ .isEmpty()) {
+ openApiFilesThrowables.add(openApiFileThrowables);
+ }
+ }
+ return throwables;
+ }
+
+ public static Throwables writeOpenApiToPumlAndTo(File openApiFile,
+ File outputDirectory,
+ Set fileFormats) {
+ createOutputDirectoryIfNeeded(outputDirectory);
+ Throwables throwables = new Throwables(openApiFile.getAbsolutePath());
+ String openApiFileName = openApiFile.getName();
+
+ String openApiFileNameWithoutExtension = openApiFileName.substring(0,
+ openApiFileName.lastIndexOf("."));
+ String puml;
+ Set openApiFileThrowables = throwables.getThrowables();
+ try {
+ puml = writeOpenApiToPuml(openApiFile,
+ outputDirectory,
+ openApiFileNameWithoutExtension);
+ } catch (IOException ioException) {
+ openApiFileThrowables.add(ioException);
+ return throwables;
+ }
+ if (fileFormats != null && !fileFormats.isEmpty()) {
+ for (String fileFormat : fileFormats) {
+ try {
+ writePumlTo(puml,
+ outputDirectory,
+ openApiFileNameWithoutExtension,
+ fileFormat);
+ } catch (Exception exception) {
+ openApiFileThrowables.add(exception);
+ }
+ }
+ }
+ return throwables;
+ }
+
+ public static boolean createOutputDirectoryIfNeeded(File outputDirectory) {
+ if (outputDirectory == null) {
+ throw new IllegalArgumentException("Output Directory is null or empty");
+ }
+ boolean mkdirs = outputDirectory.mkdirs();
+ if (mkdirs) {
+ info("Created new Directory: %s%n",
+ outputDirectory.getAbsolutePath());
+ }
+ if (!outputDirectory.isDirectory()) {
+ throw new IllegalArgumentException("Output Directory is not a Directory");
+ }
+ return mkdirs;
+ }
+
+ public static String writeOpenApiToPuml(File openApiFile,
+ File outputDirectory,
+ String openApiFileNameWithoutExtension)
+ throws
+ IOException {
+ String pumlFilePath = String.format("%s.puml",
+ openApiFileNameWithoutExtension);
+ File pumlFile = new File(outputDirectory,
+ pumlFilePath);
+ info("Converting Open API File%n%s%nto PUML%n%s%n",
+ openApiFile.getAbsolutePath(),
+ pumlFile.getAbsolutePath());
+ String puml = writeOpenApiToPuml(openApiFile,
+ pumlFile);
+ return puml;
+ }
+
+ public static String writeOpenApiToPuml(File openApiFile,
+ File pumlFile)
+ throws
+ IOException {
+ String puml = openApiToPuml(openApiFile);
+ saveUTF(PUML,
+ puml,
+ pumlFile);
+ return puml;
+ }
+
+ public static void saveUTF(String fileFormat,
+ String utf8String,
+ File outputFile)
+ throws
+ IOException {
+ deletedIfExists(fileFormat,
+ outputFile);
+ info("Saving %s File: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ Files.write(outputFile.toPath(),
+ utf8String.getBytes(StandardCharsets.UTF_8));
+ info("%s File Saved: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ }
+
+ public static DiagramDescription writePumlTo(String puml,
+ File outputDirectory,
+ String openApiFileNameWithoutExtension,
+ String fileFormat)
+ throws
+ IOException {
+ if (PUML.equalsIgnoreCase(fileFormat)) {
+ return null;
+ }
+ if (!isFileFormatSupported(fileFormat)) {
+ String message = String.format("PUML cannot be saved as %s File",
+ fileFormat);
+ throw new IOException(message);
+ }
+ FileFormat fileFormatEnum = FileFormat.valueOf(fileFormat);
+ String fileSuffix = getFileSuffix(fileFormatEnum);
+ String outputFilePath = String.format("%s.puml%s",
+ openApiFileNameWithoutExtension,
+ fileSuffix);
+ File outputFile = new File(outputDirectory,
+ outputFilePath);
+ FileFormatOption fileFormatOption = new FileFormatOption(fileFormatEnum);
+ DiagramDescription diagramDescription = writePumlTo(puml,
+ outputFile,
+ fileFormatOption);
+ return diagramDescription;
+ }
+
+ public static String getFileSuffix(FileFormat fileFormat) {
+ String fileReplacementSuffix = String.format(".%s",
+ fileFormat.name()
+ .toLowerCase(Locale.ROOT)
+ .replaceAll("_",
+ "."));
+ String fileFormatEnumSuffix = fileFormat.getFileSuffix();
+ String fileSuffix = fileReplacementSuffix.equals(fileFormatEnumSuffix)
+ ? fileFormatEnumSuffix
+ : fileReplacementSuffix + fileFormatEnumSuffix;
+ return fileSuffix;
+ }
+
+ static boolean isFileFormatSupported(FileFormat fileFormat) {
+ boolean isFileFormatSupported = isFileFormatSupported(fileFormat.name());
+ return isFileFormatSupported;
+ }
+
+ static boolean isFileFormatSupported(String fileFormat) {
+ boolean isFileFormatSupported =
+ !UNSUPPORTED_FORMATS.contains(fileFormat) && SUPPORTED_FORMATS.contains(fileFormat);
+ return isFileFormatSupported;
+ }
+
+ private static DiagramDescription writePumlTo(String puml,
+ File outputFile,
+ FileFormatOption fileFormatOption)
+ throws
+ IOException {
+ String fileFormat = fileFormatOption.getFileFormat()
+ .name();
+ deletedIfExists(fileFormat,
+ outputFile);
+ info("Saving %s File: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ SourceStringReader sourceStringReader = new SourceStringReader(puml);
+ try (OutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputFile))) {
+ DiagramDescription diagramDescription = sourceStringReader.outputImage(bufferedOutputStream,
+ fileFormatOption);
+ info("%s File Saved: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ info("%s Diagram Description: %s%n",
+ fileFormat,
+ diagramDescription.getDescription());
+ return diagramDescription;
+ } catch (IOException exception) {
+ error("PUML cannot be saved as %s File: %s%n%s",
+ fileFormat,
+ outputFile.getAbsolutePath(),
+ exception);
+ throw exception;
+ }
+ }
+
+ public static boolean deletedIfExists(String fileFormat,
+ File outputFile) {
+ if (outputFile.exists()) {
+ info("Deleting old %s File: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ boolean deleted = outputFile.delete();
+ if (deleted) {
+ info("Deleted old %s File: %s%n",
+ fileFormat,
+ outputFile.getAbsolutePath());
+ }
+ return deleted;
+ }
+ return false;
+ }
+
+ public static String openApiToPuml(InputStream in)
+ throws
+ IOException {
+ String puml = openApiToPuml(IOUtils.toString(in,
+ StandardCharsets.UTF_8));
+ return puml;
+ }
+
+ public static String openApiToPuml(File openApiFile)
+ throws
+ IOException {
+ info("Open Api File to PUML: %s%n",
+ openApiFile.getAbsolutePath());
+ try (InputStream openApiFileInputStream = new BufferedInputStream(new FileInputStream(openApiFile))) {
+ String puml = openApiToPuml(openApiFileInputStream);
+ return puml;
+ }
+ }
+
+ public static String openApiToPuml(String openApi) {
+ SwaggerParseResult result = new OpenAPIParser().readContents(openApi,
+ null,
+ null);
+ if (result.getOpenAPI() == null) {
+ throw new IllegalArgumentException("Not an OpenAPI definition");
+ }
+ return openApiToPuml(result.getOpenAPI());
+ }
+
+ private static String openApiToPuml(OpenAPI a) {
+
+ Names names = new Names(a);
+ Model model = ComponentsHelper //
+ .toModel(names) //
+ .add(PathsHelper.toModel(names));
+
+ return "@startuml" //
+ + "\nhide <<" + toStereotype(ClassType.METHOD).get() + ">> circle" //
+ + "\nhide <<" + toStereotype(ClassType.RESPONSE).get() + ">> circle" //
+ + "\nhide <<" + toStereotype(ClassType.PARAMETER).get() + ">> circle" //
+ + "\nhide empty methods" //
+ + "\nhide empty fields" //
+ // make sure that periods in class names aren't interpreted as namespace
+ // separators (which results in recursive boxing)
+ + "\nset namespaceSeparator none" //
+ + toPlantUml(model) //
+ + "\n\n@enduml";
+ }
+
+ private static String toPlantUml(Model model) {
+ int anonNumber = 0;
+ StringBuilder b = new StringBuilder();
+ for (Class cls : model.classes()) {
+ b.append("\n\nclass " + Util.quote(cls.name()) + toStereotype(cls.type()).map(x -> " <<" + x + ">>")
+ .orElse("") + " {");
+ cls.fields()
+ .stream()
+ .forEach(f -> {
+ b.append("\n {field} " + f.name() + COLON + f.type() + (f.isRequired()
+ ? ""
+ : " {O}"));
+ });
+ b.append("\n}");
+ }
+
+ for (Relationship r : model.relationships()) {
+ if (r instanceof Association) {
+ Association a = (Association) r;
+
+ final String mult = toMultiplicity(a.type());
+
+ final String label;
+ final String arrow;
+ if (a.responseCode()
+ .isPresent()) {
+ arrow = "..>";
+ label = a.responseCode()
+ .get() + a.responseContentType()
+ .filter(x -> !"application/json".equalsIgnoreCase(x))
+ .map(x -> SPACE + x)
+ .orElse("");
+ } else {
+ arrow = "-->";
+ label = a.propertyOrParameterName()
+ .orElse("");
+ }
+ b.append("\n\n"
+ + quote(a.from())
+ + SPACE
+ + arrow
+ + SPACE
+ + quote(mult)
+ + SPACE
+ + quote(a.to())
+ + (label.equals("")
+ ? ""
+ : SPACE + COLON + SPACE + quote(label)));
+ } else {
+ Inheritance a = (Inheritance) r;
+ if (a.propertyName()
+ .isPresent() || a.type() != AssociationType.ONE) {
+ String mult = toMultiplicity(a.type());
+ anonNumber++;
+ String diamond = "anon" + anonNumber;
+ b.append("\n\ndiamond " + diamond);
+ b.append("\n\n")
+ .append(quote(a.from()))
+ .append(SPACE)
+ .append("-->")
+ .append(quote(mult))
+ .append(SPACE)
+ .append(quote(diamond))
+ .append(a.propertyName()
+ .map(x -> COLON + quote(x))
+ .orElse(""));
+ for (String otherClassName : a.to()) {
+ b.append("\n\n")
+ .append(quote(otherClassName))
+ .append(SPACE)
+ .append("--|>")
+ .append(SPACE)
+ .append(quote(diamond));
+ }
+ } else {
+ for (String otherClassName : a.to()) {
+ b.append("\n\n")
+ .append(quote(otherClassName))
+ .append(SPACE)
+ .append("--|>")
+ .append(SPACE)
+ .append(quote(a.from()));
+ }
+ }
+ }
+ }
+ return b.toString();
+ }
+
+ private static String toMultiplicity(AssociationType type) {
+ final String mult;
+ if (type == AssociationType.ONE) {
+ mult = "1";
+ } else if (type == AssociationType.ZERO_ONE) {
+ mult = "0..1";
+ } else {
+ mult = "*";
+ }
+ return mult;
+ }
+
+ private static Optional toStereotype(ClassType type) {
+ final String result;
+ if (type == ClassType.METHOD) {
+ result = "Path";
+ } else if (type == ClassType.PARAMETER) {
+ result = "Parameter";
+ } else if (type == ClassType.REQUEST_BODY) {
+ result = "RequestBody";
+ } else if (type == ClassType.RESPONSE) {
+ result = "Response";
+ } else {
+ result = null;
+ }
+ return Optional.ofNullable(result);
+ }
+
+
+ static String getPropertyOrArg(String[] arguments,
+ int index,
+ String key,
+ String defaultValue) {
+ String argument = arguments.length > index
+ ? arguments[index]
+ : null;
+ String property = System.getProperty(key,
+ null);
+ String value = argument != null
+ ? argument
+ : property != null
+ ? property
+ : defaultValue;
+ info("%s=%s Default Value=%s Argument[%d]=%s Property=%s%n",
+ key,
+ value,
+ defaultValue,
+ index,
+ argument,
+ property);
+ return value;
+ }
+
+ static void info(String format,
+ Object... params) {
+ System.out.printf(format,
+ params);
+ }
+
+ static void error(String format,
+ Object... params) {
+ System.err.printf(format,
+ params);
+ }
+ static void error(Throwable throwable,
+ String format,
+ Object... params) {
+ System.err.printf(format,
+ params);
+ throwable.printStackTrace();
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/puml/ConverterMain.java b/src/main/java/com/github/davidmoten/oas3/puml/ConverterMain.java
index d1c9a86d..7b591df1 100644
--- a/src/main/java/com/github/davidmoten/oas3/puml/ConverterMain.java
+++ b/src/main/java/com/github/davidmoten/oas3/puml/ConverterMain.java
@@ -1,54 +1,54 @@
package com.github.davidmoten.oas3.puml;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.stream.Collectors;
-
-import net.sourceforge.plantuml.FileFormat;
-import net.sourceforge.plantuml.FileFormatOption;
-import net.sourceforge.plantuml.SourceStringReader;
-import net.sourceforge.plantuml.core.DiagramDescription;
+import com.github.davidmoten.oas3.internal.model.Throwables;
public final class ConverterMain {
- private ConverterMain() {
- // prevent instantiation
- }
-
- static DiagramDescription writeFileFormatFromPuml(String puml, String filename,
- FileFormat fileFormat) throws IOException {
- File file = new File(filename);
- SourceStringReader reader = new SourceStringReader(puml);
- try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
- // Write the first image to "os"
- return reader.outputImage(os, new FileFormatOption(fileFormat));
- }
- }
+ public static final String JAVA_JAR = "java -jar openapi-to-plantuml-all.jar "
+ + "|<[FILE_FORMAT1, FILE_FORMAT1...]>\n";
+ public static final String USAGE = JAVA_JAR
+ + " file or Directory containing *.yml or *.yaml files\n"
+ + " output Directory\n"
+ + " optional file format default PUML and SVG only\n"
+ + " or"
+ + "<[FILE_FORMAT1, FILE_FORMAT1...]> optional several file formats\n"
+ + "surrounded by [delimited by comma and space ', ')] i.e. supported formats "
+ + "are:\n"
+ + Converter.SUPPORTED_FORMATS_STRING
+ + "\n"
+ + Converter.SUPPORTED_FILE_FORMAT_ARRAY_STRING;
- public static void main(String[] args) throws IOException {
- String usage = "Usage: java -jar openapi-to-plantuml-all.jar "
- + "\n File formats are:\n PUML\n" + Arrays.stream(FileFormat.values())
- .map(x -> " " + x + "\n").collect(Collectors.joining());
- if (args.length != 3) {
- System.out.println(usage);
- throw new IllegalArgumentException("must pass 3 arguments");
- } else {
- String puml = Converter.openApiToPuml(new File(args[0]));
- String format = args[1];
- File out = new File(args[2]);
- if (format.equals("PUML")) {
- Files.write(out.toPath(), puml.getBytes(StandardCharsets.UTF_8));
- } else {
- FileFormat ff = FileFormat.valueOf(format);
- writeFileFormatFromPuml(puml, out.getPath(), ff);
- }
- }
- }
+ private ConverterMain() {
+ // prevent instantiation
+ }
+ public static void main(String[] arguments)
+ throws
+ Throwables {
+ try {
+ if (arguments.length < 2) {
+ throw new IllegalArgumentException("must pass 2-3 arguments");
+ }
+ String openApiFilePath = Converter.getPropertyOrArg(arguments,
+ 0,
+ "OPENAPI_YAML",
+ "./openapi.yaml");
+ String outputDirectoryPath = Converter.getPropertyOrArg(arguments,
+ 1,
+ "OUTPUT_DIRECTORY",
+ ".");
+ String fileFormatsString = Converter.getPropertyOrArg(arguments,
+ 2,
+ "FILE_FORMAT",
+ "SVG");
+ Converter.writeOpenApiToPumlAndTo(openApiFilePath,
+ outputDirectoryPath,
+ fileFormatsString);
+ } catch (Exception | Throwables throwable) {
+ Converter.error(throwable,
+ "%nUsage:%n%s%n",
+ USAGE);
+ throw throwable;
+ }
+ }
}
diff --git a/src/main/java/com/github/davidmoten/oas3/puml/package-info.java b/src/main/java/com/github/davidmoten/oas3/puml/package-info.java
index a7a105a4..f3f88d6a 100644
--- a/src/main/java/com/github/davidmoten/oas3/puml/package-info.java
+++ b/src/main/java/com/github/davidmoten/oas3/puml/package-info.java
@@ -1,7 +1,7 @@
/**
* Converts OpenAPI to PlantUML.
*
- * @since 1.0
* @see java.awt
+ * @since 1.0
*/
package com.github.davidmoten.oas3.puml;
\ No newline at end of file
diff --git a/src/main/spotbugs/filter.xml b/src/main/spotbugs/filter.xml
index 12f12056..9fa4de4e 100644
--- a/src/main/spotbugs/filter.xml
+++ b/src/main/spotbugs/filter.xml
@@ -1,12 +1,12 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://github.com/spotbugs/filter/3.0.0"
+ xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">
-
+ name="~com\.github\.davidmoten\.oas3\.internal\..*"/>
+
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/CommonTest.java b/src/test/java/com/github/davidmoten/oas3/internal/CommonTest.java
index dca8f96c..fa079ac5 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/CommonTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/CommonTest.java
@@ -1,14 +1,13 @@
package com.github.davidmoten.oas3.internal;
-import org.junit.Test;
-
import com.github.davidmoten.junit.Asserts;
+import org.junit.Test;
public class CommonTest {
- @Test
- public void testIsUtilityClass() {
- Asserts.assertIsUtilityClass(Common.class);
- }
+ @Test
+ public void testIsUtilityClass() {
+ Asserts.assertIsUtilityClass(Common.class);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/ComponentsHelperTest.java b/src/test/java/com/github/davidmoten/oas3/internal/ComponentsHelperTest.java
index df76b889..d3a4f9fc 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/ComponentsHelperTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/ComponentsHelperTest.java
@@ -1,14 +1,13 @@
package com.github.davidmoten.oas3.internal;
-import org.junit.Test;
-
import com.github.davidmoten.junit.Asserts;
+import org.junit.Test;
public class ComponentsHelperTest {
- @Test
- public void testIsUtilityClass() {
- Asserts.assertIsUtilityClass(ComponentsHelper.class);
- }
+ @Test
+ public void testIsUtilityClass() {
+ Asserts.assertIsUtilityClass(ComponentsHelper.class);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/NamesTest.java b/src/test/java/com/github/davidmoten/oas3/internal/NamesTest.java
index 2e2894af..d3ddeaaa 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/NamesTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/NamesTest.java
@@ -1,18 +1,17 @@
package com.github.davidmoten.oas3.internal;
-import org.junit.Test;
-
import io.swagger.v3.oas.models.OpenAPI;
+import org.junit.Test;
public class NamesTest {
- @Test(expected = RuntimeException.class)
- public void testRefToClassNameNotFound() {
- emptyNames().refToClassName("abc");
- }
+ private static Names emptyNames() {
+ OpenAPI a = new OpenAPI();
+ return new Names(a);
+ }
- private static Names emptyNames() {
- OpenAPI a = new OpenAPI();
- return new Names(a);
- }
+ @Test(expected = RuntimeException.class)
+ public void testRefToClassNameNotFound() {
+ emptyNames().refToClassName("abc");
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/PathsHelperTest.java b/src/test/java/com/github/davidmoten/oas3/internal/PathsHelperTest.java
index 586992d0..052c8c54 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/PathsHelperTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/PathsHelperTest.java
@@ -1,14 +1,13 @@
package com.github.davidmoten.oas3.internal;
-import org.junit.Test;
-
import com.github.davidmoten.junit.Asserts;
+import org.junit.Test;
public class PathsHelperTest {
- @Test
- public void testIsUtilityClass() {
- Asserts.assertIsUtilityClass(PathsHelper.class);
- }
+ @Test
+ public void testIsUtilityClass() {
+ Asserts.assertIsUtilityClass(PathsHelper.class);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/UtilTest.java b/src/test/java/com/github/davidmoten/oas3/internal/UtilTest.java
index c3f544a4..3b4c87b9 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/UtilTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/UtilTest.java
@@ -1,14 +1,13 @@
package com.github.davidmoten.oas3.internal;
-import org.junit.Test;
-
import com.github.davidmoten.junit.Asserts;
+import org.junit.Test;
public class UtilTest {
- @Test
- public void testIsUtilityClass() {
- Asserts.assertIsUtilityClass(Util.class);
- }
+ @Test
+ public void testIsUtilityClass() {
+ Asserts.assertIsUtilityClass(Util.class);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/model/AssociationTest.java b/src/test/java/com/github/davidmoten/oas3/internal/model/AssociationTest.java
index 1ea52a4c..6c19f727 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/model/AssociationTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/model/AssociationTest.java
@@ -1,17 +1,23 @@
package com.github.davidmoten.oas3.internal.model;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
public class AssociationTest {
- @Test
- public void testToString() {
- Association a = Association.from("thing").to("stuff").zeroOne().propertyOrParameterName("hello")
- .responseCode("200").responseContentType("application/json").build();
- assertEquals("Association [from=thing, to=stuff, type=ZERO_ONE, responseCode=200, "
- + "responseContentType=application/json, propertyOrParameterName=hello]", a.toString());
- }
+ @Test
+ public void testToString() {
+ Association a = Association.from("thing")
+ .to("stuff")
+ .zeroOne()
+ .propertyOrParameterName("hello")
+ .responseCode("200")
+ .responseContentType("application/json")
+ .build();
+ assertEquals("Association [from=thing, to=stuff, type=ZERO_ONE, responseCode=200, "
+ + "responseContentType=application/json, propertyOrParameterName=hello]",
+ a.toString());
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/model/FieldTest.java b/src/test/java/com/github/davidmoten/oas3/internal/model/FieldTest.java
index 268a5ce0..00ee2eae 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/model/FieldTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/model/FieldTest.java
@@ -1,17 +1,21 @@
package com.github.davidmoten.oas3.internal.model;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import org.junit.Test;
-
public class FieldTest {
- @Test
- public void testToString() {
- Field f = new Field("aliases", "string[]", true, false);
- assertEquals("Field [name=aliases, type=string[], isArray=true, required=false]", f.toString());
- assertTrue(f.isArray());
- }
+ @Test
+ public void testToString() {
+ Field f = new Field("aliases",
+ "string[]",
+ true,
+ false);
+ assertEquals("Field [name=aliases, type=string[], isArray=true, required=false]",
+ f.toString());
+ assertTrue(f.isArray());
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/model/InheritanceTest.java b/src/test/java/com/github/davidmoten/oas3/internal/model/InheritanceTest.java
index a26449fa..1445f086 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/model/InheritanceTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/model/InheritanceTest.java
@@ -1,22 +1,25 @@
package com.github.davidmoten.oas3.internal.model;
-import static org.junit.Assert.assertEquals;
+import com.github.davidmoten.guavamini.Lists;
+import org.junit.Test;
import java.util.Optional;
-import org.junit.Test;
-
-import com.github.davidmoten.guavamini.Lists;
+import static org.junit.Assert.assertEquals;
public class InheritanceTest {
- @Test
- public void testToString() {
- Inheritance a = new Inheritance("Vehicle", Lists.newArrayList("Car", "Motorbike"), AssociationType.ONE,
- Optional.of("vehicle"));
- assertEquals("Inheritance [from=Vehicle, to=[Car, Motorbike], type=ONE, propertyName=Optional[vehicle]]",
- a.toString());
- assertEquals(AssociationType.ONE, a.type());
- }
+ @Test
+ public void testToString() {
+ Inheritance a = new Inheritance("Vehicle",
+ Lists.newArrayList("Car",
+ "Motorbike"),
+ AssociationType.ONE,
+ Optional.of("vehicle"));
+ assertEquals("Inheritance [from=Vehicle, to=[Car, Motorbike], type=ONE, propertyName=Optional[vehicle]]",
+ a.toString());
+ assertEquals(AssociationType.ONE,
+ a.type());
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/internal/model/ModelTest.java b/src/test/java/com/github/davidmoten/oas3/internal/model/ModelTest.java
index b4e328cc..82f2cbea 100644
--- a/src/test/java/com/github/davidmoten/oas3/internal/model/ModelTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/internal/model/ModelTest.java
@@ -1,28 +1,40 @@
package com.github.davidmoten.oas3.internal.model;
-import static org.junit.Assert.assertEquals;
-
+import com.github.davidmoten.guavamini.Lists;
import org.junit.Test;
-import com.github.davidmoten.guavamini.Lists;
+import static org.junit.Assert.assertEquals;
public class ModelTest {
- @Test
- public void testToString() {
- Model model = new Model(//
- Lists.newArrayList(//
- new Class("Thing", ClassType.SCHEMA), //
- new Class("Stuff", ClassType.SCHEMA)),
- Lists.newArrayList(//
- Association.from("Thing").to("Stuff").zeroOne().build(), //
- Association.from("Thing").to("Other").one().build()));
- assertEquals("Model [\n" + " Class [name=Thing, type=Schema, fields=[]],\n"
- + " Class [name=Stuff, type=Schema, fields=[]]\n"
- + " Association [from=Thing, to=Stuff, type=ZERO_ONE, responseCode=, "
- + "responseContentType=, propertyOrParameterName=],\n"
- + " Association [from=Thing, to=Other, type=ONE, responseCode=, "
- + "responseContentType=, propertyOrParameterName=]\n" + "]", model.toString());
- }
+ @Test
+ public void testToString() {
+ Model model = new Model(//
+ Lists.newArrayList(//
+ new Class("Thing",
+ ClassType.SCHEMA),
+ //
+ new Class("Stuff",
+ ClassType.SCHEMA)),
+ Lists.newArrayList(//
+ Association.from("Thing")
+ .to("Stuff")
+ .zeroOne()
+ .build(),
+ //
+ Association.from("Thing")
+ .to("Other")
+ .one()
+ .build()));
+ assertEquals("Model [\n"
+ + " Class [name=Thing, type=Schema, fields=[]],\n"
+ + " Class [name=Stuff, type=Schema, fields=[]]\n"
+ + " Association [from=Thing, to=Stuff, type=ZERO_ONE, responseCode=, "
+ + "responseContentType=, propertyOrParameterName=],\n"
+ + " Association [from=Thing, to=Other, type=ONE, responseCode=, "
+ + "responseContentType=, propertyOrParameterName=]\n"
+ + "]",
+ model.toString());
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/ConverterBatchTest.java b/src/test/java/com/github/davidmoten/oas3/puml/ConverterBatchTest.java
index 71edfc45..9106a149 100644
--- a/src/test/java/com/github/davidmoten/oas3/puml/ConverterBatchTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/puml/ConverterBatchTest.java
@@ -1,12 +1,10 @@
package com.github.davidmoten.oas3.puml;
-import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
+import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
@@ -14,55 +12,68 @@
import java.util.Collections;
import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class ConverterBatchTest {
- private static final File INPUTS = new File("src/test/resources/inputs/");
- private static final File OUTPUTS = new File("src/test/resources/outputs/");
+ private static final File INPUTS = new File("src/test/resources/inputs/");
+ private static final File OUTPUTS = new File("src/test/resources/outputs/");
- private final File input;
+ private final File input;
- public ConverterBatchTest(File input) {
- this.input = input;
- }
+ public ConverterBatchTest(File input) {
+ this.input = input;
+ }
- @Parameterized.Parameters(name = "{0}")
- public static Collection> files() {
- File[] list = INPUTS.listFiles();
- if (list == null) {
- return Collections.emptyList();
- } else {
- List result = Arrays.asList(list);
- Collections.sort(result, (a, b) -> a.getName().compareTo(b.getName()));
- return result;
- }
- }
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection> files() {
+ File[] list = INPUTS.listFiles();
+ if (list == null) {
+ return Collections.emptyList();
+ } else {
+ List result = Arrays.asList(list);
+ Collections.sort(result,
+ (a, b) -> a.getName()
+ .compareTo(b.getName()));
+ return result;
+ }
+ }
- @Test
- public void test() {
- System.out.println("checking " + input);
- try (InputStream in = new FileInputStream(input)) {
- String puml = Converter.openApiToPuml(in).trim();
- File pumlFile = new File("target/outputs",
- input.getName().substring(0, input.getName().lastIndexOf('.')) + ".puml");
- pumlFile.getParentFile().mkdirs();
- pumlFile.delete();
- Files.write(pumlFile.toPath(), puml.getBytes(StandardCharsets.UTF_8));
- File output = new File(OUTPUTS, input.getName().substring(0, input.getName().lastIndexOf('.')) + ".puml");
- if (!output.exists()) {
- output.createNewFile();
- System.out.println(puml);
- }
- String expected = com.github.davidmoten.junit.Files.readUtf8(output).trim();
- ConverterTest.writeSvg(input, "target/outputs/" + output.getName() + ".svg");
- assertEquals(expected, puml);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
+ @Test
+ public void test() {
+ System.out.println("checking " + input);
+ try (InputStream in = new FileInputStream(input)) {
+ String puml = Converter.openApiToPuml(in)
+ .trim();
+ File pumlFile = new File("target/outputs",
+ input.getName()
+ .substring(0,
+ input.getName()
+ .lastIndexOf('.')) + ".puml");
+ pumlFile.getParentFile()
+ .mkdirs();
+ pumlFile.delete();
+ Files.write(pumlFile.toPath(),
+ puml.getBytes(StandardCharsets.UTF_8));
+ File output = new File(OUTPUTS,
+ input.getName()
+ .substring(0,
+ input.getName()
+ .lastIndexOf('.')) + ".puml");
+ if (!output.exists()) {
+ output.createNewFile();
+ System.out.println(puml);
+ }
+ String expected = com.github.davidmoten.junit.Files.readUtf8(output)
+ .trim();
+ ConverterTest.writeSvg(input,
+ "target/outputs/" + output.getName() + ".svg");
+ assertEquals(expected,
+ puml);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/ConverterMainTest.java b/src/test/java/com/github/davidmoten/oas3/puml/ConverterMainTest.java
index b09f82f9..90d19841 100644
--- a/src/test/java/com/github/davidmoten/oas3/puml/ConverterMainTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/puml/ConverterMainTest.java
@@ -1,45 +1,81 @@
package com.github.davidmoten.oas3.puml;
-import java.io.File;
-import java.io.IOException;
-
+import com.github.davidmoten.junit.Asserts;
+import com.github.davidmoten.oas3.internal.model.Throwables;
import org.junit.Test;
-import com.github.davidmoten.junit.Asserts;
+public class ConverterMainTest {
-import net.sourceforge.plantuml.FileFormat;
+ @Test(expected = Throwables.class)
+ public void testFileToPumlAndToUnsupportedFormats()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/openapi-example.yml",
+ "target/converted-puml/",
+ Converter.UNSUPPORTED_FORMATS.toString()};
+ ConverterMain.main(args);
+ }
-public class ConverterMainTest {
+ @Test(expected = IllegalArgumentException.class)
+ public void testFileToPumlAndToToSupportedFormatsNotYAML()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/log4j.properties",
+ "target/converted-puml/",
+ Converter.SUPPORTED_FORMATS.toString()};
+ ConverterMain.main(args);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testFileToPumlAndToToSupportedFormatsNotOutputDirectory()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/openapi-example.yml",
+ "src/test/resources/err.yml",
+ Converter.SUPPORTED_FORMATS.toString()};
+ ConverterMain.main(args);
+ }
+
+ @Test
+ public void testFileToPuml()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/openapi-example.yml",
+ "target/converted-puml",
+ "PUML"};
+ ConverterMain.main(args);
+ }
+
+ @Test
+ public void testFileToPumlAndToSVG()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/openapi-example.yml",
+ "target/converted-puml",
+ "SVG"};
+ ConverterMain.main(args);
+ }
+
+ @Test
+ public void testFolderToPumlAndToSupportedFormats()
+ throws
+ Throwables {
+ String[] args = new String[]{"src/test/resources/demo",
+ "target/converted-puml/demo",
+ Converter.SUPPORTED_FORMATS.toString()};
+ ConverterMain.main(args);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testWrongNumberOfArgs()
+ throws
+ Throwables {
+ ConverterMain.main(new String[]{"a"});
+ }
- @Test
- public void testToImages() throws IOException {
- for (FileFormat ff : new FileFormat[] {FileFormat.PNG, FileFormat.SVG, FileFormat.LATEX}) {
- try {
- String[] args = new String[] {"src/test/resources/openapi-example.yml",
- ff.toString(),
- new File("target/converted." + ff.getFileSuffix()).getPath()};
- ConverterMain.main(args);
- } catch (Throwable e) {
- //
- }
- }
- }
-
- @Test
- public void testToPuml() throws IOException {
- String[] args = new String[] {"src/test/resources/openapi-example.yml", "PUML",
- "target/converted.puml"};
- ConverterMain.main(args);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testWrongNumberOfArgs() throws IOException {
- ConverterMain.main(new String[] {"a"});
- }
-
- @Test
- public void isUtilityClass() {
- Asserts.assertIsUtilityClass(ConverterMain.class);
- }
+ @Test
+ public void isUtilityClass() {
+ Asserts.assertIsUtilityClass(ConverterMain.class);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/ConverterTest.java b/src/test/java/com/github/davidmoten/oas3/puml/ConverterTest.java
index 3902ea58..0a1a7f1e 100644
--- a/src/test/java/com/github/davidmoten/oas3/puml/ConverterTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/puml/ConverterTest.java
@@ -1,110 +1,143 @@
package com.github.davidmoten.oas3.puml;
-import static org.junit.Assert.assertFalse;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
import com.github.davidmoten.junit.Asserts;
-
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.core.DiagramDescription;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
+import static org.junit.Assert.assertFalse;
public class ConverterTest {
- private static final File OPENAPI_EXAMPLE = new File("src/test/resources/openapi-example.yml");
-
- @Test
- public void testIsUtility() {
- Asserts.assertIsUtilityClass(Converter.class);
- }
-
- @Test
- public void testConvert() {
- String openapi = "openapi: 3.0.1\n" + "components:\n" + " schemas:\n"
- + " CustomerType:\n" + " type: string\n" + " example: Example value\n"
- + " Customer:\n" + " properties:\n" + " firstName:\n"
- + " type: string\n" + " lastName:\n" + " type: string\n"
- + " heightMetres:\n" + " type: number\n" + " type:\n"
- + " $ref: '#/components/schemas/CustomerType'\n" + " friends:\n"
- + " type: array\n" + " items:\n"
- + " $ref: '#/components/schemas/Customer'\n" + " ";
-
- Converter.openApiToPuml(openapi);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testConvertEmpty() {
- Converter.openApiToPuml("");
- }
-
- @Test
- public void testConvertPumlToSvg() throws IOException {
- writeSvg(OPENAPI_EXAMPLE, "target/openapi-example.svg");
- }
-
- @Test
- @Ignore
- public void updateDocs() throws IOException {
- writeSvg(OPENAPI_EXAMPLE, "src/docs/openapi-example.svg");
- }
-
- @Test
- public void testReadString() throws IOException {
- assertFalse(readString("src/test/resources/openapi-example.yml").isEmpty());
- }
-
- @Test
- public void generateExamplesMd() throws IOException {
- File file = new File("src/docs/examples.md");
- StringBuilder b = new StringBuilder();
- b.append("## openapi-to-plantuml examples\n");
- for (File f : new File("src/test/resources/inputs").listFiles()) {
- b.append("\n\n* [" + f.getName() + "](../../src/test/resources/inputs/" + f.getName()
- + ")");
- String svg = f.getName().substring(0, f.getName().lastIndexOf(".")) + ".puml.svg";
- b.append("\n\n
");
- }
-
- file.delete();
- Files.write(file.toPath(), b.toString().getBytes(StandardCharsets.UTF_8));
- }
-
- private static String readString(String filename) throws IOException {
- return new String(Files.readAllBytes(new File(filename).toPath()), StandardCharsets.UTF_8);
- }
-
- static void writeSvg(File openApiFile, String filename) throws IOException {
- try (InputStream in = new FileInputStream(openApiFile)) {
- String puml = Converter.openApiToPuml(in);
- writeSvgFromPuml(puml, filename);
- }
- }
-
- static void writeSvgFromPuml(String puml, String filename) throws IOException {
- File file = new File(filename);
- SourceStringReader reader = new SourceStringReader(puml);
- try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
- // Write the first image to "os"
- DiagramDescription result = reader.outputImage(os,
- new FileFormatOption(FileFormat.SVG));
- System.out.println(" svg result: " + result.getDescription());
- }
- }
-
- public static void main(String[] args) throws IOException {
- writeSvg(new File(System.getProperty("user.home", "") + "/imdb.yml"), "target/imdb.svg");
- }
+ private static final File OPENAPI_EXAMPLE = new File("src/test/resources/openapi-example.yml");
+
+ private static String readString(String filename)
+ throws
+ IOException {
+ return new String(Files.readAllBytes(new File(filename).toPath()),
+ StandardCharsets.UTF_8);
+ }
+
+ static void writeSvg(File openApiFile,
+ String filename)
+ throws
+ IOException {
+ try (InputStream in = new FileInputStream(openApiFile)) {
+ String puml = Converter.openApiToPuml(in);
+ writeSvgFromPuml(puml,
+ filename);
+ }
+ }
+
+ static void writeSvgFromPuml(String puml,
+ String filename)
+ throws
+ IOException {
+ File file = new File(filename);
+ SourceStringReader reader = new SourceStringReader(puml);
+ try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
+ // Write the first image to "os"
+ DiagramDescription result = reader.outputImage(os,
+ new FileFormatOption(FileFormat.SVG));
+ System.out.println(" svg result: " + result.getDescription());
+ }
+ }
+
+ public static void main(String[] args)
+ throws
+ IOException {
+ writeSvg(new File(System.getProperty("user.home",
+ "") + "/imdb.yml"),
+ "target/imdb.svg");
+ }
+
+ @Test
+ public void testIsUtility() {
+ Asserts.assertIsUtilityClass(Converter.class);
+ }
+
+ @Test
+ public void testConvert() {
+ String openapi = "openapi: 3.0.1\n"
+ + "components:\n"
+ + " schemas:\n"
+ + " CustomerType:\n"
+ + " type: string\n"
+ + " example: Example value\n"
+ + " Customer:\n"
+ + " properties:\n"
+ + " firstName:\n"
+ + " type: string\n"
+ + " lastName:\n"
+ + " type: string\n"
+ + " heightMetres:\n"
+ + " type: number\n"
+ + " type:\n"
+ + " $ref: '#/components/schemas/CustomerType'\n"
+ + " friends:\n"
+ + " type: array\n"
+ + " items:\n"
+ + " $ref: '#/components/schemas/Customer'\n"
+ + " ";
+
+ Converter.openApiToPuml(openapi);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConvertEmpty() {
+ Converter.openApiToPuml("");
+ }
+
+ @Test
+ public void testConvertPumlToSvg()
+ throws
+ IOException {
+ writeSvg(OPENAPI_EXAMPLE,
+ "target/openapi-example.svg");
+ }
+
+ @Test
+ @Ignore
+ public void updateDocs()
+ throws
+ IOException {
+ writeSvg(OPENAPI_EXAMPLE,
+ "src/docs/openapi-example.svg");
+ }
+
+ @Test
+ public void testReadString()
+ throws
+ IOException {
+ assertFalse(readString("src/test/resources/openapi-example.yml").isEmpty());
+ }
+
+ @Test
+ public void generateExamplesMd()
+ throws
+ IOException {
+ File file = new File("src/docs/examples.md");
+ StringBuilder b = new StringBuilder();
+ b.append("## openapi-to-plantuml examples\n");
+ for (File f : new File("src/test/resources/inputs").listFiles()) {
+ b.append("\n\n* [" + f.getName() + "](../../src/test/resources/inputs/" + f.getName() + ")");
+ String svg = f.getName()
+ .substring(0,
+ f.getName()
+ .lastIndexOf(".")) + ".puml.svg";
+ b.append("\n\n
");
+ }
+
+ file.delete();
+ Files.write(file.toPath(),
+ b.toString()
+ .getBytes(StandardCharsets.UTF_8));
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/DeflaterTest.java b/src/test/java/com/github/davidmoten/oas3/puml/DeflaterTest.java
index b6ea9676..79e8db53 100644
--- a/src/test/java/com/github/davidmoten/oas3/puml/DeflaterTest.java
+++ b/src/test/java/com/github/davidmoten/oas3/puml/DeflaterTest.java
@@ -1,31 +1,35 @@
package com.github.davidmoten.oas3.puml;
-import static org.junit.Assert.assertTrue;
+import com.github.davidmoten.junit.Files;
+import net.sourceforge.plantuml.code.TranscoderSmart;
+import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.zip.DataFormatException;
-import org.junit.Test;
-
-import com.github.davidmoten.junit.Files;
-
-import net.sourceforge.plantuml.code.TranscoderSmart;
+import static org.junit.Assert.assertTrue;
public class DeflaterTest {
- @Test
- public void test() throws DataFormatException, IOException {
- String encodedUml = Files.readUtf8(new File("src/test/resources/encodedUml.txt"));
- assertTrue(new TranscoderSmart().decode(encodedUml).startsWith("@startuml"));
- // System.out.println("https://planttext.com/api/plantuml/img/" + encodedUml);
- }
-
- @Test
- public void testEncode() throws IOException {
- String uml = "@startuml\nBob->Alice: hello\n@enduml";
- String path = new TranscoderSmart().encode(uml);
- System.out.println("https://planttext.com/api/plantuml/img/" + path);
- }
+ @Test
+ public void test()
+ throws
+ DataFormatException,
+ IOException {
+ String encodedUml = Files.readUtf8(new File("src/test/resources/encodedUml.txt"));
+ assertTrue(new TranscoderSmart().decode(encodedUml)
+ .startsWith("@startuml"));
+ // System.out.println("https://planttext.com/api/plantuml/img/" + encodedUml);
+ }
+
+ @Test
+ public void testEncode()
+ throws
+ IOException {
+ String uml = "@startuml\nBob->Alice: hello\n@enduml";
+ String path = new TranscoderSmart().encode(uml);
+ System.out.println("https://planttext.com/api/plantuml/img/" + path);
+ }
}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/DemoBatchTest.java b/src/test/java/com/github/davidmoten/oas3/puml/DemoBatchTest.java
deleted file mode 100644
index a8af36ec..00000000
--- a/src/test/java/com/github/davidmoten/oas3/puml/DemoBatchTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.github.davidmoten.oas3.puml;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class DemoBatchTest {
-
- private static final File INPUTS = new File("src/test/resources/demo/");
-
- private final File input;
-
- public DemoBatchTest(File input) {
- this.input = input;
- }
-
- @Parameterized.Parameters(name = "{0}")
- public static Collection> files() {
- File[] list = INPUTS.listFiles();
- if (list == null) {
- return Collections.emptyList();
- } else {
- List x = Arrays.asList(list);
- Collections.sort(x, (a, b) -> a.getName().compareTo(b.getName()));
- return x;
- }
- }
-
- @Test
- public void testBatch() {
- if (!"true".equalsIgnoreCase(System.getProperty("demo", "true"))) {
- return;
- }
- System.out.println("checking " + input);
- try (InputStream in = new FileInputStream(input)) {
- File demos = new File("target/demos");
- demos.mkdirs();
- File svg = new File(demos, input.getName().substring(0, input.getName().lastIndexOf('.')) + ".svg");
- String puml;
- try (InputStream def = new FileInputStream(input)) {
- puml = com.github.davidmoten.oas3.puml.Converter.openApiToPuml(def);
- }
- File pumlFile = new File(demos, input.getName().substring(0, input.getName().lastIndexOf('.')) + ".puml");
- pumlFile.delete();
- Files.write(pumlFile.toPath(), puml.getBytes(StandardCharsets.UTF_8));
- svg.delete();
- ConverterTest.writeSvg(input, svg.getPath());
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
-}
diff --git a/src/test/java/com/github/davidmoten/oas3/puml/DemoJavaTest.java b/src/test/java/com/github/davidmoten/oas3/puml/DemoJavaTest.java
new file mode 100644
index 00000000..2186da94
--- /dev/null
+++ b/src/test/java/com/github/davidmoten/oas3/puml/DemoJavaTest.java
@@ -0,0 +1,83 @@
+package com.github.davidmoten.oas3.puml;
+
+import com.github.davidmoten.oas3.internal.model.Throwables;
+import net.sourceforge.plantuml.FileFormat;
+import org.junit.Test;
+
+import java.io.File;
+
+public class DemoJavaTest {
+
+ private static final String OPEN_API_DIRECTORY = "src/test/resources/demo/";
+ public static final File OPEN_API_DIRECTORY_FILE = new File(OPEN_API_DIRECTORY);
+ private static final String OUTPUT_DIRECTORY = "target/converted-puml/demo";
+ public static final File OUTPUT_DIRECTORY_FILE = new File(OUTPUT_DIRECTORY);
+
+ @Test
+ public void testWriteOpenApiDirectoryFilePathsToPumlAndToFileFormatSet()
+ throws
+ Throwables {
+ if (!"true".equalsIgnoreCase(System.getProperty("demo",
+ "true"))) {
+ return;
+ }
+ Converter.writeOpenApiToPumlAndTo(OPEN_API_DIRECTORY,
+ OUTPUT_DIRECTORY,
+ Converter.SUPPORTED_FORMATS);
+ }
+
+
+ @Test
+ public void testWriteOpenApiDirectoryFilesToFileFormatSet()
+ throws
+ Throwables {
+ if (!"true".equalsIgnoreCase(System.getProperty("demo",
+ "true"))) {
+ return;
+ }
+ Converter.writeOpenApiDirectoryFileToPumlAndTo(OPEN_API_DIRECTORY_FILE,
+ OUTPUT_DIRECTORY_FILE,
+ Converter.SUPPORTED_FORMATS);
+ }
+
+ @Test
+ public void testWriteOpenApiDirectoryFilePathsFileFormatArraySVGAndPNG()
+ throws
+ Throwables {
+ if (!"true".equalsIgnoreCase(System.getProperty("demo",
+ "true"))) {
+ return;
+ }
+ Converter.writeOpenApiToPumlAndTo(OPEN_API_DIRECTORY,
+ OUTPUT_DIRECTORY,
+ FileFormat.SVG,
+ FileFormat.PNG);
+ }
+
+ @Test
+ public void testWriteOpenApiDirectoryFilesFileFormatArraySVGAndPNG()
+ throws
+ Throwables {
+ if (!"true".equalsIgnoreCase(System.getProperty("demo",
+ "true"))) {
+ return;
+ }
+ Converter.writeOpenApiDirectoryFileToPumlAndTo(OPEN_API_DIRECTORY_FILE,
+ OUTPUT_DIRECTORY_FILE,
+ FileFormat.SVG,
+ FileFormat.PNG);
+ }
+
+ @Test
+ public void testWriteOpenApiDirectoryFilesToPUMLOnly()
+ throws
+ Throwables {
+ if (!"true".equalsIgnoreCase(System.getProperty("demo",
+ "true"))) {
+ return;
+ }
+ Converter.writeOpenApiDirectoryFileToPumlAndTo(OPEN_API_DIRECTORY_FILE,
+ OUTPUT_DIRECTORY_FILE);
+ }
+
+}
diff --git a/src/test/resources/demo/bookstore.yml b/src/test/resources/demo/bookstore.yml
index be48f286..915764da 100644
--- a/src/test/resources/demo/bookstore.yml
+++ b/src/test/resources/demo/bookstore.yml
@@ -1,16 +1,16 @@
openapi: 3.0.2
info:
- title: bookstore
- version: 1.0.0
- description: >-
- This is a sample server BookStore API
- contact:
- name: API Support
- url: https://italiancoders/support
- email: italiancoders@gmail.com
- license:
- name: Apache 2.0
- url: https://www.apache.org/licenses/LICENSE-2.0.html
+ title: bookstore
+ version: 1.0.0
+ description: >-
+ This is a sample server BookStore API
+ contact:
+ name: API Support
+ url: https://italiancoders/support
+ email: italiancoders@gmail.com
+ license:
+ name: Apache 2.0
+ url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://italiancoders.it/v1
description: Production server
@@ -19,13 +19,13 @@ servers:
# Apply the security globally to all operations
security:
- - bearerAuth: []
+ - bearerAuth: [ ]
paths:
/login:
post:
operationId: login
# declare /login as public endpoint
- security: []
+ security: [ ]
tags:
- Authentication
description: >
@@ -57,7 +57,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
-
+
/books:
get:
operationId: findBooks
@@ -78,14 +78,14 @@ paths:
required: true
description: The numbers of items to return
schema:
- type: integer
+ type: integer
minimum: 1
maximum: 100
- name: genre
in: query
description: genre of the book
schema:
- $ref: '#/components/schemas/BookGenre'
+ $ref: '#/components/schemas/BookGenre'
- name: search
in: query
description: Free Search (example author name, book title)
@@ -100,15 +100,15 @@ paths:
schema:
type: array
items:
- $ref: '#/components/schemas/Book'
+ $ref: '#/components/schemas/Book'
'401':
- $ref: '#/components/responses/UnauthorizedError'
+ $ref: '#/components/responses/UnauthorizedError'
'400':
description: Bad Request
content:
application/json:
schema:
- $ref: '#/components/schemas/Error'
+ $ref: '#/components/schemas/Error'
post:
operationId: addBook
tags:
@@ -121,31 +121,31 @@ paths:
$ref: '#/components/schemas/Book'
application/xml:
schema:
- $ref: '#/components/schemas/Book'
+ $ref: '#/components/schemas/Book'
required: true
responses:
'201':
- description: Book Created
+ description: Book Created
content:
- #content negotiation to support multiple media types
+ #content negotiation to support multiple media types
application/json:
schema:
- $ref: '#/components/schemas/Book'
+ $ref: '#/components/schemas/Book'
application/xml:
schema:
- $ref: '#/components/schemas/Book'
+ $ref: '#/components/schemas/Book'
'400':
description: Unable to create a Book
content:
application/json:
schema:
- $ref: '#/components/schemas/Error'
+ $ref: '#/components/schemas/Error'
'401':
- $ref: '#/components/responses/UnauthorizedError'
+ $ref: '#/components/responses/UnauthorizedError'
components:
-# 1) Define the security scheme type (HTTP bearer)
+ # 1) Define the security scheme type (HTTP bearer)
securitySchemes:
- bearerAuth: # arbitrary name for the security scheme
+ bearerAuth: # arbitrary name for the security scheme
type: http
#Authorization: Bearer
scheme: bearer
@@ -158,29 +158,29 @@ components:
type: object
properties:
accessToken:
- type: string
- expiresAt:
+ type: string
+ expiresAt:
type: string
format: date-time
required:
- - accessToken
- - expiresAt
+ - accessToken
+ - expiresAt
example:
accessToken: xuhwiuhwidhhdwuwihduh
- expiresAt: 2018-09-15T15:53:00+02:00
+ expiresAt: 2018-09-15T15:53:00+02:00
Error:
description: Error Details
#custom property
x-docs-additionalinfo: error_table.html
properties:
code:
- type: string
- message:
+ type: string
+ message:
type: string
format: date-time
- required:
- - code
- - message
+ required:
+ - code
+ - message
example:
code: 1010
message: Invalid User
@@ -190,7 +190,7 @@ components:
fullname:
type: string
minLength: 3
- maxLength: 30
+ maxLength: 30
country:
description: Nationality of the author
type: string
@@ -206,23 +206,23 @@ components:
- MALE
- FEMALE
- UNDEFINED
- required:
- - fullname
+ required:
+ - fullname
example:
fullname: Luigi Pirandello
country: Italy
birthYear: 1986-06-28
gender: MALE
BookGenre:
- description: Genre categories of a book
- enum:
- - FANTASY
- - HORROR
- - CLASSIC
- - HOMOR
- - OTHER
- type: string
- example: CLASSIC
+ description: Genre categories of a book
+ enum:
+ - FANTASY
+ - HORROR
+ - CLASSIC
+ - HOMOR
+ - OTHER
+ type: string
+ example: CLASSIC
Book:
description: Author Infos related a Book
properties:
@@ -235,7 +235,7 @@ components:
description: Title Of the Book
type: string
minLength: 3
- maxLength: 50
+ maxLength: 50
totalPages:
description: No of pages
type: integer
@@ -246,13 +246,13 @@ components:
genre:
$ref: '#/components/schemas/BookGenre'
author:
- $ref: '#/components/schemas/Author'
- required:
- - id
- - title
- - totalPages
- - publishingHouse
- - author
+ $ref: '#/components/schemas/Author'
+ required:
+ - id
+ - title
+ - totalPages
+ - publishingHouse
+ - author
example:
id: 1
title: Il fu Mattia Pascal
diff --git a/src/test/resources/demo/ecommerce.yml b/src/test/resources/demo/ecommerce.yml
index 418423ca..5cf31569 100644
--- a/src/test/resources/demo/ecommerce.yml
+++ b/src/test/resources/demo/ecommerce.yml
@@ -236,7 +236,7 @@ paths:
responses:
'200':
description: OK
- security: []
+ security: [ ]
components:
schemas:
Company:
diff --git a/src/test/resources/demo/news.yml b/src/test/resources/demo/news.yml
index 3ef6e2f0..eba32d87 100644
--- a/src/test/resources/demo/news.yml
+++ b/src/test/resources/demo/news.yml
@@ -95,7 +95,7 @@ paths:
description: 'Searches for articles mentioning a risk exposure, for example: Boeing 737, COVID-19, Firearms, Glyphosate'
searchByRegion:
summary: Search By World Region
- value:
+ value:
key: region
value: Afghanistan
description: 'Searches for articles mentioning a certain region, for example: Middle East, Afghanistan, Europe, Russia, etc. More specific regions are also indexed in less specific regions - for example all articles mentioning Germany are also indexed in the Europe region'
@@ -138,7 +138,7 @@ paths:
type: Press Release
count: 25
offset: 0
-
+
description: Search Query
required: true
/article/{slug}:
@@ -262,7 +262,7 @@ paths:
id:
type: integer
description: The local id number the article was assigned in the news instance it was uploaded to
- required: [success,id]
+ required: [ success,id ]
'400':
description: Bad Request
'403':
@@ -275,10 +275,10 @@ paths:
description: Article to Upload
required: true
security:
- - private_key_auth: []
- - public_key_auth: []
- - header_private_key_auth: []
- - header_public_key_auth: []
+ - private_key_auth: [ ]
+ - public_key_auth: [ ]
+ - header_private_key_auth: [ ]
+ - header_public_key_auth: [ ]
servers:
- url: 'https://api.newsrpm.com'
- url: 'http://api.newsrpm.com'
@@ -301,16 +301,16 @@ components:
schemas:
indexSearchQuery:
type: object
- required: [key]
+ required: [ key ]
properties:
key:
type: string
description: An Index Key is a specifier used to identify which index you would like to query from
value:
- oneOf:
+ oneOf:
- type: string
- type: array
- items:
+ items:
type: string
description: The value to look up in the Index
count:
@@ -346,27 +346,27 @@ components:
type: object
properties:
publisher:
- oneOf:
+ oneOf:
- type: string
- type: array
- items:
+ items:
type: string
description: The name of the publisher to search for
provider:
- oneOf:
+ oneOf:
- type: string
- type: array
- items:
+ items:
type: string
description: The name of the provider to search for
fullText:
type: string
description: A full text query to execute against the article headline
type:
- oneOf:
+ oneOf:
- type: string
- type: array
- items:
+ items:
type: string
description: The type of article to search for
count:
@@ -501,7 +501,7 @@ components:
type: boolean
body:
type: object
- required: [v,chunks]
+ required: [ v,chunks ]
properties:
v:
type: number
@@ -514,7 +514,7 @@ components:
articleBodyChunk:
type: object
description: A named chunk of the article body
- required: [name,format,content]
+ required: [ name,format,content ]
properties:
name:
type: string
diff --git a/src/test/resources/demo/strava.yml b/src/test/resources/demo/strava.yml
index aa0c969f..81a3f764 100644
--- a/src/test/resources/demo/strava.yml
+++ b/src/test/resources/demo/strava.yml
@@ -12,27 +12,27 @@ info:
please check the section “client code” at https://developers.strava.com/docs.
version: 3.0.0
servers:
-- url: https://www.strava.com/api/v3
+ - url: https://www.strava.com/api/v3
security:
-- strava_oauth:
- - public
+ - strava_oauth:
+ - public
paths:
/athletes/{id}/stats:
get:
tags:
- - Athletes
+ - Athletes
summary: Get Athlete Stats
description: Returns the activity stats of an athlete. Only includes data from
activities set to Everyone visibilty.
operationId: getStats
parameters:
- - name: id
- in: path
- description: The identifier of the athlete. Must match the authenticated athlete.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the athlete. Must match the authenticated athlete.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Activity stats of the athlete.
@@ -49,7 +49,7 @@ paths:
/athlete:
get:
tags:
- - Athletes
+ - Athletes
summary: Get Authenticated Athlete
description: Returns the currently authenticated athlete. Tokens with profile:read_all
scope will receive a detailed athlete representation; all others will receive
@@ -84,20 +84,20 @@ paths:
athlete_type: 1
date_preference: '%m/%d/%Y'
measurement_preference: feet
- clubs: []
+ clubs: [ ]
weight: 0
bikes:
- - id: b12345678987655
- primary: true
- name: EMC
- resource_state: 2
- distance: 0
+ - id: b12345678987655
+ primary: true
+ name: EMC
+ resource_state: 2
+ distance: 0
shoes:
- - id: g12345678987655
- primary: true
- name: adidas
- resource_state: 2
- distance: 4904
+ - id: g12345678987655
+ primary: true
+ name: adidas
+ resource_state: 2
+ distance: 4904
default:
description: Unexpected error.
content:
@@ -106,19 +106,19 @@ paths:
$ref: '#/components/schemas/Fault'
put:
tags:
- - Athletes
+ - Athletes
summary: Update Athlete
description: Update the currently authenticated athlete. Requires profile:write
scope.
operationId: updateLoggedInAthlete
parameters:
- - name: weight
- in: path
- description: The weight of the athlete in kilograms.
- required: true
- schema:
- type: number
- format: float
+ - name: weight
+ in: path
+ description: The weight of the athlete in kilograms.
+ required: true
+ schema:
+ type: number
+ format: float
responses:
200:
description: Profile information for the authenticated athlete.
@@ -148,20 +148,20 @@ paths:
athlete_type: 1
date_preference: '%m/%d/%Y'
measurement_preference: feet
- clubs: []
+ clubs: [ ]
weight: 0
bikes:
- - id: b1234567898765509876
- primary: true
- name: EMC
- resource_state: 2
- distance: 0
+ - id: b1234567898765509876
+ primary: true
+ name: EMC
+ resource_state: 2
+ distance: 0
shoes:
- - id: g1234567898765509876
- primary: true
- name: adidas
- resource_state: 2
- distance: 4904
+ - id: g1234567898765509876
+ primary: true
+ name: adidas
+ resource_state: 2
+ distance: 4904
default:
description: Unexpected error.
content:
@@ -171,7 +171,7 @@ paths:
/athlete/zones:
get:
tags:
- - Athletes
+ - Athletes
summary: Get Zones
description: Returns the the authenticated athlete's heart rate and power zones.
Requires profile:read_all.
@@ -184,43 +184,43 @@ paths:
schema:
$ref: '#/components/schemas/Zones'
example:
- - distribution_buckets:
- - max: 0
- min: 0
- time: 1498
- - max: 50
- min: 0
- time: 62
- - max: 100
- min: 50
- time: 169
- - max: 150
- min: 100
- time: 536
- - max: 200
- min: 150
- time: 672
- - max: 250
- min: 200
- time: 821
- - max: 300
- min: 250
- time: 529
- - max: 350
- min: 300
- time: 251
- - max: 400
- min: 350
- time: 80
- - max: 450
- min: 400
- time: 81
- - max: -1
- min: 450
- time: 343
- type: power
- resource_state: 3
- sensor_based: true
+ - distribution_buckets:
+ - max: 0
+ min: 0
+ time: 1498
+ - max: 50
+ min: 0
+ time: 62
+ - max: 100
+ min: 50
+ time: 169
+ - max: 150
+ min: 100
+ time: 536
+ - max: 200
+ min: 150
+ time: 672
+ - max: 250
+ min: 200
+ time: 821
+ - max: 300
+ min: 250
+ time: 529
+ - max: 350
+ min: 300
+ time: 251
+ - max: 400
+ min: 350
+ time: 80
+ - max: 450
+ min: 400
+ time: 81
+ - max: -1
+ min: 450
+ time: 343
+ type: power
+ resource_state: 3
+ sensor_based: true
default:
description: Unexpected error.
content:
@@ -230,19 +230,19 @@ paths:
/segments/{id}:
get:
tags:
- - Segments
+ - Segments
summary: Get Segment
description: Returns the specified segment. read_all scope required in order
to retrieve athlete-specific segment information, or to retrieve private segments.
operationId: getSegmentById
parameters:
- - name: id
- in: path
- description: The identifier of the segment.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the segment.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Representation of a segment.
@@ -261,11 +261,11 @@ paths:
elevation_high: 245.3
elevation_low: 92.4
start_latlng:
- - 37.8331119
- - -122.4834356
+ - 37.8331119
+ - -122.4834356
end_latlng:
- - 37.8280722
- - -122.4981393
+ - 37.8280722
+ - -122.4981393
climb_category: 1
city: San Francisco
state: CA
@@ -296,23 +296,23 @@ paths:
/segments/starred:
get:
tags:
- - Segments
+ - Segments
summary: List Starred Segments
description: List of the authenticated athlete's starred segments. Private segments
are filtered out unless requested by a token with read_all scope.
operationId: getLoggedInAthleteStarredSegments
parameters:
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: List of the authenticated athlete's starred segments.
@@ -333,11 +333,11 @@ paths:
elevation_high: 245.3
elevation_low: 92.4
start_latlng:
- - 37.8331119
- - -122.4834356
+ - 37.8331119
+ - -122.4834356
end_latlng:
- - 37.8280722
- - -122.4981393
+ - 37.8280722
+ - -122.4981393
climb_category: 1
city: San Francisco
state: CA
@@ -368,25 +368,25 @@ paths:
/segments/{id}/starred:
put:
tags:
- - Segments
+ - Segments
summary: Star Segment
description: Stars/Unstars the given segment for the authenticated athlete.
Requires profile:write scope.
operationId: starSegment
parameters:
- - name: id
- in: path
- description: The identifier of the segment to star.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the segment to star.
+ required: true
+ schema:
+ type: integer
+ format: int64
requestBody:
content:
multipart/form-data:
schema:
required:
- - starred
+ - starred
properties:
starred:
type: boolean
@@ -411,11 +411,11 @@ paths:
elevation_high: 245.3
elevation_low: 92.4
start_latlng:
- - 37.8331119
- - -122.4834356
+ - 37.8331119
+ - -122.4834356
end_latlng:
- - 37.8280722
- - -122.4981393
+ - 37.8280722
+ - -122.4981393
climb_category: 1
city: San Francisco
state: CA
@@ -446,36 +446,36 @@ paths:
/segment_efforts:
get:
tags:
- - SegmentEfforts
+ - SegmentEfforts
summary: List Segment Efforts
description: Returns a set of the authenticated athlete's segment efforts for
a given segment. Requires subscription.
operationId: getEffortsBySegmentId
parameters:
- - name: segment_id
- in: query
- description: The identifier of the segment.
- required: true
- schema:
- type: integer
- - name: start_date_local
- in: query
- description: ISO 8601 formatted date time.
- schema:
- type: string
- format: date-time
- - name: end_date_local
- in: query
- description: ISO 8601 formatted date time.
- schema:
- type: string
- format: date-time
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: segment_id
+ in: query
+ description: The identifier of the segment.
+ required: true
+ schema:
+ type: integer
+ - name: start_date_local
+ in: query
+ description: ISO 8601 formatted date time.
+ schema:
+ type: string
+ format: date-time
+ - name: end_date_local
+ in: query
+ description: ISO 8601 formatted date time.
+ schema:
+ type: string
+ format: date-time
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: List of segment efforts.
@@ -486,48 +486,48 @@ paths:
items:
$ref: '#/components/schemas/DetailedSegmentEffort'
example:
- - id: 123456789
- resource_state: 2
- name: Alpe d'Huez
- activity:
- id: 1234567890
- resource_state: 1
- athlete:
- id: 123445678689
- resource_state: 1
- elapsed_time: 1657
- moving_time: 1642
- start_date: 2007-09-15T08:15:29Z
- start_date_local: 2007-09-15T09:15:29Z
- distance: 6148.92
- start_index: 1102
- end_index: 1366
- device_watts: false
- average_watts: 220.2
- segment:
- id: 788127
+ - id: 123456789
resource_state: 2
name: Alpe d'Huez
- activity_type: Ride
- distance: 6297.46
- average_grade: 4.8
- maximum_grade: 16.3
- elevation_high: 416
- elevation_low: 104.6
- start_latlng:
- - 52.98501000581467
- - -3.1869720001197366
- end_latlng:
- - 53.02204074375785
- - -3.2039630001245736
- climb_category: 2
- city: Le Bourg D'Oisans
- state: RA
- country: France
- private: false
- hazardous: false
- starred: false
- achievements: []
+ activity:
+ id: 1234567890
+ resource_state: 1
+ athlete:
+ id: 123445678689
+ resource_state: 1
+ elapsed_time: 1657
+ moving_time: 1642
+ start_date: 2007-09-15T08:15:29Z
+ start_date_local: 2007-09-15T09:15:29Z
+ distance: 6148.92
+ start_index: 1102
+ end_index: 1366
+ device_watts: false
+ average_watts: 220.2
+ segment:
+ id: 788127
+ resource_state: 2
+ name: Alpe d'Huez
+ activity_type: Ride
+ distance: 6297.46
+ average_grade: 4.8
+ maximum_grade: 16.3
+ elevation_high: 416
+ elevation_low: 104.6
+ start_latlng:
+ - 52.98501000581467
+ - -3.1869720001197366
+ end_latlng:
+ - 53.02204074375785
+ - -3.2039630001245736
+ climb_category: 2
+ city: Le Bourg D'Oisans
+ state: RA
+ country: France
+ private: false
+ hazardous: false
+ starred: false
+ achievements: [ ]
default:
description: Unexpected error.
content:
@@ -537,48 +537,48 @@ paths:
/segments/explore:
get:
tags:
- - Segments
+ - Segments
summary: Explore segments
description: Returns the top 10 segments matching a specified query.
operationId: exploreSegments
parameters:
- - name: bounds
- in: query
- description: 'The latitude and longitude for two points describing a rectangular
+ - name: bounds
+ in: query
+ description: 'The latitude and longitude for two points describing a rectangular
boundary for the search: [southwest corner latitutde, southwest corner longitude,
northeast corner latitude, northeast corner longitude]'
- required: true
- style: form
- explode: false
- schema:
- maxItems: 4
- minItems: 4
- type: array
- items:
- type: number
- format: float
- - name: activity_type
- in: query
- description: Desired activity type.
- schema:
- type: string
- enum:
- - running
- - riding
- - name: min_cat
- in: query
- description: The minimum climbing category.
- schema:
- maximum: 5
- minimum: 0
- type: integer
- - name: max_cat
- in: query
- description: The maximum climbing category.
- schema:
- maximum: 5
- minimum: 0
- type: integer
+ required: true
+ style: form
+ explode: false
+ schema:
+ maxItems: 4
+ minItems: 4
+ type: array
+ items:
+ type: number
+ format: float
+ - name: activity_type
+ in: query
+ description: Desired activity type.
+ schema:
+ type: string
+ enum:
+ - running
+ - riding
+ - name: min_cat
+ in: query
+ description: The minimum climbing category.
+ schema:
+ maximum: 5
+ minimum: 0
+ type: integer
+ - name: max_cat
+ in: query
+ description: The maximum climbing category.
+ schema:
+ maximum: 5
+ minimum: 0
+ type: integer
responses:
200:
description: List of matching segments.
@@ -588,22 +588,22 @@ paths:
$ref: '#/components/schemas/ExplorerResponse'
example:
segments:
- - id: 229781
- resource_state: 2
- name: Hawk Hill
- climb_category: 1
- climb_category_desc: "4"
- avg_grade: 5.7
- start_latlng:
- - 37.8331119
- - -122.4834356
- end_latlng:
- - 37.8280722
- - -122.4981393
- elev_difference: 152.8
- distance: 2684.8
- points: '}g|eFnpqjVl@En@Md@HbAd@d@^h@Xx@VbARjBDh@OPQf@w@d@k@XKXDFPH\EbGT`AV`@v@|@NTNb@?XOb@cAxAWLuE@eAFMBoAv@eBt@q@b@}@tAeAt@i@dAC`AFZj@dB?~@[h@MbAVn@b@b@\d@Eh@Qb@_@d@eB|@c@h@WfBK|AMpA?VF\\t@f@t@h@j@|@b@hCb@b@XTd@Bl@GtA?jAL`ALp@Tr@RXd@Rx@Pn@^Zh@Tx@Zf@`@FTCzDy@f@Yx@m@n@Op@VJr@'
- starred: false
+ - id: 229781
+ resource_state: 2
+ name: Hawk Hill
+ climb_category: 1
+ climb_category_desc: "4"
+ avg_grade: 5.7
+ start_latlng:
+ - 37.8331119
+ - -122.4834356
+ end_latlng:
+ - 37.8280722
+ - -122.4981393
+ elev_difference: 152.8
+ distance: 2684.8
+ points: '}g|eFnpqjVl@En@Md@HbAd@d@^h@Xx@VbARjBDh@OPQf@w@d@k@XKXDFPH\EbGT`AV`@v@|@NTNb@?XOb@cAxAWLuE@eAFMBoAv@eBt@q@b@}@tAeAt@i@dAC`AFZj@dB?~@[h@MbAVn@b@b@\d@Eh@Qb@_@d@eB|@c@h@WfBK|AMpA?VF\\t@f@t@h@j@|@b@hCb@b@XTd@Bl@GtA?jAL`ALp@Tr@RXd@Rx@Pn@^Zh@Tx@Zf@`@FTCzDy@f@Yx@m@n@Op@VJr@'
+ starred: false
default:
description: Unexpected error.
content:
@@ -613,19 +613,19 @@ paths:
/segment_efforts/{id}:
get:
tags:
- - SegmentEfforts
+ - SegmentEfforts
summary: Get Segment Effort
description: Returns a segment effort from an activity that is owned by the
authenticated athlete. Requires subscription.
operationId: getSegmentEffortById
parameters:
- - name: id
- in: path
- description: The identifier of the segment effort.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the segment effort.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Representation of a segment effort.
@@ -661,11 +661,11 @@ paths:
elevation_high: 21
elevation_low: 17.2
start_latlng:
- - 37.808407654682
- - -122.426682919323
+ - 37.808407654682
+ - -122.426682919323
end_latlng:
- - 37.808297909724
- - -122.421324329674
+ - 37.808297909724
+ - -122.421324329674
climb_category: 0
city: San Francisco
state: CA
@@ -673,7 +673,7 @@ paths:
private: false
hazardous: false
starred: false
- achievements: []
+ achievements: [ ]
athlete_segment_stats:
pr_elapsed_time: 212
pr_date: 2015-02-12
@@ -687,18 +687,18 @@ paths:
/running_races/{id}:
get:
tags:
- - RunningRaces
+ - RunningRaces
summary: Get Running Race
description: Returns a running race for a given identifier.
operationId: getRunningRaceById
parameters:
- - name: id
- in: path
- description: The identifier of the running race.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the running race.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Representation of a running race.
@@ -715,16 +715,16 @@ paths:
/running_races:
get:
tags:
- - RunningRaces
+ - RunningRaces
summary: List Running Races
description: Returns a list running races based on a set of search criteria.
operationId: getRunningRaces
parameters:
- - name: year
- in: query
- description: Filters the list by a given year.
- schema:
- type: integer
+ - name: year
+ in: query
+ description: Filters the list by a given year.
+ schema:
+ type: integer
responses:
200:
description: Representation of a list of running race.
@@ -743,7 +743,7 @@ paths:
/activities:
post:
tags:
- - Activities
+ - Activities
summary: Create an Activity
description: Creates a manual activity for an athlete, requires activity:write
scope.
@@ -753,10 +753,10 @@ paths:
multipart/form-data:
schema:
required:
- - elapsed_time
- - name
- - start_date_local
- - type
+ - elapsed_time
+ - name
+ - start_date_local
+ - type
properties:
name:
type: string
@@ -833,7 +833,7 @@ paths:
total_photo_count: 0
has_kudoed: false
calories: 0
- segment_efforts: []
+ segment_efforts: [ ]
default:
description: Unexpected error.
content:
@@ -843,25 +843,25 @@ paths:
/activities/{id}:
get:
tags:
- - Activities
+ - Activities
summary: Get Activity
description: Returns the given activity that is owned by the authenticated athlete.
Requires activity:read for Everyone and Followers activities. Requires activity:read_all
for Only Me activities.
operationId: getActivityById
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
- - name: include_all_efforts
- in: query
- description: To include all segments efforts.
- schema:
- type: boolean
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: include_all_efforts
+ in: query
+ description: To include all segments efforts.
+ schema:
+ type: boolean
responses:
200:
description: The activity's detailed representation.
@@ -888,11 +888,11 @@ paths:
timezone: (GMT-08:00) America/Los_Angeles
utc_offset: -28800
start_latlng:
- - 37.83
- - -122.26
+ - 37.83
+ - -122.26
end_latlng:
- - 37.83
- - -122.26
+ - 37.83
+ - -122.26
achievement_count: 0
kudos_count: 19
comment_count: 0
@@ -929,83 +929,83 @@ paths:
description: ""
calories: 870.2
segment_efforts:
- - id: 12345678987654320
- resource_state: 2
- name: Tunnel Rd.
- activity:
- id: 12345678987654320
- resource_state: 1
- athlete:
- id: 134815
- resource_state: 1
- elapsed_time: 2038
- moving_time: 2038
- start_date: 2018-02-16T14:56:25Z
- start_date_local: 2018-02-16T06:56:25Z
- distance: 9434.8
- start_index: 211
- end_index: 2246
- average_cadence: 78.6
- device_watts: true
- average_watts: 237.6
- segment:
- id: 673683
+ - id: 12345678987654320
resource_state: 2
name: Tunnel Rd.
- activity_type: Ride
- distance: 9220.7
- average_grade: 4.2
- maximum_grade: 25.8
- elevation_high: 426.5
- elevation_low: 43.4
- start_latlng:
- - 37.8346153
- - -122.2520872
- end_latlng:
- - 37.8476261
- - -122.2008944
- climb_category: 3
- city: Oakland
- state: CA
- country: United States
- private: false
- hazardous: false
- starred: false
- achievements: []
- hidden: false
+ activity:
+ id: 12345678987654320
+ resource_state: 1
+ athlete:
+ id: 134815
+ resource_state: 1
+ elapsed_time: 2038
+ moving_time: 2038
+ start_date: 2018-02-16T14:56:25Z
+ start_date_local: 2018-02-16T06:56:25Z
+ distance: 9434.8
+ start_index: 211
+ end_index: 2246
+ average_cadence: 78.6
+ device_watts: true
+ average_watts: 237.6
+ segment:
+ id: 673683
+ resource_state: 2
+ name: Tunnel Rd.
+ activity_type: Ride
+ distance: 9220.7
+ average_grade: 4.2
+ maximum_grade: 25.8
+ elevation_high: 426.5
+ elevation_low: 43.4
+ start_latlng:
+ - 37.8346153
+ - -122.2520872
+ end_latlng:
+ - 37.8476261
+ - -122.2008944
+ climb_category: 3
+ city: Oakland
+ state: CA
+ country: United States
+ private: false
+ hazardous: false
+ starred: false
+ achievements: [ ]
+ hidden: false
splits_metric:
- - distance: 1001.5
- elapsed_time: 141
- elevation_difference: 4.4
- moving_time: 141
- split: 1
- average_speed: 7.1
- pace_zone: 0
+ - distance: 1001.5
+ elapsed_time: 141
+ elevation_difference: 4.4
+ moving_time: 141
+ split: 1
+ average_speed: 7.1
+ pace_zone: 0
laps:
- - id: 4479306946
- resource_state: 2
- name: Lap 1
- activity:
- id: 1410355832
- resource_state: 1
- athlete:
- id: 134815
- resource_state: 1
- elapsed_time: 1573
- moving_time: 1569
- start_date: 2018-02-16T14:52:54Z
- start_date_local: 2018-02-16T06:52:54Z
- distance: 8046.72
- start_index: 0
- end_index: 1570
- total_elevation_gain: 276
- average_speed: 5.12
- max_speed: 9.5
- average_cadence: 78.6
- device_watts: true
- average_watts: 233.1
- lap_index: 1
- split: 1
+ - id: 4479306946
+ resource_state: 2
+ name: Lap 1
+ activity:
+ id: 1410355832
+ resource_state: 1
+ athlete:
+ id: 134815
+ resource_state: 1
+ elapsed_time: 1573
+ moving_time: 1569
+ start_date: 2018-02-16T14:52:54Z
+ start_date_local: 2018-02-16T06:52:54Z
+ distance: 8046.72
+ start_index: 0
+ end_index: 1570
+ total_elevation_gain: 276
+ average_speed: 5.12
+ max_speed: 9.5
+ average_cadence: 78.6
+ device_watts: true
+ average_watts: 233.1
+ lap_index: 1
+ split: 1
gear:
id: b12345678987654321
primary: true
@@ -1022,10 +1022,10 @@ paths:
use_primary_photo: true
count: 2
highlighted_kudosers:
- - destination_url: strava://athletes/12345678987654321
- display_name: Marianne V.
- avatar_url: https://dgalywyr863hv.cloudfront.net/pictures/athletes/12345678987654321/12345678987654321/3/medium.jpg
- show_name: true
+ - destination_url: strava://athletes/12345678987654321
+ display_name: Marianne V.
+ avatar_url: https://dgalywyr863hv.cloudfront.net/pictures/athletes/12345678987654321/12345678987654321/3/medium.jpg
+ show_name: true
device_name: Garmin Edge 1030
embed_token: 18e4615989b47dd4ff3dc711b0aa4502e4b311a9
segment_leaderboard_opt_out: false
@@ -1038,20 +1038,20 @@ paths:
$ref: '#/components/schemas/Fault'
put:
tags:
- - Activities
+ - Activities
summary: Update Activity
description: Updates the given activity that is owned by the authenticated athlete.
Requires activity:write. Also requires activity:read_all in order to update
Only Me activities
operationId: updateActivityById
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
requestBody:
content:
'*/*':
@@ -1084,11 +1084,11 @@ paths:
timezone: (GMT-08:00) America/Los_Angeles
utc_offset: -28800
start_latlng:
- - 37.83
- - -122.26
+ - 37.83
+ - -122.26
end_latlng:
- - 37.83
- - -122.26
+ - 37.83
+ - -122.26
location_country: United States
achievement_count: 0
kudos_count: 19
@@ -1126,83 +1126,83 @@ paths:
description: ""
calories: 870.2
segment_efforts:
- - id: 12345678987654320
- resource_state: 2
- name: Tunnel Rd.
- activity:
- id: 12345678987654320
- resource_state: 1
- athlete:
- id: 12345678987654320
- resource_state: 1
- elapsed_time: 2038
- moving_time: 2038
- start_date: 2018-02-16T14:56:25Z
- start_date_local: 2018-02-16T06:56:25Z
- distance: 9434.8
- start_index: 211
- end_index: 2246
- average_cadence: 78.6
- device_watts: true
- average_watts: 237.6
- segment:
- id: 673683
+ - id: 12345678987654320
resource_state: 2
name: Tunnel Rd.
- activity_type: Ride
- distance: 9220.7
- average_grade: 4.2
- maximum_grade: 25.8
- elevation_high: 426.5
- elevation_low: 43.4
- start_latlng:
- - 37.8346153
- - -122.2520872
- end_latlng:
- - 37.8476261
- - -122.2008944
- climb_category: 3
- city: Oakland
- state: CA
- country: United States
- private: false
- hazardous: false
- starred: false
- achievements: []
- hidden: false
+ activity:
+ id: 12345678987654320
+ resource_state: 1
+ athlete:
+ id: 12345678987654320
+ resource_state: 1
+ elapsed_time: 2038
+ moving_time: 2038
+ start_date: 2018-02-16T14:56:25Z
+ start_date_local: 2018-02-16T06:56:25Z
+ distance: 9434.8
+ start_index: 211
+ end_index: 2246
+ average_cadence: 78.6
+ device_watts: true
+ average_watts: 237.6
+ segment:
+ id: 673683
+ resource_state: 2
+ name: Tunnel Rd.
+ activity_type: Ride
+ distance: 9220.7
+ average_grade: 4.2
+ maximum_grade: 25.8
+ elevation_high: 426.5
+ elevation_low: 43.4
+ start_latlng:
+ - 37.8346153
+ - -122.2520872
+ end_latlng:
+ - 37.8476261
+ - -122.2008944
+ climb_category: 3
+ city: Oakland
+ state: CA
+ country: United States
+ private: false
+ hazardous: false
+ starred: false
+ achievements: [ ]
+ hidden: false
splits_metric:
- - distance: 1001.5
- elapsed_time: 141
- elevation_difference: 4.4
- moving_time: 141
- split: 1
- average_speed: 7.1
- pace_zone: 0
+ - distance: 1001.5
+ elapsed_time: 141
+ elevation_difference: 4.4
+ moving_time: 141
+ split: 1
+ average_speed: 7.1
+ pace_zone: 0
laps:
- - id: 4479306946
- resource_state: 2
- name: Lap 1
- activity:
- id: 1410355832
- resource_state: 1
- athlete:
- id: 134815
- resource_state: 1
- elapsed_time: 1573
- moving_time: 1569
- start_date: 2018-02-16T14:52:54Z
- start_date_local: 2018-02-16T06:52:54Z
- distance: 8046.72
- start_index: 0
- end_index: 1570
- total_elevation_gain: 276
- average_speed: 5.12
- max_speed: 9.5
- average_cadence: 78.6
- device_watts: true
- average_watts: 233.1
- lap_index: 1
- split: 1
+ - id: 4479306946
+ resource_state: 2
+ name: Lap 1
+ activity:
+ id: 1410355832
+ resource_state: 1
+ athlete:
+ id: 134815
+ resource_state: 1
+ elapsed_time: 1573
+ moving_time: 1569
+ start_date: 2018-02-16T14:52:54Z
+ start_date_local: 2018-02-16T06:52:54Z
+ distance: 8046.72
+ start_index: 0
+ end_index: 1570
+ total_elevation_gain: 276
+ average_speed: 5.12
+ max_speed: 9.5
+ average_cadence: 78.6
+ device_watts: true
+ average_watts: 233.1
+ lap_index: 1
+ split: 1
gear:
id: b12345678987654321
primary: true
@@ -1219,10 +1219,10 @@ paths:
use_primary_photo: true
count: 2
highlighted_kudosers:
- - destination_url: strava://athletes/12345678987654321
- display_name: Marianne V.
- avatar_url: https://dgalywyr863hv.cloudfront.net/pictures/athletes/12345678987654321/12345678987654321/3/medium.jpg
- show_name: true
+ - destination_url: strava://athletes/12345678987654321
+ display_name: Marianne V.
+ avatar_url: https://dgalywyr863hv.cloudfront.net/pictures/athletes/12345678987654321/12345678987654321/3/medium.jpg
+ show_name: true
device_name: Garmin Edge 1030
embed_token: 18e4615989b47dd4ff3dc711b0aa4502e4b311a9
segment_leaderboard_opt_out: false
@@ -1237,36 +1237,36 @@ paths:
/athlete/activities:
get:
tags:
- - Activities
+ - Activities
summary: List Athlete Activities
description: Returns the activities of an athlete for a specific identifier.
Requires activity:read. Only Me activities will be filtered out unless requested
by a token with activity:read_all.
operationId: getLoggedInAthleteActivities
parameters:
- - name: before
- in: query
- description: An epoch timestamp to use for filtering activities that have
- taken place before a certain time.
- schema:
- type: integer
- - name: after
- in: query
- description: An epoch timestamp to use for filtering activities that have
- taken place after a certain time.
- schema:
- type: integer
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: before
+ in: query
+ description: An epoch timestamp to use for filtering activities that have
+ taken place before a certain time.
+ schema:
+ type: integer
+ - name: after
+ in: query
+ description: An epoch timestamp to use for filtering activities that have
+ taken place after a certain time.
+ schema:
+ type: integer
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: The authenticated athlete's activities
@@ -1277,102 +1277,102 @@ paths:
items:
$ref: '#/components/schemas/SummaryActivity'
example:
- - resource_state: 2
- athlete:
- id: 134815
- resource_state: 1
- name: Happy Friday
- distance: 24931.4
- moving_time: 4500
- elapsed_time: 4500
- total_elevation_gain: 0
- type: Ride
- id: 154504250376823
- external_id: garmin_push_12345678987654321
- upload_id: 987654321234567900000
- start_date: 2018-05-02T12:15:09Z
- start_date_local: 2018-05-02T05:15:09Z
- timezone: (GMT-08:00) America/Los_Angeles
- utc_offset: -25200
- location_country: United States
- achievement_count: 0
- kudos_count: 3
- comment_count: 1
- athlete_count: 1
- photo_count: 0
- map:
- id: a12345678987654321
- resource_state: 2
- trainer: true
- commute: false
- manual: false
- private: false
- flagged: false
- gear_id: b12345678987654321
- from_accepted_tag: false
- average_speed: 5.54
- max_speed: 11
- average_cadence: 67.1
- average_watts: 175.3
- weighted_average_watts: 210
- kilojoules: 788.7
- device_watts: true
- has_heartrate: true
- average_heartrate: 140.3
- max_heartrate: 178
- max_watts: 406
- pr_count: 0
- total_photo_count: 1
- has_kudoed: false
- suffer_score: 82
- - resource_state: 2
- athlete:
- id: 167560
- resource_state: 1
- name: Bondcliff
- distance: 23676.5
- moving_time: 5400
- elapsed_time: 5400
- total_elevation_gain: 0
- type: Ride
- id: 1234567809
- external_id: garmin_push_12345678987654321
- upload_id: 1234567819
- start_date: 2018-04-30T12:35:51Z
- start_date_local: 2018-04-30T05:35:51Z
- timezone: (GMT-08:00) America/Los_Angeles
- utc_offset: -25200
- location_country: United States
- achievement_count: 0
- kudos_count: 4
- comment_count: 0
- athlete_count: 1
- photo_count: 0
- map:
- id: a12345689
- resource_state: 2
- trainer: true
- commute: false
- manual: false
- private: false
- flagged: false
- gear_id: b12345678912343
- from_accepted_tag: false
- average_speed: 4.385
- max_speed: 8.8
- average_cadence: 69.8
- average_watts: 200
- weighted_average_watts: 214
- kilojoules: 1080
- device_watts: true
- has_heartrate: true
- average_heartrate: 152.4
- max_heartrate: 183
- max_watts: 403
- pr_count: 0
- total_photo_count: 1
- has_kudoed: false
- suffer_score: 162
+ - resource_state: 2
+ athlete:
+ id: 134815
+ resource_state: 1
+ name: Happy Friday
+ distance: 24931.4
+ moving_time: 4500
+ elapsed_time: 4500
+ total_elevation_gain: 0
+ type: Ride
+ id: 154504250376823
+ external_id: garmin_push_12345678987654321
+ upload_id: 987654321234567900000
+ start_date: 2018-05-02T12:15:09Z
+ start_date_local: 2018-05-02T05:15:09Z
+ timezone: (GMT-08:00) America/Los_Angeles
+ utc_offset: -25200
+ location_country: United States
+ achievement_count: 0
+ kudos_count: 3
+ comment_count: 1
+ athlete_count: 1
+ photo_count: 0
+ map:
+ id: a12345678987654321
+ resource_state: 2
+ trainer: true
+ commute: false
+ manual: false
+ private: false
+ flagged: false
+ gear_id: b12345678987654321
+ from_accepted_tag: false
+ average_speed: 5.54
+ max_speed: 11
+ average_cadence: 67.1
+ average_watts: 175.3
+ weighted_average_watts: 210
+ kilojoules: 788.7
+ device_watts: true
+ has_heartrate: true
+ average_heartrate: 140.3
+ max_heartrate: 178
+ max_watts: 406
+ pr_count: 0
+ total_photo_count: 1
+ has_kudoed: false
+ suffer_score: 82
+ - resource_state: 2
+ athlete:
+ id: 167560
+ resource_state: 1
+ name: Bondcliff
+ distance: 23676.5
+ moving_time: 5400
+ elapsed_time: 5400
+ total_elevation_gain: 0
+ type: Ride
+ id: 1234567809
+ external_id: garmin_push_12345678987654321
+ upload_id: 1234567819
+ start_date: 2018-04-30T12:35:51Z
+ start_date_local: 2018-04-30T05:35:51Z
+ timezone: (GMT-08:00) America/Los_Angeles
+ utc_offset: -25200
+ location_country: United States
+ achievement_count: 0
+ kudos_count: 4
+ comment_count: 0
+ athlete_count: 1
+ photo_count: 0
+ map:
+ id: a12345689
+ resource_state: 2
+ trainer: true
+ commute: false
+ manual: false
+ private: false
+ flagged: false
+ gear_id: b12345678912343
+ from_accepted_tag: false
+ average_speed: 4.385
+ max_speed: 8.8
+ average_cadence: 69.8
+ average_watts: 200
+ weighted_average_watts: 214
+ kilojoules: 1080
+ device_watts: true
+ has_heartrate: true
+ average_heartrate: 152.4
+ max_heartrate: 183
+ max_watts: 403
+ pr_count: 0
+ total_photo_count: 1
+ has_kudoed: false
+ suffer_score: 162
default:
description: Unexpected error.
content:
@@ -1382,20 +1382,20 @@ paths:
/activities/{id}/laps:
get:
tags:
- - Activities
+ - Activities
summary: List Activity Laps
description: Returns the laps of an activity identified by an identifier. Requires
activity:read for Everyone and Followers activities. Requires activity:read_all
for Only Me activities.
operationId: getLapsByActivityId
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Activity Laps.
@@ -1406,30 +1406,30 @@ paths:
items:
$ref: '#/components/schemas/Lap'
example:
- - id: 12345678987654320
- resource_state: 2
- name: Lap 1
- activity:
- id: 12345678987654320
- resource_state: 1
- athlete:
- id: 12345678987654320
- resource_state: 1
- elapsed_time: 1691
- moving_time: 1587
- start_date: 2018-02-08T14:13:37Z
- start_date_local: 2018-02-08T06:13:37Z
- distance: 8046.72
- start_index: 0
- end_index: 1590
- total_elevation_gain: 270
- average_speed: 4.76
- max_speed: 9.4
- average_cadence: 79
- device_watts: true
- average_watts: 228.2
- lap_index: 1
- split: 1
+ - id: 12345678987654320
+ resource_state: 2
+ name: Lap 1
+ activity:
+ id: 12345678987654320
+ resource_state: 1
+ athlete:
+ id: 12345678987654320
+ resource_state: 1
+ elapsed_time: 1691
+ moving_time: 1587
+ start_date: 2018-02-08T14:13:37Z
+ start_date_local: 2018-02-08T06:13:37Z
+ distance: 8046.72
+ start_index: 0
+ end_index: 1590
+ total_elevation_gain: 270
+ average_speed: 4.76
+ max_speed: 9.4
+ average_cadence: 79
+ device_watts: true
+ average_watts: 228.2
+ lap_index: 1
+ split: 1
default:
description: Unexpected error.
content:
@@ -1439,20 +1439,20 @@ paths:
/activities/{id}/zones:
get:
tags:
- - Activities
+ - Activities
summary: Get Activity Zones
description: Summit Feature. Returns the zones of a given activity. Requires
activity:read for Everyone and Followers activities. Requires activity:read_all
for Only Me activities.
operationId: getZonesByActivityId
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Activity Zones.
@@ -1471,31 +1471,31 @@ paths:
/activities/{id}/comments:
get:
tags:
- - Activities
+ - Activities
summary: List Activity Comments
description: Returns the comments on the given activity. Requires activity:read
for Everyone and Followers activities. Requires activity:read_all for Only
Me activities.
operationId: getCommentsByActivityId
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: Comments.
@@ -1506,14 +1506,14 @@ paths:
items:
$ref: '#/components/schemas/Comment'
example:
- - id: 12345678987654320
- activity_id: 12345678987654320
- resource_state: 2
- text: Good job and keep the cat pictures coming!
- created_at: 2018-02-08T19:25:39Z
- athlete:
- firstname: Peter
- lastname: S
+ - id: 12345678987654320
+ activity_id: 12345678987654320
+ resource_state: 2
+ text: Good job and keep the cat pictures coming!
+ created_at: 2018-02-08T19:25:39Z
+ athlete:
+ firstname: Peter
+ lastname: S
default:
description: Unexpected error.
content:
@@ -1523,31 +1523,31 @@ paths:
/activities/{id}/kudos:
get:
tags:
- - Activities
+ - Activities
summary: List Activity Kudoers
description: Returns the athletes who kudoed an activity identified by an identifier.
Requires activity:read for Everyone and Followers activities. Requires activity:read_all
for Only Me activities.
operationId: getKudoersByActivityId
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: Comments.
@@ -1558,8 +1558,8 @@ paths:
items:
$ref: '#/components/schemas/SummaryAthlete'
example:
- - firstname: Peter
- lastname: S
+ - firstname: Peter
+ lastname: S
default:
description: Unexpected error.
content:
@@ -1569,18 +1569,18 @@ paths:
/clubs/{id}:
get:
tags:
- - Clubs
+ - Clubs
summary: Get Club
description: Returns a given club using its identifier.
operationId: getClubById
parameters:
- - name: id
- in: path
- description: The identifier of the club.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the club.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: The detailed representation of a club.
@@ -1622,29 +1622,29 @@ paths:
/clubs/{id}/members:
get:
tags:
- - Clubs
+ - Clubs
summary: List Club Members
description: Returns a list of the athletes who are members of a given club.
operationId: getClubMembersById
parameters:
- - name: id
- in: path
- description: The identifier of the club.
- required: true
- schema:
- type: integer
- format: int64
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: id
+ in: path
+ description: The identifier of the club.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: A list of summary athlete representations.
@@ -1655,12 +1655,12 @@ paths:
items:
$ref: '#/components/schemas/SummaryAthlete'
example:
- - resource_state: 2
- firstname: Peter
- lastname: S.
- membership: member
- admin: false
- owner: false
+ - resource_state: 2
+ firstname: Peter
+ lastname: S.
+ membership: member
+ admin: false
+ owner: false
default:
description: Unexpected error.
content:
@@ -1670,29 +1670,29 @@ paths:
/clubs/{id}/admins:
get:
tags:
- - Clubs
+ - Clubs
summary: List Club Administrators
description: Returns a list of the administrators of a given club.
operationId: getClubAdminsById
parameters:
- - name: id
- in: path
- description: The identifier of the club.
- required: true
- schema:
- type: integer
- format: int64
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: id
+ in: path
+ description: The identifier of the club.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: A list of summary athlete representations.
@@ -1703,9 +1703,9 @@ paths:
items:
$ref: '#/components/schemas/SummaryAthlete'
example:
- - resource_state: 2
- firstname: Peter
- lastname: S.
+ - resource_state: 2
+ firstname: Peter
+ lastname: S.
default:
description: Unexpected error.
content:
@@ -1715,7 +1715,7 @@ paths:
/clubs/{id}/activities:
get:
tags:
- - Clubs
+ - Clubs
summary: List Club Activities
description: Retrieve recent activities from members of a specific club. The
authenticated athlete must belong to the requested club in order to hit this
@@ -1723,24 +1723,24 @@ paths:
for all activities.
operationId: getClubActivitiesById
parameters:
- - name: id
- in: path
- description: The identifier of the club.
- required: true
- schema:
- type: integer
- format: int64
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: id
+ in: path
+ description: The identifier of the club.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: A list of activities.
@@ -1751,17 +1751,17 @@ paths:
items:
$ref: '#/components/schemas/SummaryActivity'
example:
- - resource_state: 2
- athlete:
- resource_state: 2
- firstname: Peter
- lastname: S.
- name: World Championship
- distance: 2641.7
- moving_time: 577
- elapsed_time: 635
- total_elevation_gain: 8.8
- type: Ride
+ - resource_state: 2
+ athlete:
+ resource_state: 2
+ firstname: Peter
+ lastname: S.
+ name: World Championship
+ distance: 2641.7
+ moving_time: 577
+ elapsed_time: 635
+ total_elevation_gain: 8.8
+ type: Ride
default:
description: Unexpected error.
content:
@@ -1771,23 +1771,23 @@ paths:
/athlete/clubs:
get:
tags:
- - Clubs
+ - Clubs
summary: List Athlete Clubs
description: Returns a list of the clubs whose membership includes the authenticated
athlete.
operationId: getLoggedInAthleteClubs
parameters:
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: A list of summary club representations.
@@ -1798,22 +1798,22 @@ paths:
items:
$ref: '#/components/schemas/SummaryClub'
example:
- - id: 231407
- resource_state: 2
- name: The Strava Club
- profile_medium: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5319085/1/medium.jpg
- profile: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5319085/1/large.jpg
- cover_photo: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5098428/4/large.jpg
- cover_photo_small: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5098428/4/small.jpg
- sport_type: other
- city: San Francisco
- state: California
- country: United States
- private: false
- member_count: 93151
- featured: false
- verified: true
- url: strava
+ - id: 231407
+ resource_state: 2
+ name: The Strava Club
+ profile_medium: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5319085/1/medium.jpg
+ profile: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5319085/1/large.jpg
+ cover_photo: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5098428/4/large.jpg
+ cover_photo_small: https://dgalywyr863hv.cloudfront.net/pictures/clubs/231407/5098428/4/small.jpg
+ sport_type: other
+ city: San Francisco
+ state: California
+ country: United States
+ private: false
+ member_count: 93151
+ featured: false
+ verified: true
+ url: strava
default:
description: Unexpected error.
content:
@@ -1823,17 +1823,17 @@ paths:
/gear/{id}:
get:
tags:
- - Gears
+ - Gears
summary: Get Equipment
description: Returns an equipment using its identifier.
operationId: getGearById
parameters:
- - name: id
- in: path
- description: The identifier of the gear.
- required: true
- schema:
- type: string
+ - name: id
+ in: path
+ description: The identifier of the gear.
+ required: true
+ schema:
+ type: string
responses:
200:
description: A representation of the gear.
@@ -1859,19 +1859,19 @@ paths:
/routes/{id}:
get:
tags:
- - Routes
+ - Routes
summary: Get Route
description: Returns a route using its identifier. Requires read_all scope for
private routes.
operationId: getRouteById
parameters:
- - name: id
- in: path
- description: The identifier of the route.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the route.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: A representation of the route.
@@ -1888,24 +1888,24 @@ paths:
/athletes/{id}/routes:
get:
tags:
- - Routes
+ - Routes
summary: List Athlete Routes
description: Returns a list of the routes created by the authenticated athlete.
Private routes are filtered out unless requested by a token with read_all
scope.
operationId: getRoutesByAthleteId
parameters:
- - name: page
- in: query
- description: Page number. Defaults to 1.
- schema:
- type: integer
- - name: per_page
- in: query
- description: Number of items per page. Defaults to 30.
- schema:
- type: integer
- default: 30
+ - name: page
+ in: query
+ description: Page number. Defaults to 1.
+ schema:
+ type: integer
+ - name: per_page
+ in: query
+ description: Number of items per page. Defaults to 30.
+ schema:
+ type: integer
+ default: 30
responses:
200:
description: A representation of the route.
@@ -1924,23 +1924,23 @@ paths:
/routes/{id}/export_gpx:
get:
tags:
- - Routes
+ - Routes
summary: Export Route GPX
description: Returns a GPX file of the route. Requires read_all scope for private
routes.
operationId: getRouteAsGPX
parameters:
- - name: id
- in: path
- description: The identifier of the route.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the route.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: A GPX file with the route.
- content: {}
+ content: { }
default:
description: Unexpected error.
content:
@@ -1950,23 +1950,23 @@ paths:
/routes/{id}/export_tcx:
get:
tags:
- - Routes
+ - Routes
summary: Export Route TCX
description: Returns a TCX file of the route. Requires read_all scope for private
routes.
operationId: getRouteAsTCX
parameters:
- - name: id
- in: path
- description: The identifier of the route.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the route.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: A TCX file with the route.
- content: {}
+ content: { }
default:
description: Unexpected error.
content:
@@ -1976,7 +1976,7 @@ paths:
/uploads:
post:
tags:
- - Uploads
+ - Uploads
summary: Upload Activity
description: Uploads a new data file to create an activity from. Requires activity:write
scope.
@@ -2008,12 +2008,12 @@ paths:
type: string
description: The format of the uploaded file.
enum:
- - fit
- - fit.gz
- - tcx
- - tcx.gz
- - gpx
- - gpx.gz
+ - fit
+ - fit.gz
+ - tcx
+ - tcx.gz
+ - gpx
+ - gpx.gz
external_id:
type: string
description: The desired external identifier of the resulting activity.
@@ -2033,19 +2033,19 @@ paths:
/uploads/{uploadId}:
get:
tags:
- - Uploads
+ - Uploads
summary: Get Upload
description: Returns an upload for a given identifier. Requires activity:write
scope.
operationId: getUploadById
parameters:
- - name: uploadId
- in: path
- description: The identifier of the upload.
- required: true
- schema:
- type: integer
- format: int64
+ - name: uploadId
+ in: path
+ description: The identifier of the upload.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: Representation of the upload.
@@ -2062,49 +2062,49 @@ paths:
/activities/{id}/streams:
get:
tags:
- - Streams
+ - Streams
summary: Get Activity Streams
description: Returns the given activity's streams. Requires activity:read scope.
Requires activity:read_all scope for Only Me activities.
operationId: getActivityStreams
parameters:
- - name: id
- in: path
- description: The identifier of the activity.
- required: true
- schema:
- type: integer
- format: int64
- - name: keys
- in: query
- description: Desired stream types.
- required: true
- style: form
- explode: false
- schema:
- minItems: 1
- type: array
- items:
- type: string
- enum:
- - time
- - distance
- - latlng
- - altitude
- - velocity_smooth
- - heartrate
- - cadence
- - watts
- - temp
- - moving
- - grade_smooth
- - name: key_by_type
- in: query
- description: Must be true.
- required: true
- schema:
- type: boolean
- default: true
+ - name: id
+ in: path
+ description: The identifier of the activity.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: keys
+ in: query
+ description: Desired stream types.
+ required: true
+ style: form
+ explode: false
+ schema:
+ minItems: 1
+ type: array
+ items:
+ type: string
+ enum:
+ - time
+ - distance
+ - latlng
+ - altitude
+ - velocity_smooth
+ - heartrate
+ - cadence
+ - watts
+ - temp
+ - moving
+ - grade_smooth
+ - name: key_by_type
+ in: query
+ description: Must be true.
+ required: true
+ schema:
+ type: boolean
+ default: true
responses:
200:
description: The set of requested streams.
@@ -2113,23 +2113,23 @@ paths:
schema:
$ref: '#/components/schemas/StreamSet'
example:
- - type: distance
- data:
- - 2.9
- - 5.8
- - 8.5
- - 11.7
- - 15
- - 19
- - 23.2
- - 28
- - 32.8
- - 38.1
- - 43.8
- - 49.5
- series_type: distance
- original_size: 12
- resolution: high
+ - type: distance
+ data:
+ - 2.9
+ - 5.8
+ - 8.5
+ - 11.7
+ - 15
+ - 19
+ - 23.2
+ - 28
+ - 32.8
+ - 38.1
+ - 43.8
+ - 49.5
+ series_type: distance
+ original_size: 12
+ resolution: high
default:
description: Unexpected error.
content:
@@ -2139,49 +2139,49 @@ paths:
/segment_efforts/{id}/streams:
get:
tags:
- - Streams
+ - Streams
summary: Get Segment Effort Streams
description: Returns a set of streams for a segment effort completed by the
authenticated athlete. Requires read_all scope.
operationId: getSegmentEffortStreams
parameters:
- - name: id
- in: path
- description: The identifier of the segment effort.
- required: true
- schema:
- type: integer
- format: int64
- - name: keys
- in: query
- description: The types of streams to return.
- required: true
- style: form
- explode: false
- schema:
- minItems: 1
- type: array
- items:
- type: string
- enum:
- - time
- - distance
- - latlng
- - altitude
- - velocity_smooth
- - heartrate
- - cadence
- - watts
- - temp
- - moving
- - grade_smooth
- - name: key_by_type
- in: query
- description: Must be true.
- required: true
- schema:
- type: boolean
- default: true
+ - name: id
+ in: path
+ description: The identifier of the segment effort.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: keys
+ in: query
+ description: The types of streams to return.
+ required: true
+ style: form
+ explode: false
+ schema:
+ minItems: 1
+ type: array
+ items:
+ type: string
+ enum:
+ - time
+ - distance
+ - latlng
+ - altitude
+ - velocity_smooth
+ - heartrate
+ - cadence
+ - watts
+ - temp
+ - moving
+ - grade_smooth
+ - name: key_by_type
+ in: query
+ description: Must be true.
+ required: true
+ schema:
+ type: boolean
+ default: true
responses:
200:
description: The set of requested streams.
@@ -2190,25 +2190,25 @@ paths:
schema:
$ref: '#/components/schemas/StreamSet'
example:
- - type: distance
- data:
- - 904.5
- - 957.8
- - 963.1
- - 989.1
- - 1011.9
- - 1049.7
- - 1082.4
- - 1098.1
- - 1113.2
- - 1124.7
- - 1139.2
- - 1142.1
- - 1170.4
- - 1173
- series_type: distance
- original_size: 14
- resolution: high
+ - type: distance
+ data:
+ - 904.5
+ - 957.8
+ - 963.1
+ - 989.1
+ - 1011.9
+ - 1049.7
+ - 1082.4
+ - 1098.1
+ - 1113.2
+ - 1124.7
+ - 1139.2
+ - 1142.1
+ - 1170.4
+ - 1173
+ series_type: distance
+ original_size: 14
+ resolution: high
default:
description: Unexpected error.
content:
@@ -2218,41 +2218,41 @@ paths:
/segments/{id}/streams:
get:
tags:
- - Streams
+ - Streams
summary: Get Segment Streams
description: Returns the given segment's streams. Requires read_all scope for
private segments.
operationId: getSegmentStreams
parameters:
- - name: id
- in: path
- description: The identifier of the segment.
- required: true
- schema:
- type: integer
- format: int64
- - name: keys
- in: query
- description: The types of streams to return.
- required: true
- style: form
- explode: false
- schema:
- minItems: 1
- type: array
- items:
- type: string
- enum:
- - distance
- - latlng
- - altitude
- - name: key_by_type
- in: query
- description: Must be true.
- required: true
- schema:
- type: boolean
- default: true
+ - name: id
+ in: path
+ description: The identifier of the segment.
+ required: true
+ schema:
+ type: integer
+ format: int64
+ - name: keys
+ in: query
+ description: The types of streams to return.
+ required: true
+ style: form
+ explode: false
+ schema:
+ minItems: 1
+ type: array
+ items:
+ type: string
+ enum:
+ - distance
+ - latlng
+ - altitude
+ - name: key_by_type
+ in: query
+ description: Must be true.
+ required: true
+ schema:
+ type: boolean
+ default: true
responses:
200:
description: The set of requested streams.
@@ -2261,29 +2261,29 @@ paths:
schema:
$ref: '#/components/schemas/StreamSet'
example:
- - type: latlng
- data:
- - - 37.833112
- - -122.483436
- - - 37.832964
- - -122.483406
- series_type: distance
- original_size: 2
- resolution: high
- - type: distance
- data:
- - 0
- - 16.8
- series_type: distance
- original_size: 2
- resolution: high
- - type: altitude
- data:
- - 92.4
- - 93.4
- series_type: distance
- original_size: 2
- resolution: high
+ - type: latlng
+ data:
+ - - 37.833112
+ - -122.483436
+ - - 37.832964
+ - -122.483406
+ series_type: distance
+ original_size: 2
+ resolution: high
+ - type: distance
+ data:
+ - 0
+ - 16.8
+ series_type: distance
+ original_size: 2
+ resolution: high
+ - type: altitude
+ data:
+ - 92.4
+ - 93.4
+ series_type: distance
+ original_size: 2
+ resolution: high
default:
description: Unexpected error.
content:
@@ -2293,19 +2293,19 @@ paths:
/routes/{id}/streams:
get:
tags:
- - Streams
+ - Streams
summary: Get Route Streams
description: Returns the given route's streams. Requires read_all scope for
private routes.
operationId: getRouteStreams
parameters:
- - name: id
- in: path
- description: The identifier of the route.
- required: true
- schema:
- type: integer
- format: int64
+ - name: id
+ in: path
+ description: The identifier of the route.
+ required: true
+ schema:
+ type: integer
+ format: int64
responses:
200:
description: The set of requested streams.
@@ -2314,20 +2314,20 @@ paths:
schema:
$ref: '#/components/schemas/StreamSet'
example:
- - type: latlng
- data:
- - - 37.833112
- - -122.483436
- - - 37.832964
- - -122.483406
- - type: distance
- data:
- - 0
- - 16.8
- - type: altitude
- data:
- - 92.4
- - 93.4
+ - type: latlng
+ data:
+ - - 37.833112
+ - -122.483436
+ - - 37.832964
+ - -122.483406
+ - type: distance
+ data:
+ - 0
+ - 16.8
+ - type: altitude
+ data:
+ - 92.4
+ - 93.4
default:
description: Unexpected error.
content:
@@ -2418,94 +2418,94 @@ components:
description: The type of resource associated with this error.
DetailedAthlete:
allOf:
- - $ref: '#/components/schemas/SummaryAthlete'
- - type: object
- properties:
- follower_count:
- type: integer
- description: The athlete's follower count.
- friend_count:
- type: integer
- description: The athlete's friend count.
- measurement_preference:
- type: string
- description: The athlete's preferred unit system.
- enum:
- - feet
- - meters
- ftp:
- type: integer
- description: The athlete's FTP (Functional Threshold Power).
- weight:
- type: number
- description: The athlete's weight.
- format: float
- clubs:
- type: array
- description: The athlete's clubs.
- items:
- $ref: '#/components/schemas/SummaryClub'
- bikes:
- type: array
- description: The athlete's bikes.
- items:
- $ref: '#/components/schemas/SummaryGear'
- shoes:
- type: array
- description: The athlete's shoes.
- items:
- $ref: '#/components/schemas/SummaryGear'
+ - $ref: '#/components/schemas/SummaryAthlete'
+ - type: object
+ properties:
+ follower_count:
+ type: integer
+ description: The athlete's follower count.
+ friend_count:
+ type: integer
+ description: The athlete's friend count.
+ measurement_preference:
+ type: string
+ description: The athlete's preferred unit system.
+ enum:
+ - feet
+ - meters
+ ftp:
+ type: integer
+ description: The athlete's FTP (Functional Threshold Power).
+ weight:
+ type: number
+ description: The athlete's weight.
+ format: float
+ clubs:
+ type: array
+ description: The athlete's clubs.
+ items:
+ $ref: '#/components/schemas/SummaryClub'
+ bikes:
+ type: array
+ description: The athlete's bikes.
+ items:
+ $ref: '#/components/schemas/SummaryGear'
+ shoes:
+ type: array
+ description: The athlete's shoes.
+ items:
+ $ref: '#/components/schemas/SummaryGear'
SummaryAthlete:
allOf:
- - $ref: '#/components/schemas/MetaAthlete'
- - type: object
- properties:
- resource_state:
- type: integer
- description: 'Resource state, indicates level of detail. Possible values:
+ - $ref: '#/components/schemas/MetaAthlete'
+ - type: object
+ properties:
+ resource_state:
+ type: integer
+ description: 'Resource state, indicates level of detail. Possible values:
1 -> "meta", 2 -> "summary", 3 -> "detail"'
- firstname:
- type: string
- description: The athlete's first name.
- lastname:
- type: string
- description: The athlete's last name.
- profile_medium:
- type: string
- description: URL to a 62x62 pixel profile picture.
- profile:
- type: string
- description: URL to a 124x124 pixel profile picture.
- city:
- type: string
- description: The athlete's city.
- state:
- type: string
- description: The athlete's state or geographical region.
- country:
- type: string
- description: The athlete's country.
- sex:
- type: string
- description: The athlete's sex.
- enum:
- - M
- - F
- premium:
- type: boolean
- description: Deprecated. Use summit field instead. Whether the athlete
- has any Summit subscription.
- summit:
- type: boolean
- description: Whether the athlete has any Summit subscription.
- created_at:
- type: string
- description: The time at which the athlete was created.
- format: date-time
- updated_at:
- type: string
- description: The time at which the athlete was last updated.
- format: date-time
+ firstname:
+ type: string
+ description: The athlete's first name.
+ lastname:
+ type: string
+ description: The athlete's last name.
+ profile_medium:
+ type: string
+ description: URL to a 62x62 pixel profile picture.
+ profile:
+ type: string
+ description: URL to a 124x124 pixel profile picture.
+ city:
+ type: string
+ description: The athlete's city.
+ state:
+ type: string
+ description: The athlete's state or geographical region.
+ country:
+ type: string
+ description: The athlete's country.
+ sex:
+ type: string
+ description: The athlete's sex.
+ enum:
+ - M
+ - F
+ premium:
+ type: boolean
+ description: Deprecated. Use summit field instead. Whether the athlete
+ has any Summit subscription.
+ summit:
+ type: boolean
+ description: Whether the athlete has any Summit subscription.
+ created_at:
+ type: string
+ description: The time at which the athlete was created.
+ format: date-time
+ updated_at:
+ type: string
+ description: The time at which the athlete was last updated.
+ format: date-time
MetaAthlete:
type: object
properties:
@@ -2515,49 +2515,49 @@ components:
format: int64
SummaryClub:
allOf:
- - $ref: '#/components/schemas/MetaClub'
- - type: object
- properties:
- profile_medium:
- type: string
- description: URL to a 60x60 pixel profile picture.
- cover_photo:
- type: string
- description: URL to a ~1185x580 pixel cover photo.
- cover_photo_small:
- type: string
- description: URL to a ~360x176 pixel cover photo.
- sport_type:
- type: string
- enum:
- - cycling
- - running
- - triathlon
- - other
- city:
- type: string
- description: The club's city.
- state:
- type: string
- description: The club's state or geographical region.
- country:
- type: string
- description: The club's country.
- private:
- type: boolean
- description: Whether the club is private.
- member_count:
- type: integer
- description: The club's member count.
- featured:
- type: boolean
- description: Whether the club is featured or not.
- verified:
- type: boolean
- description: Whether the club is verified or not.
- url:
- type: string
- description: The club's vanity URL.
+ - $ref: '#/components/schemas/MetaClub'
+ - type: object
+ properties:
+ profile_medium:
+ type: string
+ description: URL to a 60x60 pixel profile picture.
+ cover_photo:
+ type: string
+ description: URL to a ~1185x580 pixel cover photo.
+ cover_photo_small:
+ type: string
+ description: URL to a ~360x176 pixel cover photo.
+ sport_type:
+ type: string
+ enum:
+ - cycling
+ - running
+ - triathlon
+ - other
+ city:
+ type: string
+ description: The club's city.
+ state:
+ type: string
+ description: The club's state or geographical region.
+ country:
+ type: string
+ description: The club's country.
+ private:
+ type: boolean
+ description: Whether the club is private.
+ member_count:
+ type: integer
+ description: The club's member count.
+ featured:
+ type: boolean
+ description: Whether the club is featured or not.
+ verified:
+ type: boolean
+ description: Whether the club is verified or not.
+ url:
+ type: string
+ description: The club's vanity URL.
MetaClub:
type: object
properties:
@@ -2627,36 +2627,36 @@ components:
$ref: '#/components/schemas/ZoneRanges'
DetailedSegment:
allOf:
- - $ref: '#/components/schemas/SummarySegment'
- - type: object
- properties:
- created_at:
- type: string
- description: The time at which the segment was created.
- format: date-time
- updated_at:
- type: string
- description: The time at which the segment was last updated.
- format: date-time
- total_elevation_gain:
- type: number
- description: The segment's total elevation gain.
- format: float
- map:
- $ref: '#/components/schemas/PolylineMap'
- effort_count:
- type: integer
- description: The total number of efforts for this segment
- athlete_count:
- type: integer
- description: The number of unique athletes who have an effort for this
- segment
- hazardous:
- type: boolean
- description: Whether this segment is considered hazardous
- star_count:
- type: integer
- description: The number of stars for this segment
+ - $ref: '#/components/schemas/SummarySegment'
+ - type: object
+ properties:
+ created_at:
+ type: string
+ description: The time at which the segment was created.
+ format: date-time
+ updated_at:
+ type: string
+ description: The time at which the segment was last updated.
+ format: date-time
+ total_elevation_gain:
+ type: number
+ description: The segment's total elevation gain.
+ format: float
+ map:
+ $ref: '#/components/schemas/PolylineMap'
+ effort_count:
+ type: integer
+ description: The total number of efforts for this segment
+ athlete_count:
+ type: integer
+ description: The number of unique athletes who have an effort for this
+ segment
+ hazardous:
+ type: boolean
+ description: Whether this segment is considered hazardous
+ star_count:
+ type: integer
+ description: The number of stars for this segment
SummarySegment:
type: object
properties:
@@ -2670,8 +2670,8 @@ components:
activity_type:
type: string
enum:
- - Ride
- - Run
+ - Ride
+ - Run
distance:
type: number
description: The segment's distance, in meters
@@ -2786,63 +2786,63 @@ components:
description: The summary polyline of the map
DetailedSegmentEffort:
allOf:
- - $ref: '#/components/schemas/SummarySegmentEffort'
- - type: object
- properties:
- name:
- type: string
- description: The name of the segment on which this effort was performed
- activity:
- $ref: '#/components/schemas/MetaActivity'
- athlete:
- $ref: '#/components/schemas/MetaAthlete'
- moving_time:
- type: integer
- description: The effort's moving time
- start_index:
- type: integer
- description: The start index of this effort in its activity's stream
- end_index:
- type: integer
- description: The end index of this effort in its activity's stream
- average_cadence:
- type: number
- description: The effort's average cadence
- format: float
- average_watts:
- type: number
- description: The average wattage of this effort
- format: float
- device_watts:
- type: boolean
- description: For riding efforts, whether the wattage was reported by a
- dedicated recording device
- average_heartrate:
- type: number
- description: The heart heart rate of the athlete during this effort
- format: float
- max_heartrate:
- type: number
- description: The maximum heart rate of the athlete during this effort
- format: float
- segment:
- $ref: '#/components/schemas/SummarySegment'
- kom_rank:
- maximum: 1E+1
- minimum: 1
- type: integer
- description: The rank of the effort on the global leaderboard if it belongs
- in the top 10 at the time of upload
- pr_rank:
- maximum: 3
- minimum: 1
- type: integer
- description: The rank of the effort on the athlete's leaderboard if it
- belongs in the top 3 at the time of upload
- hidden:
- type: boolean
- description: Whether this effort should be hidden when viewed within an
- activity
+ - $ref: '#/components/schemas/SummarySegmentEffort'
+ - type: object
+ properties:
+ name:
+ type: string
+ description: The name of the segment on which this effort was performed
+ activity:
+ $ref: '#/components/schemas/MetaActivity'
+ athlete:
+ $ref: '#/components/schemas/MetaAthlete'
+ moving_time:
+ type: integer
+ description: The effort's moving time
+ start_index:
+ type: integer
+ description: The start index of this effort in its activity's stream
+ end_index:
+ type: integer
+ description: The end index of this effort in its activity's stream
+ average_cadence:
+ type: number
+ description: The effort's average cadence
+ format: float
+ average_watts:
+ type: number
+ description: The average wattage of this effort
+ format: float
+ device_watts:
+ type: boolean
+ description: For riding efforts, whether the wattage was reported by a
+ dedicated recording device
+ average_heartrate:
+ type: number
+ description: The heart heart rate of the athlete during this effort
+ format: float
+ max_heartrate:
+ type: number
+ description: The maximum heart rate of the athlete during this effort
+ format: float
+ segment:
+ $ref: '#/components/schemas/SummarySegment'
+ kom_rank:
+ maximum: 1E+1
+ minimum: 1
+ type: integer
+ description: The rank of the effort on the global leaderboard if it belongs
+ in the top 10 at the time of upload
+ pr_rank:
+ maximum: 3
+ minimum: 1
+ type: integer
+ description: The rank of the effort on the athlete's leaderboard if it
+ belongs in the top 3 at the time of upload
+ hidden:
+ type: boolean
+ description: Whether this effort should be hidden when viewed within an
+ activity
MetaActivity:
type: object
properties:
@@ -2880,12 +2880,12 @@ components:
type: string
description: The description for the category of the climb
enum:
- - NC
- - "4"
- - "3"
- - "2"
- - "1"
- - HC
+ - NC
+ - "4"
+ - "3"
+ - "2"
+ - "1"
+ - HC
avg_grade:
type: number
description: The segment's average grade, in percents
@@ -2946,8 +2946,8 @@ components:
type: string
description: The unit system in which the race should be displayed.
enum:
- - feet
- - meters
+ - feet
+ - meters
url:
type: string
description: The vanity URL of this race on Strava.
@@ -2956,221 +2956,221 @@ components:
description: The URL of this race's website.
DetailedActivity:
allOf:
- - $ref: '#/components/schemas/SummaryActivity'
- - type: object
- properties:
- description:
- type: string
- description: The description of the activity
- photos:
- $ref: '#/components/schemas/PhotosSummary'
- gear:
- $ref: '#/components/schemas/SummaryGear'
- calories:
- type: number
- description: The number of kilocalories consumed during this activity
- format: float
- segment_efforts:
- type: array
- items:
- $ref: '#/components/schemas/DetailedSegmentEffort'
- device_name:
- type: string
- description: The name of the device used to record the activity
- embed_token:
- type: string
- description: The token used to embed a Strava activity
- splits_metric:
- type: array
- description: The splits of this activity in metric units (for runs)
- items:
- $ref: '#/components/schemas/Split'
- splits_standard:
- type: array
- description: The splits of this activity in imperial units (for runs)
- items:
- $ref: '#/components/schemas/Split'
- laps:
- type: array
- items:
- $ref: '#/components/schemas/Lap'
- best_efforts:
- type: array
- items:
- $ref: '#/components/schemas/DetailedSegmentEffort'
+ - $ref: '#/components/schemas/SummaryActivity'
+ - type: object
+ properties:
+ description:
+ type: string
+ description: The description of the activity
+ photos:
+ $ref: '#/components/schemas/PhotosSummary'
+ gear:
+ $ref: '#/components/schemas/SummaryGear'
+ calories:
+ type: number
+ description: The number of kilocalories consumed during this activity
+ format: float
+ segment_efforts:
+ type: array
+ items:
+ $ref: '#/components/schemas/DetailedSegmentEffort'
+ device_name:
+ type: string
+ description: The name of the device used to record the activity
+ embed_token:
+ type: string
+ description: The token used to embed a Strava activity
+ splits_metric:
+ type: array
+ description: The splits of this activity in metric units (for runs)
+ items:
+ $ref: '#/components/schemas/Split'
+ splits_standard:
+ type: array
+ description: The splits of this activity in imperial units (for runs)
+ items:
+ $ref: '#/components/schemas/Split'
+ laps:
+ type: array
+ items:
+ $ref: '#/components/schemas/Lap'
+ best_efforts:
+ type: array
+ items:
+ $ref: '#/components/schemas/DetailedSegmentEffort'
SummaryActivity:
allOf:
- - $ref: '#/components/schemas/MetaActivity'
- - type: object
- properties:
- external_id:
- type: string
- description: The identifier provided at upload time
- upload_id:
- type: integer
- description: The identifier of the upload that resulted in this activity
- format: int64
- athlete:
- $ref: '#/components/schemas/MetaAthlete'
- name:
- type: string
- description: The name of the activity
- distance:
- type: number
- description: The activity's distance, in meters
- format: float
- moving_time:
- type: integer
- description: The activity's moving time, in seconds
- elapsed_time:
- type: integer
- description: The activity's elapsed time, in seconds
- total_elevation_gain:
- type: number
- description: The activity's total elevation gain.
- format: float
- elev_high:
- type: number
- description: The activity's highest elevation, in meters
- format: float
- elev_low:
- type: number
- description: The activity's lowest elevation, in meters
- format: float
- type:
- $ref: '#/components/schemas/ActivityType'
- start_date:
- type: string
- description: The time at which the activity was started.
- format: date-time
- start_date_local:
- type: string
- description: The time at which the activity was started in the local timezone.
- format: date-time
- timezone:
- type: string
- description: The timezone of the activity
- start_latlng:
- $ref: '#/components/schemas/LatLng'
- end_latlng:
- $ref: '#/components/schemas/LatLng'
- achievement_count:
- type: integer
- description: The number of achievements gained during this activity
- kudos_count:
- type: integer
- description: The number of kudos given for this activity
- comment_count:
- type: integer
- description: The number of comments for this activity
- athlete_count:
- minimum: 1
- type: integer
- description: The number of athletes for taking part in a group activity
- photo_count:
- type: integer
- description: The number of Instagram photos for this activity
- total_photo_count:
- type: integer
- description: The number of Instagram and Strava photos for this activity
- map:
- $ref: '#/components/schemas/PolylineMap'
- trainer:
- type: boolean
- description: Whether this activity was recorded on a training machine
- commute:
- type: boolean
- description: Whether this activity is a commute
- manual:
- type: boolean
- description: Whether this activity was created manually
- private:
- type: boolean
- description: Whether this activity is private
- flagged:
- type: boolean
- description: Whether this activity is flagged
- workout_type:
- type: integer
- description: The activity's workout type
- upload_id_str:
- type: string
- description: The unique identifier of the upload in string format
- average_speed:
- type: number
- description: The activity's average speed, in meters per second
- format: float
- max_speed:
- type: number
- description: The activity's max speed, in meters per second
- format: float
- has_kudoed:
- type: boolean
- description: Whether the logged-in athlete has kudoed this activity
- gear_id:
- type: string
- description: The id of the gear for the activity
- kilojoules:
- type: number
- description: The total work done in kilojoules during this activity. Rides
- only
- format: float
- average_watts:
- type: number
- description: Average power output in watts during this activity. Rides
- only
- format: float
- device_watts:
- type: boolean
- description: Whether the watts are from a power meter, false if estimated
- max_watts:
- type: integer
- description: Rides with power meter data only
- weighted_average_watts:
- type: integer
- description: Similar to Normalized Power. Rides with power meter data
- only
+ - $ref: '#/components/schemas/MetaActivity'
+ - type: object
+ properties:
+ external_id:
+ type: string
+ description: The identifier provided at upload time
+ upload_id:
+ type: integer
+ description: The identifier of the upload that resulted in this activity
+ format: int64
+ athlete:
+ $ref: '#/components/schemas/MetaAthlete'
+ name:
+ type: string
+ description: The name of the activity
+ distance:
+ type: number
+ description: The activity's distance, in meters
+ format: float
+ moving_time:
+ type: integer
+ description: The activity's moving time, in seconds
+ elapsed_time:
+ type: integer
+ description: The activity's elapsed time, in seconds
+ total_elevation_gain:
+ type: number
+ description: The activity's total elevation gain.
+ format: float
+ elev_high:
+ type: number
+ description: The activity's highest elevation, in meters
+ format: float
+ elev_low:
+ type: number
+ description: The activity's lowest elevation, in meters
+ format: float
+ type:
+ $ref: '#/components/schemas/ActivityType'
+ start_date:
+ type: string
+ description: The time at which the activity was started.
+ format: date-time
+ start_date_local:
+ type: string
+ description: The time at which the activity was started in the local timezone.
+ format: date-time
+ timezone:
+ type: string
+ description: The timezone of the activity
+ start_latlng:
+ $ref: '#/components/schemas/LatLng'
+ end_latlng:
+ $ref: '#/components/schemas/LatLng'
+ achievement_count:
+ type: integer
+ description: The number of achievements gained during this activity
+ kudos_count:
+ type: integer
+ description: The number of kudos given for this activity
+ comment_count:
+ type: integer
+ description: The number of comments for this activity
+ athlete_count:
+ minimum: 1
+ type: integer
+ description: The number of athletes for taking part in a group activity
+ photo_count:
+ type: integer
+ description: The number of Instagram photos for this activity
+ total_photo_count:
+ type: integer
+ description: The number of Instagram and Strava photos for this activity
+ map:
+ $ref: '#/components/schemas/PolylineMap'
+ trainer:
+ type: boolean
+ description: Whether this activity was recorded on a training machine
+ commute:
+ type: boolean
+ description: Whether this activity is a commute
+ manual:
+ type: boolean
+ description: Whether this activity was created manually
+ private:
+ type: boolean
+ description: Whether this activity is private
+ flagged:
+ type: boolean
+ description: Whether this activity is flagged
+ workout_type:
+ type: integer
+ description: The activity's workout type
+ upload_id_str:
+ type: string
+ description: The unique identifier of the upload in string format
+ average_speed:
+ type: number
+ description: The activity's average speed, in meters per second
+ format: float
+ max_speed:
+ type: number
+ description: The activity's max speed, in meters per second
+ format: float
+ has_kudoed:
+ type: boolean
+ description: Whether the logged-in athlete has kudoed this activity
+ gear_id:
+ type: string
+ description: The id of the gear for the activity
+ kilojoules:
+ type: number
+ description: The total work done in kilojoules during this activity. Rides
+ only
+ format: float
+ average_watts:
+ type: number
+ description: Average power output in watts during this activity. Rides
+ only
+ format: float
+ device_watts:
+ type: boolean
+ description: Whether the watts are from a power meter, false if estimated
+ max_watts:
+ type: integer
+ description: Rides with power meter data only
+ weighted_average_watts:
+ type: integer
+ description: Similar to Normalized Power. Rides with power meter data
+ only
ActivityType:
type: string
description: An enumeration of the types an activity may have.
enum:
- - AlpineSki
- - BackcountrySki
- - Canoeing
- - Crossfit
- - EBikeRide
- - Elliptical
- - Golf
- - Handcycle
- - Hike
- - IceSkate
- - InlineSkate
- - Kayaking
- - Kitesurf
- - NordicSki
- - Ride
- - RockClimbing
- - RollerSki
- - Rowing
- - Run
- - Sail
- - Skateboard
- - Snowboard
- - Snowshoe
- - Soccer
- - StairStepper
- - StandUpPaddling
- - Surfing
- - Swim
- - Velomobile
- - VirtualRide
- - VirtualRun
- - Walk
- - WeightTraining
- - Wheelchair
- - Windsurf
- - Workout
- - Yoga
+ - AlpineSki
+ - BackcountrySki
+ - Canoeing
+ - Crossfit
+ - EBikeRide
+ - Elliptical
+ - Golf
+ - Handcycle
+ - Hike
+ - IceSkate
+ - InlineSkate
+ - Kayaking
+ - Kitesurf
+ - NordicSki
+ - Ride
+ - RockClimbing
+ - RollerSki
+ - Rowing
+ - Run
+ - Sail
+ - Skateboard
+ - Snowboard
+ - Snowshoe
+ - Soccer
+ - StairStepper
+ - StandUpPaddling
+ - Surfing
+ - Swim
+ - Velomobile
+ - VirtualRide
+ - VirtualRun
+ - Walk
+ - WeightTraining
+ - Wheelchair
+ - Windsurf
+ - Workout
+ - Yoga
PhotosSummary:
type: object
properties:
@@ -3311,8 +3311,8 @@ components:
type:
type: string
enum:
- - heartrate
- - power
+ - heartrate
+ - power
sensor_based:
type: boolean
points:
@@ -3330,12 +3330,12 @@ components:
TimedZoneRange:
description: A union type representing the time spent in a given zone.
allOf:
- - $ref: '#/components/schemas/ZoneRange'
- - type: object
- properties:
- time:
- type: integer
- description: The number of seconds spent in this zone
+ - $ref: '#/components/schemas/ZoneRange'
+ - type: object
+ properties:
+ time:
+ type: integer
+ description: The number of seconds spent in this zone
Comment:
type: object
properties:
@@ -3358,44 +3358,44 @@ components:
format: date-time
DetailedClub:
allOf:
- - $ref: '#/components/schemas/SummaryClub'
- - type: object
- properties:
- membership:
- type: string
- description: The membership status of the logged-in athlete.
- enum:
- - member
- - pending
- admin:
- type: boolean
- description: Whether the currently logged-in athlete is an administrator
- of this club.
- owner:
- type: boolean
- description: Whether the currently logged-in athlete is the owner of this
- club.
- following_count:
- type: integer
- description: The number of athletes in the club that the logged-in athlete
- follows.
+ - $ref: '#/components/schemas/SummaryClub'
+ - type: object
+ properties:
+ membership:
+ type: string
+ description: The membership status of the logged-in athlete.
+ enum:
+ - member
+ - pending
+ admin:
+ type: boolean
+ description: Whether the currently logged-in athlete is an administrator
+ of this club.
+ owner:
+ type: boolean
+ description: Whether the currently logged-in athlete is the owner of this
+ club.
+ following_count:
+ type: integer
+ description: The number of athletes in the club that the logged-in athlete
+ follows.
DetailedGear:
allOf:
- - $ref: '#/components/schemas/SummaryGear'
- - type: object
- properties:
- brand_name:
- type: string
- description: The gear's brand name.
- model_name:
- type: string
- description: The gear's model name.
- frame_type:
- type: integer
- description: The gear's frame type (bike only).
- description:
- type: string
- description: The gear's description.
+ - $ref: '#/components/schemas/SummaryGear'
+ - type: object
+ properties:
+ brand_name:
+ type: string
+ description: The gear's brand name.
+ model_name:
+ type: string
+ description: The gear's model name.
+ frame_type:
+ type: integer
+ description: The gear's frame type (bike only).
+ description:
+ type: string
+ description: The gear's description.
Route:
type: object
properties:
@@ -3507,14 +3507,14 @@ components:
$ref: '#/components/schemas/SmoothGradeStream'
TimeStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of time values for this stream, in seconds
- items:
- type: integer
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of time values for this stream, in seconds
+ items:
+ type: integer
BaseStream:
type: object
properties:
@@ -3525,125 +3525,125 @@ components:
type: string
description: The level of detail (sampling) in which this stream was returned
enum:
- - low
- - medium
- - high
+ - low
+ - medium
+ - high
series_type:
type: string
description: The base series used in the case the stream was downsampled
enum:
- - distance
- - time
+ - distance
+ - time
DistanceStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of distance values for this stream, in meters
- items:
- type: number
- format: float
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of distance values for this stream, in meters
+ items:
+ type: number
+ format: float
LatLngStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of lat/long values for this stream
- items:
- $ref: '#/components/schemas/LatLng'
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of lat/long values for this stream
+ items:
+ $ref: '#/components/schemas/LatLng'
AltitudeStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of altitude values for this stream, in meters
- items:
- type: number
- format: float
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of altitude values for this stream, in meters
+ items:
+ type: number
+ format: float
SmoothVelocityStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of velocity values for this stream, in meters
- per second
- items:
- type: number
- format: float
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of velocity values for this stream, in meters
+ per second
+ items:
+ type: number
+ format: float
HeartrateStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of heart rate values for this stream, in beats
- per minute
- items:
- type: integer
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of heart rate values for this stream, in beats
+ per minute
+ items:
+ type: integer
CadenceStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of cadence values for this stream, in rotations
- per minute
- items:
- type: integer
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of cadence values for this stream, in rotations
+ per minute
+ items:
+ type: integer
PowerStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of power values for this stream, in watts
- items:
- type: integer
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of power values for this stream, in watts
+ items:
+ type: integer
TemperatureStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of temperature values for this stream, in celsius
- degrees
- items:
- type: integer
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of temperature values for this stream, in celsius
+ degrees
+ items:
+ type: integer
MovingStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of moving values for this stream, as boolean
- values
- items:
- type: boolean
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of moving values for this stream, as boolean
+ values
+ items:
+ type: boolean
SmoothGradeStream:
allOf:
- - $ref: '#/components/schemas/BaseStream'
- - type: object
- properties:
- data:
- type: array
- description: The sequence of grade values for this stream, as percents
- of a grade
- items:
- type: number
- format: float
+ - $ref: '#/components/schemas/BaseStream'
+ - type: object
+ properties:
+ data:
+ type: array
+ description: The sequence of grade values for this stream, as percents
+ of a grade
+ items:
+ type: number
+ format: float
parameters:
page:
name: page
diff --git a/src/test/resources/demo/twitter.yml b/src/test/resources/demo/twitter.yml
index 8e27fdbf..5df85038 100644
--- a/src/test/resources/demo/twitter.yml
+++ b/src/test/resources/demo/twitter.yml
@@ -53,7 +53,7 @@ paths:
get:
description: Full open api spec in JSON format. (See https://github.com/OAI/OpenAPI-Specification/blob/master/README.md)
operationId: getOpenApiSpec
- parameters: []
+ parameters: [ ]
responses:
"200":
content:
@@ -97,8 +97,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Returns hydrated Tweet objects
tags:
- Tweets
@@ -228,7 +228,7 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
+ - BearerToken: [ ]
summary: Returns Tweets that match a search query.
tags:
- Search
@@ -305,7 +305,7 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
+ - BearerToken: [ ]
summary: Returns Tweets from the last 7 days that match a search query.
tags:
- Search
@@ -426,8 +426,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Returns hydrated Tweet objects
tags:
- Tweets
@@ -498,8 +498,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Return details for the specified users
tags:
- Users
@@ -533,8 +533,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Return details for the specified users
tags:
- Users
@@ -562,8 +562,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Return details for the specified users
tags:
- Users
@@ -591,8 +591,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Return details for the specified users
tags:
- Users
@@ -742,8 +742,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Returns Tweet objects that mention the username associated to the provided User ID
tags:
- Mentions
@@ -781,8 +781,8 @@ paths:
default:
$ref: "#/components/responses/HttpErrorResponse"
security:
- - BearerToken: []
- UserToken: []
+ - BearerToken: [ ]
+ UserToken: [ ]
summary: Returns Tweet objects authored by the provided User ID
tags:
- Tweets
@@ -1427,7 +1427,7 @@ components:
- status
type: object
description: A generic problem with no additional information beyond that provided by the HTTP status code.
- GenericTweetsTimelineResponse: {}
+ GenericTweetsTimelineResponse: { }
Geo:
properties:
bbox:
diff --git a/src/test/resources/err.yml b/src/test/resources/err.yml
new file mode 100644
index 00000000..e69de29b
diff --git a/src/test/resources/inputs/all-of-class-level.yml b/src/test/resources/inputs/all-of-class-level.yml
index bf08151d..ef01ea42 100644
--- a/src/test/resources/inputs/all-of-class-level.yml
+++ b/src/test/resources/inputs/all-of-class-level.yml
@@ -5,20 +5,20 @@ info:
components:
schemas:
employee:
- allOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ allOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/all-of-property-level.yml b/src/test/resources/inputs/all-of-property-level.yml
index 4ee9bb27..7574fb00 100644
--- a/src/test/resources/inputs/all-of-property-level.yml
+++ b/src/test/resources/inputs/all-of-property-level.yml
@@ -7,20 +7,20 @@ components:
employee:
properties:
role:
- allOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ allOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/anon-nested-class-level.yml b/src/test/resources/inputs/anon-nested-class-level.yml
index 0e2224c0..0e2980b1 100644
--- a/src/test/resources/inputs/anon-nested-class-level.yml
+++ b/src/test/resources/inputs/anon-nested-class-level.yml
@@ -12,17 +12,17 @@ components:
standardName:
type: object
properties:
- firstName:
+ firstName:
type: string
- lastName:
+ lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
origin:
type: string
heightMetres:
type: number
required:
- - name
+ - name
\ No newline at end of file
diff --git a/src/test/resources/inputs/anon-property-not-required.yml b/src/test/resources/inputs/anon-property-not-required.yml
index a80824bd..d510d607 100644
--- a/src/test/resources/inputs/anon-property-not-required.yml
+++ b/src/test/resources/inputs/anon-property-not-required.yml
@@ -9,13 +9,13 @@ components:
name:
type: object
properties:
- firstName:
+ firstName:
type: string
- lastName:
+ lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
heightMetres:
type: number
\ No newline at end of file
diff --git a/src/test/resources/inputs/anon-property-required.yml b/src/test/resources/inputs/anon-property-required.yml
index ede27f7d..ae276251 100644
--- a/src/test/resources/inputs/anon-property-required.yml
+++ b/src/test/resources/inputs/anon-property-required.yml
@@ -9,15 +9,15 @@ components:
name:
type: object
properties:
- firstName:
+ firstName:
type: string
- lastName:
+ lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
heightMetres:
type: number
required:
- - name
+ - name
\ No newline at end of file
diff --git a/src/test/resources/inputs/any-of-anon-class-level.yml b/src/test/resources/inputs/any-of-anon-class-level.yml
index 904d3b66..c40e8d63 100644
--- a/src/test/resources/inputs/any-of-anon-class-level.yml
+++ b/src/test/resources/inputs/any-of-anon-class-level.yml
@@ -5,22 +5,22 @@ info:
components:
schemas:
employee:
- anyOf:
- - type: object
- properties:
- employeeType:
- type: string
- enum: ['Nurse']
- level:
- type: integer
- required:
- - level
- - type: object
- properties:
- employeeType:
- type: string
- enum: ['Doctor']
- income:
- type: number
- required:
- - income
+ anyOf:
+ - type: object
+ properties:
+ employeeType:
+ type: string
+ enum: [ 'Nurse' ]
+ level:
+ type: integer
+ required:
+ - level
+ - type: object
+ properties:
+ employeeType:
+ type: string
+ enum: [ 'Doctor' ]
+ income:
+ type: number
+ required:
+ - income
diff --git a/src/test/resources/inputs/any-of-anon-property-level.yml b/src/test/resources/inputs/any-of-anon-property-level.yml
index 6bf1dc65..1fd63097 100644
--- a/src/test/resources/inputs/any-of-anon-property-level.yml
+++ b/src/test/resources/inputs/any-of-anon-property-level.yml
@@ -7,23 +7,23 @@ components:
employee:
properties:
role:
- anyOf:
- - type: object
- properties:
- employeeType:
- type: string
- enum: ['Nurse']
- level:
- type: integer
- required:
- - level
- - type: object
- properties:
- employeeType:
- type: string
- enum: ['Doctor']
- income:
- type: number
- required:
- - income
+ anyOf:
+ - type: object
+ properties:
+ employeeType:
+ type: string
+ enum: [ 'Nurse' ]
+ level:
+ type: integer
+ required:
+ - level
+ - type: object
+ properties:
+ employeeType:
+ type: string
+ enum: [ 'Doctor' ]
+ income:
+ type: number
+ required:
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/any-of-class-level.yml b/src/test/resources/inputs/any-of-class-level.yml
index 64b8900e..48fd8384 100644
--- a/src/test/resources/inputs/any-of-class-level.yml
+++ b/src/test/resources/inputs/any-of-class-level.yml
@@ -5,20 +5,20 @@ info:
components:
schemas:
employee:
- anyOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ anyOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/any-of-property-level.yml b/src/test/resources/inputs/any-of-property-level.yml
index a458d701..44aa3191 100644
--- a/src/test/resources/inputs/any-of-property-level.yml
+++ b/src/test/resources/inputs/any-of-property-level.yml
@@ -5,22 +5,22 @@ info:
components:
schemas:
employee:
- properties:
- role:
- anyOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ properties:
+ role:
+ anyOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/array-anon-class-level.yml b/src/test/resources/inputs/array-anon-class-level.yml
index 04fc42cf..f5a6a1bf 100644
--- a/src/test/resources/inputs/array-anon-class-level.yml
+++ b/src/test/resources/inputs/array-anon-class-level.yml
@@ -4,7 +4,7 @@ info:
version: 0.0.1
components:
schemas:
-
+
Customers:
type: array
items:
@@ -15,7 +15,7 @@ components:
lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
\ No newline at end of file
diff --git a/src/test/resources/inputs/array-anon-property-level.yml b/src/test/resources/inputs/array-anon-property-level.yml
index 9e08f2f8..3b921d67 100644
--- a/src/test/resources/inputs/array-anon-property-level.yml
+++ b/src/test/resources/inputs/array-anon-property-level.yml
@@ -4,7 +4,7 @@ info:
version: 0.0.1
components:
schemas:
-
+
Customers:
properties:
names:
@@ -17,5 +17,5 @@ components:
lastName:
type: string
required:
- - firstName
- - lastName
\ No newline at end of file
+ - firstName
+ - lastName
\ No newline at end of file
diff --git a/src/test/resources/inputs/array-class-level.yml b/src/test/resources/inputs/array-class-level.yml
index c4234726..66ee6101 100644
--- a/src/test/resources/inputs/array-class-level.yml
+++ b/src/test/resources/inputs/array-class-level.yml
@@ -4,12 +4,12 @@ info:
version: 0.0.1
components:
schemas:
-
+
Customers:
type: array
items:
$ref: "#/components/schemas/Customer"
-
+
Customer:
properties:
firstName:
@@ -17,6 +17,6 @@ components:
lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
\ No newline at end of file
diff --git a/src/test/resources/inputs/array-property-level.yml b/src/test/resources/inputs/array-property-level.yml
index 6e5a259d..361cb650 100644
--- a/src/test/resources/inputs/array-property-level.yml
+++ b/src/test/resources/inputs/array-property-level.yml
@@ -4,14 +4,14 @@ info:
version: 0.0.1
components:
schemas:
-
+
Customers:
properties:
group:
type: array
items:
$ref: "#/components/schemas/Customer"
-
+
Customer:
properties:
firstName:
@@ -19,6 +19,6 @@ components:
lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
\ No newline at end of file
diff --git a/src/test/resources/inputs/one-of-class-level.yml b/src/test/resources/inputs/one-of-class-level.yml
index c89f6ac9..a0e3705e 100644
--- a/src/test/resources/inputs/one-of-class-level.yml
+++ b/src/test/resources/inputs/one-of-class-level.yml
@@ -5,20 +5,20 @@ info:
components:
schemas:
employee:
- oneOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ oneOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/one-of-property-level-required.yml b/src/test/resources/inputs/one-of-property-level-required.yml
index 03aef7ef..70cc3e3f 100644
--- a/src/test/resources/inputs/one-of-property-level-required.yml
+++ b/src/test/resources/inputs/one-of-property-level-required.yml
@@ -5,24 +5,24 @@ info:
components:
schemas:
employee:
- properties:
- role:
- oneOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
- required:
- - role
-
+ properties:
+ role:
+ oneOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+ required:
+ - role
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/one-of-property-level.yml b/src/test/resources/inputs/one-of-property-level.yml
index 7e429f1f..0b526515 100644
--- a/src/test/resources/inputs/one-of-property-level.yml
+++ b/src/test/resources/inputs/one-of-property-level.yml
@@ -5,22 +5,22 @@ info:
components:
schemas:
employee:
- properties:
- role:
- oneOf:
- - $ref: "#/components/schemas/doctor"
- - $ref: "#/components/schemas/nurse"
-
+ properties:
+ role:
+ oneOf:
+ - $ref: "#/components/schemas/doctor"
+ - $ref: "#/components/schemas/nurse"
+
nurse:
properties:
level:
type: integer
required:
- - level
-
+ - level
+
doctor:
properties:
income:
type: number
required:
- - income
\ No newline at end of file
+ - income
\ No newline at end of file
diff --git a/src/test/resources/inputs/parameter-anon-empty-object.yml b/src/test/resources/inputs/parameter-anon-empty-object.yml
index 2c2f2342..0f988068 100644
--- a/src/test/resources/inputs/parameter-anon-empty-object.yml
+++ b/src/test/resources/inputs/parameter-anon-empty-object.yml
@@ -15,10 +15,10 @@ paths:
required: false
description: The number of items to skip before starting to collect the result set
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
diff --git a/src/test/resources/inputs/parameter-anon.yml b/src/test/resources/inputs/parameter-anon.yml
index f2ebc670..fc05e946 100644
--- a/src/test/resources/inputs/parameter-anon.yml
+++ b/src/test/resources/inputs/parameter-anon.yml
@@ -29,10 +29,10 @@ paths:
max:
type: integer
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
diff --git a/src/test/resources/inputs/parameter-ref-complex.yml b/src/test/resources/inputs/parameter-ref-complex.yml
index 643bd5a3..2f3ed6b9 100644
--- a/src/test/resources/inputs/parameter-ref-complex.yml
+++ b/src/test/resources/inputs/parameter-ref-complex.yml
@@ -6,12 +6,12 @@ paths:
/customer/expired:
get:
parameters:
- - $ref: '#/components/parameters/CustomerId'
+ - $ref: '#/components/parameters/CustomerId'
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
diff --git a/src/test/resources/inputs/parameter-ref-ref.yml b/src/test/resources/inputs/parameter-ref-ref.yml
index 60a346fb..ee389a04 100644
--- a/src/test/resources/inputs/parameter-ref-ref.yml
+++ b/src/test/resources/inputs/parameter-ref-ref.yml
@@ -6,12 +6,12 @@ paths:
/customer/expired:
get:
parameters:
- - $ref: '#/components/parameters/CustomerId'
+ - $ref: '#/components/parameters/CustomerId'
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
diff --git a/src/test/resources/inputs/parameter-ref.yml b/src/test/resources/inputs/parameter-ref.yml
index 8bad4ce6..933d9010 100644
--- a/src/test/resources/inputs/parameter-ref.yml
+++ b/src/test/resources/inputs/parameter-ref.yml
@@ -6,12 +6,12 @@ paths:
/customer/expired:
get:
parameters:
- - $ref: '#/components/parameters/CustomerId'
+ - $ref: '#/components/parameters/CustomerId'
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
diff --git a/src/test/resources/inputs/path-returns-non-ref.yml b/src/test/resources/inputs/path-returns-non-ref.yml
index e9c13a55..b1edd0b1 100644
--- a/src/test/resources/inputs/path-returns-non-ref.yml
+++ b/src/test/resources/inputs/path-returns-non-ref.yml
@@ -6,14 +6,14 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
-
+
components:
schemas:
Customer:
@@ -29,24 +29,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/path-returns-ref-ref.yml b/src/test/resources/inputs/path-returns-ref-ref.yml
index 90d3cea1..3ffea00b 100644
--- a/src/test/resources/inputs/path-returns-ref-ref.yml
+++ b/src/test/resources/inputs/path-returns-ref-ref.yml
@@ -6,18 +6,18 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
$ref: '#/components/responses/Customers'
-
+
components:
responses:
Customers:
content:
- application/json:
- schema:
- type: array
- items:
- $ref: '#/components/schemas/Customer'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Customer'
schemas:
Customers:
type: array
@@ -36,24 +36,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/path-returns-ref-ref2.yml b/src/test/resources/inputs/path-returns-ref-ref2.yml
index 1b9ee066..55382334 100644
--- a/src/test/resources/inputs/path-returns-ref-ref2.yml
+++ b/src/test/resources/inputs/path-returns-ref-ref2.yml
@@ -6,16 +6,16 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
$ref: '#/components/responses/Customers'
-
+
components:
responses:
Customers:
content:
- application/json:
- schema:
- $ref: '#/components/schemas/Customers'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Customers'
schemas:
Customers:
type: array
@@ -34,24 +34,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/path-returns-ref.yml b/src/test/resources/inputs/path-returns-ref.yml
index c1d47bc2..76b70d47 100644
--- a/src/test/resources/inputs/path-returns-ref.yml
+++ b/src/test/resources/inputs/path-returns-ref.yml
@@ -6,18 +6,18 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
$ref: '#/components/responses/Customers'
-
+
components:
responses:
Customers:
content:
- application/json:
- schema:
- type: array
- items:
- $ref: '#/components/schemas/Customer'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Customer'
schemas:
Customer:
properties:
@@ -32,24 +32,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/petstore-expanded.yml b/src/test/resources/inputs/petstore-expanded.yml
index fe1c9886..61d081a6 100644
--- a/src/test/resources/inputs/petstore-expanded.yml
+++ b/src/test/resources/inputs/petstore-expanded.yml
@@ -128,7 +128,7 @@ components:
allOf:
- $ref: '#/components/schemas/NewPet'
- $ref: '#/components/schemas/PetId'
-
+
PetId:
type: object
properties:
@@ -136,17 +136,17 @@ components:
type: integer
format: int64
required:
- - id
+ - id
NewPet:
type: object
required:
- - name
+ - name
properties:
name:
type: string
tag:
- type: string
+ type: string
Error:
type: object
diff --git a/src/test/resources/inputs/petstore.yml b/src/test/resources/inputs/petstore.yml
index a97931b2..091e0878 100644
--- a/src/test/resources/inputs/petstore.yml
+++ b/src/test/resources/inputs/petstore.yml
@@ -30,7 +30,7 @@ paths:
schema:
type: string
content:
- application/json:
+ application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
@@ -53,7 +53,7 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
-
+
/pets/{petId}:
get:
summary: Info for a specific pet
diff --git a/src/test/resources/inputs/ref-class-level.yml b/src/test/resources/inputs/ref-class-level.yml
index 833b6b9e..2c795345 100644
--- a/src/test/resources/inputs/ref-class-level.yml
+++ b/src/test/resources/inputs/ref-class-level.yml
@@ -11,8 +11,8 @@ components:
lastName:
type: string
required:
- - firstName
- - lastName
+ - firstName
+ - lastName
Client:
$ref: "#/components/schemas/Customer"
\ No newline at end of file
diff --git a/src/test/resources/inputs/request-body-ref-ref.yml b/src/test/resources/inputs/request-body-ref-ref.yml
index ca9188ce..21d48acc 100644
--- a/src/test/resources/inputs/request-body-ref-ref.yml
+++ b/src/test/resources/inputs/request-body-ref-ref.yml
@@ -6,16 +6,16 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
requestBody:
$ref: '#/components/requestBodies/repositories'
-
+
components:
requestBodies:
repositories:
@@ -44,24 +44,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/request-body-ref.yml b/src/test/resources/inputs/request-body-ref.yml
index 7a92820a..4f6b43c8 100644
--- a/src/test/resources/inputs/request-body-ref.yml
+++ b/src/test/resources/inputs/request-body-ref.yml
@@ -6,17 +6,17 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
-
+
requestBody:
$ref: '#/components/requestBodies/repositories'
-
+
components:
requestBodies:
repositories:
@@ -43,24 +43,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/request-body.yml b/src/test/resources/inputs/request-body.yml
index f77dc2be..045b2172 100644
--- a/src/test/resources/inputs/request-body.yml
+++ b/src/test/resources/inputs/request-body.yml
@@ -6,14 +6,14 @@ paths:
/customer/expired:
get:
responses:
- '200':
+ '200':
content:
application/json:
- schema:
+ schema:
type: array
items:
$ref: '#/components/schemas/Customer'
-
+
requestBody:
content:
application/json:
@@ -24,7 +24,7 @@ paths:
type: array
items:
type: integer
-
+
components:
schemas:
Customer:
@@ -40,24 +40,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/inputs/simple-types-and-arrays.yml b/src/test/resources/inputs/simple-types-and-arrays.yml
index 7bf8dfdb..92743a0a 100644
--- a/src/test/resources/inputs/simple-types-and-arrays.yml
+++ b/src/test/resources/inputs/simple-types-and-arrays.yml
@@ -33,24 +33,24 @@ components:
format: date
lastSessionTime:
type: string
- format: date-time
+ format: date-time
numberOfChildren:
- type: integer
+ type: integer
alive:
type: boolean
nicknames:
type: array
- items:
+ items:
type: string
favouriteNumbers:
type: array
items:
- type: integer
+ type: integer
picture:
type: string
format: binary
required:
- - firstName
- - lastName
- - dateOfBirth
+ - firstName
+ - lastName
+ - dateOfBirth
\ No newline at end of file
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
index 7b08027f..fec0b472 100644
--- a/src/test/resources/log4j.properties
+++ b/src/test/resources/log4j.properties
@@ -1,10 +1,8 @@
-log4j.rootLogger= INFO, console
-
+log4j.rootLogger=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
#log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c - %m%n
-
# Print only messages of level WARN or above in the package com.foo.
#log4j.logger.com.foo=WARN
diff --git a/src/test/resources/openapi-example.yml b/src/test/resources/openapi-example.yml
index c58f01b6..d8dffbfb 100644
--- a/src/test/resources/openapi-example.yml
+++ b/src/test/resources/openapi-example.yml
@@ -8,7 +8,7 @@ info:
servers:
- url: URL_HERE
description: DESCRIPTION_HERE
-
+
paths:
/agent:
get:
@@ -16,46 +16,46 @@ paths:
description: |
Returns the list of craft reporting agents (reporting sources), like AIS, LRIT, FIS.
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
+ schema:
$ref: '#/components/schemas/agents'
-
+
/craftType:
get:
summary: Returns the list of craft types
description: |
Returns the list of craft types, like Vessel, Aircraft, Tracking Device, etc.
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
+ schema:
$ref: '#/components/schemas/craftTypes'
-
+
/identifierType:
get:
- summary: Returns the list of craft identifier types
+ summary: Returns the list of craft identifier types
description: |
Returns the list of craft identifier types like MMSI, Serial Number, IMO Number
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
+ schema:
$ref: '#/components/schemas/identifierTypes'
-
+
/track/rect:
get:
summary: |
Returns a list of tracks (craft with positions) according to position, time and other criteria
description: |
Returns a list of track objects with identifiers, properties and positions
- parameters:
+ parameters:
- in: query
name: startTimeInclusive
description: start of the search time window, must be less than finishTimeExclusive
@@ -73,16 +73,16 @@ paths:
- in: query
name: identifierValue
description: identifier values to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
+ items:
type: string
- in: query
name: craftId
description: craftId to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
+ items:
type: string
- in: query
name: craftType
@@ -102,7 +102,7 @@ paths:
name: minLat
description: southermost latitude of the bounding box, must be less than maxLatExclusive
required: true
- schema:
+ schema:
type: number
minimum: -90
maximum: 90
@@ -141,7 +141,7 @@ paths:
description: includes craft properties if true otherwise does not
schema:
type: boolean
- default: true
+ default: true
- in: query
name: includeFixProperties
description: includes fix properties if true otherwise does not
@@ -155,18 +155,18 @@ paths:
type: boolean
default: false
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
+ schema:
$ref: '#/components/schemas/tracks'
-
+
/track/circle:
get:
summary: Returns a list of tracks (craft with positions) according to position, time and other criteria
description: Returns a list of track objects with craft identifiers and positions
- parameters:
+ parameters:
- in: query
name: startTimeInclusive
description: start of the search time window, must be less than finishTimeExclusive
@@ -184,17 +184,17 @@ paths:
- in: query
name: identifierValue
description: identifier values to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
+ items:
type: string
- in: query
name: craftId
description: craftId to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
- type: string
+ items:
+ type: string
- in: query
name: craftType
description: craft types to filter on, no filtering if empty
@@ -213,7 +213,7 @@ paths:
name: centreLat
description: latitude of the centre of the search region
required: true
- schema:
+ schema:
type: number
minimum: -90
maximum: 90
@@ -237,7 +237,7 @@ paths:
description: includes craft properties if true otherwise does not
schema:
type: boolean
- default: true
+ default: true
- in: query
name: includeFixProperties
description: includes fix properties if true otherwise does not
@@ -251,13 +251,13 @@ paths:
type: boolean
default: false
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
- $ref: '#/components/schemas/tracks'
-
+ schema:
+ $ref: '#/components/schemas/tracks'
+
/craftpic/rect:
get:
summary: |
@@ -269,7 +269,7 @@ paths:
window are considered. Note that closest actual position by time becomes
last actual position if afterHours is set to 0.
description: Returns a list of craft with position
- parameters:
+ parameters:
- in: query
name: time
description: time to predict positions at or to find the closest actual position to
@@ -281,7 +281,7 @@ paths:
name: beforeHours
description: hours before time to search for fixes
required: true
- schema:
+ schema:
type: number
minimum: 0
default: 24
@@ -289,24 +289,24 @@ paths:
name: afterHours
description: hours after time to search for fixes
required: true
- schema:
+ schema:
type: number
minimum: 0
- default: 2
+ default: 2
- in: query
name: identifierValue
description: identifier values to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
+ items:
type: string
- in: query
name: craftId
description: craftId to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
- type: string
+ items:
+ type: string
- in: query
name: craftType
description: craft types to filter on, no filtering if empty
@@ -320,12 +320,12 @@ paths:
schema:
type: array
items:
- type: string
+ type: string
- in: query
name: minLat
description: southermost latitude of the bounding box, must be less than or equal to maxLat
required: true
- schema:
+ schema:
type: number
minimum: -90
maximum: 90
@@ -400,13 +400,13 @@ paths:
default: 20
minimum: 0
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
+ schema:
$ref: '#/components/schemas/craftpic'
-
+
/craftpic/circle:
get:
summary: |
@@ -418,7 +418,7 @@ paths:
window are considered. Note that closest actual position by time becomes
last actual position if afterHours is set to 0.
description: Returns a list of craft with position
- parameters:
+ parameters:
- in: query
name: time
description: time to find closest actual by time or predicted positions at
@@ -430,7 +430,7 @@ paths:
name: beforeHours
description: hours before time to search for fixes
required: true
- schema:
+ schema:
type: number
minimum: 0
default: 24
@@ -438,24 +438,24 @@ paths:
name: afterHours
description: hours after time to search for fixes
required: true
- schema:
+ schema:
type: number
minimum: 0
- default: 2
+ default: 2
- in: query
name: identifierValue
description: identifier values to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
+ items:
type: string
- in: query
name: craftId
description: craftId to filter on, no filtering if empty
- schema:
+ schema:
type: array
- items:
- type: string
+ items:
+ type: string
- in: query
name: craftType
description: craft types to filter on, no filtering if empty
@@ -469,12 +469,12 @@ paths:
schema:
type: array
items:
- type: string
+ type: string
- in: query
name: centreLat
description: latitude of the centre of the circular search region
required: true
- schema:
+ schema:
type: number
minimum: -90
maximum: 90
@@ -513,7 +513,7 @@ paths:
default: false
- in: query
name: predicted
- description: if true then uses extrapolation/interpolation to predict the positions at target time. If false returns closest actual positions by time to the target time.
+ description: if true then uses extrapolation/interpolation to predict the positions at target time. If false returns closest actual positions by time to the target time.
schema:
type: boolean
default: true
@@ -532,51 +532,51 @@ paths:
default: 20
minimum: 0
responses:
- '200': # status code
+ '200': # status code
description: OK
content:
application/json:
- schema:
- $ref: '#/components/schemas/craftpic'
+ schema:
+ $ref: '#/components/schemas/craftpic'
components:
schemas:
-
+
agents:
description: craft reporting agents like AIS, LRIT
type: array
items:
$ref: '#/components/schemas/agent'
-
+
agent:
description: craft reporting agent like AIS, LRIT
type: string
-
+
craftTypes:
description: craft types like Vessel, Aircraft
type: array
items:
$ref: '#/components/schemas/craftType'
- tracks:
+ tracks:
description: a collection of unique craft and their position reports (fixes)
type: array
items:
$ref: '#/components/schemas/craftFixes'
-
+
craftpic:
description: a collection of unique craft and a single position report (fix)
type: array
- items:
+ items:
$ref: '#/components/schemas/craftFix'
-
+
craftId:
description: the unique system identifier of a craft (not one of the public identifiers for a craft like the MMSI no)
type: string
maxLength: 512
minLength: 1
example: 43215678
-
+
craftType:
type: string
maxLength: 512
@@ -587,13 +587,13 @@ components:
type: array
items:
$ref: '#/components/schemas/identifierType'
-
+
identifierType:
type: string
maxLength: 256
minLength: 1
example: MMSI
-
+
craftFix:
description: a single craft together with a single position for that craft (fix)
properties:
@@ -617,10 +617,10 @@ components:
fix:
$ref: '#/components/schemas/fix'
required:
- - craftId
- - craftType
- - fix
-
+ - craftId
+ - craftType
+ - fix
+
craftFixes:
description: a single craft and a collection of position reports (fixes)
properties:
@@ -646,25 +646,25 @@ components:
items:
$ref: '#/components/schemas/fix'
required:
- - craftId
- - craftType
+ - craftId
+ - craftType
identifier:
description: a unique identifier for a craft having a key and value
properties:
- key:
+ key:
$ref: '#/components/schemas/identifierType'
value:
type: string
example: '123456789'
required:
- - key
- - value
+ - key
+ - value
property:
description: a key-value property of the craft and/or fix
properties:
- key:
+ key:
type: string
minLength: 1
example: Name
@@ -672,67 +672,67 @@ components:
type: string
example: 'PACIFIC EXPLORER'
required:
- - key
- - value
+ - key
+ - value
fix:
description: a position report for a craft (may be actual or predicted)
properties:
- fixId:
+ fixId:
type: string
maxLength: 512
minLength: 1
example: '7654321'
- time:
+ time:
type: string
format: date-time
example: '2020-11-17T14:08:18.123Z'
- lat:
+ lat:
type: number
minimum: -90.0
maximum: 90.0
example: -34.2
- lon:
+ lon:
type: number
minimum: -180
maximum: 180
example: 140.0
- altitudeMetres:
+ altitudeMetres:
type: number
- cog:
+ cog:
type: number
minimum: 0
maximum: 360
example: 345.0
- speedKnots:
+ speedKnots:
type: number
minimum: 0.0
example: 10.5
- agent:
+ agent:
$ref: '#/components/schemas/agent'
- properties:
+ properties:
type: array
- items:
+ items:
$ref: '#/components/schemas/property'
identifiers:
type: array
- items:
+ items:
$ref: '#/components/schemas/identifier'
- closestActualFixTime:
+ closestActualFixTime:
type: string
format: date-time
required:
- - fixId
- - time
- - lat
- - lon
- - agent
+ - fixId
+ - time
+ - lat
+ - lon
+ - agent
securitySchemes:
- basicAuth: # <-- arbitrary name for the security scheme
+ basicAuth: # <-- arbitrary name for the security scheme
type: http
scheme: basic
-
+
security:
- - basicAuth: [] # applies to whole api
+ - basicAuth: [ ] # applies to whole api
\ No newline at end of file
diff --git a/src/test/resources/outputs/all-of-class-level.puml.svg b/src/test/resources/outputs/all-of-class-level.puml.svg
new file mode 100644
index 00000000..5c96ec8a
--- /dev/null
+++ b/src/test/resources/outputs/all-of-class-level.puml.svg
@@ -0,0 +1,101 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/all-of-property-level.puml.svg b/src/test/resources/outputs/all-of-property-level.puml.svg
new file mode 100644
index 00000000..d3a47f74
--- /dev/null
+++ b/src/test/resources/outputs/all-of-property-level.puml.svg
@@ -0,0 +1,108 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/anon-nested-class-level.puml.svg b/src/test/resources/outputs/anon-nested-class-level.puml.svg
new file mode 100644
index 00000000..6f3f8f7f
--- /dev/null
+++ b/src/test/resources/outputs/anon-nested-class-level.puml.svg
@@ -0,0 +1,116 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/anon-parameters.puml b/src/test/resources/outputs/anon-parameters.puml
deleted file mode 100644
index b104e144..00000000
--- a/src/test/resources/outputs/anon-parameters.puml
+++ /dev/null
@@ -1,25 +0,0 @@
-@startuml
-set namespaceSeparator none
-
-class "Customer" {
- firstName : string {O}
- lastName : string {O}
-}
-
-class "CustomerId" <> {
- value : string
-}
-hide <> circle
-
-class "GET /customer/expired" <> {
- customerId : string
-}
-
-class "GET /customer/expired 200 Response" <> {
-}
-
-"GET /customer/expired 200 Response" --> "*" "Customer"
-
-"GET /customer/expired" ..> "GET /customer/expired 200 Response": 200
-
-@enduml
\ No newline at end of file
diff --git a/src/test/resources/outputs/anon-property-not-required.puml.svg b/src/test/resources/outputs/anon-property-not-required.puml.svg
new file mode 100644
index 00000000..28e4532c
--- /dev/null
+++ b/src/test/resources/outputs/anon-property-not-required.puml.svg
@@ -0,0 +1,86 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/anon-property-required.puml.svg b/src/test/resources/outputs/anon-property-required.puml.svg
new file mode 100644
index 00000000..799da05d
--- /dev/null
+++ b/src/test/resources/outputs/anon-property-required.puml.svg
@@ -0,0 +1,86 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/any-of-anon-class-level.puml.svg b/src/test/resources/outputs/any-of-anon-class-level.puml.svg
new file mode 100644
index 00000000..ca5d87de
--- /dev/null
+++ b/src/test/resources/outputs/any-of-anon-class-level.puml.svg
@@ -0,0 +1,103 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/any-of-anon-property-level.puml.svg b/src/test/resources/outputs/any-of-anon-property-level.puml.svg
new file mode 100644
index 00000000..ae5857d5
--- /dev/null
+++ b/src/test/resources/outputs/any-of-anon-property-level.puml.svg
@@ -0,0 +1,120 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/any-of-class-level.puml.svg b/src/test/resources/outputs/any-of-class-level.puml.svg
new file mode 100644
index 00000000..d1d853dc
--- /dev/null
+++ b/src/test/resources/outputs/any-of-class-level.puml.svg
@@ -0,0 +1,95 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/any-of-property-level.puml.svg b/src/test/resources/outputs/any-of-property-level.puml.svg
new file mode 100644
index 00000000..0f85470c
--- /dev/null
+++ b/src/test/resources/outputs/any-of-property-level.puml.svg
@@ -0,0 +1,112 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/array-anon-class-level.puml.svg b/src/test/resources/outputs/array-anon-class-level.puml.svg
new file mode 100644
index 00000000..77cbae92
--- /dev/null
+++ b/src/test/resources/outputs/array-anon-class-level.puml.svg
@@ -0,0 +1,78 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/array-anon-property-level.puml.svg b/src/test/resources/outputs/array-anon-property-level.puml.svg
new file mode 100644
index 00000000..0ab27566
--- /dev/null
+++ b/src/test/resources/outputs/array-anon-property-level.puml.svg
@@ -0,0 +1,81 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/array-class-level.puml.svg b/src/test/resources/outputs/array-class-level.puml.svg
new file mode 100644
index 00000000..cf9df953
--- /dev/null
+++ b/src/test/resources/outputs/array-class-level.puml.svg
@@ -0,0 +1,78 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/array-property-level.puml.svg b/src/test/resources/outputs/array-property-level.puml.svg
new file mode 100644
index 00000000..7933da01
--- /dev/null
+++ b/src/test/resources/outputs/array-property-level.puml.svg
@@ -0,0 +1,81 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/components-parameter-complex.puml b/src/test/resources/outputs/components-parameter-complex.puml
deleted file mode 100644
index fe1266f0..00000000
--- a/src/test/resources/outputs/components-parameter-complex.puml
+++ /dev/null
@@ -1,29 +0,0 @@
-@startuml
-hide <> circle
-hide empty methods
-hide empty fields
-set namespaceSeparator none
-
-class "Customer" {
- firstName : string {O}
- lastName : string {O}
-}
-
-class "CustomerId" <> {
- id : string {O}
- prefix : string {O}
-}
-
-class "GET /customer/expired" <> {
-}
-
-class "GET /customer/expired 200 Response" <> {
-}
-
-"GET /customer/expired 200 Response" --> "*" "Customer"
-
-"GET /customer/expired" ..> "GET /customer/expired 200 Response": 200
-
-"GET /customer/expired" --> "1" "CustomerId" : "customerId"
-
-@enduml
\ No newline at end of file
diff --git a/src/test/resources/outputs/components-parameter.puml b/src/test/resources/outputs/components-parameter.puml
deleted file mode 100644
index 9ef1dfc9..00000000
--- a/src/test/resources/outputs/components-parameter.puml
+++ /dev/null
@@ -1,28 +0,0 @@
-@startuml
-hide <> circle
-hide empty methods
-hide empty fields
-set namespaceSeparator none
-
-class "Customer" {
- firstName : string {O}
- lastName : string {O}
-}
-
-class "CustomerId" <> {
- value : string
-}
-
-class "GET /customer/expired" <> {
-}
-
-class "GET /customer/expired 200 Response" <> {
-}
-
-"GET /customer/expired 200 Response" --> "*" "Customer"
-
-"GET /customer/expired" ..> "GET /customer/expired 200 Response": 200
-
-"GET /customer/expired" --> "1" "CustomerId" : "customerId"
-
-@enduml
\ No newline at end of file
diff --git a/src/test/resources/outputs/empty.puml.svg b/src/test/resources/outputs/empty.puml.svg
new file mode 100644
index 00000000..b8565d15
--- /dev/null
+++ b/src/test/resources/outputs/empty.puml.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/one-of-class-level-empty.puml.svg b/src/test/resources/outputs/one-of-class-level-empty.puml.svg
new file mode 100644
index 00000000..492d35ca
--- /dev/null
+++ b/src/test/resources/outputs/one-of-class-level-empty.puml.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/one-of-class-level.puml.svg b/src/test/resources/outputs/one-of-class-level.puml.svg
new file mode 100644
index 00000000..d1d853dc
--- /dev/null
+++ b/src/test/resources/outputs/one-of-class-level.puml.svg
@@ -0,0 +1,95 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/one-of-property-level-required.puml.svg b/src/test/resources/outputs/one-of-property-level-required.puml.svg
new file mode 100644
index 00000000..7c32da71
--- /dev/null
+++ b/src/test/resources/outputs/one-of-property-level-required.puml.svg
@@ -0,0 +1,112 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/one-of-property-level.puml.svg b/src/test/resources/outputs/one-of-property-level.puml.svg
new file mode 100644
index 00000000..0f85470c
--- /dev/null
+++ b/src/test/resources/outputs/one-of-property-level.puml.svg
@@ -0,0 +1,112 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/parameter-anon-empty-object.puml.svg b/src/test/resources/outputs/parameter-anon-empty-object.puml.svg
new file mode 100644
index 00000000..f4831058
--- /dev/null
+++ b/src/test/resources/outputs/parameter-anon-empty-object.puml.svg
@@ -0,0 +1,155 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/parameter-anon.puml.svg b/src/test/resources/outputs/parameter-anon.puml.svg
new file mode 100644
index 00000000..40301f80
--- /dev/null
+++ b/src/test/resources/outputs/parameter-anon.puml.svg
@@ -0,0 +1,174 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/parameter-ref-complex.puml.svg b/src/test/resources/outputs/parameter-ref-complex.puml.svg
new file mode 100644
index 00000000..619f0c58
--- /dev/null
+++ b/src/test/resources/outputs/parameter-ref-complex.puml.svg
@@ -0,0 +1,139 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/parameter-ref-ref.puml.svg b/src/test/resources/outputs/parameter-ref-ref.puml.svg
new file mode 100644
index 00000000..b82ce599
--- /dev/null
+++ b/src/test/resources/outputs/parameter-ref-ref.puml.svg
@@ -0,0 +1,156 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/parameter-ref.puml.svg b/src/test/resources/outputs/parameter-ref.puml.svg
new file mode 100644
index 00000000..4b0cec36
--- /dev/null
+++ b/src/test/resources/outputs/parameter-ref.puml.svg
@@ -0,0 +1,134 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/path-returns-non-ref.puml.svg b/src/test/resources/outputs/path-returns-non-ref.puml.svg
new file mode 100644
index 00000000..d68233d0
--- /dev/null
+++ b/src/test/resources/outputs/path-returns-non-ref.puml.svg
@@ -0,0 +1,136 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/path-returns-ref-ref.puml.svg b/src/test/resources/outputs/path-returns-ref-ref.puml.svg
new file mode 100644
index 00000000..01f8f48c
--- /dev/null
+++ b/src/test/resources/outputs/path-returns-ref-ref.puml.svg
@@ -0,0 +1,158 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/path-returns-ref-ref2.puml.svg b/src/test/resources/outputs/path-returns-ref-ref2.puml.svg
new file mode 100644
index 00000000..ac8bda41
--- /dev/null
+++ b/src/test/resources/outputs/path-returns-ref-ref2.puml.svg
@@ -0,0 +1,158 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/path-returns-ref.puml.svg b/src/test/resources/outputs/path-returns-ref.puml.svg
new file mode 100644
index 00000000..909fafe5
--- /dev/null
+++ b/src/test/resources/outputs/path-returns-ref.puml.svg
@@ -0,0 +1,136 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/petstore-expanded.puml.svg b/src/test/resources/outputs/petstore-expanded.puml.svg
new file mode 100644
index 00000000..81e49936
--- /dev/null
+++ b/src/test/resources/outputs/petstore-expanded.puml.svg
@@ -0,0 +1,352 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/petstore.puml.svg b/src/test/resources/outputs/petstore.puml.svg
new file mode 100644
index 00000000..ed531e63
--- /dev/null
+++ b/src/test/resources/outputs/petstore.puml.svg
@@ -0,0 +1,243 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/ref-class-level.puml.svg b/src/test/resources/outputs/ref-class-level.puml.svg
new file mode 100644
index 00000000..6277a24d
--- /dev/null
+++ b/src/test/resources/outputs/ref-class-level.puml.svg
@@ -0,0 +1,78 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/request-body-ref-ref.puml.svg b/src/test/resources/outputs/request-body-ref-ref.puml.svg
new file mode 100644
index 00000000..732982a5
--- /dev/null
+++ b/src/test/resources/outputs/request-body-ref-ref.puml.svg
@@ -0,0 +1,193 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/request-body-ref.puml.svg b/src/test/resources/outputs/request-body-ref.puml.svg
new file mode 100644
index 00000000..8fc9db14
--- /dev/null
+++ b/src/test/resources/outputs/request-body-ref.puml.svg
@@ -0,0 +1,167 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/request-body.puml.svg b/src/test/resources/outputs/request-body.puml.svg
new file mode 100644
index 00000000..d995eba3
--- /dev/null
+++ b/src/test/resources/outputs/request-body.puml.svg
@@ -0,0 +1,168 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/simple-has-refs.puml.svg b/src/test/resources/outputs/simple-has-refs.puml.svg
new file mode 100644
index 00000000..8f9037c4
--- /dev/null
+++ b/src/test/resources/outputs/simple-has-refs.puml.svg
@@ -0,0 +1,116 @@
+
+
\ No newline at end of file
diff --git a/src/test/resources/outputs/simple-types-and-arrays.puml.svg b/src/test/resources/outputs/simple-types-and-arrays.puml.svg
new file mode 100644
index 00000000..b4144be6
--- /dev/null
+++ b/src/test/resources/outputs/simple-types-and-arrays.puml.svg
@@ -0,0 +1,108 @@
+
+
\ No newline at end of file