Fix getValue() of bits in union
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / yangtools / sal / java / api / generator / UnionTemplate.xtend
1 /*
2  * Copyright (c) 2014 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 package org.opendaylight.yangtools.sal.java.api.generator
9
10 import static org.opendaylight.yangtools.binding.generator.util.Types.*
11 import com.google.common.base.Preconditions;
12 import java.beans.ConstructorProperties
13 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
14 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
15 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
16 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
17
18 /**
19  * Template for generating JAVA class.
20  */
21 class UnionTemplate extends ClassTemplate {
22
23     /**
24      * Creates instance of this class with concrete <code>genType</code>.
25      *
26      * @param genType generated transfer object which will be transformed to JAVA class source code
27      */
28     new(GeneratedTransferObject genType) {
29         super(genType)
30         if(isBaseEncodingImportRequired) {
31             this.importMap.put("BaseEncoding","com.google.common.io")
32         }
33     }
34
35     final private def boolean isBaseEncodingImportRequired() {
36         for (property : finalProperties) {
37             val propRet = property.returnType
38             if (propRet instanceof GeneratedTransferObject && (propRet as GeneratedTransferObject).typedef &&
39                 (propRet as GeneratedTransferObject).properties != null &&
40                 !(propRet as GeneratedTransferObject).properties.empty &&
41                 ((propRet as GeneratedTransferObject).properties.size == 1) &&
42                 (propRet as GeneratedTransferObject).properties.get(0).name.equals("value") &&
43                 "byte[]".equals((propRet as GeneratedTransferObject).properties.get(0).returnType.name)) {
44                 return true;
45             }
46         }
47     }
48
49     override constructors() '''
50         «unionConstructorsParentProperties»
51         «unionConstructors»
52         «IF !allProperties.empty»
53             «copyConstructor»
54         «ENDIF»
55         «IF properties.empty && !parentProperties.empty»
56             «parentConstructor»
57         «ENDIF»
58     '''
59
60     private def unionConstructors() '''
61         «FOR property : finalProperties SEPARATOR "\n"»
62             «val propRet = property.returnType»
63             «IF "char[]".equals(propRet.name)»
64                 /**
65                  * Constructor provided only for using in JMX. Don't use it for
66                  * construction new object of this union type.
67                  */
68                 @«ConstructorProperties.importedName»("«property.name»")
69                 public «type.name»(«propRet.importedName» «property.fieldName») {
70                     «String.importedName» defVal = new «String.importedName»(«property.fieldName»);
71                     «type.name» defInst = «typeBuilder()».getDefaultInstance(defVal);
72                     «FOR other : finalProperties»
73                         «IF other.name.equals("value")»
74                             «IF other.returnType.importedName.contains("[]")»
75                             this.«other.fieldName» = «other.fieldName» == null ? null : «other.fieldName».clone();
76                             «ELSE»
77                             this.«other.fieldName» = «other.fieldName»;
78                             «ENDIF»
79                         «ELSE»
80                             this.«other.fieldName» = defInst.«other.fieldName»;
81                         «ENDIF»
82                     «ENDFOR»
83                 }
84             «ELSE»
85                 «val propertyAndTopParentProperties = parentProperties + #[property]»
86                 public «type.name»(«propertyAndTopParentProperties.asArgumentsDeclaration») {
87                     super(«parentProperties.asArguments»);
88                     this.«property.fieldName» = «property.fieldName»;
89                     «FOR other : finalProperties»
90                         «IF property != other && !"value".equals(other.name)»
91                              this.«other.fieldName» = null;
92                         «ENDIF»
93                     «ENDFOR»
94                 }
95             «ENDIF»
96         «ENDFOR»
97     '''
98
99     def typeBuilder() {
100         val outerCls = getOuterClassName(type);
101         if(outerCls !== null) {
102             return outerCls + type.name + "Builder"
103         }
104         return type.name + "Builder"
105     }
106
107     private def unionConstructorsParentProperties() '''
108         «FOR property : parentProperties SEPARATOR "\n"»
109             public «type.name»(«property.returnType.importedName» «property.fieldName») {
110                 super(«property.fieldName»);
111             }
112         «ENDFOR»
113     '''
114
115     override protected getterMethod(GeneratedProperty field) {
116         if (!"value".equals(field.name)) {
117             return super.getterMethod(field)
118         }
119
120         Preconditions.checkArgument("char[]".equals(field.returnType.importedName))
121
122         '''
123             public char[] «field.getterMethodName»() {
124                 if («field.fieldName» == null) {
125                     «FOR property : finalProperties.filter([ p | !"value".equals(p.name)]) SEPARATOR " else"»
126                         if («property.fieldName» != null) {
127                             «val propRet = property.returnType»
128                             «IF "java.lang.String".equals(propRet.fullyQualifiedName)»
129                                 ««« type string
130                                 «field.fieldName» = «property.fieldName».toCharArray();
131                             «ELSEIF "org.opendaylight.yangtools.yang.binding.InstanceIdentifier".equals(propRet.fullyQualifiedName)»
132                                 ««« type instance-identifier
133                                 «field.fieldName» = «property.fieldName».toString().toCharArray();
134                             «ELSEIF "byte[]".equals(propRet.name)»
135                                 ««« type binary
136                                 «field.fieldName» = new «String.importedName»(«property.fieldName»).toCharArray();
137                             «ELSEIF propRet.fullyQualifiedName.startsWith("java.lang")
138                                 || propRet instanceof Enumeration
139                                 || propRet.fullyQualifiedName.startsWith("java.math")»
140                                 ««« type int*, uint, decimal64 or enumeration*
141                                 «field.fieldName» = «property.fieldName».toString().toCharArray();
142                             «ELSEIF propRet instanceof GeneratedTransferObject && (propRet as GeneratedTransferObject).unionType»
143                                 ««« union type
144                                 «field.fieldName» = «property.fieldName».getValue();
145                             «ELSEIF propRet instanceof GeneratedTransferObject // Is it a GeneratedTransferObject
146                                     && (propRet as GeneratedTransferObject).typedef  // Is it a typedef
147                                     && (propRet as GeneratedTransferObject).properties != null
148                                     && !(propRet as GeneratedTransferObject).properties.empty
149                                     && ((propRet as GeneratedTransferObject).properties.size == 1)
150                                     && (propRet as GeneratedTransferObject).properties.get(0).name.equals("value")
151                                     && BOOLEAN.equals((propRet as GeneratedTransferObject).properties.get(0).returnType)» // And the property value is of type boolean
152                                 ««« generated boolean typedef
153                                 «field.fieldName» = «property.fieldName».isValue().toString().toCharArray();
154                             «ELSEIF propRet instanceof GeneratedTransferObject // Is it a GeneratedTransferObject
155                                     && (propRet as GeneratedTransferObject).typedef  // Is it a typedef
156                                     && (propRet as GeneratedTransferObject).properties != null
157                                     && !(propRet as GeneratedTransferObject).properties.empty
158                                     && ((propRet as GeneratedTransferObject).properties.size == 1)
159                                     && (propRet as GeneratedTransferObject).properties.get(0).name.equals("value")
160                                     && "byte[]".equals((propRet as GeneratedTransferObject).properties.get(0).returnType.name)»
161                                 ««« generated byte[] typedef
162                                 «field.fieldName» = BaseEncoding.base64().encode(«property.fieldName».getValue()).toCharArray();
163                             «ELSEIF propRet instanceof GeneratedTransferObject // Is it a GeneratedTransferObject
164                                     && (propRet as GeneratedTransferObject).typedef  // Is it a typedef
165                                     && (propRet as GeneratedTransferObject).baseType instanceof BitsTypeDefinition»
166                                 ««« generated bits typedef
167                                 «field.fieldName» = java.util.Arrays.toString(«property.fieldName».getValue()).toCharArray();
168                             «ELSE»
169                                 ««« generated type
170                                 «field.fieldName» = «property.fieldName».getValue().toString().toCharArray();
171                             «ENDIF»
172                         }
173                     «ENDFOR»
174                 }
175                 return «field.fieldName» == null ? null : «field.fieldName».clone();
176             }
177         '''
178     }
179
180     override def isReadOnly(GeneratedProperty field) {
181         return !"value".equals(field.name) && super.isReadOnly(field)
182     }
183
184     override protected copyConstructor() '''
185         /**
186          * Creates a copy from Source Object.
187          *
188          * @param source Source object
189          */
190         public «type.name»(«type.name» source) {
191             «IF !parentProperties.empty»
192                 super(source);
193             «ENDIF»
194             «IF !properties.empty»
195                 «FOR p : properties»
196                     «IF !"value".equals(p.name) && p.returnType.importedName.contains("[]")»
197                     this.«p.fieldName» = source.«p.fieldName» == null ? null : source.«p.fieldName».clone();
198                     «ELSE»
199                     this.«p.fieldName» = source.«p.fieldName»;
200                     «ENDIF»
201                 «ENDFOR»
202             «ENDIF»
203         }
204     '''
205
206 }