import static org.opendaylight.yangtools.yang.binding.BindingMapping.MODEL_BINDING_PROVIDER_CLASS_NAME
import static org.opendaylight.yangtools.yang.binding.BindingMapping.MODULE_INFO_CLASS_NAME
-import static org.opendaylight.yangtools.yang.binding.BindingMapping.getClassName
-import static org.opendaylight.yangtools.yang.binding.BindingMapping.getRootPackageName
+import static org.opendaylight.yangtools.yang.binding.BindingMapping.MODULE_INFO_QNAMEOF_METHOD_NAME
+import static extension org.opendaylight.yangtools.yang.binding.BindingMapping.getClassName
+import static extension org.opendaylight.yangtools.yang.binding.BindingMapping.getRootPackageName
import com.google.common.base.Preconditions
import com.google.common.collect.ImmutableSet
-import java.io.IOException
-import java.io.InputStream
-import java.text.DateFormat
-import java.text.SimpleDateFormat
import java.util.Collections
-import java.util.Date
+import java.util.Comparator
import java.util.HashSet
import java.util.LinkedHashMap
import java.util.Map
import java.util.Set
import java.util.TreeMap
import java.util.function.Function
-import org.eclipse.xtend.lib.Property
+import org.eclipse.xtend.lib.annotations.Accessors
import org.opendaylight.mdsal.binding.model.api.ParameterizedType
import org.opendaylight.mdsal.binding.model.api.Type
import org.opendaylight.mdsal.binding.model.api.WildcardType
import org.opendaylight.mdsal.binding.model.util.Types
+import org.opendaylight.yangtools.yang.binding.ResourceYangModuleInfo
import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider
import org.opendaylight.yangtools.yang.binding.YangModuleInfo
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.Revision
import org.opendaylight.yangtools.yang.model.api.Module
import org.opendaylight.yangtools.yang.model.api.SchemaContext
+/**
+ * Template for {@link YangModuleInfo} implementation for a particular module. Aside from fulfilling that contract,
+ * this class provides a static {@code createQName(String)} method, which is used by co-generated code to initialize
+ * QNAME constants.
+ */
class YangModuleInfoTemplate {
+ static val Comparator<Optional<Revision>> REVISION_COMPARATOR =
+ [ Optional<Revision> first, Optional<Revision> second | Revision.compare(first, second) ]
val Module module
val SchemaContext ctx
val Map<String, String> importMap = new LinkedHashMap()
val Function<Module, Optional<String>> moduleFilePathResolver
- @Property
- val String packageName;
+ @Accessors
+ val String packageName
- @Property
- val String modelBindingProviderName;
+ @Accessors
+ val String modelBindingProviderName
new(Module module, SchemaContext ctx, Function<Module, Optional<String>> moduleFilePathResolver) {
- Preconditions.checkArgument(module !== null, "Module must not be null.");
+ Preconditions.checkArgument(module !== null, "Module must not be null.")
this.module = module
this.ctx = ctx
this.moduleFilePathResolver = moduleFilePathResolver
- _packageName = getRootPackageName(module.getQNameModule());
- _modelBindingProviderName = '''«packageName».«MODEL_BINDING_PROVIDER_CLASS_NAME»''';
+ packageName = module.QNameModule.rootPackageName;
+ modelBindingProviderName = '''«packageName».«MODEL_BINDING_PROVIDER_CLASS_NAME»'''
}
def String generate() {
val body = '''
- public final class «MODULE_INFO_CLASS_NAME» implements «YangModuleInfo.importedName» {
-
+ public final class «MODULE_INFO_CLASS_NAME» extends «ResourceYangModuleInfo.importedName» {
+ «val rev = module.revision»
+ private static final «QName.importedName» NAME = «QName.importedName».create("«module.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF»"«module.name»").intern();
private static final «YangModuleInfo.importedName» INSTANCE = new «MODULE_INFO_CLASS_NAME»();
- private final «String.importedName» name = "«module.name»";
- private final «String.importedName» namespace = "«module.namespace.toString»";
- «val DateFormat df = new SimpleDateFormat("yyyy-MM-dd")»
- private final «String.importedName» revision = "«df.format(module.revision)»";
- private final «String.importedName» resourcePath = "«sourcePath(module)»";
-
- private final «Set.importedName»<YangModuleInfo> importedModules;
+ private final «Set.importedName»<«YangModuleInfo.importedName»> importedModules;
public static «YangModuleInfo.importedName» getInstance() {
return INSTANCE;
}
+ public static «QName.importedName» «MODULE_INFO_QNAMEOF_METHOD_NAME»(final «String.importedName» localName) {
+ return «QName.importedName».create(NAME, localName).intern();
+ }
+
«classBody(module, MODULE_INFO_CLASS_NAME)»
}
'''
return '''
- package «packageName» ;
+ package «packageName»;
+
«imports»
+
«body»
'''.toString
}
«FOR imp : m.imports»
«val name = imp.moduleName»
«val rev = imp.revision»
- «IF rev === null»
+ «IF !rev.present»
«val Set<Module> modules = ctx.modules»
- «val TreeMap<Date, Module> sorted = new TreeMap()»
+ «val TreeMap<Optional<Revision>, Module> sorted = new TreeMap(REVISION_COMPARATOR)»
«FOR module : modules»
«IF module.name.equals(name)»
«sorted.put(module.revision, module)»
«ENDIF»
«ENDFOR»
- set.add(«getRootPackageName(sorted.lastEntry().value.QNameModule)».«MODULE_INFO_CLASS_NAME».getInstance());
+ set.add(«sorted.lastEntry().value.QNameModule.rootPackageName».«MODULE_INFO_CLASS_NAME».getInstance());
«ELSE»
- set.add(«getRootPackageName((ctx.findModuleByName(name, rev).QNameModule))».«MODULE_INFO_CLASS_NAME».getInstance());
+ set.add(«(ctx.findModule(name, rev).get.QNameModule).rootPackageName».«MODULE_INFO_CLASS_NAME».getInstance());
«ENDIF»
«ENDFOR»
«ENDIF»
«IF !m.submodules.empty»
«FOR submodule : m.submodules»
- set.add(«getClassName(submodule.name)»Info.getInstance());
+ set.add(«submodule.name.className»Info.getInstance());
«ENDFOR»
«ENDIF»
«IF m.imports.empty && m.submodules.empty»
«ELSE»
importedModules = «ImmutableSet.importedName».copyOf(set);
«ENDIF»
-
- «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream(resourcePath);
- if (stream == null) {
- throw new IllegalStateException("Resource '" + resourcePath + "' is missing");
- }
- try {
- stream.close();
- } catch («IOException.importedName» e) {
- // Resource leak, but there is nothing we can do
- }
}
@Override
- public «String.importedName» getName() {
- return name;
+ public «QName.importedName» getName() {
+ return NAME;
}
@Override
- public «String.importedName» getRevision() {
- return revision;
- }
-
- @Override
- public «String.importedName» getNamespace() {
- return namespace;
- }
-
- @Override
- public «InputStream.importedName» getModuleSourceStream() throws IOException {
- «InputStream.importedName» stream = «MODULE_INFO_CLASS_NAME».class.getResourceAsStream(resourcePath);
- if (stream == null) {
- throw new «IOException.importedName»("Resource " + resourcePath + " is missing");
- }
- return stream;
+ protected «String.importedName» resourceName() {
+ return "«sourcePath(m)»";
}
@Override
return importedModules;
}
- @Override
- public «String.importedName» toString() {
- «StringBuilder.importedName» sb = new «StringBuilder.importedName»(this.getClass().getCanonicalName());
- sb.append("[");
- sb.append("name = " + name);
- sb.append(", namespace = " + namespace);
- sb.append(", revision = " + revision);
- sb.append(", resourcePath = " + resourcePath);
- sb.append(", imports = " + importedModules);
- sb.append("]");
- return sb.toString();
- }
-
«generateSubInfo(m)»
'''
private def imports() '''
«IF !importMap.empty»
«FOR entry : importMap.entrySet»
- «IF entry.value != getRootPackageName(module.QNameModule)»
+ «IF entry.value != module.QNameModule.rootPackageName»
import «entry.value».«entry.key»;
«ENDIF»
«ENDFOR»
final protected def importedName(Class<?> cls) {
val Type intype = Types.typeForClass(cls)
- putTypeIntoImports(intype);
- getExplicitType(intype)
+ putTypeIntoImports(intype)
+ intype.explicitType
}
final def void putTypeIntoImports(Type type) {
- val String typeName = type.getName();
- val String typePackageName = type.getPackageName();
- if (typePackageName.startsWith("java.lang") || typePackageName.isEmpty()) {
- return;
+ val String typeName = type.name
+ val String typePackageName = type.packageName
+ if (typePackageName.startsWith("java.lang") || typePackageName.empty) {
+ return
}
if (!importMap.containsKey(typeName)) {
- importMap.put(typeName, typePackageName);
+ importMap.put(typeName, typePackageName)
}
if (type instanceof ParameterizedType) {
- val Type[] params = type.getActualTypeArguments()
+ val Type[] params = type.actualTypeArguments
if (params !== null) {
for (Type param : params) {
- putTypeIntoImports(param);
+ putTypeIntoImports(param)
}
}
}
}
final def String getExplicitType(Type type) {
- val String typePackageName = type.getPackageName();
- val String typeName = type.getName();
- val String importedPackageName = importMap.get(typeName);
- var StringBuilder builder;
+ val String typePackageName = type.packageName
+ val String typeName = type.name
+ val String importedPackageName = importMap.get(typeName)
+ var StringBuilder builder
if (typePackageName.equals(importedPackageName)) {
- builder = new StringBuilder(type.getName());
+ builder = new StringBuilder(typeName)
if (builder.toString().equals("Void")) {
- return "void";
+ return "void"
}
- addActualTypeParameters(builder, type);
+ addActualTypeParameters(builder, type)
} else {
if (type.equals(Types.voidType())) {
- return "void";
+ return "void"
}
- builder = new StringBuilder();
- if (!typePackageName.isEmpty()) {
- builder.append(typePackageName + Constants.DOT + type.getName());
+ builder = new StringBuilder()
+ if (!typePackageName.empty) {
+ builder.append(typePackageName).append(Constants.DOT).append(typeName)
} else {
- builder.append(type.getName());
+ builder.append(typeName)
}
- addActualTypeParameters(builder, type);
+ addActualTypeParameters(builder, type)
}
- return builder.toString();
+ return builder.toString()
}
final def StringBuilder addActualTypeParameters(StringBuilder builder, Type type) {
if (type instanceof ParameterizedType) {
- val Type[] pTypes = type.getActualTypeArguments();
- builder.append('<');
- builder.append(getParameters(pTypes));
- builder.append('>');
+ val Type[] pTypes = type.actualTypeArguments
+ builder.append('<').append(getParameters(pTypes)).append('>')
}
- return builder;
+ return builder
}
final def String getParameters(Type[] pTypes) {
if (pTypes === null || pTypes.length == 0) {
- return "?";
+ return "?"
}
- val StringBuilder builder = new StringBuilder();
+ val StringBuilder builder = new StringBuilder()
- var int i = 0;
+ var int i = 0
for (pType : pTypes) {
val Type t = pTypes.get(i)
- var String separator = ",";
+ var String separator = ","
if (i == (pTypes.length - 1)) {
- separator = "";
+ separator = ""
}
- var String wildcardParam = "";
+ var String wildcardParam = ""
if (t.equals(Types.voidType())) {
- builder.append("java.lang.Void" + separator);
+ builder.append("java.lang.Void").append(separator)
} else {
if (t instanceof WildcardType) {
- wildcardParam = "? extends ";
+ wildcardParam = "? extends "
}
- builder.append(wildcardParam + getExplicitType(t) + separator);
+ builder.append(wildcardParam).append(t.explicitType).append(separator)
i = i + 1
}
}
- return builder.toString();
+ return builder.toString()
}
private def generateSubInfo(Module module) '''
«FOR submodule : module.submodules»
- private static final class «getClassName(submodule.name)»Info implements «YangModuleInfo.importedName» {
-
- private static final «YangModuleInfo.importedName» INSTANCE = new «getClassName(submodule.name)»Info();
-
- private final «String.importedName» name = "«submodule.name»";
- private final «String.importedName» namespace = "«submodule.namespace.toString»";
- «val DateFormat df = new SimpleDateFormat("yyyy-MM-dd")»
- private final «String.importedName» revision = "«df.format(submodule.revision)»";
- private final «String.importedName» resourcePath = "«sourcePath(submodule)»";
+ «val className = submodule.name.className»
+ private static final class «className»Info extends «ResourceYangModuleInfo.importedName» {
+ «val rev = submodule.revision»
+ private final «QName.importedName» NAME = «QName.importedName».create("«
+ submodule.namespace.toString»", «IF rev.present»"«rev.get.toString»", «ENDIF»"«submodule.name»").intern();
+ private static final «YangModuleInfo.importedName» INSTANCE = new «className»Info();
private final «Set.importedName»<YangModuleInfo> importedModules;
return INSTANCE;
}
- «classBody(submodule, getClassName(submodule.name + "Info"))»
+ «classBody(submodule, className + "Info")»
}
«ENDFOR»
'''
-
}