@@ -333,6 +333,11 @@ apiTemplateFiles are for API outputs only (controllers/handlers).
333333 // Whether to automatically hardcode params that are considered Constants by OpenAPI Spec
334334 @ Setter protected boolean autosetConstants = false ;
335335
336+ @ Setter @ Getter boolean arrayDefaultToEmpty , arrayNullableDefaultToEmpty , arrayOptionalNullableDefaultToEmpty , arrayOptionalDefaultToEmpty ;
337+ @ Setter @ Getter boolean mapDefaultToEmpty , mapNullableDefaultToEmpty , mapOptionalNullableDefaultToEmpty , mapOptionalDefaultToEmpty ;
338+ final String DEFAULT_TO_EMPTY_CONTAINER = "defaultToEmptyContainer" ;
339+ final List EMPTY_LIST = new ArrayList ();
340+
336341 @ Override
337342 public boolean getAddSuffixToDuplicateOperationNicknames () {
338343 return addSuffixToDuplicateOperationNicknames ;
@@ -392,8 +397,11 @@ public void processOpts() {
392397 convertPropertyToBooleanAndWriteBack (CodegenConstants .DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT , this ::setDisallowAdditionalPropertiesIfNotPresent );
393398 convertPropertyToBooleanAndWriteBack (CodegenConstants .ENUM_UNKNOWN_DEFAULT_CASE , this ::setEnumUnknownDefaultCase );
394399 convertPropertyToBooleanAndWriteBack (CodegenConstants .AUTOSET_CONSTANTS , this ::setAutosetConstants );
395- }
396400
401+ if (additionalProperties .containsKey (DEFAULT_TO_EMPTY_CONTAINER ) && additionalProperties .get (DEFAULT_TO_EMPTY_CONTAINER ) instanceof String ) {
402+ parseDefaultToEmptyContainer ((String ) additionalProperties .get (DEFAULT_TO_EMPTY_CONTAINER ));
403+ }
404+ }
397405
398406 /***
399407 * Preset map builder with commonly used Mustache lambdas.
@@ -4172,6 +4180,11 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo
41724180 }
41734181 }
41744182
4183+ // override defaultValue if it's not set and defaultToEmptyContainer is set
4184+ if (p .getDefault () == null && additionalProperties .containsKey ("defaultToEmptyContainer" )) {
4185+ updateDefaultToEmptyContainer (property , p );
4186+ }
4187+
41754188 // set the default value
41764189 property .defaultValue = toDefaultValue (property , p );
41774190 property .defaultValueWithParam = toDefaultValueWithParam (name , p );
@@ -4181,6 +4194,90 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo
41814194 return property ;
41824195 }
41834196
4197+ /**
4198+ * update container's default to empty container according rules provided by the user.
4199+ *
4200+ * @param cp codegen property
4201+ * @param p schema
4202+ */
4203+ void updateDefaultToEmptyContainer (CodegenProperty cp , Schema p ) {
4204+ if (cp .isArray ) {
4205+ if (!cp .required ) { // optional
4206+ if (cp .isNullable && arrayOptionalNullableDefaultToEmpty ) { // nullable
4207+ p .setDefault (EMPTY_LIST );
4208+ } else if (!cp .isNullable && arrayOptionalDefaultToEmpty ) { // non-nullable
4209+ p .setDefault (EMPTY_LIST );
4210+ }
4211+ } else { // required
4212+ if (cp .isNullable && arrayNullableDefaultToEmpty ) { // nullable
4213+ p .setDefault (EMPTY_LIST );
4214+ } else if (!cp .isNullable && arrayDefaultToEmpty ) { // non-nullable
4215+ p .setDefault (EMPTY_LIST );
4216+ }
4217+ }
4218+ } else if (cp .isMap ) {
4219+ if (!cp .required ) { // optional
4220+ if (cp .isNullable && mapOptionalNullableDefaultToEmpty ) { // nullable
4221+ p .setDefault (EMPTY_LIST );
4222+ } else if (!cp .isNullable && mapOptionalDefaultToEmpty ) { // non-nullable
4223+ p .setDefault (EMPTY_LIST );
4224+ }
4225+ } else { // required
4226+ if (cp .isNullable && mapNullableDefaultToEmpty ) { // nullable
4227+ p .setDefault (EMPTY_LIST );
4228+ } else if (!cp .isNullable && mapOptionalDefaultToEmpty ) { // non-nullable
4229+ p .setDefault (EMPTY_LIST );
4230+ }
4231+ }
4232+ }
4233+ }
4234+
4235+ /**
4236+ * Parse the rules for defaulting to the empty container.
4237+ *
4238+ * @param input a set of rules separated by `|`
4239+ */
4240+ void parseDefaultToEmptyContainer (String input ) {
4241+ String [] inputs = ((String ) input ).split ("[|]" );
4242+ String containerType ;
4243+ for (String rule : inputs ) {
4244+ if (StringUtils .isEmpty (rule )) {
4245+ LOGGER .error ("updateDefaultToEmptyContainer: Skipped empty input in `{}`." , input );
4246+ continue ;
4247+ }
4248+
4249+ if (rule .startsWith ("?" ) && rule .endsWith ("?" )) { // nullable optional
4250+ containerType = rule .substring (1 , rule .length () - 1 );
4251+ if ("array" .equalsIgnoreCase (containerType )) {
4252+ arrayOptionalNullableDefaultToEmpty = true ;
4253+ } else if ("map" .equalsIgnoreCase (containerType )) {
4254+ mapOptionalNullableDefaultToEmpty = true ;
4255+ } else {
4256+ LOGGER .error ("Skipped invalid container type `{}` in `{}`." , containerType , input );
4257+ }
4258+ } else if (rule .startsWith ("?" )) { // nullable (required)
4259+ containerType = rule .substring (1 , rule .length ());
4260+ if ("array" .equalsIgnoreCase (containerType )) {
4261+ arrayNullableDefaultToEmpty = true ;
4262+ } else if ("map" .equalsIgnoreCase (containerType )) {
4263+ mapNullableDefaultToEmpty = true ;
4264+ } else {
4265+ LOGGER .error ("Skipped invalid container type `{}` in `{}`." , containerType , input );
4266+ }
4267+ } else if (rule .endsWith ("?" )) { // optional
4268+ containerType = rule .substring (0 , rule .length ()-1 );
4269+ if ("array" .equalsIgnoreCase (containerType )) {
4270+ arrayOptionalDefaultToEmpty = true ;
4271+ } else if ("map" .equalsIgnoreCase (containerType )) {
4272+ mapOptionalDefaultToEmpty = true ;
4273+ } else {
4274+ LOGGER .error ("Skipped invalid container type `{}` in the rule `{}`." , containerType , input );
4275+ }
4276+ }
4277+ }
4278+
4279+ }
4280+
41844281 /**
41854282 * Update property for array(list) container
41864283 *
0 commit comments