2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.mdsal.binding.javav2.java.api.generator.renderers;
11 import com.google.common.base.Preconditions;
12 import java.util.AbstractMap.SimpleEntry;
13 import java.util.ArrayDeque;
14 import java.util.ArrayList;
15 import java.util.Deque;
16 import java.util.List;
17 import java.util.Map.Entry;
18 import java.util.Optional;
19 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
20 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
21 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
22 import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.constantsTemplate;
23 import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.enumTemplate;
24 import org.opendaylight.mdsal.binding.javav2.java.api.generator.txt.interfaceTemplate;
25 import org.opendaylight.mdsal.binding.javav2.java.api.generator.util.TextTemplateUtil;
26 import org.opendaylight.mdsal.binding.javav2.model.api.AnnotationType;
27 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
28 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
29 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
30 import org.opendaylight.mdsal.binding.javav2.model.api.MethodSignature;
31 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
32 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
33 import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
34 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
35 import org.opendaylight.yangtools.yang.common.QName;
37 public class InterfaceRenderer extends BaseRenderer {
39 private static final char NEW_LINE = '\n';
42 * Creates the instance of this class which is used for generating the interface file source
43 * code from <code>type</code>.
44 * @param type generated type
46 public InterfaceRenderer(final GeneratedType type) {
48 Preconditions.checkNotNull(type, "Generated type reference cannot be NULL!");
52 protected String body() {
53 // mainAnnotations string with annotations for whole interface
54 final String mainAnnotations = generateAnnotations(getType().getAnnotations());
55 // StringBuilder string with the declaration of methods source code in JAVA format
56 final StringBuilder sb1 = new StringBuilder();
57 for (MethodSignature method : getType().getMethodDefinitions()) {
58 if (isAccessor(method)) {
59 sb1.append(TextTemplateUtil.asJavadoc(method.getComment()));
61 sb1.append(TextTemplateUtil.getJavaDocForInterface(method));
63 sb1.append(generateAnnotations(method.getAnnotations()))
64 .append(importedName(method.getReturnType()))
66 .append(method.getName())
68 .append(generateParameters(method.getParameters()))
72 final String methodList = sb1.toString();
74 // enums string with rendered enums from template
75 final StringBuilder sb2 = new StringBuilder();
76 for (Enumeration enumeration : getType().getEnumerations()) {
77 final String importedName = importedName(String.class);
78 final String enumBody = enumTemplate.render(enumeration, importedName).body();
81 final String enums = sb2.toString();
83 final String generatedImports = generateImports(getType().getImplements());
85 getImportedNames().put("qname", importedName(QName.class));
86 final String generatedConstants = constantsTemplate.render(getType(), getImportedNames(),
87 this::importedName, true).body();
89 final Entry<String, String> identifier = generateInstanceIdentifier();
91 final List<String> innerClasses = new ArrayList<>(getType().getEnclosedTypes().size());
92 for (GeneratedType innerClass : getType().getEnclosedTypes()) {
93 if (innerClass instanceof GeneratedTransferObject) {
94 if (((GeneratedTransferObject) innerClass).isUnionType()) {
95 final UnionRenderer unionRenderer = new UnionRenderer((GeneratedTransferObject) innerClass);
96 innerClasses.add(unionRenderer.generateAsInnerClass());
97 this.putAllToImportMap(unionRenderer.getImportMap());
99 final ClassRenderer classRenderer = new ClassRenderer((GeneratedTransferObject) innerClass);
100 innerClasses.add(classRenderer.generateAsInnerClass());
101 this.putAllToImportMap(classRenderer.getImportMap());
105 final String generatedInnerClasses = String.join("\n", innerClasses);
107 return interfaceTemplate.render(getType(), enums, mainAnnotations, methodList, generatedImports,
108 generatedConstants, generatedInnerClasses, identifier.getKey(), identifier.getValue()).body();
111 private static boolean isAccessor(final MethodSignature maybeGetter) {
112 return maybeGetter.getName().startsWith("is") || maybeGetter.getName().startsWith("get");
116 * Return string of annotations.
117 * @param annotationTypeList list of annotations
118 * @return String of annotations in format:
120 * (parameterName1=ParameterSingleValue1,...)
123 private String generateAnnotations(final List<AnnotationType> annotationTypeList) {
124 final StringBuilder sb1 = new StringBuilder();
125 for (AnnotationType annotationType : annotationTypeList) {
126 sb1.append('@').append(importedName(annotationType));
127 if (!annotationType.getParameters().isEmpty()) {
130 final List<String> parameterList = new ArrayList<>(annotationType.getParameters().size());
131 for (AnnotationType.Parameter parameter : annotationType.getParameters()) {
132 final StringBuilder sb2 = new StringBuilder();
133 sb2.append(parameter.getName()).append('=').append(parameter.getSingleValue());
134 parameterList.add(sb2.toString());
136 sb1.append(String.join(",", parameterList));
137 if (!annotationType.getParameters().isEmpty()) {
140 sb1.append(NEW_LINE);
142 return sb1.toString();
146 * Generate default method getInstanceIdentifier.
147 * @return string pair of instance identifier and key parameters
149 private Entry<String, String> generateInstanceIdentifier() {
150 //Only tree data nodes need to generate the method.
151 if (null == getType().getBindingNamespaceType()
152 || !BindingNamespaceType.isTreeData(getType().getBindingNamespaceType())
153 || !getType().getImplements().contains(BindingTypes.TREE_CHILD_NODE)) {
154 return new SimpleEntry<>(null, null);
157 final Deque<GeneratedType> dataPath = new ArrayDeque<>();
158 GeneratedType type = getType();
159 GeneratedTypeBuilder parentTypeBuilder;
161 while (type != null) {
164 parentTypeBuilder = (GeneratedTypeBuilder) type.getParentTypeForBuilder();
165 type = parentTypeBuilder != null ? parentTypeBuilder.toInstance() : null;
170 final StringBuilder iiBuidler = new StringBuilder();
171 type = dataPath.pop();
172 iiBuidler.append("InstanceIdentifier.builder(").append(type.getName()).append(".class)");
173 importedName(InstanceIdentifier.class);
174 final List<String> keys = new ArrayList<>();
175 while (dataPath.peek() != null) {
176 type = dataPath.pop();
177 if (type.getImplements().contains(BindingTypes.AUGMENTATION)) {
178 iiBuidler.append(".augmentation(").append(type.getName()).append(".class)");
180 Optional<MethodSignature> method = type.getMethodDefinitions().stream().filter(m ->
181 m.getName().equals("getIdentifier")).findFirst();
182 if (method.isPresent()) {
183 importedName(method.get().getReturnType());
184 final String keyName = method.get().getReturnType().getName();
185 final String normalizedKeyName = JavaIdentifierNormalizer.normalizeSpecificIdentifier(keyName,
186 JavaIdentifier.METHOD);
187 keys.add(new StringBuilder().append("final ").append(keyName).append(" _")
188 .append(normalizedKeyName).toString());
189 iiBuidler.append(".child(").append(type.getFullyQualifiedName()).append(".class, _")
190 .append(normalizedKeyName).append(")");
192 iiBuidler.append(".child(").append(type.getFullyQualifiedName()).append(".class)");
196 iiBuidler.append(".build()");
197 return new SimpleEntry<>(iiBuidler.toString(), String.join(", ", keys));
202 * Return list of parameters.
203 * @param parameters list of parameters
204 * @return list of parameters separated with ","
206 private String generateImports(final List<Type> parameters) {
207 final List<String> strings = new ArrayList<>(parameters.size());
208 for (Type parameter : parameters) {
209 strings.add(importedName(parameter));
212 return String.join(", ", strings);