Bug 1411-5 #8: MDSAL Binding2 Java API Generator
[mdsal.git] / binding2 / mdsal-binding2-java-api-generator / src / main / java / org / opendaylight / mdsal / binding2 / java / api / generator / renderers / UnionRenderer.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.mdsal.binding2.java.api.generator.renderers;
10
11 import static org.opendaylight.mdsal.binding2.generator.util.Types.BOOLEAN;
12 import static org.opendaylight.mdsal.binding2.java.api.generator.util.TextTemplateUtil.fieldName;
13
14 import com.google.common.base.Function;
15 import com.google.common.base.Predicate;
16 import com.google.common.collect.Iterables;
17 import java.beans.ConstructorProperties;
18 import java.util.HashMap;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.Map;
22 import org.opendaylight.mdsal.binding2.model.api.Enumeration;
23 import org.opendaylight.mdsal.binding2.model.api.GeneratedProperty;
24 import org.opendaylight.mdsal.binding2.model.api.GeneratedTransferObject;
25 import org.opendaylight.mdsal.binding2.model.api.Type;
26 import org.opendaylight.mdsal.binding2.txt.unionTemplate;
27
28 public class UnionRenderer extends ClassRenderer {
29     /**
30      * list of all imported names for template
31      */
32     private final Map<String, String> importedNames = new HashMap<>();
33
34     public UnionRenderer(final GeneratedTransferObject type) {
35         super(type);
36     }
37
38     @Override
39     protected String generateConstructors() {
40         if(isBaseEncodingImportRequired()) {
41             this.putToImportMap("BaseEncoding","com.google.common.io");
42         }
43         for (GeneratedProperty finalProperty : getFinalProperties()) {
44             importedNames.put("constructorProperties", importedName(ConstructorProperties.class));
45             importedNames.put("string", importedName(String.class));
46             importedNames.put(finalProperty.getName(), importedName(finalProperty.getReturnType()));
47         }
48
49         final StringBuilder sb = new StringBuilder();
50         if (!getProperties().isEmpty()) {
51             for (GeneratedProperty property : getProperties()) {
52                 sb.append(generateField(property));
53             }
54         }
55
56         if (getProperties().isEmpty() && !getParentProperties().isEmpty()) {
57             importedNames.put("superType", importedName(genTO.getSuperType()));
58         }
59
60         for (GeneratedProperty parentProperty : getParentProperties()) {
61             importedNames.put(parentProperty.getName(), importedName(parentProperty.getReturnType()));
62         }
63
64         return unionTemplate.render(getType(), importedNames, getFinalProperties(), getParentProperties(),
65                 getProperties(), sb.toString()).body();
66     }
67
68     private boolean isBaseEncodingImportRequired() {
69         for (GeneratedProperty property : getFinalProperties()) {
70             final Type returnType = property.getReturnType();
71             if (returnType instanceof GeneratedTransferObject) {
72                 final GeneratedTransferObject returnTypeGto = (GeneratedTransferObject)returnType;
73                 if (returnTypeGto.isTypedef() && returnTypeGto.getProperties() != null &&
74                         !returnTypeGto.getProperties().isEmpty() && returnTypeGto.getProperties().size() == 1 &&
75                         "value".equals(returnTypeGto.getProperties().get(0).getName()) &&
76                         "byte[]".equals(returnTypeGto.getProperties().get(0).getReturnType().getName())) {
77                     return true;
78                 }
79             }
80         }
81         return false;
82     }
83
84     private String generateField(final GeneratedProperty generatedProperty) {
85         final StringBuilder sb = new StringBuilder();
86         final String name = fieldName(generatedProperty);
87         sb.append("this.")
88             .append(name)
89             .append(" = source.")
90             .append(name);
91         if (!"value".equals(name) && importedName(generatedProperty.getReturnType()).contains("[]")) {
92             sb.append(" == null ? null : source._")
93                 .append(name)
94                 .append(".clone()");
95         }
96         sb.append(';');
97         return sb.toString();
98     }
99
100     @Override
101     protected String getterMethod(final GeneratedProperty field) {
102         if (!"value".equals(field.getName())) {
103             return super.getterMethod(field);
104         }
105
106         final List<CharSequence> strings = new LinkedList<>();
107         final Function<GeneratedProperty, Boolean> tempFunction = (GeneratedProperty p) -> {
108             String name = p.getName();
109             return !"value".equals(name);
110         };
111         Iterable<GeneratedProperty> filtered = Iterables.<GeneratedProperty>filter(this.getFinalProperties(),
112                 (Predicate<? super GeneratedProperty>) tempFunction);
113
114         for (GeneratedProperty property : filtered) {
115             final Type propertyReturnType = property.getReturnType();
116             final StringBuilder currentProperty = new StringBuilder();
117             currentProperty.append("if (")
118                 .append(fieldName(property))
119                 .append(" != null) {")
120                 .append(fieldName(field))
121                 .append(" = ");
122             if ("java.lang.String".equals(propertyReturnType.getFullyQualifiedName())) {
123                 currentProperty.append(fieldName(property))
124                         .append(".toCharArray();");
125             } else if ("byte[]".equals(propertyReturnType.getName())) {
126                 currentProperty.append("new ")
127                     .append(importedName(String.class))
128                     .append('(')
129                     .append(fieldName(property))
130                     .append(").toCharArray();");
131             } else if (propertyReturnType.getFullyQualifiedName().startsWith("java.lang") ||
132                     propertyReturnType instanceof Enumeration ||
133                     propertyReturnType.getFullyQualifiedName().startsWith("java.math")) {
134                 currentProperty.append(fieldName(property))
135                         .append(".toString().toCharArray();");
136             } else if (propertyReturnType instanceof GeneratedTransferObject &&
137                     ((GeneratedTransferObject)propertyReturnType).isUnionType()) {
138                 currentProperty.append(fieldName(property))
139                         .append(".getValue();");
140             } else if (propertyReturnType instanceof GeneratedTransferObject &&
141                     ((GeneratedTransferObject) propertyReturnType).isTypedef() &&
142                     ((GeneratedTransferObject) propertyReturnType).getProperties() != null &&
143                     ((GeneratedTransferObject) propertyReturnType).getProperties().isEmpty() &&
144                     (((GeneratedTransferObject) propertyReturnType).getProperties().size() == 1) &&
145                     ((GeneratedTransferObject) propertyReturnType).getProperties().get(0).getName().equals("value") &&
146                     BOOLEAN.equals(((GeneratedTransferObject) propertyReturnType).getProperties().get(0)
147                             .getReturnType())) {
148                 currentProperty.append(fieldName(property))
149                         .append(".isValue().toString().toCharArray();");
150             } else if (propertyReturnType instanceof GeneratedTransferObject &&
151                     ((GeneratedTransferObject) propertyReturnType).isTypedef() &&
152                     ((GeneratedTransferObject) propertyReturnType).getProperties() != null &&
153                     ((GeneratedTransferObject) propertyReturnType).getProperties().isEmpty() &&
154                     (((GeneratedTransferObject) propertyReturnType).getProperties().size() == 1) &&
155                     ((GeneratedTransferObject) propertyReturnType).getProperties().get(0).getName().equals("value") &&
156                     "byte[]".equals(((GeneratedTransferObject) propertyReturnType).getProperties().get(0)
157                             .getReturnType().getName())) {
158                 currentProperty.append("BaseEncoding.base64().encode(")
159                         .append(fieldName(property))
160                         .append(".getValue()).toCharArray();");
161             } else {
162                 currentProperty.append(fieldName(property))
163                         .append(".getValue().toString().toCharArray();");
164             }
165             currentProperty.append("}");
166             strings.add(currentProperty);
167         }
168         return String.join(" else ", strings);
169     }
170 }