*/
package org.opendaylight.yangtools.sal.java.api.generator
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import java.util.Map
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.binding.generator.util.Types
-import com.google.common.base.Splitter
-import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
+import com.google.common.collect.ImmutableList
import com.google.common.collect.Range
+import java.math.BigDecimal
+import java.math.BigInteger
+import java.util.Arrays
+import java.util.Collection
+import java.util.HashMap
import java.util.List
+import java.util.Map
+import java.util.StringTokenizer
+import org.opendaylight.yangtools.binding.generator.util.Types
import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType
-import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
-import java.util.Collection
-import java.util.Arrays
-import java.util.HashMap
-import com.google.common.collect.ImmutableList
-import java.math.BigInteger
-import java.math.BigDecimal
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
+import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
+import org.opendaylight.yangtools.sal.binding.model.api.Type
abstract class BaseTemplate {
protected val GeneratedType type;
protected val Map<String, String> importMap;
- static val paragraphSplitter = Splitter.on("\n\n").omitEmptyStrings();
+
+ private static final String NEW_LINE = '\n'
new(GeneratedType _type) {
if (_type == null) {
'''
«packageDefinition»
«imports»
-
+
«_body»
'''.toString
}
«ENDIF»
«ENDFOR»
«ENDIF»
-
+
'''
protected abstract def CharSequence body();
* @return string with comment in JAVA format
*/
def protected CharSequence asJavadoc(String comment) {
- if(comment == null) return '';
+ if(comment == null) return ''
var txt = comment
- if (txt.contains("*/")) {
- txt = txt.replace("*/", "*/")
- }
- val paragraphs = paragraphSplitter.split(txt)
+
+ txt = comment.trim
+ txt = formatToParagraph(txt)
return '''
- /**
- «FOR p : paragraphs SEPARATOR "<p>"»
- «p»
- «ENDFOR»
- **/
+ «wrapToDocumentation(txt)»
'''
}
+ def String wrapToDocumentation(String text) {
+ val StringTokenizer tokenizer = new StringTokenizer(text, "\n", false)
+ val StringBuilder sb = new StringBuilder()
+
+ if(text.empty)
+ return ""
+
+ sb.append("/**")
+ sb.append(NEW_LINE)
+
+ while(tokenizer.hasMoreTokens) {
+ sb.append(" * ")
+ sb.append(tokenizer.nextToken)
+ sb.append(NEW_LINE)
+ }
+ sb.append(" */")
+
+ return sb.toString
+ }
+
+ def protected String formatDataForJavaDoc(GeneratedType type) {
+ val typeDescription = type.getDescription().encodeJavadocSymbols;
+
+ return '''
+ «IF !typeDescription.nullOrEmpty»
+ «typeDescription»
+ «ENDIF»
+ '''.toString
+ }
+
+ def encodeJavadocSymbols(String description) {
+ if (!description.nullOrEmpty) {
+ return description.replace("*/", "*/")
+ }
+ return description;
+ }
+
+ def asLink(String text) {
+ val StringBuilder sb = new StringBuilder()
+ var tempText = text
+ var char lastChar = ' '
+ var boolean badEnding = false
+
+ if(text.endsWith(".") || text.endsWith(":") || text.endsWith(",")) {
+ tempText = text.substring(0, text.length - 1)
+ lastChar = text.charAt(text.length - 1)
+ badEnding = true
+ }
+ sb.append("<a href = \"")
+ sb.append(tempText)
+ sb.append("\">")
+ sb.append(tempText)
+ sb.append("</a>")
+
+ if(badEnding)
+ sb.append(lastChar)
+
+ return sb.toString
+ }
+
+ protected def formatToParagraph(String text) {
+ if(text == null || text.isEmpty)
+ return text
+
+ var formattedText = text
+ val StringBuilder sb = new StringBuilder();
+ var StringBuilder lineBuilder = new StringBuilder();
+ var boolean isFirstElementOnNewLineEmptyChar = false;
+
+ formattedText = formattedText.encodeJavadocSymbols
+ formattedText = formattedText.replace(NEW_LINE, "")
+ formattedText = formattedText.replace("\t", "")
+ formattedText = formattedText.replaceAll(" +", " ");
+
+ val StringTokenizer tokenizer = new StringTokenizer(formattedText, " ", true);
+
+ while(tokenizer.hasMoreElements) {
+ val nextElement = tokenizer.nextElement.toString
+
+ if(lineBuilder.length + nextElement.length > 80) {
+ if (lineBuilder.charAt(lineBuilder.length - 1) == ' ') {
+ lineBuilder.setLength(0)
+ lineBuilder.append(lineBuilder.substring(0, lineBuilder.length - 1))
+ }
+ if (lineBuilder.charAt(0) == ' ') {
+ lineBuilder.setLength(0)
+ lineBuilder.append(lineBuilder.substring(1))
+ }
+
+ sb.append(lineBuilder);
+ lineBuilder.setLength(0)
+ sb.append(NEW_LINE)
+
+ if(nextElement.toString == ' ') {
+ isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar;
+ }
+ }
+
+ if(isFirstElementOnNewLineEmptyChar) {
+ isFirstElementOnNewLineEmptyChar = !isFirstElementOnNewLineEmptyChar
+ }
+
+ else {
+ lineBuilder.append(nextElement)
+ }
+ }
+ sb.append(lineBuilder)
+ sb.append(NEW_LINE)
+
+ return sb.toString
+ }
+
+ def isDocumentationParametersNullOrEmtpy(GeneratedType type) {
+ val boolean isTypeDescriptionNullOrEmpty = type.description.nullOrEmpty
+ val boolean isTypeReferenceNullOrEmpty = type.reference.nullOrEmpty
+ val boolean isTypeModuleNameNullOrEmpty = type.moduleName.nullOrEmpty
+ val boolean isTypeSchemaPathNullOrEmpty = type.schemaPath.nullOrEmpty
+
+ if (isTypeDescriptionNullOrEmpty && isTypeReferenceNullOrEmpty && isTypeModuleNameNullOrEmpty
+ && isTypeSchemaPathNullOrEmpty) {
+ return true
+ }
+ return false
+ }
+
def generateRestrictions(Type type, String paramName, Type returnType) '''
«val restrictions = type.getRestrictions»
«IF restrictions !== null»
«generateLengthRestriction(returnType, restrictions, paramName, isNestedType)»
«ENDIF»
«IF !restrictions.rangeConstraints.empty»
- «generateRangeRestriction(returnType, restrictions, paramName, isNestedType)»
+ «generateRangeRestriction(returnType, paramName, isNestedType)»
«ENDIF»
«ENDIF»
'''
}
'''
- def private generateRangeRestriction(Type returnType, Restrictions restrictions, String paramName, boolean isNestedType) '''
- «val clazz = restrictions.rangeConstraints.iterator.next.min.class»
+ def private generateRangeRestriction(Type returnType, String paramName, boolean isNestedType) '''
if («paramName» != null) {
- «printRangeConstraint(returnType, clazz, paramName, isNestedType)»
+ «printRangeConstraint(returnType, paramName, isNestedType)»
boolean isValidRange = false;
- for («Range.importedName»<«clazz.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) {
+ for («Range.importedName»<«returnType.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) {
if (r.contains(_constraint)) {
isValidRange = true;
}
«clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»«IF isNestedType».getValue()«ENDIF».length«IF !isArray»()«ENDIF»);
'''
- def printRangeConstraint(Type returnType, Class<? extends Number> clazz, String paramName, boolean isNestedType) '''
- «IF clazz.canonicalName.equals(BigDecimal.canonicalName)»
- «clazz.importedNumber» _constraint = new «clazz.importedNumber»(«paramName»«IF isNestedType».getValue()«ENDIF».toString());
+ 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)»
- «clazz.importedNumber» _constraint = «paramName».getValue();
+ «BigInteger.importedName» _constraint = «paramName».getValue();
«ELSE»
- «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName».getValue());
+ «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName».getValue());
«ENDIF»
«ELSE»
«IF returnType.fullyQualifiedName.equals(BigInteger.canonicalName)»
- «clazz.importedNumber» _constraint = «paramName»;
+ «BigInteger.importedName» _constraint = «paramName»;
«ELSE»
- «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»);
+ «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName»);
«ENDIF»
«ENDIF»
«ENDIF»
«IF !properties.empty»
@Override
public «String.importedName» toString() {
- «StringBuilder.importedName» builder = new «StringBuilder.importedName»("«type.name» [");
+ «StringBuilder.importedName» builder = new «StringBuilder.importedName»(«type.importedName».class.getSimpleName()).append(" [");
boolean first = true;
«FOR property : properties»
«ENDIF»
'''
- def GeneratedProperty getPropByName(GeneratedType gt, String name) {
- for (GeneratedProperty prop : gt.properties) {
- if (prop.name.equals(name)) {
- return prop;
- }
- }
- return null;
- }
-
def getRestrictions(Type type) {
var Restrictions restrictions = null
if (type instanceof ConcreteType) {
«val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
«IF numberClass.equals(typeof(BigDecimal))»
- «lengthMethodBody(restrictions, numberClass, className, varName)»
+ «lengthBody(restrictions, numberClass, className, varName)»
«ELSE»
- «lengthMethodBody(restrictions, typeof(BigInteger), className, varName)»
+ «lengthBody(restrictions, typeof(BigInteger), className, varName)»
«ENDIF»
}
«ENDIF»
'''
- def private lengthMethodBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+ def private lengthBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
if («varName» == null) {
synchronized («className».class) {
if («varName» == null) {
return «varName»;
'''
- def protected generateRangeMethod(String methodName, Type type, String className, String varName) '''
- «val Restrictions restrictions = type.restrictions»
+ def protected generateRangeMethod(String methodName, Restrictions restrictions, Type returnType, String className, String varName) '''
«IF restrictions != null && !(restrictions.rangeConstraints.empty)»
- «val numberClass = restrictions.rangeConstraints.iterator.next.min.class»
- public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
- «IF numberClass.equals(typeof(BigDecimal))»
- «rangeMethodBody(restrictions, numberClass, className, varName)»
+ «val number = returnType.importedNumber»
+ public static «List.importedName»<«Range.importedName»<«number»>> «methodName»() {
+ «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
+ «rangeBody(restrictions, BigDecimal, className, varName)»
«ELSE»
- «rangeMethodBody(restrictions, typeof(BigInteger), className, varName)»
+ «rangeBody(restrictions, BigInteger, className, varName)»
«ENDIF»
}
«ENDIF»
'''
- def private rangeMethodBody(Restrictions restrictions, Class<? extends Number> numberClass, String className, String varName) '''
+ 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) {
return BigInteger.importedName
}
- def private String numericValue(Class<? extends Number> clazz, Object numberValue) {
+ def protected String importedNumber(Type clazz) {
+ if (clazz.fullyQualifiedName.equals(BigDecimal.canonicalName)) {
+ return BigDecimal.importedName
+ }
+ return BigInteger.importedName
+ }
+
+ def protected String numericValue(Class<? extends Number> clazz, Object numberValue) {
val number = clazz.importedName;
val value = numberValue.toString
if (clazz.equals(typeof(BigInteger)) || clazz.equals(typeof(BigDecimal))) {