import java.util.HashSet
import java.util.Collection
import org.opendaylight.yangtools.yang.binding.Identifiable
+import com.google.common.collect.Range
+import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType
/**
* Template for generating JAVA builder classes.
* @param set of method signature instances which should be transformed to list of properties
* @return set of generated property instances which represents the getter <code>methods</code>
*/
- def private propertiesFromMethods(Set<MethodSignature> methods) {
+ def private propertiesFromMethods(Collection<MethodSignature> methods) {
if (methods == null || methods.isEmpty()) {
return Collections.emptySet
}
«generateFields(false)»
+ «generateAugmentField(true)»
+
«generateConstructorsFromIfcs(type)»
+ «generateCopyConstructor(false)»
+
«generateMethodFieldsFrom(type)»
«generateGetters(false)»
«generateFields(true)»
- «generateConstructor»
+ «generateAugmentField(false)»
+
+ «generateCopyConstructor(true)»
«generateGetters(true)»
/**
* Generate constructor with argument of given type.
*/
- def private generateConstructorFromIfc(Type impl) '''
+ def private Object generateConstructorFromIfc(Type impl) '''
«IF (impl instanceof GeneratedType)»
«val implType = impl as GeneratedType»
«ENDIF»
'''
- def private printConstructorPropertySetter(Type implementedIfc) '''
+ def private Object printConstructorPropertySetter(Type implementedIfc) '''
«IF (implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject))»
«val ifc = implementedIfc as GeneratedType»
«FOR getter : ifc.methodDefinitions»
return names
}
- /**
- * Template method which generates class attributes.
- *
- * @param boolean value which specify whether field is|isn't final
- * @return string with class attributes and their types
- */
+ /**
+ * Template method which generates class attributes.
+ *
+ * @param boolean value which specify whether field is|isn't final
+ * @return string with class attributes and their types
+ */
def private generateFields(boolean _final) '''
- «IF !properties.empty»
+ «IF properties !== null»
«FOR f : properties»
private«IF _final» final«ENDIF» «f.returnType.importedName» «f.fieldName»;
+ «val restrictions = f.returnType.restrictions»
+ «IF !_final && restrictions != null»
+ «IF !(restrictions.lengthConstraints.empty)»
+ private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_length;
+ «ENDIF»
+ «IF !(restrictions.rangeConstraints.empty)»
+ private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_range;
+ «ENDIF»
+ «ENDIF»
«ENDFOR»
«ENDIF»
+ '''
+
+ def private generateAugmentField(boolean init) '''
«IF augmentField != null»
- private «Map.importedName»<Class<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> «augmentField.name» = new «HashMap.importedName»<>();
+ private «Map.importedName»<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> «augmentField.name» = new «HashMap.importedName»<>();
«ENDIF»
'''
- /**
- * Template method which generates setter methods
- *
- * @return string with the setter methods
- */
+ /**
+ * Template method which generates setter methods
+ *
+ * @return string with the setter methods
+ */
def private generateSetters() '''
«FOR field : properties SEPARATOR '\n'»
+ «val length = field.fieldName + "_length"»
+ «val range = field.fieldName + "_range"»
public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) {
- «generateRestrictions(field, "value")»
-
+ «generateRestrictions(field, "value", length, range)»
this.«field.fieldName» = value;
return this;
}
+ «generateLengthMethod(length, field.returnType, type.name+BUILDER, length)»
+ «generateRangeMethod(range, field.returnType.restrictions, field.returnType, type.name+BUILDER, range)»
«ENDFOR»
«IF augmentField != null»
- public «type.name»«BUILDER» add«augmentField.name.toFirstUpper»(Class<? extends «augmentField.returnType.importedName»> augmentationType, «augmentField.returnType.importedName» augmentation) {
+ public «type.name»«BUILDER» add«augmentField.name.toFirstUpper»(«Class.importedName»<? extends «augmentField.returnType.importedName»> augmentationType, «augmentField.returnType.importedName» augmentation) {
this.«augmentField.name».put(augmentationType, augmentation);
return this;
}
«ENDIF»
'''
- /**
- * Template method which generate constructor for IMPL class.
- *
- * @return string with IMPL class constructor
- */
- def private generateConstructor() '''
- private «type.name»«IMPL»(«type.name»«BUILDER» builder) {
+ def generateRestrictions(GeneratedProperty field, String paramName, String lengthGetter, String rangeGetter) '''
+ «val Type type = field.returnType»
+ «IF type instanceof ConcreteType»
+ «createRestrictions(type, paramName, type.name.contains("["), lengthGetter, rangeGetter)»
+ «ELSEIF type instanceof GeneratedTransferObject»
+ «createRestrictions(type, paramName, isArrayType(type as GeneratedTransferObject), lengthGetter, rangeGetter)»
+ «ENDIF»
+ '''
+
+ def private createRestrictions(Type type, String paramName, boolean isArray, String lengthGetter, String rangeGetter) '''
+ «val restrictions = type.getRestrictions»
+ «IF restrictions !== null»
+ «val boolean isNestedType = !(type instanceof ConcreteType)»
+ «IF !restrictions.lengthConstraints.empty»
+ «generateLengthRestriction(type, paramName, lengthGetter, isNestedType, isArray)»
+ «ENDIF»
+ «IF !restrictions.rangeConstraints.empty»
+ «generateRangeRestriction(type, paramName, rangeGetter, isNestedType)»
+ «ENDIF»
+ «ENDIF»
+ '''
+
+ def private generateLengthRestriction(Type type, String paramName, String getterName, boolean isNestedType, boolean isArray) '''
+ «val restrictions = type.getRestrictions»
+ if («paramName» != null) {
+ «val clazz = restrictions.lengthConstraints.iterator.next.min.class»
+ «printLengthConstraint(type, clazz, paramName, isNestedType, isArray)»
+ boolean isValidLength = false;
+ for («Range.importedName»<«clazz.importedNumber»> r : «getterName»()) {
+ if (r.contains(_constraint)) {
+ isValidLength = true;
+ }
+ }
+ if (!isValidLength) {
+ throw new IllegalArgumentException(String.format("Invalid length: %s, expected: %s.", «paramName», «getterName»));
+ }
+ }
+ '''
+
+ def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType) '''
+ if («paramName» != null) {
+ «printRangeConstraint(type, paramName, isNestedType)»
+ boolean isValidRange = false;
+ for («Range.importedName»<«type.importedNumber»> r : «getterName»()) {
+ if (r.contains(_constraint)) {
+ isValidRange = true;
+ }
+ }
+ if (!isValidRange) {
+ throw new IllegalArgumentException(String.format("Invalid range: %s, expected: %s.", «paramName», «getterName»));
+ }
+ }
+ '''
+
+ def private CharSequence generateCopyConstructor(boolean impl) '''
+ «IF impl»private«ELSE»public«ENDIF» «type.name»«IF impl»«IMPL»«ELSE»«BUILDER»«ENDIF»(«type.name»«IF impl»«BUILDER»«ENDIF» base) {
«val allProps = new ArrayList(properties)»
«val isList = implementsIfc(type, Types.parameterizedTypeFor(Types.typeForClass(Identifiable), type))»
«val keyType = type.getKey»
«removeProperty(allProps, field.name)»
«ENDFOR»
«removeProperty(allProps, "key")»
- if (builder.getKey() == null) {
+ if (base.getKey() == null) {
this._key = new «keyType.importedName»(
«FOR keyProp : keyProps SEPARATOR ", "»
- builder.«keyProp.getterMethodName»()
+ base.«keyProp.getterMethodName»()
«ENDFOR»
);
«FOR field : keyProps»
- this.«field.fieldName» = builder.«field.getterMethodName»();
+ this.«field.fieldName» = base.«field.getterMethodName»();
«ENDFOR»
} else {
- this._key = builder.getKey();
+ this._key = base.getKey();
«FOR field : keyProps»
this.«field.fieldName» = _key.«field.getterMethodName»();
«ENDFOR»
}
«ENDIF»
«FOR field : allProps»
- this.«field.fieldName» = builder.«field.getterMethodName»();
+ this.«field.fieldName» = base.«field.getterMethodName»();
«ENDFOR»
«IF augmentField != null»
- this.«augmentField.name».putAll(builder.«augmentField.name»);
+ «IF !impl»if (base instanceof «type.name»«IMPL») {«ENDIF»
+ «IF !impl»«type.name»«IMPL» _impl = («type.name»«IMPL») base;«ENDIF»
+ «val prop = if (impl) "base" else "_impl"»
+ switch («prop».«augmentField.name».size()) {
+ case 0:
+ this.«augmentField.name» = «Collections.importedName».emptyMap();
+ break;
+ case 1:
+ final «Map.importedName».Entry<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»> e = «prop».«augmentField.name».entrySet().iterator().next();
+ this.«augmentField.name» = «Collections.importedName».<«Class.importedName»<? extends «augmentField.returnType.importedName»>, «augmentField.returnType.importedName»>singletonMap(e.getKey(), e.getValue());
+ break;
+ default :
+ this.«augmentField.name» = new «HashMap.importedName»<>(«prop».«augmentField.name»);
+ }
+ «IF !impl»}«ENDIF»
«ENDIF»
}
'''
@SuppressWarnings("unchecked")
«IF addOverride»@Override«ENDIF»
- public <E extends «augmentField.returnType.importedName»> E get«augmentField.name.toFirstUpper»(Class<E> augmentationType) {
+ public <E extends «augmentField.returnType.importedName»> E get«augmentField.name.toFirstUpper»(«Class.importedName»<E> augmentationType) {
if (augmentationType == null) {
throw new IllegalArgumentException("Augmentation Type reference cannot be NULL!");
}
def protected generateEquals() '''
«IF !properties.empty || augmentField != null»
@Override
- public boolean equals(java.lang.Object obj) {
+ public boolean equals(«Object.importedName» obj) {
if (this == obj) {
return true;
}
'''
def override generateToString(Collection<GeneratedProperty> properties) '''
- «IF !properties.empty»
+ «IF !(properties === null)»
@Override
- public String toString() {
- StringBuilder builder = new StringBuilder("«type.name» [");
+ public «String.importedName» toString() {
+ «StringBuilder.importedName» builder = new «StringBuilder.importedName» ("«type.name» [");
boolean first = true;
«FOR property : properties»