blob: e2190f0f91917f40ec4de9f8a305942bf21b6302 [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;
Vidyashree Rama76faccc2016-10-17 22:06:52 +053024import org.onosproject.yms.app.yob.exception.YobExceptions;
Rama-Huaweib711e5c2016-08-31 07:55:46 +053025import org.onosproject.yms.app.ysr.YangSchemaRegistry;
26import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
29import java.lang.reflect.Constructor;
30import java.lang.reflect.InvocationTargetException;
31import java.lang.reflect.Method;
32import java.math.BigDecimal;
33import java.math.BigInteger;
34
35import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
36import static org.onosproject.yms.app.ydt.AppType.YOB;
37import static org.onosproject.yms.app.yob.YobConstants.DATA_TYPE_NOT_SUPPORT;
38import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
39import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CONSTRUCTOR;
40import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
41import static org.onosproject.yms.app.yob.YobConstants.OF;
42import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
43import static org.onosproject.yms.app.yob.YobWorkBench.getQualifiedDefaultClassName;
44
45/**
46 * Represents a YANG object builder handler to process the ydt content and
47 * build yang object.
48 */
49abstract class YobHandler {
50
51 private static final Logger log = LoggerFactory.getLogger(YobHandler.class);
52
53 /**
54 * reference to YANG schema registry.
55 */
56 private YangSchemaRegistry registry;
57
58 /**
59 * Creates a YANG builder object.
60 *
61 * @param curYdtNode ydtExtendedContext is used to get
62 * application related information maintained
63 * in YDT
64 * @param rootYdtNode ydtRootNode is refers to module node
65 * @param registry registry
66 */
67 public void createYangBuilderObject(YdtExtendedContext curYdtNode,
68 YdtExtendedContext rootYdtNode,
69 YangSchemaRegistry registry) {
70 String setterName = null;
71 YangSchemaNode node = curYdtNode.getYangSchemaNode();
72
73 String qualName = getQualifiedDefaultClassName(node);
Vidyashree Rama76faccc2016-10-17 22:06:52 +053074 ClassLoader classLoader = getClassLoader(registry,
75 qualName,
76 curYdtNode, rootYdtNode);
Rama-Huaweib711e5c2016-08-31 07:55:46 +053077
78 if (curYdtNode != rootYdtNode) {
79 setterName = node.getJavaAttributeName();
80 }
81
82 Object builderObject = new YobWorkBench(node, classLoader,
83 qualName, setterName);
84
85 curYdtNode.addAppInfo(YOB, builderObject);
86 }
87
88 /**
89 * Sets the YANG built object in corresponding parent class method.
90 *
91 * @param ydtNode ydtExtendedContext is used to get application
92 * related information maintained in YDT
93 * @param schemaRegistry YANG schema registry
94 */
95 public void setObjectInParent(YdtExtendedContext ydtNode,
96 YangSchemaRegistry schemaRegistry) {
97 }
98
99 /**
100 * Builds the object.
101 *
102 * @param ydtNode ydtExtendedContext is used to get
103 * application related
104 * information maintained in YDT
105 * @param ydtRootNode ydtRootNode
106 * @param schemaRegistry YANG schema registry
107 */
108 public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
109 YdtExtendedContext ydtRootNode,
110 YangSchemaRegistry schemaRegistry) {
111 YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
112 yobWorkBench.buildObject(ydtNode, ydtRootNode);
113 }
114
115 /**
116 * This method is used to set data from string value in parent method.
117 *
118 * @param type refers to YANG type
119 * @param leafValue leafValue argument is used to set the value
120 * in method
121 * @param parentSetterMethod Invokes the underlying method represented
122 * by this parentSetterMethod
123 * @param parentBuilderObject the parentBuilderObject is to invoke the
124 * underlying method
125 * @param ydtExtendedContext ydtExtendedContext is used to get
126 * application related
127 * information maintained in YDT
128 * @throws InvocationTargetException throws InvocationTargetException
129 * @throws IllegalAccessException throws IllegalAccessException
130 * @throws NoSuchMethodException throws NoSuchMethodException
131 */
132 void setDataFromStringValue(YangType<?> type, String leafValue,
133 Method parentSetterMethod,
134 Object parentBuilderObject,
135 YdtExtendedContext ydtExtendedContext)
136 throws InvocationTargetException, IllegalAccessException,
137 NoSuchMethodException {
138 switch (type.getDataType()) {
139 case INT8: {
140 parentSetterMethod.invoke(parentBuilderObject,
141 Byte.parseByte(leafValue));
142 break;
143 }
144 case UINT8:
145 case INT16: {
146 parentSetterMethod.invoke(parentBuilderObject,
147 Short.parseShort(leafValue));
148 break;
149 }
150 case UINT16:
151 case INT32: {
152 parentSetterMethod.invoke(parentBuilderObject,
153 Integer.parseInt(leafValue));
154 break;
155 }
156 case UINT32:
157 case INT64: {
158 parentSetterMethod.invoke(parentBuilderObject,
159 Long.parseLong(leafValue));
160 break;
161 }
162 case UINT64: {
163 parentSetterMethod.invoke(parentBuilderObject,
164 new BigInteger(leafValue));
165 break;
166 }
167 case EMPTY:
168 case BOOLEAN: {
169 parentSetterMethod.invoke(parentBuilderObject,
170 Boolean.parseBoolean(leafValue));
171 break;
172 }
173 case STRING: {
174 parentSetterMethod.invoke(parentBuilderObject, leafValue);
175 break;
176 }
177 case BINARY: {
178 parentSetterMethod.invoke(parentBuilderObject,
179 new YangBinary(leafValue));
180 break;
181 }
182 case BITS: {
183 //TODO
184 break;
185 }
186 case DECIMAL64: {
187 parentSetterMethod.invoke(parentBuilderObject,
188 new BigDecimal(leafValue));
189 break;
190 }
191 case DERIVED: {
192 parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
193 parentBuilderObject, leafValue, false);
194 break;
195 }
196 case UNION: {
197 // TODO
198 break;
199 }
200 case LEAFREF: {
201 // TODO
202 break;
203 }
204 case ENUMERATION: {
205 parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
206 parentBuilderObject, leafValue, true);
207 break;
208 }
209 default: {
210 log.error(DATA_TYPE_NOT_SUPPORT);
211 }
212 }
213 }
214
215 /**
216 * To set data into parent setter method from string value for derived type.
217 *
218 * @param leafValue leafValue argument is used to set the value
219 * in method
220 * @param parentSetterMethod Invokes the underlying method represented
221 * by this parentSetterMethod
222 * @param parentBuilderObject the parentBuilderObject is to invoke the
223 * underlying method
224 * @param ydtExtendedContext ydtExtendedContext is used to get
225 * application related
226 * information maintained in YDT
227 * @param isEnum isEnum parameter is used to check whether
228 * type is enum or derived
229 * information maintained in YDT
230 * @throws InvocationTargetException throws InvocationTargetException
231 * @throws IllegalAccessException throws IllegalAccessException
232 * @throws NoSuchMethodException throws NoSuchMethodException
233 */
234 private void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
235 Method parentSetterMethod,
236 Object parentBuilderObject,
237 String leafValue, boolean isEnum)
238 throws InvocationTargetException, IllegalAccessException,
239 NoSuchMethodException {
240 Class<?> childSetClass = null;
241 Constructor<?> childConstructor = null;
242 Object childValue = null;
243 Object childObject = null;
244 Method childMethod = null;
245
246 YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
247 String packageName = yangJavaModule.getJavaPackage();
248 String className = getCapitalCase(
249 yangJavaModule.getJavaClassNameOrBuiltInType());
250 String qualifiedClassName = packageName + PERIOD + className;
251 ClassLoader classLoader = getClassLoader(registry,
252 qualifiedClassName,
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530253 ydtExtendedContext, null);
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530254 try {
255 childSetClass = classLoader.loadClass(qualifiedClassName);
256 } catch (ClassNotFoundException e) {
257 log.error(FAIL_TO_LOAD_CLASS + packageName + PERIOD + className);
258 }
259 if (!isEnum) {
260
261 if (childSetClass != null) {
262 childConstructor = childSetClass.getDeclaredConstructor();
263 }
264
265 if (childConstructor != null) {
266 childConstructor.setAccessible(true);
267 }
268 try {
269 if (childConstructor != null) {
270 childObject = childConstructor.newInstance();
271 }
272 } catch (InstantiationException e) {
273 log.error(FAIL_TO_LOAD_CONSTRUCTOR + className);
274 }
275 if (childSetClass != null) {
276 childMethod = childSetClass
277 .getDeclaredMethod(FROM_STRING, String.class);
278 }
279 } else {
280 if (childSetClass != null) {
281 childMethod = childSetClass.getDeclaredMethod(OF, String.class);
282 }
283 //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
284 //leafValue = leafValue.toUpperCase();
285 }
286 if (childMethod != null) {
287 childValue = childMethod.invoke(childObject, leafValue);
288 }
289
290 parentSetterMethod.invoke(parentBuilderObject, childValue);
291 }
292
293 /**
294 * Updates class loader for all the classes.
295 *
296 * @param registry YANG schema registry
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530297 * @param curNode YDT context
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530298 * @param qualifiedClassName qualified class name
299 * @return current class loader
300 */
301 private ClassLoader getClassLoader(YangSchemaRegistry registry,
302 String qualifiedClassName,
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530303 YdtExtendedContext curNode,
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530304 YdtExtendedContext context) {
305
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530306 if (context != null && curNode == context) {
307 YangSchemaNode yangSchemaNode = curNode.getYangSchemaNode();
308 while (!(yangSchemaNode instanceof RpcNotificationContainer)) {
309 curNode = (YdtExtendedContext) curNode.getParent();
310 if (curNode == null) {
311 throw new YobExceptions("Invalid YANG data tree");
312 }
313 yangSchemaNode = curNode.getYangSchemaNode();
314 }
315
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530316 Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
317 qualifiedClassName);
318 return regClass.getClassLoader();
319 } else {
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530320 YdtExtendedContext parent =
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530321 (YdtExtendedContext) curNode.getParent();
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530322 YobWorkBench parentBuilderContainer =
323 (YobWorkBench) parent.getAppInfo(YOB);
324 Object parentObj =
Vidyashree Rama76faccc2016-10-17 22:06:52 +0530325 parentBuilderContainer.getParentBuilder(curNode, registry);
Rama-Huaweib711e5c2016-08-31 07:55:46 +0530326 return parentObj.getClass().getClassLoader();
327 }
328 }
329
330 /**
331 * Returns the YANG schema registry.
332 *
333 * @return registry YANG schema registry
334 */
335 public YangSchemaRegistry getRegistry() {
336 return registry;
337 }
338
339 /**
340 * Sets the YANG schema registry.
341 *
342 * @param registry YANG schema registry
343 */
344 public void setRegistry(YangSchemaRegistry registry) {
345 this.registry = registry;
346 }
347}