Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions boat-scaffold/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>**/*.jar</excludes>
</configuration>
<executions>
<execution>
<id>report</id>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.openapitools.codegen.languages;

import org.openapitools.codegen.SupportingFile;

public class BoatAndroidClientCodegen extends KotlinClientCodegen {

public static final String NAME = "boat-android";
public static final String DBS_DATA_PROVIDER = "DBSDataProvider";

public BoatAndroidClientCodegen() {
super();
supportedLibraries.put(DBS_DATA_PROVIDER, "Backbase: client");
library = DBS_DATA_PROVIDER;
embeddedTemplateDir = NAME;
templateDir = NAME;
propertyAdditionalKeywords.remove("size");
specialCharReplacements.put("-", "");
supportingFiles.add(new SupportingFile("manifest.mustache", "", "src/main/AndroidManifest.xml"));
supportingFiles.add(new SupportingFile("gradle.properties.mustache", "", "gradle.properties"));
}


@Override
public void setLibrary(String library) {
this.library = library;
}

@Override
public String getName() {
return NAME;
}

@Override
public String toString() {
return super.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ com.backbase.oss.codegen.java.BoatSpringCodeGen
com.backbase.oss.codegen.java.BoatJavaCodeGen
com.backbase.oss.codegen.doc.BoatDocsGenerator
com.backbase.oss.codegen.angular.BoatAngularGenerator
com.backbase.oss.codegen.marina.BoatMarinaGenerator
com.backbase.oss.codegen.marina.BoatMarinaGenerator
org.openapitools.codegen.languages.BoatAndroidClientCodegen
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{#additionalModelTypeAnnotations}}{{{.}}}
{{/additionalModelTypeAnnotations}}
138 changes: 138 additions & 0 deletions boat-scaffold/src/main/templates/boat-android/api.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{{>licenseInfo}}
package {{apiPackage}}

{{#imports}}import {{import}}
{{/imports}}
import java.net.URI
import com.backbase.android.dbs.DBSClient
import com.backbase.android.common.utils.dbs.MutableParams
import com.backbase.android.common.utils.dbs.Params
import com.backbase.android.dbs.DBSDataProvider
import com.backbase.android.common.utils.dbs.DBSDataImpl
import com.backbase.android.common.utils.dbs.CustomNetworkDBSProvider
import com.backbase.android.Backbase
import com.backbase.android.utils.net.MultiPartWrapper
import com.backbase.android.utils.net.PartContent
import com.backbase.android.utils.net.request.RequestMethods
import com.backbase.android.utils.net.request.Request
import android.content.Context

import com.squareup.moshi.Types
import com.squareup.moshi.Moshi

import dev.drewhamilton.extracare.DataApi

import com.backbase.android.clients.common.Call
import com.backbase.android.clients.common.MultipartCall
import com.backbase.android.clients.common.ResponseBodyParser
import com.backbase.android.clients.common.MoshiResponseBodyParser
import com.backbase.android.clients.common.buildRequest
import com.backbase.android.clients.common.serializeToHttpRequestPart

{{#operations}}
/**
* API root for {{classname}}.
*
* @param context the current android context.
* @param moshi the json library instance.
* @param parser the response body parser for DTOs returned by the REST API.
* @param serverUri the server URI where the REST API can be reached.
* @param provider the DBS data provider.
* @param backbase the backbase sdk instance.
*/
class {{classname}}(
val context: Context,
val moshi: Moshi,
val parser: ResponseBodyParser,
var serverUri: URI,
var provider: DBSDataProvider = CustomNetworkDBSProvider(context),
var backbase: Backbase = requireNotNull(Backbase.getInstance()) { "The Backbase instance must not be null!" }
) : DBSClient, DBSDataImpl(backbase) {

override fun setBaseURI(baseUri: URI) {
this.serverUri = baseUri
}

override fun getBaseURI() = this.serverUri

override fun setDataProvider(provider: DBSDataProvider?) {
this.provider = requireNotNull(provider) { "The provider must not be null!" }
}

override fun getDataProvider(): DBSDataProvider? = provider

{{#operation}}

/**
* {{summary}}
* {{notes}}
* @param params the params of this request.
* @return the request that can be executed to perform the {{{operationId}}} operation.{{#isDeprecated}}
* @deprecated{{/isDeprecated}}
*/{{#isDeprecated}}
@Deprecated(message = "This operation is deprecated. Do not use"){{/isDeprecated}}
fun {{operationId}}(params: {{classname}}Params.{{{operationIdCamelCase}}}): {{^isMultipart}}{{#isListContainer}}Call<{{{returnType}}}>{{/isListContainer}}{{^isListContainer}}Call<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}>{{/isListContainer}}{{/isMultipart}}{{#isMultipart}}{{#isListContainer}}MultipartCall<{{{returnType}}}>{{/isListContainer}}{{^isListContainer}}MultipartCall<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}>{{/isListContainer}}{{/isMultipart}} {
{{^isMultipart}}
val bodyType = {{#bodyParam}}{{>api_parameter_model_type}}{{/bodyParam}} {{^hasBodyParam}}{{#hasFormParams}}Types.newParameterizedType(Map::class.java, String::class.java, String::class.java){{/hasFormParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{/hasBodyParam}}
val serializedBody: kotlin.String? = {{#bodyParam}}moshi.adapter<{{{dataType}}}>(bodyType).toJson(params.{{{paramName}}}){{/bodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}moshi.adapter<Map<String, String>>(bodyType).toJson(mapOf({{#formParams}}"{{{baseName}}}" to params.{{{paramName}}}?.toString(){{#hasMore}}, {{/hasMore}}{{/formParams}})){{/hasFormParams}}{{/hasBodyParam}}
val headers: MutableMap<String,String> = mutableMapOf<String,String>()
{{#hasConsumes}}{{#consumes.0}}headers["Content-Type"] = "{{mediaType}}"{{/consumes.0}}{{/hasConsumes}}
{{#hasHeaderParams}}
{{#headerParams}}
headers["{{{baseName}}}"] = {{#isContainer}}params.{{{paramName}}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}params.{{paramName}}.toString(){{/isContainer}}
{{/headerParams}}
{{/hasHeaderParams}}

{{/isMultipart}}
val queryParams = mutableMapOf<String, List<String>>()
val path = "{{{path}}}"{{#pathParams}}.replace("{" + "{{{paramName}}}" + "}", params.{{{paramName}}}.toString()){{/pathParams}}

{{>queryParams}}

val request = buildRequest(RequestMethods.{{{httpMethod}}}, serverUri, path, queryParams, backbase)
{{^isMultipart}}
request.body = serializedBody
request.headers = headers{{#isMapContainer}}

return Call<{{{returnType}}}>(request, provider, parser, Types.newParameterizedType(Map::class.java, String::class.java, {{{returnBaseType}}}::class.java)){{/isMapContainer}}{{^isMapContainer}}{{#isListContainer}}
return Call<{{{returnType}}}>(request, provider, parser, Types.newParameterizedType(List::class.java, {{{returnBaseType}}}::class.java)){{/isListContainer}}{{^isListContainer}}{{#isArray}}
return Call<{{{returnType}}}>(request, provider, parser, Types.newParameterizedType(List::class.java, {{{returnBaseType}}}::class.java)){{/isArray}}{{^isArray}}
return Call<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}>(request, provider, parser, {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}::class.java){{/isArray}}{{/isListContainer}}{{/isMapContainer}}
{{/isMultipart}}
{{#isMultipart}}
val multiPartWrapper = MultiPartWrapper("multipart/form-data")
{{#formParams}}
{{#isFile}}{{#isContainer}} /* an array of files */
if (params.{{{paramName}}} != null && params.{{{paramName}}}FileNames != null && params.{{{paramName}}}ContentTypes != null) {
{{{paramName}}}.filterNotNull().forEachIndexed { fileIndex, fileElement ->
multiPartWrapper.addPart(PartContent("{{{paramName}}}", params.{{{paramName}}}FileNames[fileIndex], fileElement, params.{{{paramName}}}ContentTypes[fileIndex]))
}
}
{{/isContainer}}{{/isFile}}
{{#isFile}}{{^isContainer}} /* single file */
if (params.{{{paramName}}} != null && params.{{{paramName}}}FileName != null && params.{{{paramName}}}ContentType != null) {
multiPartWrapper.addPart(PartContent("{{{paramName}}}", params.{{paramName}}FileName, params.{{{paramName}}}, params.{{{paramName}}}ContentType))
}
{{/isContainer}}{{/isFile}}
{{^isFile}} /* not a file */
if (params.{{{paramName}}} != null) {
val nonFileContentType = params.{{{paramName}}}ContentType ?: "{{#isPrimitive}}text/plain{{/isPrimitive}}{{^isPrimitive}}application/json{{/isPrimitive}}"
multiPartWrapper.addPart(PartContent("{{{paramName}}}", "", {{>api_parameter}}.toString().toByteArray(), nonFileContentType))
}
{{/isFile}}
{{/formParams}}

{{#isListContainer}}
return MultipartCall<{{{returnType}}}>(request, multiPartWrapper, parser, Types.newParameterizedType(List::class.java, {{{returnBaseType}}}::class.java))
{{/isListContainer}}
{{^isListContainer}}
return MultipartCall<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}>(request, multiPartWrapper, parser, {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}}::class.java)
{{/isListContainer}}
{{/isMultipart}}
}

{{/operation}}
}
{{/operations}}

{{>api_parameters}}
86 changes: 86 additions & 0 deletions boat-scaffold/src/main/templates/boat-android/api_doc.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# {{classname}}{{#description}}
{{description}}{{/description}}

All URIs are relative to *{{basePath}}*

Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}

{{#operations}}
{{#operation}}
<a name="{{operationId}}"></a>
# **{{operationId}}**
> {{#returnType}}{{returnType}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}})

{{summary}}{{#notes}}

{{notes}}{{/notes}}

### Example
```kotlin
// Import classes:
//import {{{packageName}}}.infrastructure.*
//import {{{modelPackage}}}.*

val apiInstance = {{{classname}}}()
{{#allParams}}
val {{{paramName}}} : {{{dataType}}} = {{{example}}} // {{{dataType}}} | {{{description}}}
{{/allParams}}
try {
{{#returnType}}val result : {{{returnType}}} = {{/returnType}}apiInstance.{{{operationId}}}({{#allParams}}{{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}
println(result){{/returnType}}
} catch (e: ClientException) {
println("4xx response calling {{{classname}}}#{{{operationId}}}")
e.printStackTrace()
} catch (e: ServerException) {
println("5xx response calling {{{classname}}}#{{{operationId}}}")
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}}{{#generateModelDocs}}[**{{dataType}}**]({{baseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{dataType}}**{{/generateModelDocs}}{{/isFile}}{{/isPrimitiveType}}| {{description}} |{{^required}} [optional]{{/required}}{{#defaultValue}} [default to {{defaultValue}}]{{/defaultValue}}{{#allowableValues}} [enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}}
{{/allParams}}

### Return type

{{#returnType}}{{#returnTypeIsPrimitive}}**{{returnType}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#generateModelDocs}}[**{{returnType}}**]({{returnBaseType}}.md){{/generateModelDocs}}{{^generateModelDocs}}**{{returnType}}**{{/generateModelDocs}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}null (empty response body){{/returnType}}

### Authorization

{{^authMethods}}No authorization required{{/authMethods}}
{{#authMethods}}
{{#isApiKey}}
Configure {{name}}:
ApiClient.apiKey["{{keyParamName}}"] = ""
ApiClient.apiKeyPrefix["{{keyParamName}}"] = ""
{{/isApiKey}}
{{#isBasic}}
{{^isBasicBearer}}
Configure {{name}}:
ApiClient.username = ""
ApiClient.password = ""
{{/isBasicBearer}}
{{#isBasicBearer}}
Configure {{name}}:
ApiClient.accessToken = ""
{{/isBasicBearer}}
{{/isBasic}}
{{#isOAuth}}
Configure {{name}}:
ApiClient.accessToken = ""
{{/isOAuth}}
{{/authMethods}}

### HTTP request headers

- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}

{{/operation}}
{{/operations}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
{{#allParams}}* @param {{paramName}} {{{description}}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#isFile}}
* @param {{paramName}}FileName{{#isContainer}}s{{/isContainer}} the name of the file(s) whose content is [{{paramName}}]. Optional only if the related file(s) optional.
* @param {{paramName}}ContentType{{#isContainer}}s{{/isContainer}} the mime type of the file(s) whose content is [{{paramName}}]. Optional only if the related file(s) optional.
{{/isFile}}{{^isFile}}{{#isMultipart}}{{#isFormParam}}
* @param {{paramName}}ContentType the mime type of [{{paramName}}]. Optional. Defaults to text/plain for primitives and application/json for everything else.
{{/isFormParam}}{{/isMultipart}}{{/isFile}}{{/allParams}}
*/
{{#hasParams}}@DataApi {{/hasParams}}class {{{operationIdCamelCase}}} internal constructor(
{{#allParams}}

val {{{paramName}}}: {{{dataType}}}{{^required}}? = null{{/required}},

{{#isMultipart}}
{{#isFormParam}}
{{^isFile}}
val {{{paramName}}}ContentType: String? = null,
{{/isFile}}
{{/isFormParam}}
{{/isMultipart}}

{{#isFile}}
{{^isContainer}}
val {{{paramName}}}FileName: String{{^required}}? = null{{/required}},
val {{{paramName}}}ContentType: String{{^required}}? = null{{/required}}
{{/isContainer}}

{{#isContainer}}
val {{{paramName}}}FileNames: List<String>{{^required}}? = null{{/required}},
val {{{paramName}}}ContentTypes: List<String>{{^required}}? = null{{/required}},
{{/isContainer}}
{{/isFile}}
{{/allParams}}
) {

class Builder {
{{#allParams}}
var {{{paramName}}}: {{{dataType}}}? = null
{{#isMultipart}}
{{#isFormParam}}
{{^isFile}}
var {{{paramName}}}ContentType: String? = null
{{/isFile}}
{{/isFormParam}}
{{/isMultipart}}
{{#isFile}}
{{^isContainer}}
var {{{paramName}}}FileName: String? = null
var {{{paramName}}}ContentType: String? = null
{{/isContainer}}
{{#isContainer}}
var {{{paramName}}}FileNames: List<String>? = null
var {{{paramName}}}ContentTypes: List<String>? = null
{{/isContainer}}
{{/isFile}}
{{/allParams}}

fun build() = {{{operationIdCamelCase}}}(
{{#allParams}}
{{#required}}
requireNotNull({{{paramName}}}),
{{/required}}
{{^required}}
{{{paramName}}},
{{/required}}
{{#isMultipart}}
{{#isFormParam}}
{{^isFile}}
requireNotNull({{{paramName}}}ContentType),
{{/isFile}}
{{/isFormParam}}
{{/isMultipart}}
{{#isFile}}
{{^isContainer}}
requireNotNull({{{paramName}}}FileName),
requireNotNull({{{paramName}}}ContentType),
{{/isContainer}}
{{#isContainer}}
requireNotNull({{{paramName}}}FileNames),
requireNotNull({{{paramName}}}ContentTypes),
{{/isContainer}}
{{/isFile}}
{{/allParams}}
)
}
}

/**
* Builds an instance of [{{{operationIdCamelCase}}}] with the [initializer] parameters.
*/
@Suppress("FunctionName") // DSL initializer
@JvmSynthetic // Hide from Java callers who should use Builder
fun {{{operationIdCamelCase}}}(initializer: {{{operationIdCamelCase}}}.Builder.() -> Unit): {{{operationIdCamelCase}}} {
return {{{operationIdCamelCase}}}.Builder().apply(initializer).build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#isPrimitiveType}}params.{{{paramName}}}{{^required}}{{/required}}.{{#isNumber}}toPlainString(){{/isNumber}}{{^isNumber}}toString(){{/isNumber}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{^allowableValues.empty}}{{#enumVars.empty}}{{>api_parameter_model_type}}.let { moshi.adapter<{{{dataType}}}>(it).toJson(params.{{{paramName}}}) }{{/enumVars.empty}}{{^enumVars.empty}}params.{{{paramName}}}{{^required}}{{/required}}.toString(){{/enumVars.empty}}{{/allowableValues.empty}}{{#allowableValues.empty}}params.{{{paramName}}}{{^required}}{{/required}}.toString(){{/allowableValues.empty}}{{/isPrimitiveType}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#isContainer}}{{^isMap}}{{^isArray}}Types.newParameterizedType(List::class.java, {{{baseType}}}::class.java){{/isArray}}{{/isMap}}{{/isContainer}}{{#isMap}}Types.newParameterizedType(Map::class.java, String::class.java, {{{baseType}}}::class.java){{/isMap}} {{#isArray}}Types.newParameterizedType(List::class.java, {{{baseType}}}::class.java){{/isArray}} {{^isContainer}}{{{dataType}}}::class.java{{/isContainer}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
object {{classname}}Params {

{{#operations}}
{{#operation}}
{{>api_operation_parameter_model}}
{{/operation}}
{{/operations}}
}
Loading