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