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