Bug 1411-5 #8: MDSAL Binding2 Java API Generator 98/46898/20
authorMartin Ciglan <mciglan@cisco.com>
Thu, 8 Dec 2016 09:02:11 +0000 (10:02 +0100)
committerRobert Varga <nite@hq.sk>
Tue, 10 Jan 2017 21:46:35 +0000 (21:46 +0000)
- union and union builder renderers and templates
- bit of a cleanup

Change-Id: I413bf4f284d5f3151436f5a96e31e4c7ada0c021
Signed-off-by: Filip Gregor <fgregor@cisco.com>
Signed-off-by: Martin Ciglan <mciglan@cisco.com>
binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionBuilderRenderer.java [new file with mode: 0644]
binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionRenderer.java [new file with mode: 0644]
binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionBuilderTemplate.scala.txt [new file with mode: 0644]
binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionTemplate.scala.txt [new file with mode: 0644]

diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionBuilderRenderer.java b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionBuilderRenderer.java
new file mode 100644 (file)
index 0000000..f6d54c9
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.binding2.java.api.generator.renderers;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.mdsal.binding2.model.api.GeneratedTransferObject;
+import org.opendaylight.mdsal.binding2.model.api.MethodSignature;
+import org.opendaylight.mdsal.binding2.txt.unionBuilderTemplate;
+
+public class UnionBuilderRenderer extends ClassRenderer {
+    /**
+     * list of all imported names for template
+     */
+    private final Map<String, String> importedNames = new HashMap<>();
+    private final Map<String, String> generatedParameters = new HashMap<>();
+
+    public UnionBuilderRenderer(final GeneratedTransferObject type) {
+        super(type);
+    }
+
+    protected String body() {
+        importedNames.put("unsupportedOperationException", importedName(UnsupportedOperationException.class));
+        for (MethodSignature methodSignature : genTO.getMethodDefinitions()) {
+            importedNames.put(methodSignature.getName(), importedName(methodSignature.getReturnType()));
+            generatedParameters.put(methodSignature.getName(), generateParameters(methodSignature.getParameters()));
+        }
+        return unionBuilderTemplate.render(genTO, getType().getName(), importedNames, generatedParameters).body();
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionRenderer.java b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionRenderer.java
new file mode 100644 (file)
index 0000000..4d239cf
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.binding2.java.api.generator.renderers;
+
+import static org.opendaylight.mdsal.binding2.generator.util.Types.BOOLEAN;
+import static org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.fieldName;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import java.beans.ConstructorProperties;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.mdsal.binding2.model.api.Enumeration;
+import org.opendaylight.mdsal.binding2.model.api.GeneratedProperty;
+import org.opendaylight.mdsal.binding2.model.api.GeneratedTransferObject;
+import org.opendaylight.mdsal.binding2.model.api.Type;
+import org.opendaylight.mdsal.binding2.txt.unionTemplate;
+
+public class UnionRenderer extends ClassRenderer {
+    /**
+     * list of all imported names for template
+     */
+    private final Map<String, String> importedNames = new HashMap<>();
+
+    public UnionRenderer(final GeneratedTransferObject type) {
+        super(type);
+    }
+
+    @Override
+    protected String generateConstructors() {
+        if(isBaseEncodingImportRequired()) {
+            this.putToImportMap("BaseEncoding","com.google.common.io");
+        }
+        for (GeneratedProperty finalProperty : getFinalProperties()) {
+            importedNames.put("constructorProperties", importedName(ConstructorProperties.class));
+            importedNames.put("string", importedName(String.class));
+            importedNames.put(finalProperty.getName(), importedName(finalProperty.getReturnType()));
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        if (!getProperties().isEmpty()) {
+            for (GeneratedProperty property : getProperties()) {
+                sb.append(generateField(property));
+            }
+        }
+
+        if (getProperties().isEmpty() && !getParentProperties().isEmpty()) {
+            importedNames.put("superType", importedName(genTO.getSuperType()));
+        }
+
+        for (GeneratedProperty parentProperty : getParentProperties()) {
+            importedNames.put(parentProperty.getName(), importedName(parentProperty.getReturnType()));
+        }
+
+        return unionTemplate.render(getType(), importedNames, getFinalProperties(), getParentProperties(),
+                getProperties(), sb.toString()).body();
+    }
+
+    private boolean isBaseEncodingImportRequired() {
+        for (GeneratedProperty property : getFinalProperties()) {
+            final Type returnType = property.getReturnType();
+            if (returnType instanceof GeneratedTransferObject) {
+                final GeneratedTransferObject returnTypeGto = (GeneratedTransferObject)returnType;
+                if (returnTypeGto.isTypedef() && returnTypeGto.getProperties() != null &&
+                        !returnTypeGto.getProperties().isEmpty() && returnTypeGto.getProperties().size() == 1 &&
+                        "value".equals(returnTypeGto.getProperties().get(0).getName()) &&
+                        "byte[]".equals(returnTypeGto.getProperties().get(0).getReturnType().getName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private String generateField(final GeneratedProperty generatedProperty) {
+        final StringBuilder sb = new StringBuilder();
+        final String name = fieldName(generatedProperty);
+        sb.append("this.")
+            .append(name)
+            .append(" = source.")
+            .append(name);
+        if (!"value".equals(name) && importedName(generatedProperty.getReturnType()).contains("[]")) {
+            sb.append(" == null ? null : source._")
+                .append(name)
+                .append(".clone()");
+        }
+        sb.append(';');
+        return sb.toString();
+    }
+
+    @Override
+    protected String getterMethod(final GeneratedProperty field) {
+        if (!"value".equals(field.getName())) {
+            return super.getterMethod(field);
+        }
+
+        final List<CharSequence> strings = new LinkedList<>();
+        final Function<GeneratedProperty, Boolean> tempFunction = (GeneratedProperty p) -> {
+            String name = p.getName();
+            return !"value".equals(name);
+        };
+        Iterable<GeneratedProperty> filtered = Iterables.<GeneratedProperty>filter(this.getFinalProperties(),
+                (Predicate<? super GeneratedProperty>) tempFunction);
+
+        for (GeneratedProperty property : filtered) {
+            final Type propertyReturnType = property.getReturnType();
+            final StringBuilder currentProperty = new StringBuilder();
+            currentProperty.append("if (")
+                .append(fieldName(property))
+                .append(" != null) {")
+                .append(fieldName(field))
+                .append(" = ");
+            if ("java.lang.String".equals(propertyReturnType.getFullyQualifiedName())) {
+                currentProperty.append(fieldName(property))
+                        .append(".toCharArray();");
+            } else if ("byte[]".equals(propertyReturnType.getName())) {
+                currentProperty.append("new ")
+                    .append(importedName(String.class))
+                    .append('(')
+                    .append(fieldName(property))
+                    .append(").toCharArray();");
+            } else if (propertyReturnType.getFullyQualifiedName().startsWith("java.lang") ||
+                    propertyReturnType instanceof Enumeration ||
+                    propertyReturnType.getFullyQualifiedName().startsWith("java.math")) {
+                currentProperty.append(fieldName(property))
+                        .append(".toString().toCharArray();");
+            } else if (propertyReturnType instanceof GeneratedTransferObject &&
+                    ((GeneratedTransferObject)propertyReturnType).isUnionType()) {
+                currentProperty.append(fieldName(property))
+                        .append(".getValue();");
+            } else if (propertyReturnType instanceof GeneratedTransferObject &&
+                    ((GeneratedTransferObject) propertyReturnType).isTypedef() &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties() != null &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties().isEmpty() &&
+                    (((GeneratedTransferObject) propertyReturnType).getProperties().size() == 1) &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties().get(0).getName().equals("value") &&
+                    BOOLEAN.equals(((GeneratedTransferObject) propertyReturnType).getProperties().get(0)
+                            .getReturnType())) {
+                currentProperty.append(fieldName(property))
+                        .append(".isValue().toString().toCharArray();");
+            } else if (propertyReturnType instanceof GeneratedTransferObject &&
+                    ((GeneratedTransferObject) propertyReturnType).isTypedef() &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties() != null &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties().isEmpty() &&
+                    (((GeneratedTransferObject) propertyReturnType).getProperties().size() == 1) &&
+                    ((GeneratedTransferObject) propertyReturnType).getProperties().get(0).getName().equals("value") &&
+                    "byte[]".equals(((GeneratedTransferObject) propertyReturnType).getProperties().get(0)
+                            .getReturnType().getName())) {
+                currentProperty.append("BaseEncoding.base64().encode(")
+                        .append(fieldName(property))
+                        .append(".getValue()).toCharArray();");
+            } else {
+                currentProperty.append(fieldName(property))
+                        .append(".getValue().toString().toCharArray();");
+            }
+            currentProperty.append("}");
+            strings.add(currentProperty);
+        }
+        return String.join(" else ", strings);
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionBuilderTemplate.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionBuilderTemplate.scala.txt
new file mode 100644 (file)
index 0000000..8415e00
--- /dev/null
@@ -0,0 +1,31 @@
+@*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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
+ *@
+
+@import java.util.List
+@import org.opendaylight.mdsal.binding2.model.api.GeneratedTransferObject
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.formatDataForJavaDoc
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.wrapToDocumentation
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.getAccessModifier
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.getClarification
+
+@(genType: GeneratedTransferObject, typeName: String, importedNames: Map[String, String], generatedParameters: Map[String, String])
+@if(genType != null) {
+@{wrapToDocumentation(formatDataForJavaDoc(genType, getClarification))}
+public class @{typeName} {
+    @for(method <- genType.getMethodDefinitions) {
+        @{getAccessModifier(method.getAccessModifier)}
+        @if(method.isStatic) {static}
+        @if(method.isFinal) { final}
+        @{importedNames.get(method.getName)}
+        @{method.getName}
+        (@{generatedParameters.get(method.getName)}) {
+            throw new @{importedNames.get("unsupportedOperationException")}("Not yet implemented");
+        }
+    }
+}
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionTemplate.scala.txt b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionTemplate.scala.txt
new file mode 100644 (file)
index 0000000..9bd3caa
--- /dev/null
@@ -0,0 +1,88 @@
+@*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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
+ *@
+
+@import org.opendaylight.mdsal.binding2.model.api.GeneratedType
+@import org.opendaylight.mdsal.binding2.model.api.GeneratedProperty
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.fieldName
+@import org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.asArguments
+@import org.opendaylight.mdsal.binding2.generator.util.Types.getOuterClassName
+
+@(baseType: GeneratedType, importedNames: Map[String, String], finalProperties: List[GeneratedProperty],
+parentProperties: List[GeneratedProperty], properties: List[GeneratedProperty], propertyList: String)
+@for(property <- parentProperties) {
+    public @{baseType.getName}(@{importedNames.get(property.getName)} @{fieldName(property)}) {
+        super(@{fieldName(property)});
+    }
+}
+@for(property <- finalProperties) {
+    @if("char[]".equals(property.getReturnType.getName)) {
+    /**
+     * Constructor provided only for using in JMX. Don't use it for
+     * construction new object of this union type.
+     */
+    @@@{importedNames.get("constructorProperties")}("@{property.getName}")
+    public @{baseType.getName}({importedNames.get(property.getName)} @{fieldName(property)}) {
+        @{importedNames.get("string")} defVal = new @{importedNames.get("string")}(@{fieldName(property)});
+        @{baseType.getName} defInst = @{typeBuilder}.getDefaultInstance(defVal);
+        @for(otherProperty <- finalProperties) {
+            this.@{fieldName(otherProperty)} =
+            @if("value".equals(otherProperty.getName)) {
+                @if(importedNames.get(otherProperty.getName).contains("[]")) {
+                    @{fieldName(otherProperty)} == null ? null : @{fieldName(otherProperty)}.clone();
+                } else {
+                    @{fieldName(otherProperty)};
+                }
+            } else {
+                defInst.@{fieldName(otherProperty)};
+            }
+        }
+    }
+    } else {
+        @*TO DO parentProperties + #[property] as argument to method below see  unionTemplate 84 *@
+        public @{baseType.getName}() {
+            super(@{asArguments(parentProperties)});
+            this.@{fieldName(property)} = @{fieldName(property)};
+            @for(otherProperty <- finalProperties) {
+                @if(property != otherProperty && !"value".equals(otherProperty.getName)) {
+                    this.@{fieldName(otherProperty)} = null;
+                }
+            }
+        }
+    }
+}
+@if(!properties.isEmpty && !parentProperties.isEmpty) {
+    /**
+     * Creates a copy from Source Object.
+     *
+     * @@param source Source object
+     */
+    public @{baseType.getName}
+    (@{baseType.getName}
+     source) {
+    @if(!parentProperties.isEmpty()) {super(source);}
+    @{propertyList}
+    }
+}
+@if(properties.isEmpty && !parentProperties.isEmpty) {
+    /**
+     * Creates a new instance from @{importedNames.get("superType")}
+     *
+     * @@param source Source object
+     */
+    public @{baseType.getName}(@{importedNames.get("superType")} source) {
+            super(source);
+    }
+}
+
+@typeBuilder() = {
+@if(getOuterClassName(baseType) != null) {
+    @{getOuterClassName(baseType)}@{baseType.getName}Builder
+} else {
+    @{baseType.getName}Builder
+}
+}
\ No newline at end of file