From 58b7a6e88be1ddfb1ed08c353e0ef66ef41b5543 Mon Sep 17 00:00:00 2001 From: Martin Ciglan Date: Thu, 8 Dec 2016 10:02:11 +0100 Subject: [PATCH] Bug 1411-5 #8: MDSAL Binding2 Java API Generator - union and union builder renderers and templates - bit of a cleanup Change-Id: I413bf4f284d5f3151436f5a96e31e4c7ada0c021 Signed-off-by: Filip Gregor Signed-off-by: Martin Ciglan --- .../renderers/UnionBuilderRenderer.java | 36 ++++ .../generator/renderers/UnionRenderer.java | 170 ++++++++++++++++++ .../binding2/unionBuilderTemplate.scala.txt | 31 ++++ .../mdsal/binding2/unionTemplate.scala.txt | 88 +++++++++ 4 files changed, 325 insertions(+) create mode 100644 binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionBuilderRenderer.java create mode 100644 binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionRenderer.java create mode 100644 binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionBuilderTemplate.scala.txt create mode 100644 binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionTemplate.scala.txt 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 index 0000000000..f6d54c907e --- /dev/null +++ b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionBuilderRenderer.java @@ -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 importedNames = new HashMap<>(); + private final Map 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 index 0000000000..4d239cf243 --- /dev/null +++ b/binding2/mdsal-binding2-java-api-generator/src/main/java/org/opendaylight/mdsal/binding2/java/api/generator/renderers/UnionRenderer.java @@ -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 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 strings = new LinkedList<>(); + final Function tempFunction = (GeneratedProperty p) -> { + String name = p.getName(); + return !"value".equals(name); + }; + Iterable filtered = Iterables.filter(this.getFinalProperties(), + (Predicate) 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 index 0000000000..8415e00aeb --- /dev/null +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionBuilderTemplate.scala.txt @@ -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 index 0000000000..9bd3caabf1 --- /dev/null +++ b/binding2/mdsal-binding2-java-api-generator/src/main/twirl/org/opendaylight/mdsal/binding2/unionTemplate.scala.txt @@ -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 -- 2.36.6