Create common files for Helidon generators

Signed-off-by: spericas <santiago.pericasgeertsen@oracle.com>
This commit is contained in:
spericas
2022-09-23 17:11:14 -05:00
committed by tim.quinn@oracle.com
parent 53873ff6d8
commit 6be539db83
6 changed files with 444 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.languages.features.PerformBeanValidationFeatures;
import static org.openapitools.codegen.CodegenConstants.DEVELOPER_EMAIL;
import static org.openapitools.codegen.CodegenConstants.DEVELOPER_NAME;
import static org.openapitools.codegen.CodegenConstants.DEVELOPER_ORGANIZATION;
import static org.openapitools.codegen.CodegenConstants.DEVELOPER_ORGANIZATION_URL;
import static org.openapitools.codegen.CodegenConstants.PARENT_ARTIFACT_ID;
import static org.openapitools.codegen.CodegenConstants.PARENT_GROUP_ID;
import static org.openapitools.codegen.CodegenConstants.PARENT_VERSION;
import static org.openapitools.codegen.CodegenConstants.SCM_CONNECTION;
import static org.openapitools.codegen.CodegenConstants.SCM_DEVELOPER_CONNECTION;
import static org.openapitools.codegen.CodegenConstants.SCM_URL;
public abstract class JavaHelidonCommonCodegen extends AbstractJavaCodegen
implements BeanValidationFeatures, PerformBeanValidationFeatures {
static final String HELIDON_MP = "mp";
static final String HELIDON_SE = "se";
static final String HELIDON_NIMA = "nima";
static final String HELIDON_NIMA_ANNOTATIONS = "nima-annotations";
static final String MICROPROFILE_ROOT_PACKAGE = "rootJavaEEPackage";
static final String MICROPROFILE_ROOT_DEP_PREFIX = "x-helidon-rootJavaEEDepPrefix";
static final String MICROPROFILE_ROOT_PACKAGE_DESC = "Root package name for Java EE";
static final String MICROPROFILE_ROOT_PACKAGE_JAVAX = "javax";
static final String MICROPROFILE_ROOT_PACKAGE_JAKARTA = "jakarta";
private static final String VALIDATION_ARTIFACT_PREFIX_KEY = "x-helidon-validationArtifactPrefix";
private static final String VALIDATION_ARTIFACT_PREFIX_JAVAX = "";
private static final String VALIDATION_ARTIFACT_PREFIX_JAKARTA = MICROPROFILE_ROOT_PACKAGE_JAKARTA + ".";
// for generated doc
static final String MICROPROFILE_ROOT_PACKAGE_DEFAULT =
"Helidon 2.x and earlier: " + MICROPROFILE_ROOT_PACKAGE_JAVAX
+ "; Helidon 3.x and later: " + MICROPROFILE_ROOT_PACKAGE_JAKARTA;
static final String SERIALIZATION_LIBRARY_JACKSON = "jackson";
static final String SERIALIZATION_LIBRARY_JSONB = "jsonb";
public static final String HELIDON_VERSION = "helidonVersion";
public static final String DEFAULT_HELIDON_VERSION = "3.0.1";
static final String HELIDON_VERSION_DESC = "Helidon version for generated code";
static final String FULL_PROJECT = "fullProject";
static final String FULL_PROJECT_DESC = "If set to true, it will generate all files; if set to false, " +
"it will only generate API files. If unspecified, the behavior depends on whether a project " +
"exists or not: if it does not, same as true; if it does, same as false. Note that test files " +
"are never overwritten.";
private String helidonVersion;
private String rootJavaEEPackage;
private String rootJavaEEDepPrefix;
public JavaHelidonCommonCodegen() {
super();
cliOptions.add(new CliOption(HELIDON_VERSION, HELIDON_VERSION_DESC)
.defaultValue(DEFAULT_HELIDON_VERSION));
cliOptions.add(new CliOption(MICROPROFILE_ROOT_PACKAGE, MICROPROFILE_ROOT_PACKAGE_DESC)
.defaultValue(MICROPROFILE_ROOT_PACKAGE_DEFAULT));
cliOptions.add(new CliOption(FULL_PROJECT, FULL_PROJECT_DESC)
.defaultValue("")); // depends on project state
}
@Override
public void processOpts() {
super.processOpts();
String userHelidonVersion = "";
String userParentVersion = "";
if (additionalProperties.containsKey(CodegenConstants.PARENT_VERSION)) {
userParentVersion = additionalProperties.get(CodegenConstants.PARENT_VERSION).toString();
}
if (additionalProperties.containsKey(HELIDON_VERSION)) {
userHelidonVersion = additionalProperties.get(HELIDON_VERSION).toString();
}
if (!userHelidonVersion.isEmpty()) {
if (!userParentVersion.isEmpty() && !userHelidonVersion.equals(userParentVersion)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT,
"Both %s and %s properties were set with different value.",
CodegenConstants.PARENT_VERSION,
HELIDON_VERSION));
}
setHelidonVersion(userHelidonVersion);
} else if (!userParentVersion.isEmpty()) {
setHelidonVersion(userParentVersion);
} else {
setHelidonVersion(DEFAULT_HELIDON_VERSION);
}
additionalProperties.put(HELIDON_VERSION, helidonVersion);
setEEPackageAndDependencies(helidonVersion);
}
/**
* Remove set of options not currently used by any Helidon generator. Should be
* called during construction but only on leaf classes.
*/
protected void removeUnusedOptions() {
removeCliOptions(SCM_CONNECTION,
SCM_DEVELOPER_CONNECTION,
SCM_URL,
DEVELOPER_NAME,
DEVELOPER_ORGANIZATION,
DEVELOPER_ORGANIZATION_URL,
DEVELOPER_EMAIL,
PARENT_ARTIFACT_ID,
PARENT_VERSION,
PARENT_GROUP_ID,
DISABLE_HTML_ESCAPING);
}
/**
* Determine whether to generate or overwrite files depending on fullProject property.
* If property is unspecified, then check if sources are already there and avoid overwriting
* modifiable files.
*
* @param modifiable list of modifiable files to be processed
* @param unmodifiable list of unmodifiable files to be processed
*/
protected void processSupportingFiles(List<SupportingFile> modifiable, List<SupportingFile> unmodifiable) {
Boolean fullProject = !additionalProperties.containsKey(FULL_PROJECT) ? null :
Boolean.parseBoolean(additionalProperties.get(FULL_PROJECT).toString());
if (fullProject == null && !projectFilesExist()) { // not explicitly set
supportingFiles.addAll(modifiable);
} else if (Boolean.TRUE.equals(fullProject)) { // explicitly set to true
supportingFiles.addAll(modifiable);
}
supportingFiles.addAll(unmodifiable);
}
/**
* Check if project is already generated to determine default for the fullProject
* flag. Can be overridden in subclasses to strengthen test condition.
*
* @return outcome of test
*/
protected boolean projectFilesExist() {
return Paths.get(getOutputTestFolder()).toFile().exists();
}
protected String rootJavaEEPackage() {
return rootJavaEEPackage;
}
private void setHelidonVersion(String version) {
helidonVersion = version;
setParentVersion(version);
}
private void setEEPackageAndDependencies(String version) {
rootJavaEEPackage = checkAndSelectRootEEPackage(version);
additionalProperties.put(MICROPROFILE_ROOT_PACKAGE, rootJavaEEPackage);
rootJavaEEDepPrefix = checkAndSelectRootEEDepPrefix(version);
additionalProperties.put(MICROPROFILE_ROOT_DEP_PREFIX, rootJavaEEDepPrefix);
additionalProperties.put(VALIDATION_ARTIFACT_PREFIX_KEY,
rootJavaEEDepPrefix.equals(MICROPROFILE_ROOT_PACKAGE_JAVAX)
? VALIDATION_ARTIFACT_PREFIX_JAVAX
: VALIDATION_ARTIFACT_PREFIX_JAKARTA);
}
private String checkAndSelectRootEEPackage(String version) {
String packagePrefixImpliedByVersion = usesJakartaPackages(version)
? MICROPROFILE_ROOT_PACKAGE_JAKARTA
: MICROPROFILE_ROOT_PACKAGE_JAVAX;
// Make sure any user-specified root EE package is correct for the chosen Helidon version.
if (additionalProperties.containsKey(MICROPROFILE_ROOT_PACKAGE)) {
String userRootEEPackage = additionalProperties.get(MICROPROFILE_ROOT_PACKAGE).toString();
if (!packagePrefixImpliedByVersion.equals(userRootEEPackage)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT,
"Helidon version %s uses the %s namespace but options specified '%s'",
version,
packagePrefixImpliedByVersion,
userRootEEPackage));
}
return userRootEEPackage;
}
// No explicit setting for the root EE package.
return packagePrefixImpliedByVersion;
}
private String checkAndSelectRootEEDepPrefix(String version) {
String mavenDepPrefixImpliedByVersion = usesJakartaPrefix(version)
? MICROPROFILE_ROOT_PACKAGE_JAKARTA
: MICROPROFILE_ROOT_PACKAGE_JAVAX;
// Make sure any user-specified prefix is correct for the chosen Helidon version.
if (additionalProperties.containsKey(MICROPROFILE_ROOT_DEP_PREFIX)) {
String userMavenDepPrefix = additionalProperties.get(MICROPROFILE_ROOT_DEP_PREFIX).toString();
if (!mavenDepPrefixImpliedByVersion.equals(userMavenDepPrefix)) {
throw new IllegalArgumentException(
String.format(Locale.ROOT,
"Helidon version %s uses the %s prefix for EE dependencies but options specified '%s'",
version,
mavenDepPrefixImpliedByVersion,
userMavenDepPrefix));
}
return userMavenDepPrefix;
}
// No explicit setting for the dependency prefix.
return mavenDepPrefixImpliedByVersion;
}
private boolean usesJakartaPackages(String version) {
return !version.startsWith("2.") && !version.startsWith("1.");
}
private boolean usesJakartaPrefix(String version) {
return !version.startsWith("1.");
}
protected void removeCliOptions(String... opt) {
List<String> opts = Arrays.asList(opt);
Set<CliOption> forRemoval = cliOptions.stream()
.filter(cliOption -> opts.contains(cliOption.getOpt()))
.collect(Collectors.toSet());
forRemoval.forEach(cliOptions::remove);
}
}

