Skip to content

Commit

Permalink
Merge branch 'jaxrs-jersey3-server' of https://github.com/CDerksen/op…
Browse files Browse the repository at this point in the history
…enapi-generator into CDerksen-jaxrs-jersey3-server10
  • Loading branch information
wing328 committed Sep 27, 2023
2 parents beb67aa + aeb75ae commit a35306d
Show file tree
Hide file tree
Showing 114 changed files with 10,771 additions and 5 deletions.
9 changes: 9 additions & 0 deletions bin/configs/jaxrs-jersey-jersey3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
generatorName: jaxrs-jersey
outputDir: samples/server/petstore/jaxrs/jersey3
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS
library: jersey3
additionalProperties:
artifactId: jaxrs-jersey3-petstore-server
hideGenerationTimestamp: "true"
serverPort: "8082"
2 changes: 1 addition & 1 deletion docs/generators/jaxrs-jersey.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|implicitHeadersRegex|Skip header parameters that matches given regex in the generated API methods using @ApiImplicitParams annotation. Note: this parameter is ignored when implicitHeaders=true| |null|
|invokerPackage|root package for generated code| |org.openapitools.api|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|library|library template (sub-template)|<dl><dt>**jersey2**</dt><dd>Jersey core 2.x</dd></dl>|jersey2|
|library|library template (sub-template)|<dl><dt>**jersey2**</dt><dd>Jersey core 2.x</dd><dt>**jersey3**</dt><dd>Jersey core 3.x</dd></dl>|jersey2|
|licenseName|The name of the license| |Unlicense|
|licenseUrl|The URL of the license| |http://unlicense.org|
|modelPackage|package for generated models| |org.openapitools.model|
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
invoker.goals = -nsu clean generate-sources
# The expected result of the build, possible values are "success" (default) and "failure"
invoker.buildResult = success
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2022 OpenAPI-Generator Contributors (https://openapi-generator.tech)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.openapitools.maven.its</groupId>
<artifactId>jaxrs-jersey3</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<configuration>
<inputSpec>https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml</inputSpec>
<generatorName>jaxrs-jersey</generatorName>
<library>jersey3</library>
<dateLibrary>java8</dateLibrary>
<output>${basedir}/out</output>
<templateDirectory>${project.basedir}/templates</templateDirectory>
<configOptions>
</configOptions>
</configuration>
<executions>
<execution>
<id>remote</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# TEST TEST TEST

# {{artifactId}}

{{appName}}

- API version: {{appVersion}}
{{^hideGenerationTimestamp}}

- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}

{{#appDescriptionWithNewLines}}{{{appDescriptionWithNewLines}}}{{/appDescriptionWithNewLines}}

{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}

*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)*

… etc.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2022 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

File readme = new File(basedir, "out/README.md")

assert readme.isFile()
assert readme.text.contains("# TEST TEST TEST")
assert readme.text.contains("# openapi-jaxrs-server")
assert readme.text.contains("OpenAPI Petstore")

File mavenPomXml = new File(basedir, "out/pom.xml")
assert mavenPomXml.isFile()

File petApi = new File(basedir, "out/src/gen/java/org/openapitools/api/PetApi.java")
assert petApi.isFile()
assert petApi.text.contains("import org.openapitools.api.PetApiService;")

File petApiService = new File(basedir, "out/src/gen/java/org/openapitools/api/PetApiService.java")
assert petApiService.isFile()
assert petApiService.text.contains("import jakarta.ws.rs.core.Response;")

File petModel = new File(basedir, "out/src/gen/java/org/openapitools/model/Pet.java")
assert petModel.isFile()
assert petModel.text.contains("public class Pet")
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen {

protected static final String LIBRARY_JERSEY2 = "jersey2";

protected static final String LIBRARY_JERSEY3 = "jersey3";

/**
* Default library template to use. (Default: jersey2)
*/
Expand Down Expand Up @@ -58,6 +59,7 @@ public JavaJerseyServerCodegen() {

CliOption library = new CliOption(CodegenConstants.LIBRARY, CodegenConstants.LIBRARY_DESC).defaultValue(DEFAULT_JERSEY_LIBRARY);
supportedLibraries.put(LIBRARY_JERSEY2, "Jersey core 2.x");
supportedLibraries.put(LIBRARY_JERSEY3, "Jersey core 3.x");
library.setEnum(supportedLibraries);
cliOptions.add(library);
}
Expand All @@ -79,14 +81,20 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
property.example = null;
}

//Add imports for Jackson
// --- Add imports for Jackson ----------
if (!BooleanUtils.toBoolean(model.isEnum)) {
model.imports.add("JsonProperty");

if (BooleanUtils.toBoolean(model.hasEnums)) {
model.imports.add("JsonValue");
}
}

// --- Imports for Swagger2 -------------
if (this.isLibrary(LIBRARY_JERSEY3)) {
model.imports.add("Schema");
}

}

