@@ -145,55 +145,39 @@ public class ${class.name}
145145 #end
146146
147147 /**
148- * Constructor for this class, package protected .
148+ * Constructor for this class, to be called from its subclasses and {@link Builder} .
149149 * @see Builder#build()
150150 */
151- ${class.name}(
152- #if ( $class == $root )
153- String namespaceUri,
154- String modelEncoding,
155- #end
156- #foreach ( $field in $allFields )
157- #set ( $sep = "#if(${locationTracking}||$field!=${allFields[${allFields.size()} - 1]}),#end" )
158- #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
159- #if ( $type.startsWith("List<") )
160- #set ( $type = ${type.replace('List<','Collection<')} )
161- #end
162- $type $field.name${sep}
163- #end
164- #if ( $locationTracking )
165- Map<Object, InputLocation> locations,
166- InputLocation importedFrom
167- #end
168- ) {
151+ protected ${class.name}(Builder builder) {
169152 #if ( $class.superClass )
170- super(
171- #foreach ( $field in $inheritedFields )
172- #set ( $sep = "#if(${locationTracking}||$field!=${inheritedFields[${inheritedFields.size()} - 1]}),#end" )
173- ${field.name}${sep}
174- #end
175- #if ( $locationTracking )
176- locations,
177- importedFrom
178- #end
179- );
153+ super(builder);
180154 #end
181155 #if ( $class == $root )
182- this.namespaceUri = namespaceUri;
183- this.modelEncoding = modelEncoding;
156+ this.namespaceUri = builder. namespaceUri != null ? builder.namespaceUri : (builder.base != null ? builder.base.namespaceUri : null) ;
157+ this.modelEncoding = builder. modelEncoding != null ? builder.modelEncoding : (builder.base != null ? builder.base.modelEncoding : "UTF-8") ;
184158 #end
185159 #foreach ( $field in $class.getFields($version) )
186160 #if ( $field.type == "java.util.List" || $field.type == "java.util.Properties" || $field.type == "java.util.Map" )
187- this.${field.name} = ImmutableCollections.copy(${field.name});
161+ this.${field.name} = ImmutableCollections.copy(builder. ${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : null) );
188162 #else
189- this.${field.name} = ${field.name};
163+ #if ( $field.type == "boolean" || $field.type == "int" )
164+ this.${field.name} = builder.${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : ${field.defaultValue});
165+ #else
166+ this.${field.name} = builder.${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : null);
167+ #end
190168 #end
191169 #end
192170 #if ( $locationTracking )
171+ Map<Object, InputLocation> newlocs = builder.locations != null ? builder.locations : Collections.emptyMap();
172+ Map<Object, InputLocation> oldlocs = builder.base != null && builder.base.locations != null ? builder.base.locations : Collections.emptyMap();
193173 #if ( ! $class.superClass )
194- this.locations = ImmutableCollections.copy(locations);
195- this.importedFrom = importedFrom;
174+ this.locations = new HashMap<>();
175+ this.importedFrom = builder.importedFrom;
176+ this.locations.put("", newlocs.containsKey("") ? newlocs.get("") : oldlocs.get(""));
196177 #end
178+ #foreach ( $field in $class.getFields($version) )
179+ this.locations.put("${field.name}", newlocs.containsKey("${field.name}") ? newlocs.get("${field.name}") : oldlocs.get("${field.name}"));
180+ #end
197181 #end
198182 }
199183
@@ -406,7 +390,7 @@ public class ${class.name}
406390 InputLocation importedFrom;
407391 #end
408392
409- Builder(boolean withDefaults) {
393+ protected Builder(boolean withDefaults) {
410394 #if ( $class.superClass )
411395 super(withDefaults);
412396 #end
@@ -424,7 +408,7 @@ public class ${class.name}
424408 }
425409 }
426410
427- Builder(${class.name} base, boolean forceCopy) {
411+ protected Builder(${class.name} base, boolean forceCopy) {
428412 #if ( $class.superClass )
429413 super(base, forceCopy);
430414 #end
@@ -493,40 +477,15 @@ public class ${class.name}
493477 #end
494478 @Nonnull
495479 public ${class.name} build() {
480+ // this method should not contain any logic other than creating the object in order to ease subclassing
496481 if (base != null
497482 #foreach ( $field in $allFields )
498483 && (${field.name} == null || ${field.name} == base.${field.name})
499484 #end
500485 ) {
501486 return base;
502487 }
503- #if ( $locationTracking )
504- Map<Object, InputLocation> newlocs = this.locations != null ? this.locations : Collections.emptyMap();
505- Map<Object, InputLocation> oldlocs = this.base != null && this.base.locations != null ? this.base.locations : Collections.emptyMap();
506- Map<Object, InputLocation> locations = new HashMap<>();
507- locations.put("", newlocs.containsKey("") ? newlocs.get("") : oldlocs.get(""));
508- #foreach ( $field in $allFields )
509- locations.put("${field.name}", newlocs.containsKey("${field.name}") ? newlocs.get("${field.name}") : oldlocs.get("${field.name}"));
510- #end
511- #end
512- return new ${class.name}(
513- #if ( $class == $root )
514- namespaceUri != null ? namespaceUri : (base != null ? base.namespaceUri : ""),
515- modelEncoding != null ? modelEncoding : (base != null ? base.modelEncoding : "UTF-8"),
516- #end
517- #foreach ( $field in $allFields )
518- #set ( $sep = "#if(${locationTracking}||$field!=${allFields[${allFields.size()} - 1]}),#end" )
519- #if ( $field.type == "boolean" || $field.type == "int" )
520- ${field.name} != null ? ${field.name} : (base != null ? base.${field.name} : ${field.defaultValue})${sep}
521- #else
522- ${field.name} != null ? ${field.name} : (base != null ? base.${field.name} : null)${sep}
523- #end
524- #end
525- #if ( $locationTracking )
526- locations,
527- importedFrom
528- #end
529- );
488+ return new ${class.name}(this);
530489 }
531490 }
532491
0 commit comments