Add Helidon client generator SE library Java classes and resources

Signed-off-by: tim.quinn@oracle.com <tim.quinn@oracle.com>
This commit is contained in:
tim.quinn@oracle.com 2022-09-23 17:11:14 -05:00
parent 74c600c877
commit cea7a14b25
43 changed files with 1692 additions and 0 deletions

View File

@ -0,0 +1,276 @@
{{>licenseInfo}}
package {{invokerPackage}};
{{#jsonb}}import {{rootJavaEEPackage}}.json.bind.JsonbBuilder;
import {{rootJavaEEPackage}}.json.bind.JsonbConfig;
{{/jsonb}}
{{#jackson}}import com.fasterxml.jackson.databind.ObjectMapper;
{{/jackson}}
{{#openApiNullable}}
{{#jackson}}
import org.openapitools.jackson.nullable.JsonNullableModule;
{{/jackson}}
{{/openApiNullable}}
import io.helidon.config.Config;
{{#jsonb}}
import io.helidon.media.jsonb.JsonbSupport;
{{/jsonb}}
{{#jackson}}
import io.helidon.media.jackson.JacksonSupport;
{{/jackson}}
import io.helidon.webclient.WebClient;
import java.net.URI;
import java.net.URLEncoder;
import java.time.Duration;
{{#java8}}
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
{{/java8}}
import java.util.Collection;
import java.util.Collections;
import java.util.List;
{{#jsonb}}
import java.util.Map;
{{/jsonb}}
import java.util.StringJoiner;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Configuration and utility class for API clients.
* <p>
* Use the {@link ApiClient.Builder} class to prepare and ultimately create the {@code ApiClient} instance.
* </p>
*/
public class ApiClient {
private final WebClient webClient;
/**
* @return a {@code Builder} for an {@code ApiClient}
*/
public static ApiClient.Builder builder() {
return new Builder();
}
/**
* URL encode a string in the UTF-8 encoding.
*
* @param s String to encode.
* @return URL-encoded representation of the input string.
*/
public static String urlEncode(String s) {
return URLEncoder.encode(s, UTF_8);
}
/**
* Convert a URL query name/value parameter to a list of encoded {@link Pair}
* objects.
*
* <p>The value can be null, in which case an empty list is returned.</p>
*
* @param name The query name parameter.
* @param value The query value, which may not be a collection but may be
* null.
* @return A singleton list of the {@link Pair} objects representing the input
* parameters, which is encoded for use in a URL. If the value is null, an
* empty list is returned.
*/
public static List<Pair> parameterToPairs(String name, Object value) {
if (name == null || name.isEmpty() || value == null) {
return Collections.emptyList();
}
return Collections.singletonList(new Pair(urlEncode(name), urlEncode(valueToString(value))));
}
/**
* Convert a URL query name/collection parameter to a list of encoded
* {@link Pair} objects.
*
* @param collectionFormat The swagger collectionFormat string (csv, tsv, etc).
* @param name The query name parameter.
* @param values A collection of values for the given query name, which may be
* null.
* @return A list of {@link Pair} objects representing the input parameters,
* which is encoded for use in a URL. If the values collection is null, an
* empty list is returned.
*/
public static List<Pair> parameterToPairs(
String collectionFormat, String name, Collection<?> values) {
if (name == null || name.isEmpty() || values == null || values.isEmpty()) {
return Collections.emptyList();
}
// get the collection format (default: csv)
String format = collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat;
// create the params based on the collection format
if ("multi".equals(format)) {
return values.stream()
.map(value -> new Pair(urlEncode(name), urlEncode(valueToString(value))))
.collect(Collectors.toList());
}
String delimiter;
switch(format) {
case "csv":
delimiter = urlEncode(",");
break;
case "ssv":
delimiter = urlEncode(" ");
break;
case "tsv":
delimiter = urlEncode("\t");
break;
case "pipes":
delimiter = urlEncode("|");
break;
default:
throw new IllegalArgumentException("Illegal collection format: " + collectionFormat);
}
StringJoiner joiner = new StringJoiner(delimiter);
for (Object value : values) {
joiner.add(urlEncode(valueToString(value)));
}
return Collections.singletonList(new Pair(urlEncode(name), joiner.toString()));
}
private ApiClient(Builder builder) {
webClient = builder.webClientBuilder().build();
}
/**
* Get the {@link WebClient} prepared by the builder of this {@code ApiClient}.
*
* @return the WebClient
*/
public WebClient webClient() {
return webClient;
}
private static String valueToString(Object value) {
if (value == null) {
return "";
}
{{#java8}}
if (value instanceof OffsetDateTime) {
return ((OffsetDateTime) value).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
{{/java8}}
return value.toString();
}
/**
* Builder for creating a new {@code ApiClient} instance.
*
* <p>
* The builder accepts a {@link WebClient.Builder} via the {@code webClientBuilder} method but will provide a default one
* using available configuration (the {@code client} node) and the base URI set in the OpenAPI document.
* </p>
*/
public static class Builder {
private WebClient.Builder webClientBuilder;
private Config clientConfig;
{{#jsonb}}
private JsonbConfig jsonbConfig;
{{/jsonb}}
{{#jackson}}
private ObjectMapper objectMapper;
{{/jackson}}
public ApiClient build() {
return new ApiClient(this);
}
/**
* Sets the {@code WebClient.Builder} which the {@code ApiClient.Builder} uses. Any previous setting is discarded.
*
* @param webClientBuilder the {@code WebClient.Builder} to be used going forward
* @return the updated builder
*/
public Builder webClientBuilder(WebClient.Builder webClientBuilder) {
this.webClientBuilder = webClientBuilder;
return this;
}
/**
* Sets the client {@code Config} which the {@code ApiClient.Builder} uses in preparing a default {@code WebClient.Builder}.
* The builder ignores this setting if you provide your own {@code WebClient.Builder} by invoking the
* {@code webClientBuilder} method.
*
* @param clientConfig the {@code Config} node containing client settings
* @return the updated builder
*/
public Builder clientConfig(Config clientConfig) {
this.clientConfig = clientConfig;
return this;
}
/**
* @return the previously-stored web client builder or, if none, a default one using the provided or defaulted
* client configuration
*/
public WebClient.Builder webClientBuilder() {
if (webClientBuilder == null) {
webClientBuilder = defaultWebClientBuilder();
}
return webClientBuilder;
}
{{#jsonb}}
/**
* Stores the JSON-B configuration the builder uses in preparing the {@code WebClient}.
*
* @param jsonbConfig the JSON-B config to use in all API invocations via the built {@code ApiClient}
* @return the updated builder
*/
public Builder jsonbConfig(JsonbConfig jsonbConfig) {
this.jsonbConfig = jsonbConfig;
return this;
}
{{/jsonb}}
{{#jackson}}
/**
* Stores the Jackson {@code ObjectMapper} the builder uses in preparing the {@code WebClient}.
*
* @param objectMapper the Jackson object mapper to use in all API invocations via the built {@code ApiClient}
* @return the updated builder
*/
public Builder objectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
return this;
}
{{/jackson}}
private WebClient.Builder defaultWebClientBuilder() {
WebClient.Builder defaultWebClientBuilder = WebClient.builder()
.baseUri("{{basePath}}")
.config(clientConfig());
{{#jsonb}}
defaultWebClientBuilder.addMediaSupport(jsonbConfig == null
? JsonbSupport.create()
: JsonbSupport.create(jsonbConfig));
{{/jsonb}}
{{#jackson}}
defaultWebClientBuilder.addMediaSupport(objectMapper == null
? JacksonSupport.create()
: JacksonSupport.create(objectMapper));
{{/jackson}}
return defaultWebClientBuilder;
}
private Config clientConfig() {
if (clientConfig == null) {
clientConfig = Config.create().get("client");
}
return clientConfig;
}
}
}

View File

@ -0,0 +1,34 @@
{{>licenseInfo}}
package {{invokerPackage}};
import java.util.concurrent.ExecutionException;
import io.helidon.common.GenericType;
import io.helidon.common.reactive.Single;
import io.helidon.webclient.WebClientResponse;
{{#appName}}
/**
* Generic-typed response.
*
* Return type for generated API methods.
*
* @param <T> type of the return value from the generated API method
*/
{{/appName}}
public interface ApiResponse<T> {
static <T> ApiResponse<T> create(GenericType<T> responseType, Single<WebClientResponse> webClientResponse) {
return new ApiResponseBase<>(responseType, webClientResponse);
}
/**
* @returns reactive access to the {@link WebClientResponse} describing the response from the server
*/
Single<WebClientResponse> webClientResponse();
/**
* @return reactive access to the value returned in the response from the server
*/
Single<T> result() throws ExecutionException, InterruptedException;
}

View File

@ -0,0 +1,36 @@
{{>licenseInfo}}
package {{invokerPackage}};
import java.util.concurrent.ExecutionException;
import io.helidon.common.GenericType;
import io.helidon.common.reactive.Single;
import io.helidon.webclient.WebClientResponse;
{{#appName}}
/**
* Implementation of a generic-typed response.
*
* @param <T> type of the return value from the generated API method
*/
{{/appName}}
class ApiResponseBase<T> implements ApiResponse<T> {
private final Single<WebClientResponse> webClientResponse;
private final GenericType<T> responseType;
protected ApiResponseBase(GenericType<T> responseType, Single<WebClientResponse> webClientResponse) {
this.webClientResponse = webClientResponse;
this.responseType = responseType;
}
@Override
public Single<WebClientResponse> webClientResponse() {
return webClientResponse;
}
@Override
public Single<T> result() throws ExecutionException, InterruptedException {
return webClientResponse.get().content().as(responseType);
}
}

View File

@ -0,0 +1,53 @@
{{>licenseInfo}}
package {{invokerPackage}};
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
/**
* Class that add parsing/formatting support for Java 8+ {@code OffsetDateTime} class.
* It's generated for java clients when {@code AbstractJavaCodegen#dateLibrary} specified as {@code java8}.
*/
{{>generatedAnnotation}}
public class JavaTimeFormatter {
private DateTimeFormatter offsetDateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
/**
* Get the date format used to parse/format {@code OffsetDateTime} parameters.
* @return DateTimeFormatter
*/
public DateTimeFormatter getOffsetDateTimeFormatter() {
return offsetDateTimeFormatter;
}
/**
* Set the date format used to parse/format {@code OffsetDateTime} parameters.
* @param offsetDateTimeFormatter {@code DateTimeFormatter}
*/
public void setOffsetDateTimeFormatter(DateTimeFormatter offsetDateTimeFormatter) {
this.offsetDateTimeFormatter = offsetDateTimeFormatter;
}
/**
* Parse the given string into {@code OffsetDateTime} object.
* @param str String
* @return {@code OffsetDateTime}
*/
public OffsetDateTime parseOffsetDateTime(String str) {
try {
return OffsetDateTime.parse(str, offsetDateTimeFormatter);
} catch (DateTimeParseException e) {
throw new RuntimeException(e);
}
}
/**
* Format the given {@code OffsetDateTime} object into string.
* @param offsetDateTime {@code OffsetDateTime}
* @return {@code OffsetDateTime} in string format
*/
public String formatOffsetDateTime(OffsetDateTime offsetDateTime) {
return offsetDateTimeFormatter.format(offsetDateTime);
}
}

View File

@ -0,0 +1,45 @@
{{>licenseInfo}}
package {{invokerPackage}};
public class Pair {
private String name = "";
private String value = "";
public Pair (String name, String value) {
setName(name);
setValue(value);
}
private void setName(String name) {
if (!isValidString(name)) {
return;
}
this.name = name;
}
private void setValue(String value) {
if (!isValidString(value)) {
return;
}
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
private boolean isValidString(String arg) {
if (arg == null) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,26 @@
# {{appName}}
{{#appDescriptionWithNewLines}}
{{{.}}}
{{/appDescriptionWithNewLines}}
## Overview
This project was generated using the Helidon OpenAPI Generator.
The generated classes use the programming model from the Helidon WebClient implementation, primarily the `WebClient` interface and its
`WebClient.Builder` class. Refer to the Helidon WebClient documentation for complete information about them.
## Using the Generated Classes and Interfaces
The generated `ApiClient` class wraps a `WebClient` instance. Similarly, the `ApiClient.Builder` class wraps the `WebClient.Builder` class.
The generated `xxxApi` interfaces and `xxxApiImpl` classes make it very simple for your code to send requests (with input parameters) to the remote service which the OpenAPI document describes and to process the response (with output values) from the remote service.
To use the generated API, your code performs the following steps.
1. Create an instance of the `ApiClient` using its `Builder`.
2. Create an instance of a `xxxApi` it wants to access, typically by invoking `xxxApiImpl.create(ApiClient)` and passing the `ApiClient` instance just created.
3. Invoke any of the `public` methods on the `xxxApi` instance, passing the input parameters and saving the returned `Single<WebClientResponse>` object.
4. Invoke methods on the returned `Single<WebClientResponse>` to process the response and any output from it.
Browse the methods and JavaDoc on the generated classes for more information.

View File

@ -0,0 +1,46 @@
{{>licenseInfo}}
package {{invokerPackage}};
import com.fasterxml.jackson.databind.util.StdDateFormat;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.Date;
import java.text.DecimalFormat;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class RFC3339DateFormat extends DateFormat {
private static final long serialVersionUID = 1L;
private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
private final StdDateFormat fmt = new StdDateFormat()
.withTimeZone(TIMEZONE_Z)
.withColonInTimeZone(true);
public RFC3339DateFormat() {
this.calendar = new GregorianCalendar();
this.numberFormat = new DecimalFormat();
}
@Override
public Date parse(String source) {
return parse(source, new ParsePosition(0));
}
@Override
public Date parse(String source, ParsePosition pos) {
return fmt.parse(source, pos);
}
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
return fmt.format(date, toAppendTo, fieldPosition);
}
@Override
public Object clone() {
return super.clone();
}
}

View File

@ -0,0 +1,32 @@
{{>licenseInfo}}
package {{apiPackage}};
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import io.helidon.common.GenericType;
class ResponseType<T> {
static <T> GenericType<T> create(Type rawType, Type... typeParams) {
return typeParams.length == 0
? GenericType.create(rawType)
: GenericType.create(new ParameterizedType() {
@Override
public Type[] getActualTypeArguments() {
return typeParams;
}
@Override
public Type getRawType() {
return rawType;
}
@Override
public Type getOwnerType() {
return null;
}
});
}
}

View File

@ -0,0 +1,72 @@
{{>licenseInfo}}
package {{invokerPackage}};
import java.util.Collection;
import java.util.Iterator;
{{>generatedAnnotation}}
public class StringUtil {
/**
* Check if the given array contains the given value (with case-insensitive comparison).
*
* @param array The array
* @param value The value to search
* @return true if the array contains the value
*/
public static boolean containsIgnoreCase(String[] array, String value) {
for (String str : array) {
if (value == null && str == null) {
return true;
}
if (value != null && value.equalsIgnoreCase(str)) {
return true;
}
}
return false;
}
/**
* Join an array of strings with the given separator.
* <p>
* Note: This might be replaced by utility method from commons-lang or guava someday
* if one of those libraries is added as dependency.
* </p>
*
* @param array The array of strings
* @param separator The separator
* @return the resulting string
*/
public static String join(String[] array, String separator) {
int len = array.length;
if (len == 0) {
return "";
}
StringBuilder out = new StringBuilder();
out.append(array[0]);
for (int i = 1; i < len; i++) {
out.append(separator).append(array[i]);
}
return out.toString();
}
/**
* Join a list of strings with the given separator.
*
* @param list The list of strings
* @param separator The separator
* @return the resulting string
*/
public static String join(Collection<String> list, String separator) {
Iterator<String> iterator = list.iterator();
StringBuilder out = new StringBuilder();
if (iterator.hasNext()) {
out.append(iterator.next());
}
while (iterator.hasNext()) {
out.append(separator).append(iterator.next());
}
return out.toString();
}
}

View File

@ -0,0 +1,2 @@
{{#additionalEnumTypeAnnotations}}{{{.}}}
{{/additionalEnumTypeAnnotations}}

View File

@ -0,0 +1,2 @@
{{#additionalModelTypeAnnotations}}{{{.}}}
{{/additionalModelTypeAnnotations}}

View File

@ -0,0 +1,43 @@
{{>licenseInfo}}
package {{package}};
import {{invokerPackage}}.ApiResponse;
{{#imports}}import {{import}};
{{/imports}}
{{#appName}}
/**
* {{{appName}}}
*
{{#appDescription}}
* <p>{{{.}}}
{{/appDescription}}
*/
{{/appName}}
public interface {{classname}} {
{{#operations}}
{{#operation}}
{{#summary}}
/**
* {{summary}}
{{#notes}}
* {{.}}
{{/notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/isContainer}}{{/required}}
{{/allParams}}
* @return {@code {{>operationResponseSig}}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
{{/summary}}
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{>operationResponseSig}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{/operation}}
{{/operations}}
}

View File

@ -0,0 +1,28 @@
{{>licenseInfo}}
package {{invokerPackage}};
import io.swagger.v3.oas.models.Operation;
public class ApiOperation {
private final String path;
private final String method;
private final Operation operation;
public ApiOperation(String path, String method, Operation operation) {
this.path = path;
this.method = method;
this.operation = operation;
}
public Operation getOperation() {
return operation;
}
public String getPath() {
return path;
}
public String getMethod() {
return method;
}
}

View File

@ -0,0 +1,108 @@
# {{classname}}{{#description}}
{{.}}{{/description}}
All URIs are relative to *{{basePath}}*
| Method | HTTP request | Description |
|------------- | ------------- | -------------|
{{#operations}}{{#operation}}| [**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{commonPath}}{{path}} | {{summary}} |
{{/operation}}{{/operations}}
{{#operations}}
{{#operation}}
## {{operationId}}
> {{#returnType}}{{.}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}})
{{summary}}{{#notes}}
{{.}}{{/notes}}
### Example
```java
// Import classes:
import {{{invokerPackage}}}.ApiClient;
import {{{invokerPackage}}}.ApiException;
import {{{invokerPackage}}}.Configuration;{{#hasAuthMethods}}
import {{{invokerPackage}}}.auth.*;{{/hasAuthMethods}}
import {{{invokerPackage}}}.models.*;
import {{{package}}}.{{{classname}}};
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("{{{basePath}}}");
{{#hasAuthMethods}}
{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
// Configure HTTP basic authorization: {{{name}}}
HttpBasicAuth {{{name}}} = (HttpBasicAuth) defaultClient.getAuthentication("{{{name}}}");
{{{name}}}.setUsername("YOUR USERNAME");
{{{name}}}.setPassword("YOUR PASSWORD");{{/isBasicBasic}}{{#isBasicBearer}}
// Configure HTTP bearer authorization: {{{name}}}
HttpBearerAuth {{{name}}} = (HttpBearerAuth) defaultClient.getAuthentication("{{{name}}}");
{{{name}}}.setBearerToken("BEARER TOKEN");{{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}
// Configure API key authorization: {{{name}}}
ApiKeyAuth {{{name}}} = (ApiKeyAuth) defaultClient.getAuthentication("{{{name}}}");
{{{name}}}.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//{{{name}}}.setApiKeyPrefix("Token");{{/isApiKey}}{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
OAuth {{{name}}} = (OAuth) defaultClient.getAuthentication("{{{name}}}");
{{{name}}}.setAccessToken("YOUR ACCESS TOKEN");{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
{{{classname}}} apiInstance = new {{{classname}}}(defaultClient);
{{#allParams}}
{{{dataType}}} {{{paramName}}} = {{{example}}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}
try {
{{#returnType}}{{{.}}} result = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}});{{#returnType}}
System.out.println(result);{{/returnType}}
} catch (ApiException e) {
System.err.println("Exception when calling {{{classname}}}#{{{operationId}}}");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
```
### Parameters
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
| Name | Type | Description | Notes |
|------------- | ------------- | ------------- | -------------|{{/-last}}{{/allParams}}
{{#allParams}}| **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}[**{{dataType}}**]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{^isContainer}}{{#defaultValue}} [default to {{.}}]{{/defaultValue}}{{/isContainer}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} |
{{/allParams}}
### Return type
{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{returnType}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}}
### Authorization
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{name}}](../README.md#{{name}}){{^-last}}, {{/-last}}{{/authMethods}}
### HTTP request headers
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{#responses.0}}
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
{{#responses}}
| **{{code}}** | {{message}} | {{#headers}} * {{baseName}} - {{description}} <br> {{/headers}}{{^headers.0}} - {{/headers.0}} |
{{/responses}}
{{/responses.0}}
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,182 @@
{{>licenseInfo}}
package {{package}};
import java.util.Objects;
import {{invokerPackage}}.ApiResponse;
{{#jsonb}}
import {{rootJavaEEPackage}}.json.bind.JsonbBuilder;
{{/jsonb}}
{{#jackson}}
import com.fasterxml.jackson.databind.ObjectMapper;
{{/jackson}}
import io.helidon.common.GenericType;
import io.helidon.common.http.MediaType;
import io.helidon.common.reactive.Single;
import io.helidon.config.Config;
import io.helidon.media.common.MediaSupport;
{{#jsonb}}import io.helidon.media.jsonb.JsonbSupport;{{/jsonb}}
{{#jackson}}import io.helidon.media.jackson.JacksonSupport;{{/jackson}}
import io.helidon.webclient.WebClientRequestBuilder;
import io.helidon.webclient.WebClientResponse;
import {{invokerPackage}}.ApiClient;
{{#x-helidon-implImports}}import {{import}};
{{/x-helidon-implImports}}
{{#appName}}
/**
* {{{appName}}}
*
{{#appDescription}}
* <p>{{{.}}}
{{/appDescription}}
*/
{{/appName}}
public class {{classname}}Impl implements {{classname}} {
private final ApiClient apiClient;
{{#operations}}
{{#operation}}
protected static final GenericType<{{>operationResponseTypeDecl}}> RESPONSE_TYPE_{{operationId}} = ResponseType.create({{#isArray}}List.class, {{/isArray}}{{#isMap}}Map.class, String.class, {{/isMap}}{{#returnBaseType}}{{returnBaseType}}{{/returnBaseType}}{{^returnBaseType}}Void{{/returnBaseType}}.class);
{{/operation}}
{{/operations}}
/**
* Creates a new instance of {{classname}}Impl initialized with the specified {@link ApiClient}.
*
*/
public static {{classname}}Impl create(ApiClient apiClient) {
return new {{classname}}Impl(apiClient);
}
protected {{classname}}Impl(ApiClient apiClient) {
this.apiClient = apiClient;
}
{{#operations}}
{{#operation}}
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
@Override
public {{>operationResponseSig}} {{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {
{{#requiredParams}}
Objects.requireNonNull({{paramName}}, "Required parameter '{{paramName}}' not specified");
{{/requiredParams}}
WebClientRequestBuilder webClientRequestBuilder = {{operationId}}RequestBuilder({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
return {{operationId}}Submit(webClientRequestBuilder{{#allParams}}, {{paramName}}{{/allParams}});
}
/**
* Creates a {@code WebClientRequestBuilder} for the {{operationId}} operation.
* Optional customization point for subclasses.
*
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/isContainer}}{{/required}}
{{/allParams}}
* @return WebClientRequestBuilder for {{operationId}}
*/
protected WebClientRequestBuilder {{operationId}}RequestBuilder({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {
WebClientRequestBuilder webClientRequestBuilder = apiClient.webClient()
.method("{{httpMethod}}");
{{#hasQueryParams}}
{{javaUtilPrefix}}List<Pair> queryParams = new {{javaUtilPrefix}}ArrayList<>();
{{#queryParams}}
{{#collectionFormat}}
queryParams.addAll(ApiClient.parameterToPairs("{{{collectionFormat}}}", "{{baseName}}", {{paramName}}));
{{/collectionFormat}}
{{^collectionFormat}}
{{#isDeepObject}}
if ({{paramName}} != null) {
{{#items.vars}}
queryParams.addAll(ApiClient.parameterToPairs({{#isArray}}"csv", {{/isArray}}"{{baseName}}", {{paramName}}.{{getter}}()));
{{/items.vars}}
}
{{/isDeepObject}}
{{^isDeepObject}}
{{#isExplode}}
{{#hasVars}}
{{#vars}}
queryParams.addAll(ApiClent.parameterToPairs("{{baseName}}", {{paramName}}.{{getter}}()));
{{/vars}}
{{/hasVars}}
{{^hasVars}}
queryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}));
{{/hasVars}}
{{/isExplode}}
{{^isExplode}}
queryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}));
{{/isExplode}}
{{/isDeepObject}}
{{/collectionFormat}}
{{/queryParams}}
queryParams.forEach(p -> webClientRequestBuilder.queryParam(p.getName(), p.getValue()));
{{/hasQueryParams}}
{{#hasHeaderParams}}
WebClientRequestHeaders headers = webClientRequestBuilder.headers();
{{#headerParams}}
if ({{paramName}} != null) {
headers.put("{{baseName}}", {{paramName}}{{^isString}}.toString(){{/isString}});
}
{{/headerParams}}
{{/hasHeaderParams}}
{{#hasCookieParams}}
String cookies = new StringJoiner("; ")
{{#cookieParams}}
.add("{{{baseName}}}=" + {{{paramName}}})
{{/cookieParams}}
.toString();
webClientRequestBuilder.headers().add("Cookie", cookies);
{{/hasCookieParams}}
{{#hasPathParams}}
String path = "{{{path}}}"
{{! Switch delimiters from double braces to <% and %> for baseName so we can use curly braces in the string as literals and not have mustache
interpret them, then switch back. }}
{{#pathParams}}
.replace({{=<% %>=}}"{<%baseName%>}"<%={{ }}=%>, ApiClient.urlEncode({{{paramName}}}{{^isString}}.toString(){{/isString}})){{/pathParams}};
{{/hasPathParams}}
webClientRequestBuilder.path({{#hasPathParams}}path{{/hasPathParams}}{{^hasPathParams}}"{{{path}}}"{{/hasPathParams}});
{{#bodyParam}}
webClientRequestBuilder.contentType(MediaType.APPLICATION_JSON);
{{/bodyParam}}
{{#hasFormParams}}
webClientRequestBuilder.contentType(MediaType.APPLICATION_FORM_URLENCODED);
{{/hasFormParams}}
webClientRequestBuilder.accept(MediaType.APPLICATION_JSON);
return webClientRequestBuilder;
}
/**
* Initiates the request for the {{operationId}} operation.
* Optional customization point for subclasses.
*
* @param webClientRequestBuilder the request builder to use for submitting the request
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/isContainer}}{{/required}}
{{/allParams}}
* @return {@code {{>operationResponseSig}}} for the submitted request
*/
protected {{>operationResponseSig}} {{operationId}}Submit(WebClientRequestBuilder webClientRequestBuilder{{#allParams}}, {{{dataType}}} {{paramName}}{{/allParams}}) {
{{#hasFormParams}}
String formParams = new StringJoiner("&")
{{#formParams}}
.add("{{{baseName}}}=" + {{paramName}})
{{/formParams}}
.toString();
{{/hasFormParams}}
Single<WebClientResponse> webClientResponse = webClientRequestBuilder.submit({{#bodyParam}}{{paramName}}{{/bodyParam}}{{#hasFormParams}}formParams{{/hasFormParams}});
return ApiResponse.create(RESPONSE_TYPE_{{operationId}}, webClientResponse);
}
{{/operation}}
{{/operations}}
}

View File

@ -0,0 +1,72 @@
{{>licenseInfo}}
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.ApiResponse;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
{{^fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
import io.helidon.common.reactive.Single;
import io.helidon.webclient.WebClientResponse;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
/**
* {{#appName}}
* {{{.}}} Test
*
* {{/appName}}
* API tests for {{classname}}
*/
public class {{classname}}Test {
private static ApiClient apiClient;
private static {{classname}} api;
private static final String baseUrl = "http://localhost:8080";
@BeforeAll
public static void setup() {
apiClient = ApiClient.builder().build();
api = {{classname}}Impl.create(apiClient);
}
{{#operations}}
{{#operation}}
/**
* {{summary}}
{{#notes}}
* {{.}}
{{/notes}}
*/
@Test
public void {{operationId}}Test() {
{{#allParams}}
// TODO - assign values to the input arguments.
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// TODO - uncomment the following two lines to invoke the service with valid parameters.
//ApiResponse<{{>operationResponseTypeDecl}}> response = api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
//response.webClientResponse().await();
// TODO - check for appropriate return status
// assertThat("Return status", response.get().status().code(), is(expectedStatus));
// TODO: test validations
}
{{/operation}}
{{/operations}}
}

View File

@ -0,0 +1 @@
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}

View File

@ -0,0 +1 @@
{{#isCookieParam}}@CookieParam("{{baseName}}"){{^isContainer}}{{#defaultValue}} @DefaultValue("{{{.}}}"){{/defaultValue}}{{/isContainer}} {{#useSwaggerAnnotations}}{{#description}} @ApiParam("{{.}}"){{/description}}{{/useSwaggerAnnotations}} {{{dataType}}} {{paramName}}{{/isCookieParam}}

View File

@ -0,0 +1,46 @@
{{#jsonb}}
@JsonbTypeSerializer({{datatypeWithEnum}}.Serializer.class)
@JsonbTypeDeserializer({{datatypeWithEnum}}.Deserializer.class)
{{/jsonb}}
{{>additionalEnumTypeAnnotations}}public enum {{datatypeWithEnum}} {
{{#allowableValues}}
{{#enumVars}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{/allowableValues}}
{{dataType}} value;
{{datatypeWithEnum}} ({{dataType}} v) {
value = v;
}
public {{dataType}} value() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
{{#jsonb}}
public static final class Deserializer implements JsonbDeserializer<{{datatypeWithEnum}}> {
@Override
public {{datatypeWithEnum}} deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(parser.getString())) {
return b;
}
}
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + parser.getString() + "'");{{/useNullForUnknownEnumValue}}
}
}
public static final class Serializer implements JsonbSerializer<{{datatypeWithEnum}}> {
@Override
public void serialize({{datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
generator.write(obj.value);
}
}
{{/jsonb}}
}

View File

@ -0,0 +1,39 @@
{{#jackson}}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
{{/jackson}}
/**
* {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
*/
{{>additionalEnumTypeAnnotations}}public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#allowableValues}}{{#enumVars}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
private {{{dataType}}} value;
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
@Override
{{#jackson}}
@JsonValue
{{/jackson}}
public String toString() {
return String.valueOf(value);
}
{{#jackson}}
@JsonCreator
{{/jackson}}
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(text)) {
return b;
}
}
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
}
}

View File

@ -0,0 +1,7 @@
# {{classname}}
## Enum
{{#allowableValues}}{{#enumVars}}
* `{{name}}` (value: `{{{value}}}`)
{{/enumVars}}{{/allowableValues}}

View File

@ -0,0 +1 @@
{{#isFormParam}}@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isFormParam}}

View File

@ -0,0 +1 @@
@{{rootJavaEEPackage}}.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})

View File

@ -0,0 +1 @@
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}}

View File

@ -0,0 +1,19 @@
{{!
If this is map and items are nullable, make sure that nulls are included.
To determine what JsonInclude.Include method to use, consider the following:
* If the field is required, always include it, even if it is null.
* Else use custom behaviour, IOW use whatever is defined on the object mapper
}}
@JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
@JsonInclude({{#isMap}}{{#items.isNullable}}content = JsonInclude.Include.ALWAYS, {{/items.isNullable}}{{/isMap}}value = JsonInclude.Include.{{#required}}ALWAYS{{/required}}{{^required}}USE_DEFAULTS{{/required}})
{{#withXml}}
{{^isContainer}}
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
{{/isContainer}}
{{#isContainer}}
{{#isXmlWrapped}}
// items.xmlName={{items.xmlName}}
@JacksonXmlElementWrapper(useWrapping = {{isXmlWrapped}}, {{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{#items.xmlName}}{{items.xmlName}}{{/items.xmlName}}{{^items.xmlName}}{{items.baseName}}{{/items.xmlName}}")
{{/isXmlWrapped}}
{{/isContainer}}
{{/withXml}}

View File

@ -0,0 +1,11 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}}
* {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -0,0 +1,3 @@
<manifest package="{{invokerPackage}}" xmlns:android="http://schemas.android.com/apk/res/android">
<application />
</manifest>

View File

@ -0,0 +1,31 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
#
# This file is auto-generated by OpenAPI Generator (https://openapi-generator.tech)
name: Java CI with Maven
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
build:
name: Build {{{appName}}}
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '8' ]
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
{{=< >=}}
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --no-transfer-progress --file pom.xml

View File

@ -0,0 +1,19 @@
{{>licenseInfo}}
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}
import java.io.Serializable;
{{/serializableModel}}
{{#models}}
{{#model}}
{{#isEnum}}
{{>enumOuterClass}}
{{/isEnum}}
{{^isEnum}}
{{>pojo}}
{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -0,0 +1,95 @@
/**
* {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}}
*/
{{#gson}}
@JsonAdapter({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.Adapter.class)
{{/gson}}
{{#jsonb}}
@JsonbTypeSerializer({{datatypeWithEnum}}.Serializer.class)
@JsonbTypeDeserializer({{datatypeWithEnum}}.Deserializer.class)
{{/jsonb}}
{{#withXml}}
@XmlType(name="{{datatypeWithEnum}}")
@XmlEnum({{dataType}}.class)
{{/withXml}}
{{>additionalEnumTypeAnnotations}}public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
{{#allowableValues}}
{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{/withXml}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
private {{{dataType}}} value;
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
{{#jackson}}
@JsonCreator
{{/jackson}}
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (b.value.equals(value)) {
return b;
}
}
{{#isNullable}}return null;{{/isNullable}}{{^isNullable}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/isNullable}}
}
{{#gson}}
public static class Adapter extends TypeAdapter<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}> {
@Override
public void write(final JsonWriter jsonWriter, final {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} enumeration) throws IOException {
jsonWriter.value(enumeration.getValue());
}
@Override
public {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException {
{{^isNumber}}{{{dataType}}}{{/isNumber}}{{#isNumber}}String{{/isNumber}} value = {{#isFloat}}(float){{/isFloat}} jsonReader.{{#isNumber}}nextString(){{/isNumber}}{{#isInteger}}nextInt(){{/isInteger}}{{^isNumber}}{{^isInteger}}{{#isFloat}}nextDouble{{/isFloat}}{{^isFloat}}next{{{dataType}}}{{/isFloat}}(){{/isInteger}}{{/isNumber}};
return {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}.fromValue({{#isNumber}}new BigDecimal({{/isNumber}}value{{#isNumber}}){{/isNumber}});
}
}
{{/gson}}
{{#jsonb}}
public static final class Deserializer implements JsonbDeserializer<{{datatypeWithEnum}}> {
@Override
public {{datatypeWithEnum}} deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (String.valueOf(b.value).equals(parser.getString())) {
return b;
}
}
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + parser.getString() + "'");{{/useNullForUnknownEnumValue}}
}
}
public static final class Serializer implements JsonbSerializer<{{datatypeWithEnum}}> {
@Override
public void serialize({{datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
generator.write(obj.value);
}
}
{{/jsonb}}
}

View File

@ -0,0 +1,4 @@
{{#models}}{{#model}}
{{#isEnum}}{{>enum_outer_doc}}{{/isEnum}}{{^isEnum}}{{>pojo_doc}}{{/isEnum}}
{{/model}}{{/models}}

View File

@ -0,0 +1,49 @@
{{>licenseInfo}}
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import org.junit.jupiter.api.Test;
{{#fullJavaUtil}}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
/**
* Model tests for {{classname}}
*/
public class {{classname}}Test {
{{#models}}
{{#model}}
{{^vendorExtensions.x-is-one-of-interface}}
{{^isEnum}}
private final {{classname}} model = new {{classname}}();
{{/isEnum}}
/**
* Model tests for {{classname}}
*/
@Test
public void test{{classname}}() {
// TODO: test {{classname}}
}
{{#allVars}}
/**
* Test the property '{{name}}'
*/
@Test
public void {{name}}Test() {
// TODO: test {{name}}
}
{{/allVars}}
{{/vendorExtensions.x-is-one-of-interface}}
{{/model}}
{{/models}}
}

View File

@ -0,0 +1,6 @@
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
}

View File

@ -0,0 +1 @@
{{{openapi-yaml}}}

View File

@ -0,0 +1 @@
ApiResponse<{{>operationResponseTypeDecl}}>

View File

@ -0,0 +1 @@
{{#returnType}}{{#isArray}}List<{{/isArray}}{{#isMap}}Map<String, {{/isMap}}{{returnBaseType}}{{#isArray}}>{{/isArray}}{{#isMap}}>{{/isMap}}{{/returnType}}{{^returnType}}Void{{/returnType}}

View File

@ -0,0 +1 @@
{{#isPathParam}}@PathParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}

View File

@ -0,0 +1,155 @@
{{#jsonb}}
import java.lang.reflect.Type;
import {{rootJavaEEPackage}}.json.bind.annotation.JsonbTypeDeserializer;
import {{rootJavaEEPackage}}.json.bind.annotation.JsonbTypeSerializer;
import {{rootJavaEEPackage}}.json.bind.serializer.DeserializationContext;
import {{rootJavaEEPackage}}.json.bind.serializer.JsonbDeserializer;
import {{rootJavaEEPackage}}.json.bind.serializer.JsonbSerializer;
import {{rootJavaEEPackage}}.json.bind.serializer.SerializationContext;
import {{rootJavaEEPackage}}.json.stream.JsonGenerator;
import {{rootJavaEEPackage}}.json.stream.JsonParser;
import {{rootJavaEEPackage}}.json.bind.annotation.JsonbProperty;
{{#vendorExtensions.x-has-readonly-properties}}
import {{rootJavaEEPackage}}.json.bind.annotation.JsonbCreator;
{{/vendorExtensions.x-has-readonly-properties}}
{{/jsonb}}
{{#description}}
/**
* {{{.}}}
**/
{{/description}}
{{>additionalModelTypeAnnotations}}
{{#vendorExtensions.x-class-extra-annotation}}
{{{vendorExtensions.x-class-extra-annotation}}}
{{/vendorExtensions.x-class-extra-annotation}}
public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} {
{{#vars}}{{#isEnum}}{{^isContainer}}
{{>enumClass}}{{/isContainer}}{{#isContainer}}{{#mostInnerItems}}
{{>enumClass}}{{/mostInnerItems}}{{/isContainer}}{{/isEnum}}
{{#description}}
/**
* {{{.}}}
**/
{{/description}}
{{#vendorExtensions.x-field-extra-annotation}}
{{{vendorExtensions.x-field-extra-annotation}}}
{{/vendorExtensions.x-field-extra-annotation}}
{{#isContainer}}
private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}};
{{/isContainer}}
{{^isContainer}}
private {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
{{/isContainer}}
{{/vars}}
{{#vendorExtensions.x-has-readonly-properties}}{{#jsonb}}
public {{classname}}() {
}
@JsonbCreator
public {{classname}}(
{{#readOnlyVars}}
@JsonbProperty("{{baseName}}") {{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}
{{/readOnlyVars}}
) {
{{#readOnlyVars}}
this.{{name}} = {{name}};
{{/readOnlyVars}}
}
{{/jsonb}}{{/vendorExtensions.x-has-readonly-properties}}
{{#vars}}
/**
{{#description}}
* {{.}}
{{/description}}
{{^description}}
* Get {{name}}
{{/description}}
{{#minimum}}
* minimum: {{.}}
{{/minimum}}
{{#maximum}}
* maximum: {{.}}
{{/maximum}}
* @return {{name}}
{{#deprecated}}
* @deprecated
{{/deprecated}}
**/
{{#deprecated}}
@Deprecated
{{/deprecated}}
{{#vendorExtensions.x-extra-annotation}}
{{{vendorExtensions.x-extra-annotation}}}
{{/vendorExtensions.x-extra-annotation}}
{{#withXml}}{{#isEnum}}{{^isArray}}{{^isMap}}public {{dataType}} {{getter}}() {
if ({{name}} == null) {
return null;
}
return {{name}}.value();
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{^withXml}}{{#isEnum}}{{^isArray}}{{^isMap}}public {{datatypeWithEnum}} {{getter}}() {
return {{name}};
}{{/isMap}}{{/isArray}}{{/isEnum}}{{/withXml}}{{#isEnum}}{{#isArray}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}{{/isArray}}{{/isEnum}}{{#isEnum}}{{#isMap}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}{{/isMap}}{{/isEnum}}{{^isEnum}}public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}{{/isEnum}}
{{^isReadOnly}}
/**
* Set {{name}}
**/
{{#vendorExtensions.x-setter-extra-annotation}} {{{vendorExtensions.x-setter-extra-annotation}}}
{{/vendorExtensions.x-setter-extra-annotation}}public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
return this;
}
{{#isArray}}
public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) {
this.{{name}}.add({{name}}Item);
return this;
}
{{/isArray}}
{{#isMap}}
public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) {
this.{{name}}.put(key, {{name}}Item);
return this;
}
{{/isMap}}
{{/isReadOnly}}
{{/vars}}
/**
* Create a string representation of this pojo.
**/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n");
{{/vars}}sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private static String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,37 @@
# {{#vendorExtensions.x-is-one-of-interface}}Interface {{/vendorExtensions.x-is-one-of-interface}}{{classname}}
{{#description}}{{&description}}
{{/description}}
{{^vendorExtensions.x-is-one-of-interface}}
## Properties
| Name | Type | Description | Notes |
|------------ | ------------- | ------------- | -------------|
{{#vars}}|**{{name}}** | {{#isEnum}}[**{{datatypeWithEnum}}**](#{{datatypeWithEnum}}){{/isEnum}}{{^isEnum}}{{#isContainer}}{{#isArray}}{{#items}}{{#isModel}}[{{/isModel}}{{/items}}**{{baseType}}{{#items}}&lt;{{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{#isModel}}[{{/isModel}}**Map&lt;String, {{dataType}}&gt;**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{#isModel}}[{{/isModel}}**{{dataType}}**{{#isModel}}]({{^baseType}}{{dataType}}{{/baseType}}{{baseType}}.md){{/isModel}}{{/isContainer}}{{/isEnum}} | {{description}} | {{^required}} [optional]{{/required}}{{#isReadOnly}} [readonly]{{/isReadOnly}} |
{{/vars}}
{{#vars}}{{#isEnum}}
## Enum: {{datatypeWithEnum}}
| Name | Value |
|---- | -----|{{#allowableValues}}{{#enumVars}}
| {{name}} | {{value}} |{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{#vendorExtensions.x-implements.0}}
## Implemented Interfaces
{{#vendorExtensions.x-implements}}
* {{{.}}}
{{/vendorExtensions.x-implements}}
{{/vendorExtensions.x-implements.0}}
{{/vendorExtensions.x-is-one-of-interface}}
{{#vendorExtensions.x-is-one-of-interface}}
## Implementing Classes
{{#oneOf}}
* {{{.}}}
{{/oneOf}}
{{/vendorExtensions.x-is-one-of-interface}}

View File

@ -0,0 +1,83 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<parent>
<groupId>io.helidon.applications</groupId>
<artifactId>helidon-se</artifactId>
<version>{{helidonVersion}}</version>
<relativePath/>
</parent>
<artifactId>{{artifactId}}</artifactId>
<name>{{artifactId}}</name>
{{#appDescription}}
<description>{{.}}</description>
{{/appDescription}}
<version>{{artifactVersion}}</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>io.helidon.webclient</groupId>
<artifactId>helidon-webclient</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
</dependency>
<dependency>
<groupId>{{x-helidon-rootJavaEEDepPrefix}}.json</groupId>
<artifactId>{{x-helidon-rootJavaEEDepPrefix}}.json-api</artifactId>
</dependency>
{{#jackson}}
<dependency>
<groupId>io.helidon.media</groupId>
<artifactId>helidon-media-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
</dependency>
{{/jackson}}
{{#jsonb}}
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<groupId>{{x-helidon-rootJavaEEDepPrefix}}.json.bind</groupId>
<artifactId>{{x-helidon-rootJavaEEDepPrefix}}.json.bind-api</artifactId>
</dependency>
{{/jsonb}}
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-libs</id>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1 @@
{{#isQueryParam}}@QueryParam("{{baseName}}") {{^isContainer}}{{#defaultValue}}@DefaultValue("{{{.}}}") {{/defaultValue}}{{/isContainer}}{{{dataType}}} {{paramName}}{{/isQueryParam}}

View File

@ -0,0 +1,4 @@
{{#useGenericResponse}}Response{{/useGenericResponse}}{{! non-generic response:
}}{{^useGenericResponse}}{{!
}}{{{returnType}}}{{!
}}{{/useGenericResponse}}

View File

@ -0,0 +1,17 @@
{{#jackson}}
@JsonIgnoreProperties(
value = "{{{discriminator.propertyBaseName}}}", // ignore manually set {{{discriminator.propertyBaseName}}}, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the {{{discriminator.propertyBaseName}}} to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true)
{{#discriminator.mappedModels}}
{{#-first}}
@JsonSubTypes({
{{/-first}}
@JsonSubTypes.Type(value = {{modelName}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{mappingName}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"),
{{#-last}}
})
{{/-last}}
{{/discriminator.mappedModels}}
{{/jackson}}