@Override
Expand All @@ -95,9 +103,18 @@ public void processOpts() {

// use default library if unset
if (StringUtils.isEmpty(library)) {
setLibrary(DEFAULT_JERSEY_LIBRARY);
this.setLibrary(DEFAULT_JERSEY_LIBRARY);

} else if (this.isLibrary(LIBRARY_JERSEY3)) {
// --- Ensure to use Jakarta for jersey3 ----
this.setUseJakartaEe(true);
additionalProperties.put(USE_JAKARTA_EE, true);
this.applyJakartaPackage();
// --- Set Swagger2 annotations ---------------
annotationLibrary = AnnotationLibrary.SWAGGER2;

}

if (additionalProperties.containsKey(CodegenConstants.IMPL_FOLDER)) {
implFolder = (String) additionalProperties.get(CodegenConstants.IMPL_FOLDER);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package {{apiPackage}};

import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
import jakarta.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.time.LocalDate;

@Provider
public class LocalDateProvider implements ParamConverterProvider {
public <T> ParamConverter<T> getConverter(Class<T> clazz, Type type, Annotation[] annotations) {
if (clazz.getName().equals(LocalDate.class.getName())) {
return new ParamConverter<T>() {
@SuppressWarnings("unchecked")
public T fromString(String value) {
return value!=null ? (T) LocalDate.parse(value) : null;
}

public String toString(T bean) {
return bean!=null ? bean.toString() : "";
}
};
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package {{apiPackage}};

import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
import jakarta.ws.rs.ext.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.time.OffsetDateTime;

@Provider
public class OffsetDateTimeProvider implements ParamConverterProvider {
public <T> ParamConverter<T> getConverter(Class<T> clazz, Type type, Annotation[] annotations) {
if (clazz.getName().equals(OffsetDateTime.class.getName())) {
return new ParamConverter<T>() {
@SuppressWarnings("unchecked")
public T fromString(String value) {
return value != null ? (T) OffsetDateTime.parse(value) : null;
}

public String toString(T bean) {
return bean != null ? bean.toString() : "";
}
};
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# JAX-RS/Jersey server with OpenAPI

## Overview
This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using an
[OpenAPI-Spec](https://openapis.org), you can easily generate a server stub.

This is an example of building a OpenAPI-enabled JAX-RS server.
This example uses the [JAX-RS](https://jax-rs-spec.java.net/) framework.
Jersey is used as JAX-RS implementation, `io.swagger:swagger-jersey3-jaxrs` is used to derive the OpenAPI Specification from the annotated code.

To run the server, please execute the following:

```
mvn clean package jetty:run
```

You can then view the OpenAPI v2 specification here:

```
http://localhost:{{serverPort}}{{contextPath}}/openapi.json
```

Note that if you have configured the `host` to be something other than localhost, the calls through
swagger-ui will be directed to that host and not localhost!
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package {{package}};

{{#models.0}}
import {{modelPackage}}.*;
{{/models.0}}
import {{package}}.{{classname}}Service;
import {{package}}.factories.{{classname}}ServiceFactory;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;

{{#imports}}import {{import}};
{{/imports}}

import java.util.Map;
import java.util.List;
import {{package}}.NotFoundException;

import java.io.InputStream;

import org.glassfish.jersey.media.multipart.FormDataParam;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;

import {{javaxPackage}}.servlet.ServletConfig;
import {{javaxPackage}}.ws.rs.core.Context;
import {{javaxPackage}}.ws.rs.core.Response;
import {{javaxPackage}}.ws.rs.core.SecurityContext;
import {{javaxPackage}}.ws.rs.*;
{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}

@Path("{{commonPath}}")
{{#hasConsumes}}@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}
{{#hasProduces}}@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}
@Tag(description = "the {{{baseName}}} API", name = "")
{{>generatedAnnotation}}
{{#operations}}
public class {{classname}} {
private final {{classname}}Service delegate;

public {{classname}}(@Context ServletConfig servletContext) {
{{classname}}Service delegate = null;
if (servletContext != null) {
String implClass = servletContext.getInitParameter("{{classname}}.implementation");
if (implClass != null && !"".equals(implClass.trim())) {
try {
delegate = ({{classname}}Service) Class.forName(implClass).getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

if (delegate == null) {
delegate = {{classname}}ServiceFactory.get{{classname}}();
}
this.delegate = delegate;
}

{{#operation}}

@{{javaxPackage}}.ws.rs.{{httpMethod}}{{!
}}{{#subresourceOperation}}
@Path("{{{path}}}"){{/subresourceOperation}}{{!
}}{{#hasConsumes}}
@Consumes({ {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }){{/hasConsumes}}{{!
}}{{#hasProduces}}
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }){{/hasProduces}}
@Operation(summary = "{{{summary}}}", description = "{{{description}}}", responses = {
{{#responses}}
@ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}", content =
@Content(schema = @Schema(implementation = {{{baseType}}}.class))),
{{/responses}}
}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
public Response {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}}@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.{{nickname}}({{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}Bodypart{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}}securityContext);
}
{{/operation}}
}
{{/operations}}
Loading

0 comments on commit a35306d

Please sign in to comment.