@@ -225,6 +225,8 @@ protected enum ENUM_PROPERTY_NAMING_TYPE {MACRO_CASE, legacy, original}
225225 @ Setter
226226 protected boolean useJspecify ;
227227 protected JSpecifyNullableLambda jSpecifyNullableLambda ;
228+ protected RemoveAnnotationLambda removeAnnotationLambda ;
229+
228230 @ Getter @ Setter
229231 protected boolean useDeductionForOneOfInterfaces = false ;
230232
@@ -706,9 +708,8 @@ public void processOpts() {
706708 }
707709 writer .write (content );
708710 });
709- additionalProperties .put ("removeAnnotations" , (Mustache .Lambda ) (fragment , writer ) -> {
710- writer .write (removeAnnotations (fragment .execute ()));
711- });
711+ this .removeAnnotationLambda = new RemoveAnnotationLambda ();
712+ additionalProperties .put ("removeAnnotations" , removeAnnotationLambda );
712713 additionalProperties .put ("sanitizeDataType" , (Mustache .Lambda ) (fragment , writer ) -> {
713714 writer .write (sanitizeDataType (fragment .execute ()));
714715 });
@@ -881,6 +882,8 @@ protected void applyJspecify() {
881882 (sourceFolder + File .separator + apiPackage ).replace ("." , java .io .File .separator ),
882883 "package-info.java" ));
883884 }
885+ // simplify mustache template for jspecify. @Nullable is kept
886+ this .removeAnnotationLambda .keepAnnotation ("@Nullable" );
884887 }
885888
886889 @ Override
@@ -2076,6 +2079,7 @@ public void postProcessResponseWithProperty(CodegenResponse response, CodegenPro
20762079 * <p>
20772080 * For example:
20782081 * <ul>
2082+ * <li>{@code @jakarta.annotation.Nullable String} -> {@code String}</li>
20792083 * <li>{@code @Min(0) @Max(10)Integer} -> {@code Integer}</li>
20802084 * <li>{@code @Pattern(regexp = "^[a-z]$")String>} -> {@code String}</li>
20812085 * <li>{@code List<@Pattern(regexp = "^[a-z]$")String>}" -> "{@code List<String>}"</li>
@@ -2087,7 +2091,38 @@ public void postProcessResponseWithProperty(CodegenResponse response, CodegenPro
20872091 */
20882092 public String removeAnnotations (String dataType ) {
20892093 if (dataType != null && dataType .contains ("@" )) {
2090- return dataType .replaceAll ("(?:(?i)@[a-z0-9]*+([(].*[)]|\\ s*))*+" , "" );
2094+ return dataType .replaceAll ("(?:(?i)@[a-z0-9\\ .]*+([(].*[)]|\\ s*))*+" , "" );
2095+ }
2096+ return dataType ;
2097+ }
2098+
2099+ /**
2100+ * Remove annotations from the given data type string except annotationToKeep.
2101+ * <p>
2102+ * For example:
2103+ * <ul>
2104+ * <li>{@code @Nullable @Min(0) @Max(10)Integer} -> {@code @Nullable Integer}</li>
2105+ * <li>{@code @Nullable List<@Valid Pet>}" -> "{@code @Nullable List<Pet>}"</li>
2106+ * </ul>
2107+ *
2108+ * @param dataType the data type string
2109+ * @param annotationToKeep annotation to keep. For example @Nullable
2110+ * @return the data type string without annotations.
2111+ */
2112+ public String removeAnnotationsWithExclusion (String dataType , String annotationToKeep ) {
2113+ if (dataType != null && dataType .contains ("@" )) {
2114+ if (annotationToKeep == null ) {
2115+ return dataType .replaceAll ("(?:(?i)@[a-z0-9\\ .]*+([(].*[)]|\\ s*))*+" , "" );
2116+ }
2117+ annotationToKeep += " " ;
2118+ boolean annotationPresent = dataType .indexOf (annotationToKeep ) >=0 ;
2119+ if (annotationPresent ) {
2120+ dataType = dataType .replace ( annotationToKeep , "%%" );
2121+ }
2122+ dataType = dataType .replaceAll ("(?:(?i)@[a-z0-9\\ .]*+([(].*[)]|\\ s*))*+" , "" );
2123+ if (annotationPresent ) {
2124+ dataType = dataType .replace ("%%" , annotationToKeep );
2125+ }
20912126 }
20922127 return dataType ;
20932128 }
@@ -2876,7 +2911,7 @@ private int getLastIndex(String dataType) {
28762911 /**
28772912 * for Jspecify, remove @Nullable before the datatype and set keptNullable to true if done.
28782913 */
2879- class JSpecifyNullableLambda implements Mustache .Lambda {
2914+ protected class JSpecifyNullableLambda implements Mustache .Lambda {
28802915 private String nullableAnnotation = "@Nullable" ;
28812916 // remember @Nullable annotation value when jspecify is used.
28822917 private String keptNullable = null ;
@@ -2926,4 +2961,21 @@ protected void addNullableImportForOperation(CodegenOperation codegenOperation)
29262961 .findAny ()
29272962 .ifPresent (param -> codegenOperation .imports .add ("Nullable" ));
29282963 }
2964+
2965+ /**
2966+ * Simplify the removeAnnotations lambda for custom removal.
2967+ */
2968+ protected class RemoveAnnotationLambda implements Mustache .Lambda {
2969+
2970+ private String keep ;
2971+
2972+ @ Override
2973+ public void execute (Template .Fragment fragment , Writer writer ) throws IOException {
2974+ writer .write (removeAnnotationsWithExclusion (fragment .execute (), keep ));
2975+ }
2976+
2977+ public void keepAnnotation (String keep ) {
2978+ this .keep = keep ;
2979+ }
2980+ }
29292981}
0 commit comments