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