b2c5d5a0bbdfdb83edfb6b7002cf2532f8afdb23
[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
17 /**
18  * Template for generating JAVA class.
19  */
20 class UnionTemplate extends ClassTemplate {
21
22     /**
23      * Creates instance of this class with concrete <code>genType</code>.
24      *
25      * @param genType generated transfer object which will be transformed to JAVA class source code
26      */
27     new(GeneratedTransferObject genType) {
28         super(genType)
29         if(isBaseEncodingImportRequired) {
30             this.importMap.put("BaseEncoding","com.google.common.io")
31         }
32     }
33
34     final private def boolean isBaseEncodingImportRequired() {
35         for (property : finalProperties) {
36             val propRet = property.returnType
37             if (propRet instanceof GeneratedTransferObject && (propRet as GeneratedTransferObject).typedef &&
38                 (propRet as GeneratedTransferObject).properties != null &&
39                 !(propRet as GeneratedTransferObject).properties.empty &&
40                 ((propRet as GeneratedTransferObject).properties.size == 1) &&
41                 (propRet as GeneratedTransferObject).properties.get(0).name.equals("value") &&
42                 "byte[]".equals((propRet as GeneratedTransferObject).properties.get(0).returnType.name)) {
43                 return true;
44             }
45         }
46     }
47
48     override constructors() '''
49         «unionConstructorsParentProperties»
50         «unionConstructors»
51         «IF !allProperties.empty»
52             «copyConstructor»
53         «ENDIF»
54         «IF properties.empty && !parentProperties.empty»
55             «parentConstructor»
56         «ENDIF»
57     '''
58
59     private def unionConstructors() '''
60         «FOR property : finalProperties SEPARATOR "\n"»
61             «val propRet = property.returnType»
62             «IF "char[]".equals(propRet.name)»
63                 /**
64                  * Constructor provided only for using in JMX. Don't use it for
65                  * construction new object of this union type.
66                  */
67                 @«ConstructorProperties.importedName»("«property.name»")
68                 public «type.name»(«propRet.importedName» «property.fieldName») {
69                     «String.importedName» defVal = new «String.importedName»(«property.fieldName»);
70                     «type.name» defInst = «typeBuilder()».getDefaultInstance(defVal);
71                     «FOR other : finalProperties»
72                         «IF other.name.equals("value")»
73                             «IF other.returnType.importedName.contains("[]")»
74                             this.«other.fieldName» = «other.fieldName» == null ? null : «other.fieldName».clone();
75                             «ELSE»
76                             this.«other.fieldName» = «other.fieldName»;
77                             «ENDIF»
78                         «ELSE»
79                             this.«other.fieldName» = defInst.«other.fieldName»;
80                         «ENDIF»
81                     «ENDFOR»
82                 }
83             «ELSE»
84                 «val propertyAndTopParentProperties = parentProperties + #[property]»
85                 public «type.name»(«propertyAndTopParentProperties.asArgumentsDeclaration») {
86                     super(«parentProperties.asArguments»);
87                     this.«property.fieldName» = «property.fieldName»;
88                     «FOR other : finalProperties»
89                         «IF property != other && !"value".equals(other.name)»
90                              this.«other.fieldName» = null;
91                         «ENDIF»
92                     «ENDFOR»
93                 }
94             «ENDIF»
95         «ENDFOR»
96     '''
97
98     def typeBuilder() {
99         val outerCls = getOuterClassName(type);
100         if(outerCls !== null) {
101             return outerCls + type.name + "Builder"
102         }
103         return type.name + "Builder"
104     }
105
106     private def unionConstructorsParentProperties() '''
107         «FOR property : parentProperties SEPARATOR "\n"»
108             public «type.name»(«property.returnType.importedName» «property.fieldName») {
109                 super(«property.fieldName»);
110             }
111         «ENDFOR»
112     '''
113
114     override protected getterMethod(GeneratedProperty field) {
115         if (!"value".equals(field.name)) {
116             return super.getterMethod(field)
117         }
118
119         Preconditions.checkArgument("char[]".equals(field.returnType.importedName))
120
121         '''
122             public char[] «field.getterMethodName»() {
123                 if («field.fieldName» == null) {
124                     «FOR property : finalProperties.filter([ p | !"value".equals(p.name)]) SEPARATOR " else"»
125                         if («property.fieldName» != null) {
126                             «val propRet = property.returnType»
127                             «IF "java.lang.String".equals(propRet.fullyQualifiedName)»
128                                 ««« type string
129                                 «field.fieldName» = «property.fieldName».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.base64().encode(«property.fieldName».getValue()).toCharArray();
159                             «ELSE»
160                                 ««« generated type
161                                 «field.fieldName» = «property.fieldName».getValue().toString().toCharArray();
162                             «ENDIF»
163                         }
164                     «ENDFOR»
165                 }
166                 return «field.fieldName» == null ? null : «field.fieldName».clone();
167             }
168         '''
169     }
170
171     override def isReadOnly(GeneratedProperty field) {
172         return !"value".equals(field.name) && super.isReadOnly(field)
173     }
174
175     override protected copyConstructor() '''
176         /**
177          * Creates a copy from Source Object.
178          *
179          * @param source Source object
180          */
181         public «type.name»(«type.name» source) {
182             «IF !parentProperties.empty»
183                 super(source);
184             «ENDIF»
185             «IF !properties.empty»
186                 «FOR p : properties»
187                     «IF !"value".equals(p.name) && p.returnType.importedName.contains("[]")»
188                     this.«p.fieldName» = source.«p.fieldName» == null ? null : source.«p.fieldName».clone();
189                     «ELSE»
190                     this.«p.fieldName» = source.«p.fieldName»;
191                     «ENDIF»
192                 «ENDFOR»
193             «ENDIF»
194         }
195     '''
196
197 }