4747import static com .google .common .base .CaseFormat .LOWER_CAMEL ;
4848import static com .google .common .base .CaseFormat .UPPER_UNDERSCORE ;
4949import static java .util .Collections .sort ;
50+ import static org .openapitools .codegen .CodegenConstants .SERIALIZATION_LIBRARY ;
5051import static org .openapitools .codegen .CodegenConstants .X_IMPLEMENTS ;
5152import static org .openapitools .codegen .utils .CamelizeOption .LOWERCASE_FIRST_LETTER ;
5253import static org .openapitools .codegen .utils .StringUtils .camelize ;
@@ -117,6 +118,11 @@ public class JavaClientCodegen extends AbstractJavaCodegen
117118 public static final String SERIALIZATION_LIBRARY_JACKSON = "jackson" ;
118119 public static final String SERIALIZATION_LIBRARY_JSONB = "jsonb" ;
119120
121+ public static final String USE_SPRING_7 = "useSpring7" ;
122+ private static final String JACKSON2_PACKAGE = "com.fasterxml.jackson" ;
123+ private static final String JACKSON3_PACKAGE = "tools.jackson" ;
124+ private static final String JACKSON_PACKAGE = "jacksonPackage" ;
125+
120126 public static final String GENERATE_CLIENT_AS_BEAN = "generateClientAsBean" ;
121127
122128 protected String gradleWrapperPackage = "gradle.wrapper" ;
@@ -134,7 +140,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
134140 @ Setter protected boolean microProfileRegisterExceptionMapper = true ;
135141 @ Setter protected String configKey = null ;
136142 @ Setter (AccessLevel .PRIVATE ) protected boolean configKeyFromClassName = false ;
137-
138143 @ Setter protected boolean asyncNative = false ;
139144 @ Setter protected boolean parcelableModel = false ;
140145 @ Setter protected boolean performBeanValidation = false ;
@@ -158,6 +163,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
158163 * Serialization library.
159164 */
160165 @ Getter protected String serializationLibrary = null ;
166+ @ Getter @ Setter protected boolean useSpring7 = false ;
161167 @ Setter protected boolean useOneOfDiscriminatorLookup = false ; // use oneOf discriminator's mapping for model lookup
162168 protected String rootJavaEEPackage ;
163169 protected Map <String , MpRestClientVersion > mpRestClientVersions = new LinkedHashMap <>();
@@ -298,7 +304,9 @@ public JavaClientCodegen() {
298304 serializationOptions .put (SERIALIZATION_LIBRARY_JSONB , "Use JSON-B as serialization library" );
299305 serializationLibrary .setEnum (serializationOptions );
300306 cliOptions .add (serializationLibrary );
301-
307+ cliOptions .add (CliOption .newBoolean (USE_SPRING_7 ,
308+ "Generate code and provide dependencies for use with Spring Boot 4.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`." ,
309+ useSpring7 ));
302310 // Ensure the OAS 3.x discriminator mappings include any descendent schemas that allOf
303311 // inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values,
304312 // and the discriminator mapping schemas in the OAS document.
@@ -367,8 +375,13 @@ public void processOpts() {
367375 // default jackson unless overridden by setSerializationLibrary
368376 this .jackson = !additionalProperties .containsKey (CodegenConstants .SERIALIZATION_LIBRARY ) ||
369377 SERIALIZATION_LIBRARY_JACKSON .equals (additionalProperties .get (CodegenConstants .SERIALIZATION_LIBRARY ));
370-
371378 convertPropertyToBooleanAndWriteBack (CodegenConstants .USE_ONEOF_DISCRIMINATOR_LOOKUP , this ::setUseOneOfDiscriminatorLookup );
379+ convertPropertyToBooleanAndWriteBack (USE_SPRING_7 , this ::setUseSpring7 );
380+ if (this .useSpring7 ){
381+ this .applyJackson3Package ();
382+ } else {
383+ this .applyJackson2Package ();
384+ }
372385
373386 // RxJava
374387 if (additionalProperties .containsKey (USE_RX_JAVA2 ) && additionalProperties .containsKey (USE_RX_JAVA3 )) {
@@ -476,15 +489,20 @@ public void processOpts() {
476489 authFolder = (sourceFolder + '/' + invokerPackage + ".auth" ).replace ("." , "/" );
477490
478491 //Common files
479- supportingFiles .add (new SupportingFile ("pom.mustache" , "" , "pom.xml" ).doNotOverwrite ());
492+ if (useSpring7 ) {
493+ supportingFiles .add (new SupportingFile ("pom-s7.mustache" , "" , "pom.xml" ).doNotOverwrite ());
494+ supportingFiles .add (new SupportingFile ("ApiClient-s7.mustache" , invokerFolder , "ApiClient.java" ));
495+ } else {
496+ supportingFiles .add (new SupportingFile ("pom.mustache" , "" , "pom.xml" ).doNotOverwrite ());
497+ supportingFiles .add (new SupportingFile ("ApiClient.mustache" , invokerFolder , "ApiClient.java" ));
498+ }
480499 supportingFiles .add (new SupportingFile ("README.mustache" , "" , "README.md" ).doNotOverwrite ());
481500 supportingFiles .add (new SupportingFile ("build.gradle.mustache" , "" , "build.gradle" ).doNotOverwrite ());
482501 supportingFiles .add (new SupportingFile ("build.sbt.mustache" , "" , "build.sbt" ).doNotOverwrite ());
483502 supportingFiles .add (new SupportingFile ("settings.gradle.mustache" , "" , "settings.gradle" ).doNotOverwrite ());
484503 supportingFiles .add (new SupportingFile ("gradle.properties.mustache" , "" , "gradle.properties" ).doNotOverwrite ());
485504 supportingFiles .add (new SupportingFile ("manifest.mustache" , projectFolder , "AndroidManifest.xml" ).doNotOverwrite ());
486505 supportingFiles .add (new SupportingFile ("travis.mustache" , "" , ".travis.yml" ));
487- supportingFiles .add (new SupportingFile ("ApiClient.mustache" , invokerFolder , "ApiClient.java" ));
488506 supportingFiles .add (new SupportingFile ("ServerConfiguration.mustache" , invokerFolder , "ServerConfiguration.java" ));
489507 supportingFiles .add (new SupportingFile ("ServerVariable.mustache" , invokerFolder , "ServerVariable.java" ));
490508 supportingFiles .add (new SupportingFile ("maven.yml.mustache" , ".github/workflows" , "maven.yml" ));
@@ -685,6 +703,10 @@ public void processOpts() {
685703 // The flag below should be set for all Java libraries, but the templates need to be ported
686704 // one by one for each library.
687705 supportsAdditionalPropertiesWithComposedSchema = true ;
706+ if (useSpring7 ) {
707+ // currently not supported for spring7 (neither for Jackson nor JSON-B)
708+ openApiNullable = false ;
709+ }
688710 } else if (libVertx ) {
689711 typeMapping .put ("file" , "AsyncFile" );
690712 importMapping .put ("AsyncFile" , "io.vertx.core.file.AsyncFile" );
@@ -790,8 +812,10 @@ public void processOpts() {
790812 additionalProperties .remove (SERIALIZATION_LIBRARY_GSON );
791813 additionalProperties .remove (SERIALIZATION_LIBRARY_JSONB );
792814 supportingFiles .add (new SupportingFile ("RFC3339DateFormat.mustache" , invokerFolder , "RFC3339DateFormat.java" ));
793- supportingFiles .add (new SupportingFile ("RFC3339InstantDeserializer.mustache" , invokerFolder , "RFC3339InstantDeserializer.java" ));
794- supportingFiles .add (new SupportingFile ("RFC3339JavaTimeModule.mustache" , invokerFolder , "RFC3339JavaTimeModule.java" ));
815+ if (!useSpring7 ) {
816+ supportingFiles .add (new SupportingFile ("RFC3339InstantDeserializer.mustache" , invokerFolder , "RFC3339InstantDeserializer.java" ));
817+ supportingFiles .add (new SupportingFile ("RFC3339JavaTimeModule.mustache" , invokerFolder , "RFC3339JavaTimeModule.java" ));
818+ }
795819 break ;
796820 case SERIALIZATION_LIBRARY_GSON :
797821 additionalProperties .put (SERIALIZATION_LIBRARY_GSON , "true" );
@@ -809,7 +833,7 @@ public void processOpts() {
809833 additionalProperties .remove (SERIALIZATION_LIBRARY_JSONB );
810834 break ;
811835 }
812-
836+
813837 if (isLibrary (FEIGN )) {
814838 additionalProperties .put ("feign-okhttp" , "true" );
815839 } else if (isLibrary (FEIGN_HC5 )) {
@@ -1028,6 +1052,10 @@ private static boolean isMultipartType(List<Map<String, String>> consumes) {
10281052 @ Override
10291053 public void postProcessModelProperty (CodegenModel model , CodegenProperty property ) {
10301054 super .postProcessModelProperty (model , property );
1055+
1056+ if (useSpring7 ) {
1057+ importMapping .put ("JsonDeserialize" , "tools.jackson.databind.annotation.JsonDeserialize" );
1058+ }
10311059 if (!model .isEnum ) {
10321060 //Needed imports for Jackson based libraries
10331061 if (additionalProperties .containsKey (SERIALIZATION_LIBRARY_JACKSON )) {
@@ -1241,6 +1269,14 @@ public void setCaseInsensitiveResponseHeaders(final Boolean caseInsensitiveRespo
12411269 this .caseInsensitiveResponseHeaders = caseInsensitiveResponseHeaders ;
12421270 }
12431271
1272+ protected void applyJackson2Package () {
1273+ writePropertyBack (JACKSON_PACKAGE , JACKSON2_PACKAGE );
1274+ }
1275+
1276+ protected void applyJackson3Package () {
1277+ writePropertyBack (JACKSON_PACKAGE , JACKSON3_PACKAGE );
1278+ }
1279+
12441280 public void setSerializationLibrary (String serializationLibrary ) {
12451281 if (SERIALIZATION_LIBRARY_JACKSON .equalsIgnoreCase (serializationLibrary )) {
12461282 this .serializationLibrary = SERIALIZATION_LIBRARY_JACKSON ;
@@ -1281,7 +1317,7 @@ public String toApiVarName(String name) {
12811317
12821318 @ Override
12831319 public void addImportsToOneOfInterface (List <Map <String , String >> imports ) {
1284- if (additionalProperties .containsKey (SERIALIZATION_LIBRARY_JACKSON )) {
1320+ if (additionalProperties .containsKey (SERIALIZATION_LIBRARY_JACKSON )) {
12851321 for (String i : Arrays .asList ("JsonSubTypes" , "JsonTypeInfo" , "JsonIgnoreProperties" )) {
12861322 Map <String , String > oneImport = new HashMap <>();
12871323 oneImport .put ("import" , importMapping .get (i ));
0 commit comments