import com.google.common.base.CharMatcher
import com.google.common.base.Splitter
-import com.google.common.collect.ImmutableList
-import com.google.common.collect.Range
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Arrays
def packageDefinition() '''package «type.packageName»;'''
- protected def getFullyQualifiedName() {
- return type.fullyQualifiedName
- }
-
final public def generate() {
val _body = body()
'''
'''.toString
}
- protected def imports() '''
+ protected def imports() '''
«IF !importMap.empty»
«FOR entry : importMap.entrySet»
- «IF entry.value != fullyQualifiedName»
+ «IF !hasSamePackage(entry.value)»
import «entry.value».«entry.key»;
«ENDIF»
«ENDFOR»
'''
+ /**
+ * Checks if packages of generated type and imported type is the same
+ *
+ * @param importedTypePackageNam
+ * the package name of imported type
+ * @return true if the packages are the same false otherwise
+ */
+ final private def boolean hasSamePackage(String importedTypePackageName) {
+ return type.packageName.equals(importedTypePackageName);
+ }
+
protected abstract def CharSequence body();
// Helper patterns
/**
* Template method which generates the getter method for <code>field</code>
- *
- * @param field
+ *
+ * @param field
* generated property with data about field which is generated as the getter method
- * @return string with the getter method source code in JAVA format
+ * @return string with the getter method source code in JAVA format
*/
final protected def getterMethod(GeneratedProperty field) {
'''
/**
* Template method which generates the setter method for <code>field</code>
- *
- * @param field
+ *
+ * @param field
* generated property with data about field which is generated as the setter method
- * @return string with the setter method source code in JAVA format
+ * @return string with the setter method source code in JAVA format
*/
final protected def setterMethod(GeneratedProperty field) '''
«val returnType = field.returnType.importedName»
/**
* Template method which generates method parameters with their types from <code>parameters</code>.
- *
+ *
* @param parameters
* group of generated property instances which are transformed to the method parameters
* @return string with the list of the method parameters with their types in JAVA format
/**
* Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
- *
- * @param parameters
+ *
+ * @param parameters
* group of generated property instances which are transformed to the sequence of parameter names
- * @return string with the list of the parameter names of the <code>parameters</code>
+ * @return string with the list of the parameter names of the <code>parameters</code>
*/
def final protected asArguments(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
fieldName»«ENDFOR»«ENDIF»'''
/**
* Template method which generates JAVA comments.
- *
+ *
* @param comment string with the comment for whole JAVA class
* @return string with comment in JAVA format
*/
sb.append(NEW_LINE)
for (String t : NL_SPLITTER.split(text)) {
- sb.append(" * ")
- sb.append(t)
+ sb.append(" *")
+ if (!t.isEmpty()) {
+ sb.append(' ');
+ sb.append(t)
+ }
sb.append(NEW_LINE)
}
sb.append(" */")
return sb.toString
}
- def generateRestrictions(Type type, String paramName, Type returnType) '''
- «val restrictions = type.getRestrictions»
- «IF restrictions !== null»
- «val boolean isNestedType = !(returnType instanceof ConcreteType)»
- «IF !restrictions.lengthConstraints.empty»
- «generateLengthRestriction(returnType, restrictions, paramName, isNestedType)»
- «ENDIF»
- «IF !restrictions.rangeConstraints.empty»
- «generateRangeRestriction(returnType, paramName, isNestedType)»
- «ENDIF»
- «ENDIF»
- '''
-
- def private generateLengthRestriction(Type returnType, Restrictions restrictions, String paramName, boolean isNestedType) '''
- «val clazz = restrictions.lengthConstraints.iterator.next.min.class»
- if («paramName» != null) {
- «printLengthConstraint(returnType, clazz, paramName, isNestedType, returnType.name.contains("["))»
- boolean isValidLength = false;
- for («Range.importedName»<«clazz.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»length()) {
- if (r.contains(_constraint)) {
- isValidLength = true;
- }
- }
- if (!isValidLength) {
- throw new IllegalArgumentException(String.format("Invalid length: %s, expected: %s.", «paramName», «IF isNestedType»«returnType.importedName».«ENDIF»length()));
- }
- }
- '''
-
- def private generateRangeRestriction(Type returnType, String paramName, boolean isNestedType) '''
- if («paramName» != null) {
- «printRangeConstraint(returnType, paramName, isNestedType)»
- boolean isValidRange = false;
- for («Range.importedName»<«returnType.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) {
- if (r.contains(_constraint)) {
- isValidRange = true;
- }
- }
- if (!isValidRange) {
- throw new IllegalArgumentException(String.format("Invalid range: %s, expected: %s.", «paramName», «IF isNestedType»«returnType.importedName».«ENDIF»range()));
- }
- }
- '''
-
- /**
- * Print length constraint.
- * This should always be a BigInteger (only string and binary can have length restriction)
- */
- def printLengthConstraint(Type returnType, Class<? extends Number> clazz, String paramName, boolean isNestedType, boolean isArray) '''
- «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»«IF isNestedType».getValue()«ENDIF».length«IF !isArray»()«ENDIF»);
- '''
-
- def printRangeConstraint(Type returnType, String paramName, boolean isNestedType) '''
- «IF BigDecimal.canonicalName.equals(returnType.fullyQualifiedName)»
- «BigDecimal.importedName» _constraint = new «BigDecimal.importedName»(«paramName»«IF isNestedType».getValue()«ENDIF».toString());
- «ELSE»
- «IF isNestedType»
- «val propReturnType = findProperty(returnType as GeneratedTransferObject, "value").returnType»
- «IF propReturnType.fullyQualifiedName.equals(BigInteger.canonicalName)»
- «BigInteger.importedName» _constraint = «paramName».getValue();
- «ELSE»
- «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName».getValue());
- «ENDIF»
- «ELSE»
- «IF returnType.fullyQualifiedName.equals(BigInteger.canonicalName)»
- «BigInteger.importedName» _constraint = «paramName»;
- «ELSE»
- «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName»);
- «ENDIF»
- «ENDIF»
- «ENDIF»
- '''
-
def protected generateToString(Collection<GeneratedProperty> properties) '''
«IF !properties.empty»
@Override
def getRestrictions(Type type) {
var Restrictions restrictions = null
if (type instanceof ConcreteType) {
- restrictions = (type as ConcreteType).restrictions
+ restrictions = type.restrictions
} else if (type instanceof GeneratedTransferObject) {
- restrictions = (type as GeneratedTransferObject).restrictions
+ restrictions = type.restrictions
}
return restrictions
}
- def boolean isArrayType(GeneratedTransferObject type) {
- var isArray = false
- val GeneratedProperty value = findProperty(type, "value")
- if (value != null && value.returnType.name.contains("[")) {
- isArray = true
- }
- return isArray
- }
-
- def String toQuote(Object obj) {
- return "\"" + obj.toString + "\"";
- }
-
/**
* Template method which generates method parameters with their types from <code>parameters</code>.
- *
+ *
* @param parameters
* list of parameter instances which are transformed to the method parameters
* @return string with the list of the method parameters with their types in JAVA format
ENDIF
»'''
- def protected generateLengthMethod(String methodName, Type type, String className, String varName) '''
- «val Restrictions restrictions = type.restrictions»
- «IF restrictions != null && !(restrictions.lengthConstraints.empty)»
- «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
- public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
- «IF numberClass.equals(typeof(BigDecimal))»
- «lengthBody(restrictions, numberClass, className, varName)»
- «ELSE»
- «lengthBody(restrictions, typeof(BigInteger), className, varName)»
- «ENDIF»
- }
- «ENDIF»
- '''
-
- def private lengthBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
- if («varName» == null) {
- synchronized («className».class) {
- if («varName» == null) {
- «ImmutableList.importedName».Builder<«Range.importedName»<«numberClass.importedName»>> builder = «ImmutableList.importedName».builder();
- «FOR r : restrictions.lengthConstraints»
- builder.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
- «ENDFOR»
- «varName» = builder.build();
- }
- }
- }
- return «varName»;
- '''
-
- def protected generateRangeMethod(String methodName, Restrictions restrictions, Type returnType, String className, String varName) '''
- «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
- «val number = returnType.importedNumber»
- public static «List.importedName»<«Range.importedName»<«number»>> «methodName»() {
- «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
- «rangeBody(restrictions, BigDecimal, className, varName)»
- «ELSE»
- «rangeBody(restrictions, BigInteger, className, varName)»
- «ENDIF»
- }
- «ENDIF»
- '''
-
- def protected generateRangeMethod(String methodName, Restrictions restrictions, String className, String varName, Iterable<GeneratedProperty> properties) '''
- «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
- «val returnType = properties.iterator.next.returnType»
- public static «List.importedName»<«Range.importedName»<«returnType.importedNumber»>> «methodName»() {
- «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
- «rangeBody(restrictions, BigDecimal, className, varName)»
- «ELSE»
- «rangeBody(restrictions, BigInteger, className, varName)»
- «ENDIF»
- }
- «ENDIF»
- '''
-
- def private rangeBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
- if («varName» == null) {
- synchronized («className».class) {
- if («varName» == null) {
- «ImmutableList.importedName».Builder<«Range.importedName»<«numberClass.importedName»>> builder = «ImmutableList.importedName».builder();
- «FOR r : restrictions.rangeConstraints»
- builder.add(«Range.importedName».closed(«numericValue(numberClass, r.min)», «numericValue(numberClass, r.max)»));
- «ENDFOR»
- «varName» = builder.build();
- }
- }
- }
- return «varName»;
- '''
-
+ @Deprecated
def protected String importedNumber(Class<? extends Number> clazz) {
if (clazz.equals(typeof(BigDecimal))) {
return BigDecimal.importedName
return BigInteger.importedName
}
+ @Deprecated
def protected String importedNumber(Type clazz) {
if (clazz.fullyQualifiedName.equals(BigDecimal.canonicalName)) {
return BigDecimal.importedName
return BigInteger.importedName
}
+ @Deprecated
def protected String numericValue(Class<? extends Number> clazz, Object numberValue) {
val number = clazz.importedName;
val value = numberValue.toString
return "new " + number + "(\"" + value + "\")"
}
- def private GeneratedProperty findProperty(GeneratedTransferObject gto, String name) {
+ def protected GeneratedProperty findProperty(GeneratedTransferObject gto, String name) {
val props = gto.properties
for (prop : props) {
if (prop.name.equals(name)) {