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