From: Robert Varga Date: Thu, 1 Mar 2018 23:23:38 +0000 (+0100) Subject: Split out JavaFileTemplate X-Git-Tag: release/fluorine~305 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F79%2F68979%2F3;p=mdsal.git Split out JavaFileTemplate This is a useful piece with a bit of logic. Separate it out into Java, where maintenance is easier. This forces us to define operations on import map, which is always good. Change-Id: Idf279352c57a96112b235f700ec7e910bf886461 Signed-off-by: Robert Varga --- diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BaseTemplate.xtend b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BaseTemplate.xtend index 832a436cbd..c02a2d2960 100644 --- a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BaseTemplate.xtend +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BaseTemplate.xtend @@ -14,19 +14,13 @@ import com.google.common.base.Splitter import com.google.common.collect.Iterables 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 java.util.regex.Pattern -import org.opendaylight.mdsal.binding.model.api.ConcreteType import org.opendaylight.mdsal.binding.model.api.Constant import org.opendaylight.mdsal.binding.model.api.GeneratedProperty -import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject import org.opendaylight.mdsal.binding.model.api.GeneratedType import org.opendaylight.mdsal.binding.model.api.MethodSignature -import org.opendaylight.mdsal.binding.model.api.Restrictions -import org.opendaylight.mdsal.binding.model.api.Type import org.opendaylight.mdsal.binding.model.api.TypeMember import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition.Single import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition.Multiple @@ -39,10 +33,7 @@ import org.opendaylight.yangtools.yang.model.api.NotificationDefinition import org.opendaylight.yangtools.yang.model.api.RpcDefinition import org.opendaylight.yangtools.yang.model.api.SchemaNode -abstract class BaseTemplate { - protected val Map importMap = new HashMap() - protected val GeneratedType type; - +abstract class BaseTemplate extends JavaFileTemplate { private static final char NEW_LINE = '\n' private static val AMP_MATCHER = CharMatcher.is('&') private static val NL_MATCHER = CharMatcher.is(NEW_LINE) @@ -51,47 +42,20 @@ abstract class BaseTemplate { private static val NL_SPLITTER = Splitter.on(NL_MATCHER) private static val TAIL_COMMENT_PATTERN = Pattern.compile("*/", Pattern.LITERAL); - new(GeneratedType _type) { - if (_type === null) { - throw new IllegalArgumentException("Generated type reference cannot be NULL!") - } - this.type = _type; + new(GeneratedType type) { + super(type) } - def packageDefinition() '''package «type.packageName»;''' - final public def generate() { val _body = body() ''' - «packageDefinition» - «imports» + package «type.packageName»; + «generateImportBlock» «_body» '''.toString } - protected def imports() ''' - «FOR entry : importMap.entrySet» - «IF !hasSamePackage(entry.value) && !isLocalInnerClass(entry.value)» - import «entry.value».«entry.key»; - «ENDIF» - «ENDFOR» - ''' - - /** - * Checks if packages of generated type and imported type is the same - * - * @param importedTypePackageName 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); - } - - def isLocalInnerClass(String importedTypePackageName) { - return type.fullyQualifiedName.equals(importedTypePackageName); - } - protected abstract def CharSequence body(); // Helper patterns @@ -152,15 +116,6 @@ abstract class BaseTemplate { } ''' - final protected def importedName(Type intype) { - GeneratorUtil.putTypeIntoImports(type, intype, importMap); - GeneratorUtil.getExplicitType(type, intype, importMap) - } - - final protected def importedName(Class cls) { - importedName(Types.typeForClass(cls)) - } - /** * Template method which generates method parameters with their types from parameters. * @@ -450,16 +405,6 @@ abstract class BaseTemplate { «ENDIF» ''' - def getRestrictions(Type type) { - var Restrictions restrictions = null - if (type instanceof ConcreteType) { - restrictions = type.restrictions - } else if (type instanceof GeneratedTransferObject) { - restrictions = type.restrictions - } - return restrictions - } - /** * Template method which generates method parameters with their types from parameters. * @@ -475,20 +420,6 @@ abstract class BaseTemplate { ENDIF »''' - def protected GeneratedProperty findProperty(GeneratedTransferObject gto, String name) { - val props = gto.properties - for (prop : props) { - if (prop.name.equals(name)) { - return prop - } - } - val GeneratedTransferObject parent = gto.superType - if (parent !== null) { - return findProperty(parent, name) - } - return null - } - def protected emitConstant(Constant c) ''' «IF c.value instanceof QName» «val qname = c.value as QName» diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend index 6113ce9334..4f5049915c 100644 --- a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend @@ -80,7 +80,7 @@ class BuilderTemplate extends BaseTemplate { new(GeneratedType genType) { super(genType) this.properties = propertiesFromMethods(createMethods) - importMap.put(Builder.simpleName, Builder.package.name) + addImport(Builder.simpleName, Builder.package.name) } /** diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend index e732521c94..28f8adaee3 100644 --- a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend @@ -126,11 +126,11 @@ class InterfaceTemplate extends BaseTemplate { «IF innerClass.unionType» «val unionTemplate = new UnionTemplate(innerClass)» «unionTemplate.generateAsInnerClass» - «this.importMap.putAll(unionTemplate.importMap)» + «addImports(unionTemplate)» «ELSE» «val classTemplate = new ClassTemplate(innerClass)» «classTemplate.generateAsInnerClass» - «this.importMap.putAll(classTemplate.importMap)» + «addImports(classTemplate)» «ENDIF» «ENDIF» diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileTemplate.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileTemplate.java new file mode 100644 index 0000000000..b0d3c31644 --- /dev/null +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/JavaFileTemplate.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.java.api.generator; + +import static java.util.Objects.requireNonNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.opendaylight.mdsal.binding.model.api.ConcreteType; +import org.opendaylight.mdsal.binding.model.api.GeneratedProperty; +import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.mdsal.binding.model.api.GeneratedType; +import org.opendaylight.mdsal.binding.model.api.Restrictions; +import org.opendaylight.mdsal.binding.model.api.Type; +import org.opendaylight.mdsal.binding.model.util.Types; + +/** + * Base Java file template. Contains a non-null type and imports which the generated code refers to. + */ +class JavaFileTemplate { + // Hidden to well-define operations + private final Map importMap = new HashMap<>(); + + protected final GeneratedType type; + + JavaFileTemplate(final GeneratedType type) { + this.type = requireNonNull(type); + } + + final GeneratedProperty findProperty(final GeneratedTransferObject gto, final String name) { + final Optional optProp = gto.getProperties().stream() + .filter(prop -> prop.getName().equals(name)).findFirst(); + if (optProp.isPresent()) { + return optProp.get(); + } + + final GeneratedTransferObject parent = gto.getSuperType(); + return parent != null ? findProperty(parent, name) : null; + } + + static final Restrictions getRestrictions(final Type type) { + if (type instanceof ConcreteType) { + return ((ConcreteType)type).getRestrictions(); + } + if (type instanceof GeneratedTransferObject) { + return ((GeneratedTransferObject)type).getRestrictions(); + } + return null; + } + + final String generateImportBlock() { + return importMap.entrySet().stream() + .filter(e -> isDefaultVisible(e.getValue())) + .sorted((e1, e2) -> { + final int cmp = e1.getValue().compareTo(e2.getValue()); + return cmp != 0 ? cmp : e1.getKey().compareTo(e2.getKey()); + }) + .map(e -> "import " + e.getValue() + "." + e.getKey() + ";\n") + .collect(Collectors.joining()); + } + + final String importedName(final Type intype) { + GeneratorUtil.putTypeIntoImports(type, intype, importMap); + return GeneratorUtil.getExplicitType(type, intype, importMap); + } + + final String importedName(final Class cls) { + return importedName(Types.typeForClass(cls)); + } + + final void addImport(final String className, final String packageName) { + importMap.put(className, packageName); + } + + final void addImports(final JavaFileTemplate from) { + importMap.putAll(from.importMap); + } + + // Exposed for BuilderTemplate + boolean isLocalInnerClass(final String importedTypePackageName) { + return type.getFullyQualifiedName().equals(importedTypePackageName); + } + + private boolean isDefaultVisible(final String prefix) { + return !hasSamePackage(prefix) || !isLocalInnerClass(prefix); + } + + /** + * Checks if packages of generated type and imported type is the same + * + * @param importedTypePackageName the package name of imported type + * @return true if the packages are the same false otherwise + */ + private boolean hasSamePackage(final String importedTypePackageName) { + return type.getPackageName().equals(importedTypePackageName); + } +} diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/UnionTemplate.xtend b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/UnionTemplate.xtend index fa718d366e..3c7444e527 100644 --- a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/UnionTemplate.xtend +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/UnionTemplate.xtend @@ -29,8 +29,8 @@ class UnionTemplate extends ClassTemplate { */ new(GeneratedTransferObject genType) { super(genType) - if(isBaseEncodingImportRequired) { - this.importMap.put("BaseEncoding","com.google.common.io") + if (isBaseEncodingImportRequired) { + addImport("BaseEncoding","com.google.common.io") } }