blob: 7e12be32fadb410afa54c277974bf15f1e93d2f3 [file] [log] [blame]
Rama-Huaweib711e5c2016-08-31 07:55:46 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yms.app.yob;
18
19import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
20import org.onosproject.yangutils.datamodel.YangBinary;
21import org.onosproject.yangutils.datamodel.YangSchemaNode;
22import org.onosproject.yangutils.datamodel.YangType;
23import org.onosproject.yms.app.ydt.YdtExtendedContext;
24import org.onosproject.yms.app.ysr.YangSchemaRegistry;
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
28import java.lang.reflect.Constructor;
29import java.lang.reflect.InvocationTargetException;
30import java.lang.reflect.Method;
31import java.math.BigDecimal;
32import java.math.BigInteger;
33
34import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
35import static org.onosproject.yms.app.ydt.AppType.YOB;
36import static org.onosproject.yms.app.yob.YobConstants.DATA_TYPE_NOT_SUPPORT;
37import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
38import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CONSTRUCTOR;
39import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
40import static org.onosproject.yms.app.yob.YobConstants.OF;
41import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
42import static org.onosproject.yms.app.yob.YobWorkBench.getQualifiedDefaultClassName;
43
44/**
45 * Represents a YANG object builder handler to process the ydt content and
46 * build yang object.
47 */
48abstract class YobHandler {
49
50 private static final Logger log = LoggerFactory.getLogger(YobHandler.class);
51
52 /**
53 * reference to YANG schema registry.
54 */
55 private YangSchemaRegistry registry;
56
57 /**
58 * Creates a YANG builder object.
59 *
60 * @param curYdtNode ydtExtendedContext is used to get
61 * application related information maintained
62 * in YDT
63 * @param rootYdtNode ydtRootNode is refers to module node
64 * @param registry registry
65 */
66 public void createYangBuilderObject(YdtExtendedContext curYdtNode,
67 YdtExtendedContext rootYdtNode,
68 YangSchemaRegistry registry) {
69 String setterName = null;
70 YangSchemaNode node = curYdtNode.getYangSchemaNode();
71
72 String qualName = getQualifiedDefaultClassName(node);
73 ClassLoader classLoader = getClassLoader(registry, qualName,
74 curYdtNode);
75
76 if (curYdtNode != rootYdtNode) {
77 setterName = node.getJavaAttributeName();
78 }
79
80 Object builderObject = new YobWorkBench(node, classLoader,
81 qualName, setterName);
82
83 curYdtNode.addAppInfo(YOB, builderObject);
84 }
85
86 /**
87 * Sets the YANG built object in corresponding parent class method.
88 *
89 * @param ydtNode ydtExtendedContext is used to get application
90 * related information maintained in YDT
91 * @param schemaRegistry YANG schema registry
92 */
93 public void setObjectInParent(YdtExtendedContext ydtNode,
94 YangSchemaRegistry schemaRegistry) {
95 }
96
97 /**
98 * Builds the object.
99 *
100 * @param ydtNode ydtExtendedContext is used to get
101 * application related
102 * information maintained in YDT
103 * @param ydtRootNode ydtRootNode
104 * @param schemaRegistry YANG schema registry
105 */
106 public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
107 YdtExtendedContext ydtRootNode,
108 YangSchemaRegistry schemaRegistry) {
109 YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
110 yobWorkBench.buildObject(ydtNode, ydtRootNode);
111 }
112
113 /**
114 * This method is used to set data from string value in parent method.
115 *
116 * @param type refers to YANG type
117 * @param leafValue leafValue argument is used to set the value
118 * in method
119 * @param parentSetterMethod Invokes the underlying method represented
120 * by this parentSetterMethod
121 * @param parentBuilderObject the parentBuilderObject is to invoke the
122 * underlying method
123 * @param ydtExtendedContext ydtExtendedContext is used to get
124 * application related
125 * information maintained in YDT
126 * @throws InvocationTargetException throws InvocationTargetException
127 * @throws IllegalAccessException throws IllegalAccessException
128 * @throws NoSuchMethodException throws NoSuchMethodException
129 */
130 void setDataFromStringValue(YangType<?> type, String leafValue,
131 Method parentSetterMethod,
132 Object parentBuilderObject,
133 YdtExtendedContext ydtExtendedContext)
134 throws InvocationTargetException, IllegalAccessException,
135 NoSuchMethodException {
136 switch (type.getDataType()) {
137 case INT8: {
138 parentSetterMethod.invoke(parentBuilderObject,
139 Byte.parseByte(leafValue));
140 break;
141 }
142 case UINT8:
143 case INT16: {
144 parentSetterMethod.invoke(parentBuilderObject,
145 Short.parseShort(leafValue));
146 break;
147 }
148 case UINT16:
149 case INT32: {
150 parentSetterMethod.invoke(parentBuilderObject,
151 Integer.parseInt(leafValue));
152 break;
153 }
154 case UINT32:
155 case INT64: {
156 parentSetterMethod.invoke(parentBuilderObject,
157 Long.parseLong(leafValue));
158 break;
159 }
160 case UINT64: {
161 parentSetterMethod.invoke(parentBuilderObject,
162 new BigInteger(leafValue));
163 break;
164 }
165 case EMPTY:
166 case BOOLEAN: {
167 parentSetterMethod.invoke(parentBuilderObject,
168 Boolean.parseBoolean(leafValue));
169 break;
170 }
171 case STRING: {
172 parentSetterMethod.invoke(parentBuilderObject, leafValue);
173 break;
174 }
175 case BINARY: {
176 parentSetterMethod.invoke(parentBuilderObject,
177 new YangBinary(leafValue));
178 break;
179 }
180 case BITS: {
181 //TODO
182 break;
183 }
184 case DECIMAL64: {
185 parentSetterMethod.invoke(parentBuilderObject,
186 new BigDecimal(leafValue));
187 break;
188 }
189 case DERIVED: {
190 parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
191 parentBuilderObject, leafValue, false);
192 break;
193 }
194 case UNION: {
195 // TODO
196 break;
197 }
198 case LEAFREF: {
199 // TODO
200 break;
201 }
202 case ENUMERATION: {
203 parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
204 parentBuilderObject, leafValue, true);
205 break;
206 }
207 default: {
208 log.error(DATA_TYPE_NOT_SUPPORT);
209 }
210 }
211 }
212
213 /**
214 * To set data into parent setter method from string value for derived type.
215 *
216 * @param leafValue leafValue argument is used to set the value
217 * in method
218 * @param parentSetterMethod Invokes the underlying method represented
219 * by this parentSetterMethod
220 * @param parentBuilderObject the parentBuilderObject is to invoke the
221 * underlying method
222 * @param ydtExtendedContext ydtExtendedContext is used to get
223 * application related
224 * information maintained in YDT
225 * @param isEnum isEnum parameter is used to check whether
226 * type is enum or derived
227 * information maintained in YDT
228 * @throws InvocationTargetException throws InvocationTargetException
229 * @throws IllegalAccessException throws IllegalAccessException
230 * @throws NoSuchMethodException throws NoSuchMethodException
231 */
232 private void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
233 Method parentSetterMethod,
234 Object parentBuilderObject,
235 String leafValue, boolean isEnum)
236 throws InvocationTargetException, IllegalAccessException,
237 NoSuchMethodException {
238 Class<?> childSetClass = null;
239 Constructor<?> childConstructor = null;
240 Object childValue = null;
241 Object childObject = null;
242 Method childMethod = null;
243
244 YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
245 String packageName = yangJavaModule.getJavaPackage();
246 String className = getCapitalCase(
247 yangJavaModule.getJavaClassNameOrBuiltInType());
248 String qualifiedClassName = packageName + PERIOD + className;
249 ClassLoader classLoader = getClassLoader(registry,
250 qualifiedClassName,
251 ydtExtendedContext);
252 try {
253 childSetClass = classLoader.loadClass(qualifiedClassName);
254 } catch (ClassNotFoundException e) {
255 log.error(FAIL_TO_LOAD_CLASS + packageName + PERIOD + className);
256 }
257 if (!isEnum) {
258
259 if (childSetClass != null) {
260 childConstructor = childSetClass.getDeclaredConstructor();
261 }
262
263 if (childConstructor != null) {
264 childConstructor.setAccessible(true);
265 }
266 try {
267 if (childConstructor != null) {
268 childObject = childConstructor.newInstance();
269 }
270 } catch (InstantiationException e) {
271 log.error(FAIL_TO_LOAD_CONSTRUCTOR + className);
272 }
273 if (childSetClass != null) {
274 childMethod = childSetClass
275 .getDeclaredMethod(FROM_STRING, String.class);
276 }
277 } else {
278 if (childSetClass != null) {
279 childMethod = childSetClass.getDeclaredMethod(OF, String.class);
280 }
281 //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
282 //leafValue = leafValue.toUpperCase();
283 }
284 if (childMethod != null) {
285 childValue = childMethod.invoke(childObject, leafValue);
286 }
287
288 parentSetterMethod.invoke(parentBuilderObject, childValue);
289 }
290
291 /**
292 * Updates class loader for all the classes.
293 *
294 * @param registry YANG schema registry
295 * @param context YDT context
296 * @param qualifiedClassName qualified class name
297 * @return current class loader
298 */
299 private ClassLoader getClassLoader(YangSchemaRegistry registry,
300 String qualifiedClassName,
301 YdtExtendedContext context) {
302
303 YangSchemaNode yangSchemaNode = context.getYangSchemaNode();
304 if (yangSchemaNode instanceof RpcNotificationContainer) {
305 Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
306 qualifiedClassName);
307 return regClass.getClassLoader();
308 } else {
309
310 YdtExtendedContext parent =
311 (YdtExtendedContext) context.getParent();
312 YobWorkBench parentBuilderContainer =
313 (YobWorkBench) parent.getAppInfo(YOB);
314 Object parentObj =
315 parentBuilderContainer.getParentBuilder(context, registry);
316 return parentObj.getClass().getClassLoader();
317 }
318 }
319
320 /**
321 * Returns the YANG schema registry.
322 *
323 * @return registry YANG schema registry
324 */
325 public YangSchemaRegistry getRegistry() {
326 return registry;
327 }
328
329 /**
330 * Sets the YANG schema registry.
331 *
332 * @param registry YANG schema registry
333 */
334 public void setRegistry(YangSchemaRegistry registry) {
335 this.registry = registry;
336 }
337}