logging changes
[ccsdk/sli/core.git] / sli / provider / src / main / java / org / onap / ccsdk / sli / core / sli / provider / MdsalHelper.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                         reserved.
7  * ================================================================================
8  * Modifications Copyright (C) 2018 IBM.
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.ccsdk.sli.core.sli.provider;
25
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.InputStream;
29 import java.io.PrintStream;
30 import java.lang.reflect.Constructor;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.lang.reflect.ParameterizedType;
34 import java.lang.reflect.Type;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Properties;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
46 import org.opendaylight.yangtools.yang.binding.Identifier;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public class MdsalHelper {
51
52     private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
53     private static Properties yangMappingProperties = new Properties();
54     private static final String IP_ADDRESS="IpAddress";
55     private static final String IPV4_ADDRESS="Ipv4Address";
56     private static final String IPV6_ADDRESS="Ipv6Address";
57     
58     private static final String IP_PREFIX="IpPrefix";
59     private static final String SETTING_PROPERTY="Setting property ";
60     private static final String BUILDER="-builder";
61     
62     @Deprecated
63     public static void setProperties(Properties input) {
64         setYangMappingProperties(input);
65     }
66
67     @Deprecated
68     public static void setYangMappingProperties(Properties properties) {
69         for (Object propNameObj : properties.keySet()) {
70             String propName = (String) propNameObj;
71             MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
72         }
73     }
74
75     @Deprecated
76     public static void loadProperties(String propertiesFile) {
77         File file = new File(propertiesFile);
78         Properties properties = new Properties();
79         if (file.isFile() && file.canRead()) {
80             try (InputStream input = new FileInputStream(file)) {
81                 properties.load(input);
82                 MdsalHelper.setYangMappingProperties(properties);
83                 LOG.info("Loaded properties from " + propertiesFile);
84             } catch (Exception e) {
85                 LOG.error("Failed to load properties " + propertiesFile + "\n", e);
86             }
87         } else {
88             LOG.error("Failed to load the properties file " + propertiesFile + "\n");
89             LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
90         }
91     }
92
93     public static Properties toProperties(Properties props, Object fromObj) {
94         return toProperties(props, fromObj, false);
95     }
96
97     public static Properties toProperties(Properties props, Object fromObj, Boolean useLegacyEnumerationMapping) {
98         Class fromClass = null;
99
100         if (fromObj != null) {
101             fromClass = fromObj.getClass();
102         }
103         return toProperties(props, "", fromObj, fromClass, useLegacyEnumerationMapping);
104     }
105
106     public static Properties toProperties(Properties props, String pfx, Object fromObj) {
107         return toProperties(props, pfx, fromObj, false);
108     }
109
110     public static Properties toProperties(Properties props, String pfx, Object fromObj, Boolean useLegacyEnumerationMapping) {
111         Class fromClass = null;
112
113         if (fromObj != null) {
114             fromClass = fromObj.getClass();
115         }
116
117         return toProperties(props, pfx, fromObj, fromClass, useLegacyEnumerationMapping);
118     }
119
120     public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
121         return toProperties(props, pfx, fromObj, fromClass, false);
122     }
123
124     public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass, Boolean useLegacyEnumerationMapping) {
125
126         if (fromObj == null) {
127             return props;
128         }
129         String simpleTypeName = fromObj.getClass().getTypeName();
130         simpleTypeName = simpleTypeName.substring(simpleTypeName.lastIndexOf(".") + 1);
131         
132         if (classHasSpecialHandling(simpleTypeName)) {
133             try {
134
135                 Method m = fromClass.getMethod(getStringValueMethod(simpleTypeName), null);
136                 boolean isAccessible = m.isAccessible();
137                 if (!isAccessible) {
138                     m.setAccessible(true);
139                 }
140                 Object retValue = m.invoke(fromObj);
141                 if (retValue != null) {
142                     String propVal = null;
143                     if (IP_ADDRESS.equals(simpleTypeName) || IP_PREFIX.equals(simpleTypeName)
144                                 || IPV4_ADDRESS.equals(simpleTypeName) || IPV6_ADDRESS.equals(simpleTypeName)) {
145                         propVal = (String) retValue;
146                     } else if ("Dscp".equals(simpleTypeName)) {
147                         propVal = String.valueOf((short) retValue);
148                     } else if ("PortNumber".equals(simpleTypeName)) {
149                         propVal = String.valueOf((Integer) retValue);
150                     }
151                     LOG.debug(SETTING_PROPERTY + pfx + " to " + propVal);
152                     props.setProperty(pfx, propVal);
153                 }
154             } catch (Exception e) {
155                 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
156                         + ".getValue() to Properties entry", e);
157             }
158         } else if (fromObj instanceof List) {
159             List fromList = (List) fromObj;
160
161             for (int i = 0; i < fromList.size(); i++) {
162                 toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass, useLegacyEnumerationMapping);
163             }
164             props.setProperty(pfx + "_length", Integer.toString(fromList.size()));
165
166         } else if (isYangGenerated(fromClass)) {
167             // Class is yang generated.
168
169             String propNamePfx = null;
170
171             // If called from a list (so prefix ends in ']'), don't
172             // add class name again
173             if (pfx.endsWith("]")) {
174                 propNamePfx = pfx;
175             } else {
176                 if ((pfx != null) && (pfx.length() > 0)) {
177                     propNamePfx = pfx;
178                 } else {
179                     propNamePfx = toLowerHyphen(fromClass.getSimpleName());
180                 }
181
182                 if (propNamePfx.endsWith(BUILDER)) {
183                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
184                 }
185
186                 if (propNamePfx.endsWith("-impl")) {
187                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
188                 }
189             }
190
191             // Iterate through getter methods to figure out values we need to
192             // save from
193
194             int numGetters = 0;
195             String lastGetterName = null;
196             String propVal = null;
197
198             for (Method m : fromClass.getMethods()) {
199                 if (isGetter(m)) {
200
201                     numGetters++;
202                     lastGetterName = m.getName();
203
204                     Class returnType = m.getReturnType();
205                     String fieldName;
206                     if (m.getName().startsWith("get")) {
207                         fieldName = toLowerHyphen(m.getName().substring(3));
208                     } else {
209
210                         fieldName = toLowerHyphen(m.getName().substring(2));
211                     }
212
213                     fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
214
215                     // Is the return type a yang generated class?
216                     if (isYangGenerated(returnType)) {
217                         // Is it an enum?
218                         if (returnType.isEnum()) {
219                             // Return type is a typedef. Save its value.
220                             try {
221                                 boolean isAccessible = m.isAccessible();
222                                 if (!isAccessible) {
223                                     m.setAccessible(true);
224                                 }
225
226                                 Object retValue = m.invoke(fromObj);
227
228                                 if (!isAccessible) {
229                                     m.setAccessible(isAccessible);
230                                 }
231                                 if (retValue != null) {
232                                     String propName = propNamePfx + "." + fieldName;
233                                     if (useLegacyEnumerationMapping) {
234                                         propVal = retValue.toString();
235                                         props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
236                                     } else {
237                                         Method method = retValue.getClass().getMethod("getName");
238                                         String yangValue = (String) method.invoke(retValue);
239                                         props.setProperty(propName, yangValue);
240                                     }
241
242                                 }
243                             } catch (Exception e) {
244                                 LOG.error(
245                                         "Caught exception trying to convert Yang-generated enum returned by "
246                                                 + fromClass.getName() + "." + m.getName() + "() to Properties entry",
247                                         e);
248                             }
249                         } else {
250                             try {
251                                 boolean isAccessible = m.isAccessible();
252                                 if (!isAccessible) {
253                                     m.setAccessible(true);
254                                 }
255                                 Object retValue = m.invoke(fromObj);
256
257                                 if (retValue instanceof byte[]) {
258                                     retValue = new String((byte[]) retValue, "UTF-8");
259                                 }
260                                 if (!isAccessible) {
261                                     m.setAccessible(isAccessible);
262                                 }
263                                 if (retValue != null) {
264                                     toProperties(props, propNamePfx + "." + fieldName, retValue, returnType, useLegacyEnumerationMapping);
265                                 }
266                             } catch (Exception e) {
267
268                                 if (m.getName().equals("getKey")) {
269                                     LOG.trace("Caught " + e.getClass().getName()
270                                             + " exception trying to convert results from getKey() - ignoring");
271                                 } else {
272                                     LOG.error("Caught exception trying to convert Yang-generated class returned by"
273                                             + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
274                                 }
275                             }
276                         }
277                     } else if (returnType.equals(Class.class)) {
278
279                     } else if (List.class.isAssignableFrom(returnType)) {
280
281                         // This getter method returns a list.
282                         try {
283                             boolean isAccessible = m.isAccessible();
284                             if (!isAccessible) {
285                                 m.setAccessible(true);
286                             }
287                             Object retList = m.invoke(fromObj);
288                             if (!isAccessible) {
289                                 m.setAccessible(isAccessible);
290                             }
291                             // Figure out what type of elements are stored in
292                             // this array.
293                             Type paramType = m.getGenericReturnType();
294                             Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
295                             toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType, useLegacyEnumerationMapping);
296                         } catch (Exception e) {
297                             LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "."
298                                     + m.getName() + "() to Properties entry", e);
299                         }
300
301                     } else {
302
303                         // Method returns something that is not a List and not
304                         // yang-generated.
305                         // Save its value
306                         try {
307                             String propName = propNamePfx + "." + fieldName;
308                             boolean isAccessible = m.isAccessible();
309                             if (!isAccessible) {
310                                 m.setAccessible(true);
311                             }
312                             Object propValObj = m.invoke(fromObj);
313                             if (!isAccessible) {
314                                 m.setAccessible(isAccessible);
315                             }
316
317                             if (propValObj != null) {
318                                 if (propValObj instanceof byte[]) {
319                                     propVal = new String((byte[]) propValObj, "UTF-8");
320                                 } else {
321                                     propVal = propValObj.toString();
322                                 }
323                                 LOG.debug(SETTING_PROPERTY + propName + " to " + propVal);
324                                 props.setProperty(propName, propVal);
325
326                             }
327                         } catch (Exception e) {
328                             if (m.getName().equals("getKey")) {
329                                 LOG.trace("Caught " + e.getClass().getName()
330                                         + " exception trying to convert results from getKey() - ignoring");
331                             } else {
332                                 LOG.error("Caught exception trying to convert value returned by" + fromClass.getName()
333                                         + "." + m.getName() + "() to Properties entry", e);
334                             }
335                         }
336                     }
337
338                 }
339             }
340
341             // End of method loop. If there was only one getter, named
342             // "getValue", then
343             // set value identified by "prefix" to that one value.
344             if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
345                 props.setProperty(propNamePfx, propVal);
346             }
347         } else {
348             // Class is not yang generated and not a list
349             // It must be an element of a leaf list - set "prefix" to value
350             String fromVal = null;
351             if (fromObj instanceof byte[]) {
352                 try {
353                     fromVal = new String((byte[]) fromObj, "UTF-8");
354                 } catch (Exception e) {
355                     LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
356                     fromVal = fromObj.toString();
357                 }
358
359             } else {
360                 fromVal = fromObj.toString();
361             }
362             LOG.debug(SETTING_PROPERTY + pfx + " to " + fromVal);
363             props.setProperty(pfx, fromVal);
364         }
365
366         return (props);
367     }
368
369     public static Object toBuilder(Properties props, Object toObj) {
370
371         return (toBuilder(props, "", toObj));
372     }
373
374     public static List toList(Properties props, String pfx, List toObj, Class elemType) {
375
376         int maxIdx = -1;
377         boolean foundValue = false;
378
379         if (props.containsKey(pfx + "_length")) {
380             try {
381                 int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
382
383                 if (listLength > 0) {
384                     maxIdx = listLength - 1;
385                 }
386             } catch (NumberFormatException e) {
387                 LOG.info("Invalid input for length ", e);
388             }
389         }
390
391         String arrayKey = pfx + "[";
392         int arrayKeyLength = arrayKey.length();
393         if (maxIdx == -1) {
394             // Figure out array size
395             for (Object pNameObj : props.keySet()) {
396                 String key = (String) pNameObj;
397
398                 if (key.startsWith(arrayKey)) {
399                     String idxStr = key.substring(arrayKeyLength);
400                     int endloc = idxStr.indexOf("]");
401                     if (endloc != -1) {
402                         idxStr = idxStr.substring(0, endloc);
403                     }
404                     try {
405                         int curIdx = Integer.parseInt(idxStr);
406                         if (curIdx > maxIdx) {
407                             maxIdx = curIdx;
408                         }
409                     } catch (Exception e) {
410                         LOG.error("Illegal subscript in property {}", key, e);
411                     }
412
413                 }
414             }
415         }
416
417         for (int i = 0; i <= maxIdx; i++) {
418
419             String curBase = pfx + "[" + i + "]";
420
421             if (isYangGenerated(elemType)) {
422
423                 if (isIpAddress(elemType)) {
424
425                     String curValue = props.getProperty(curBase, "");
426
427                     if ((curValue != null) && (curValue.length() > 0)) {
428                         toObj.add(IpAddressBuilder.getDefaultInstance(curValue));
429                         foundValue = true;
430                     }
431                 } else if (isIpv4Address(elemType)) {
432                     String curValue = props.getProperty(curBase, "");
433
434                     if ((curValue != null) && (curValue.length() > 0)) {
435                         toObj.add(new Ipv4Address(curValue));
436                         foundValue = true;
437                     }
438
439                 } else if (isIpv6Address(elemType)) {
440                     String curValue = props.getProperty(curBase, "");
441
442                     if ((curValue != null) && (curValue.length() > 0)) {
443                         toObj.add(new Ipv6Address(curValue));
444                         foundValue = true;
445                     }
446                 } else if (isIpPrefix(elemType)) {
447
448                     String curValue = props.getProperty(curBase, "");
449
450                     if ((curValue != null) && (curValue.length() > 0)) {
451                         toObj.add(IpPrefixBuilder.getDefaultInstance(curValue));
452                         foundValue = true;
453                     }
454                 } else if (isPortNumber(elemType)) {
455
456                     String curValue = props.getProperty(curBase, "");
457
458                     if ((curValue != null) && (curValue.length() > 0)) {
459                         toObj.add(PortNumber.getDefaultInstance(curValue));
460                         foundValue = true;
461                     }
462                 } else if (isDscp(elemType)) {
463
464                     String curValue = props.getProperty(curBase, "");
465
466                     if ((curValue != null) && (curValue.length() > 0)) {
467                         toObj.add(Dscp.getDefaultInstance(curValue));
468                         foundValue = true;
469                     }
470                 } else {
471                     String builderName = elemType.getName() + "Builder";
472                     try {
473                         Class builderClass = Class.forName(builderName);
474                         Object builderObj = builderClass.newInstance();
475                         Method buildMethod = builderClass.getMethod("build");
476                         builderObj = toBuilder(props, curBase, builderObj, true);
477                         if (builderObj != null) {
478                             Object builtObj = buildMethod.invoke(builderObj);
479                             toObj.add(builtObj);
480                             foundValue = true;
481                         }
482
483                     } catch (ClassNotFoundException e) {
484                         LOG.warn("Could not find builder class {}", builderName, e);
485                     } catch (Exception e) {
486                         LOG.error("Caught exception trying to populate list from {}", pfx, e);
487                     }
488                 }
489             } else {
490                 // Must be a leaf list
491                 String curValue = props.getProperty(curBase, "");
492
493                 toObj.add(curValue);
494
495                 if ((curValue != null) && (curValue.length() > 0)) {
496                     foundValue = true;
497                 }
498             }
499
500         }
501
502         if (foundValue) {
503             return (toObj);
504         } else {
505             return (null);
506         }
507
508     }
509
510     public static Object toBuilder(Properties props, String pfx, Object toObj) {
511         return (toBuilder(props, pfx, toObj, false));
512     }
513
514     public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
515
516         Class toClass = toObj.getClass();
517         boolean foundValue = false;
518
519         Ipv4Address addr;
520
521         if (isYangGenerated(toClass)) {
522             // Class is yang generated.
523             String propNamePfx = null;
524             if (preservePfx) {
525                 propNamePfx = pfx;
526             } else {
527
528                 if ((pfx != null) && (pfx.length() > 0)) {
529                     propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
530                 } else {
531                     propNamePfx = toLowerHyphen(toClass.getSimpleName());
532                 }
533
534                 if (propNamePfx.endsWith(BUILDER)) {
535                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
536                 }
537
538                 if (propNamePfx.endsWith("-impl")) {
539                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
540                 }
541             }
542
543             if (toObj instanceof Identifier) {
544                 return (toObj);
545             }
546
547             // Iterate through getter methods to figure out values we need to
548             // set
549
550             for (Method m : toClass.getMethods()) {
551                 if (isSetter(m)) {
552                     Class paramTypes[] = m.getParameterTypes();
553                     Class paramClass = paramTypes[0];
554
555                     String fieldName = toLowerHyphen(m.getName().substring(3));
556                     fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
557
558                     String propName = propNamePfx + "." + fieldName;
559
560                     String paramValue = props.getProperty(propName);
561                     if (paramValue == null) {
562
563                     } else if ("".equals(paramValue)) {
564                         LOG.trace(propName + " was set to the empty string, setting it to null");
565                         paramValue = null;
566                     } else {
567
568                     }
569
570                     // Is the return type a yang generated class?
571                     if (isYangGenerated(paramClass)) {
572                         // Is it an enum?
573                         if (paramClass.isEnum()) {
574
575                             // Param type is a typedef.
576                             if ((paramValue != null) && (paramValue.length() > 0)) {
577                                 Object paramObj = null;
578
579                                 try {
580                                     paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
581                                 } catch (Exception e) {
582                                     LOG.error("Caught exception trying to convert field " + propName + " to enum "
583                                             + paramClass.getName(), e);
584                                 }
585
586                                 try {
587                                     boolean isAccessible = m.isAccessible();
588                                     if (!isAccessible) {
589                                         m.setAccessible(true);
590                                     }
591
592                                     m.invoke(toObj, paramObj);
593
594                                     if (!isAccessible) {
595                                         m.setAccessible(isAccessible);
596                                     }
597                                     foundValue = true;
598
599                                 } catch (Exception e) {
600                                     LOG.error("Caught exception trying to create Yang-generated enum expected by"
601                                             + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
602                                 }
603                             }
604                         } else {
605
606                             String simpleName = paramClass.getSimpleName();
607
608                             if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
609                                     || IP_ADDRESS.equals(simpleName)) {
610                                 
611
612                                 if ((paramValue != null) && (paramValue.length() > 0)) {
613                                     try {
614                                         IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
615
616                                         if (IPV4_ADDRESS.equals(simpleName)) {
617                                             m.invoke(toObj, ipAddr.getIpv4Address());
618                                         } else if (IPV6_ADDRESS.equals(simpleName)) {
619                                             m.invoke(toObj, ipAddr.getIpv6Address());
620
621                                         } else {
622                                             m.invoke(toObj, ipAddr);
623                                         }
624                                         foundValue = true;
625                                     } catch (Exception e) {
626                                         LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
627                                                 + "(" + paramValue + ")", e);
628
629                                     }
630                                 } else {
631                                     try {
632                                         boolean isAccessible = m.isAccessible();
633                                         if (!isAccessible) {
634                                             m.setAccessible(true);
635                                         }
636
637                                         m.invoke(toObj, paramValue);
638                                         if (!isAccessible) {
639                                             m.setAccessible(isAccessible);
640                                         }
641                                         foundValue = true;
642
643                                     } catch (Exception e) {
644                                         LOG.error("Caught exception trying to call " + toClass.getName() + "."
645                                                 + m.getName() + "() with Properties entry", e);
646                                     }
647                                 }
648                             } else if (IP_PREFIX.equals(simpleName)) {
649                                 if ((paramValue != null) && (paramValue.length() > 0)) {
650                                     try {
651                                         IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
652                                         m.invoke(toObj, ipPrefix);
653                                         foundValue = true;
654                                     } catch (Exception e) {
655                                         LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
656                                                 + "(" + paramValue + ")", e);
657                                     }
658                                 }
659                             } else if ("PortNumber".equals(simpleName)) {
660                                 if ((paramValue != null) && (paramValue.length() > 0)) {
661                                     try {
662                                         PortNumber portNumber = PortNumber.getDefaultInstance(paramValue);
663                                         m.invoke(toObj, portNumber);
664                                         foundValue = true;
665                                     } catch (Exception e) {
666                                         LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
667                                                 + "(" + paramValue + ")", e);
668                                     }
669                                 }
670                             } else if ("Dscp".equals(simpleName)) {
671                                 if ((paramValue != null) && (paramValue.length() > 0)) {
672                                     try {
673                                         Dscp dscp = Dscp.getDefaultInstance(paramValue);
674                                         m.invoke(toObj, dscp);
675                                         foundValue = true;
676                                     } catch (Exception e) {
677                                         LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
678                                                 + "(" + paramValue + ")", e);
679                                     }
680                                 }
681                             } else {
682                                 // setter expects a yang-generated class. Need
683                                 // to
684                                 // create a builder to set it.
685
686                                 String builderName = paramClass.getName() + "Builder";
687                                 Class builderClass = null;
688                                 Object builderObj = null;
689                                 Object paramObj = null;
690
691                                 Object constObj = null;
692
693                                 try {
694                                     builderClass = Class.forName(builderName);
695                                     builderObj = builderClass.newInstance();
696                                     paramObj = toBuilder(props, propNamePfx, builderObj);
697                                 } catch (ClassNotFoundException e) {
698                                     LOG.info("Builder class {} not found ", builderName, e);
699                                     if (paramValue == null) {
700                                         try {
701                                             boolean isAccessible = m.isAccessible();
702                                             if (!isAccessible) {
703                                                 m.setAccessible(true);
704                                             }
705
706                                             m.invoke(toObj, new Object[] { null });
707                                             if (!isAccessible) {
708                                                 m.setAccessible(isAccessible);
709                                             }
710                                             foundValue = true;
711
712                                         } catch (Exception e1) {
713                                             LOG.error("Caught exception trying to cally" + toClass.getName() + "."
714                                                     + m.getName() + "() with Properties entry", e1);
715                                         }
716                                     } else {
717                                         try {
718                                             // See if I can find a constructor I
719                                             // can
720                                             // use
721                                             Constructor[] constructors = paramClass.getConstructors();
722                                             // Is there a String constructor?
723                                             for (Constructor c : constructors) {
724                                                 Class[] cParms = c.getParameterTypes();
725                                                 if ((cParms != null) && (cParms.length == 1)) {
726                                                     if (String.class.isAssignableFrom(cParms[0])) {
727                                                         constObj = c.newInstance(paramValue);
728                                                     }
729                                                 }
730                                             }
731
732                                             if (constObj == null) {
733                                                 // Is there a Long constructor?
734                                                 for (Constructor c : constructors) {
735                                                     Class[] cParms = c.getParameterTypes();
736                                                     if ((cParms != null) && (cParms.length == 1)) {
737                                                         if (Long.class.isAssignableFrom(cParms[0])) {
738                                                             constObj = c.newInstance(Long.parseLong(paramValue));
739                                                         }
740                                                     }
741                                                 }
742
743                                             }
744
745                                             if (constObj == null) {
746
747                                                 // Last chance - see if
748                                                 // parameter class has a static
749                                                 // method
750                                                 // getDefaultInstance(String)
751                                                 try {
752                                                     Method gm =
753                                                             paramClass.getMethod("getDefaultInstance", String.class);
754
755                                                     int gmodifier = gm.getModifiers();
756                                                     if (Modifier.isStatic(gmodifier)) {
757                                                         // Invoke static
758                                                         // getDefaultInstance(String)
759                                                         paramObj = gm.invoke(null, paramValue);
760                                                     }
761
762                                                 } catch (Exception gme) {
763                                                     LOG.info("Unable to find static method getDefaultInstance for "
764                                                             + "class {}", paramClass.getSimpleName(), gme);
765                                                 }
766                                             }
767
768                                         } catch (Exception e1) {
769                                             LOG.warn(
770                                                     "Could not find a suitable constructor for " + paramClass.getName(),
771                                                     e1);
772                                         }
773
774                                         if (constObj == null) {
775                                             LOG.warn("Could not find builder class " + builderName
776                                                     + " and could not find a String or Long constructor or static "
777                                                     + "getDefaultInstance(String) - trying just to set passing paramValue");
778
779                                         }
780                                     }
781                                 } catch (Exception e) {
782                                     LOG.error("Caught exception trying to create builder " + builderName, e);
783                                 }
784
785                                 if (paramObj != null && builderClass != null) {
786
787                                     try {
788                                         Method buildMethod = builderClass.getMethod("build");
789
790                                         Object builtObj = buildMethod.invoke(paramObj);
791
792                                         boolean isAccessible = m.isAccessible();
793                                         if (!isAccessible) {
794                                             m.setAccessible(true);
795                                         }
796
797                                         m.invoke(toObj, builtObj);
798                                         if (!isAccessible) {
799                                             m.setAccessible(isAccessible);
800                                         }
801                                         foundValue = true;
802
803                                     } catch (Exception e) {
804                                         LOG.error("Caught exception trying to set Yang-generated class expected by"
805                                                 + toClass.getName() + "." + m.getName() + "() from Properties entry",
806                                                 e);
807                                     }
808                                 } else {
809                                     try {
810                                         boolean isAccessible = m.isAccessible();
811                                         if (!isAccessible) {
812                                             m.setAccessible(true);
813                                         }
814
815                                         if (constObj != null) {
816                                             m.invoke(toObj, constObj);
817                                         } else {
818                                             m.invoke(toObj, paramValue);
819                                         }
820                                         if (!isAccessible) {
821                                             m.setAccessible(isAccessible);
822                                         }
823                                         foundValue = true;
824
825                                     } catch (Exception e) {
826                                         LOG.error("Caught exception trying to convert value returned by"
827                                                 + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
828                                     }
829                                 }
830                             }
831                         }
832                     } else {
833
834                         // Setter's argument is not a yang-generated class. See
835                         // if it is a List.
836
837                         if (List.class.isAssignableFrom(paramClass)) {
838                             // Figure out what type of args are in List and pass
839                             // that to toList().
840
841                             Type paramType = m.getGenericParameterTypes()[0];
842                             Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
843                             Object paramObj = new LinkedList();
844                             try {
845                                 paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
846                             } catch (Exception e) {
847                                 LOG.error("Caught exception trying to create list expected as argument to {}.{}",
848                                         toClass.getName(), m.getName(), e);
849                             }
850
851                             if (paramObj != null) {
852                                 try {
853                                     boolean isAccessible = m.isAccessible();
854                                     if (!isAccessible) {
855                                         m.setAccessible(true);
856                                     }
857                                     m.invoke(toObj, paramObj);
858                                     if (!isAccessible) {
859                                         m.setAccessible(isAccessible);
860                                     }
861                                     foundValue = true;
862
863                                 } catch (Exception e) {
864                                     LOG.error("Caught exception trying to convert List returned by" + toClass.getName()
865                                             + "." + m.getName() + "() to Properties entry", e);
866                                 }
867                             }
868                         } else {
869
870                             // Setter expects something that is not a List and
871                             // not yang-generated. Just pass the parameter value
872                             if ((paramValue != null) && (paramValue.length() > 0)) {
873
874                                 Object constObj = null;
875
876                                 try {
877                                     // See if I can find a constructor I can use
878                                     Constructor[] constructors = paramClass.getConstructors();
879                                     // Is there a String constructor?
880                                     for (Constructor c : constructors) {
881                                         Class[] cParms = c.getParameterTypes();
882                                         if ((cParms != null) && (cParms.length == 1)) {
883                                             if (String.class.isAssignableFrom(cParms[0])) {
884                                                 constObj = c.newInstance(paramValue);
885                                             }
886                                         }
887                                     }
888
889                                     if (constObj == null) {
890                                         // Is there a Long constructor?
891                                         for (Constructor c : constructors) {
892                                             Class[] cParms = c.getParameterTypes();
893                                             if ((cParms != null) && (cParms.length == 1)) {
894                                                 if (Long.class.isAssignableFrom(cParms[0])) {
895                                                     constObj = c.newInstance(Long.parseLong(paramValue));
896                                                 }
897                                             }
898                                         }
899
900                                     }
901
902                                     if (constObj != null) {
903                                         try {
904                                             m.invoke(toObj, constObj);
905                                             foundValue = true;
906                                         } catch (Exception e2) {
907                                             LOG.error("Caught exception trying to call " + m.getName(), e2);
908                                         }
909                                     } else {
910                                         try {
911                                             boolean isAccessible = m.isAccessible();
912                                             if (!isAccessible) {
913                                                 m.setAccessible(true);
914                                             }
915                                             m.invoke(toObj, paramValue);
916                                             if (!isAccessible) {
917                                                 m.setAccessible(isAccessible);
918                                             }
919                                             foundValue = true;
920
921                                         } catch (Exception e) {
922                                             LOG.error("Caught exception trying to convert value returned by"
923                                                     + toClass.getName() + "." + m.getName() + "() to Properties entry",
924                                                     e);
925                                         }
926                                     }
927                                 } catch (Exception e1) {
928                                     LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
929                                 }
930
931                             }
932                         }
933                     }
934                 } // End of section handling "setter" method
935             } // End of loop through Methods
936         } // End of section handling yang-generated class
937
938         if (foundValue) {
939             return (toObj);
940         } else {
941             return (null);
942         }
943     }
944
945     private static boolean classHasSpecialHandling(String simpleName) {
946         if (IP_ADDRESS.equals(simpleName) || IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
947                 || IP_PREFIX.equals(simpleName) || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
948             return true;
949         }
950         return false;
951     }
952     
953     private static String getStringValueMethod(String simpleName){
954         if (IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)) {
955                 return("stringValue");
956         } else {
957                 return("getValue");
958         }
959     }
960
961     public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
962         boolean foundValue = false;
963
964         if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
965             // Class is yang generated.
966             String propNamePfx = null;
967             if (pfx.endsWith("]")) {
968                 propNamePfx = pfx;
969             } else {
970
971                 if ((pfx != null) && (pfx.length() > 0)) {
972                     propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
973                 } else {
974                     propNamePfx = toLowerHyphen(toClass.getSimpleName());
975                 }
976
977                 if (propNamePfx.endsWith(BUILDER)) {
978                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
979                 }
980
981                 if (propNamePfx.endsWith("-impl")) {
982                     propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
983                 }
984             }
985
986             // Iterate through getter methods to figure out values we need to
987             // set
988
989             for (Method m : toClass.getMethods()) {
990                 if (isGetter(m)) {
991                     Class returnClass = m.getReturnType();
992
993                     String fieldName = toLowerHyphen(m.getName().substring(3));
994                     if (fieldName != null) {
995                         fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
996                     } else {
997                         fieldName = "";
998                     }
999                     String propName = propNamePfx + "." + fieldName;
1000
1001                     // Is the return type a yang generated class?
1002                     if (isYangGenerated(returnClass)) {
1003                         // Is it an enum?
1004                         if (returnClass.isEnum()) {
1005                             pstr.print("\n\n     * " + propName);
1006                         } else {
1007
1008                             String simpleName = returnClass.getSimpleName();
1009
1010                             if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
1011                                     || IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)
1012                                     || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
1013                                 pstr.print("\n\n     * " + propName);
1014                             } else {
1015                                 printPropertyList(pstr, propNamePfx, returnClass);
1016                             }
1017
1018                         }
1019                     } else {
1020
1021                         // Setter's argument is not a yang-generated class. See
1022                         // if it is a List.
1023
1024                         if (List.class.isAssignableFrom(returnClass)) {
1025                             // Figure out what type of args are in List and pass
1026                             // that to toList().
1027
1028                             Type returnType = m.getGenericReturnType();
1029                             Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
1030                             Class elementClass = (Class) elementType;
1031                             printPropertyList(pstr,
1032                                     propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]",
1033                                     elementClass);
1034
1035                         } else if (!returnClass.equals(Class.class)) {
1036
1037                             // Setter expects something that is not a List and
1038                             // not yang-generated. Just pass the parameter value
1039                             pstr.print("\n\n     * " + propName);
1040                         }
1041                     }
1042                 } // End of section handling "setter" method
1043             } // End of loop through Methods
1044         } // End of section handling yang-generated class
1045
1046     }
1047
1048     public static boolean isYangGenerated(Class c) {
1049         if (c != null) {
1050             return (c.getName().startsWith("org.opendaylight.yang.gen."));
1051         }
1052         return false;
1053     }
1054
1055     public static boolean isIpPrefix(Class c) {
1056
1057         if (c == null) {
1058             return (false);
1059         }
1060         if (!isIetfInet(c)) {
1061             return (false);
1062         }
1063         String simpleName = c.getSimpleName();
1064         return (IP_PREFIX.equals(simpleName));
1065     }
1066
1067     public static boolean isIpv4Address(Class c) {
1068
1069         if (c == null) {
1070             return (false);
1071         }
1072         if (!isIetfInet(c)) {
1073             return (false);
1074         }
1075         String simpleName = c.getSimpleName();
1076         return (IPV4_ADDRESS.equals(simpleName));
1077     }
1078
1079     public static boolean isIpv6Address(Class c) {
1080
1081         if (c == null) {
1082             return (false);
1083         }
1084         if (!isIetfInet(c)) {
1085             return (false);
1086         }
1087         String simpleName = c.getSimpleName();
1088         return (IPV6_ADDRESS.equals(simpleName));
1089     }
1090
1091     public static boolean isIpAddress(Class c) {
1092
1093         if (c == null) {
1094             return (false);
1095         }
1096         if (!isIetfInet(c)) {
1097             return (false);
1098         }
1099         String simpleName = c.getSimpleName();
1100         return (IP_ADDRESS.equals(simpleName));
1101     }
1102
1103     public static boolean isPortNumber(Class c) {
1104
1105         if (c == null) {
1106             return (false);
1107         }
1108         if (!isIetfInet(c)) {
1109             return (false);
1110         }
1111
1112         String simpleName = c.getSimpleName();
1113         return ("PortNumber".equals(simpleName));
1114     }
1115
1116     public static boolean isDscp(Class c) {
1117
1118         if (c == null) {
1119             return (false);
1120         }
1121         if (!isIetfInet(c)) {
1122             return (false);
1123         }
1124         String simpleName = c.getSimpleName();
1125         return ("Dscp".equals(simpleName));
1126     }
1127
1128     public static boolean isIetfInet(Class c) {
1129
1130         Package p = c.getPackage();
1131         if (p != null) {
1132             String pkgName = p.getName();
1133
1134             if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) {
1135                 return (true);
1136             }
1137         }
1138
1139         return (false);
1140     }
1141
1142     public static String toLowerHyphen(String inStr) {
1143         if (inStr == null) {
1144             return (null);
1145         }
1146
1147         String str = inStr.substring(0, 1).toLowerCase();
1148         if (inStr.length() > 1) {
1149             str = str + inStr.substring(1);
1150         }
1151
1152         String regex = "(([a-z0-9])([A-Z]))";
1153         String replacement = "$2-$3";
1154
1155         String retval = str.replaceAll(regex, replacement).toLowerCase();
1156
1157         return (retval);
1158     }
1159
1160     // This is called when mapping the yang value back to a valid java enumeration
1161     public static String toJavaEnum(String inStr) {
1162         if (inStr == null) {
1163             return (null);
1164         } else if (inStr.length() == 0) {
1165             return (inStr);
1166         }
1167
1168         // This is needed for enums containing under scores
1169         inStr = inStr.replaceAll("_", "");
1170
1171         // This will strip out all periods, which cannot be in a java enum
1172         inStr = inStr.replaceAll("\\.", "");
1173
1174         // This is needed for enums containing spaces
1175         inStr = inStr.replaceAll(" ", "");
1176
1177         String[] terms = inStr.split("-");
1178         StringBuffer sbuff = new StringBuffer();
1179
1180         // appends an _ if the string starts with a digit to make it a valid java enum
1181         if (Character.isDigit(inStr.charAt(0))) {
1182             sbuff.append('_');
1183         }
1184         // If the string contains hyphens it will convert the string to upperCamelCase without hyphens
1185         for (String term : terms) {
1186             sbuff.append(term.substring(0, 1).toUpperCase());
1187             if (term.length() > 1) {
1188                 sbuff.append(term.substring(1));
1189             }
1190         }
1191         return (sbuff.toString());
1192
1193     }
1194
1195     public static boolean isGetter(Method m) {
1196         if (m == null) {
1197             return (false);
1198         }
1199
1200         if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
1201             if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
1202                 if (!"getClass".equals(m.getName())) {
1203                     return (true);
1204                 }
1205             }
1206
1207             if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
1208                 return (true);
1209             }
1210
1211             if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
1212                 return (true);
1213             }
1214         }
1215
1216         return (false);
1217     }
1218
1219     public static boolean isSetter(Method m) {
1220         if (m == null) {
1221             return (false);
1222         }
1223
1224         if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
1225             if (m.getName().matches("^set[A-Z].*")) {
1226                 Class[] paramTypes = m.getParameterTypes();
1227                 if (paramTypes[0].isAssignableFrom(Identifier.class)
1228                         || Identifier.class.isAssignableFrom(paramTypes[0])) {
1229                     return (false);
1230                 } else {
1231                     return (true);
1232                 }
1233             }
1234
1235         }
1236
1237         return (false);
1238     }
1239
1240     @Deprecated
1241     public static String getFullPropertiesPath(String propertiesFileName) {
1242         String karafHome = System.getProperty("karaf.home","/opt/lsc/controller");
1243         return karafHome + "/configuration/" + propertiesFileName;
1244     }
1245
1246     // This is called when mapping a valid java enumeration back to the yang model value
1247     @Deprecated
1248     public static String mapEnumeratedValue(String propertyName, String propertyValue) {
1249         LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
1250         String mappingKey = "yang." + propertyName + "." + propertyValue;
1251         if (yangMappingProperties.containsKey(mappingKey)) {
1252             return (yangMappingProperties.getProperty(mappingKey));
1253         } else {
1254             LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
1255             return propertyValue;
1256         }
1257     }
1258
1259 }