View File

@@ -0,0 +1,9 @@
# {{appName}}
{{#appDescriptionWithNewLines}}
{{{.}}}
{{/appDescriptionWithNewLines}}
## Overview
This project was generated using the Helidon OpenAPI Generator.

View File

@@ -0,0 +1,21 @@
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# exclude jar for gradle wrapper
!gradle/wrapper/*.jar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# build files
**/target
target
.gradle
build

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,23 @@
{{>licenseInfo}}
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#serializableModel}}
import java.io.Serializable;
{{/serializableModel}}
{{#useBeanValidation}}
import {{rootJavaEEPackage}}.validation.constraints.*;
import {{rootJavaEEPackage}}.validation.Valid;
{{/useBeanValidation}}
{{#models}}
{{#model}}
{{#isEnum}}
{{>enumOuterClass}}
{{/isEnum}}
{{^isEnum}}
{{>pojo}}
{{/isEnum}}
{{/model}}
{{/models}}

View File

@@ -0,0 +1,121 @@
{{#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}}
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}}
private {{{datatypeWithEnum}}} {{{name}}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
{{/vars}}
/**
* Default constructor.
*/
public {{classname}}() {
// JSON-B / Jackson
}
/**
* Create {{classname}}.
*
{{#vars}}
* @param {{name}} {{description}}{{^description}}{{name}}{{/description}}
{{/vars}}
*/
public {{classname}}(
{{#vars}}
{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}
{{/vars}}
) {
{{#vars}}
this.{{name}} = {{name}};
{{/vars}}
}
{{#vars}}{{#vendorExtensions.x-has-readonly-properties}}{{#jsonb}}
@JsonbCreator
public {{classname}}(
{{#readOnlyVars}}
@JsonbProperty("{{baseName}}") {{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}
{{/readOnlyVars}}
) {
{{#readOnlyVars}}
this.{{name}} = {{name}};
{{/readOnlyVars}}
}{{/jsonb}}{{/vendorExtensions.x-has-readonly-properties}}
/**
{{#description}}
* {{{.}}}
{{/description}}
{{^description}}
* Get {{name}}
{{/description}}
{{#minimum}}
* minimum: {{.}}
{{/minimum}}
{{#maximum}}
* maximum: {{.}}
{{/maximum}}
* @return {{name}}
*/
public {{{datatypeWithEnum}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
this.{{name}} = {{name}};
}{{/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 ");
}
}