2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.openecomp.sdnc.sli.provider;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.PrintStream;
29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.Method;
31 import java.lang.reflect.Modifier;
32 import java.lang.reflect.ParameterizedType;
33 import java.lang.reflect.Type;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Properties;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
44 import org.opendaylight.yangtools.yang.binding.Identifier;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
48 public class MdsalHelper {
50 private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
51 public static final String PROPERTIES_FILE="/opt/bvc/controller/configuration/l3sdn.properties";
52 private static Properties properties = new Properties();
55 public static void setProperties(Properties properties) {
57 for (Object propNameObj: properties.keySet()) {
58 String propName = (String) propNameObj;
59 MdsalHelper.properties.setProperty(propName, properties.getProperty(propName));
63 public static void loadProperties() {
65 File file = new File(PROPERTIES_FILE);
66 Properties properties = new Properties();
67 InputStream input = null;
68 if (file.isFile() && file.canRead()) {
70 input = new FileInputStream(file);
71 properties.load(input);
72 MdsalHelper.setProperties(properties);
73 LOG.info("Loaded properties from " + PROPERTIES_FILE );
74 } catch (Exception e) {
75 LOG.error("Failed to load properties " + PROPERTIES_FILE +"\n",e);
80 } catch (IOException e) {
81 LOG.error("Failed to close properties file " + PROPERTIES_FILE +"\n",e);
88 public static Properties toProperties(Properties props, Object fromObj) {
89 Class fromClass = null;
93 fromClass = fromObj.getClass();
95 return (toProperties(props, "", fromObj, fromClass));
98 public static Properties toProperties(Properties props, String pfx, Object fromObj)
100 Class fromClass = null;
104 fromClass = fromObj.getClass();
107 return(toProperties(props, pfx, fromObj, fromClass));
110 public static Properties toProperties(Properties props, String pfx,
111 Object fromObj, Class fromClass) {
113 if (fromObj == null) {
118 String simpleName = fromClass.getSimpleName();
120 LOG.trace("Extracting properties from " + fromClass.getName()
122 if (fromObj instanceof List) {
124 // Class is a List. List should contain yang-generated classes.
125 LOG.trace(fromClass.getName() + " is a List");
127 List fromList = (List) fromObj;
129 for (int i = 0; i < fromList.size(); i++) {
130 toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
132 props.setProperty(pfx + "_length", "" + fromList.size());
134 } else if (isYangGenerated(fromClass)) {
135 // Class is yang generated.
136 LOG.trace(fromClass.getName() + " is a Yang-generated class");
138 String propNamePfx = null;
140 // If called from a list (so prefix ends in ']'), don't
141 // add class name again
142 if (pfx.endsWith("]")) {
145 if ((pfx != null) && (pfx.length() > 0)) {
148 propNamePfx = toLowerHyphen(fromClass.getSimpleName());
151 if (propNamePfx.endsWith("-builder")) {
152 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
153 - "-builder".length());
156 if (propNamePfx.endsWith("-impl")) {
157 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
162 // Iterate through getter methods to figure out values we need to
166 String lastGetterName = null;
167 String propVal = null;
169 for (Method m : fromClass.getMethods()) {
173 lastGetterName = m.getName();
175 Class returnType = m.getReturnType();
177 if (m.getName().startsWith("get")) {
178 fieldName = toLowerHyphen(m.getName().substring(3));
181 fieldName = toLowerHyphen(m.getName().substring(2));
184 fieldName = fieldName.substring(0, 1).toLowerCase()
185 + fieldName.substring(1);
187 // Is the return type a yang generated class?
188 if (isYangGenerated(returnType)) {
190 if (returnType.isEnum()) {
191 // Return type is a typedef. Save its value.
193 boolean isAccessible = m.isAccessible();
195 m.setAccessible(true);
198 Object retValue = m.invoke(fromObj);
201 m.setAccessible(isAccessible);
203 if (retValue != null) {
204 String propName = propNamePfx + "."
206 propVal = retValue.toString();
207 String yangProp = "yang." + fieldName + "." + propVal;
208 if ( properties.containsKey(yangProp)) {
209 propVal = properties.getProperty(yangProp);
210 LOG.trace("Adjusting property " + yangProp + " " + propVal);
212 LOG.debug("Setting property " + propName
214 props.setProperty(propName, propVal);
216 } catch (Exception e) {
218 "Caught exception trying to convert Yang-generated enum returned by "
219 + fromClass.getName() + "."
221 + "() to Properties entry", e);
223 } else if (isIpv4Address(returnType)) {
226 String propName = propNamePfx + "." + fieldName;
227 boolean isAccessible = m.isAccessible();
229 m.setAccessible(true);
231 Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
233 m.setAccessible(isAccessible);
236 if (retValue != null) {
237 propVal = retValue.getValue().toString();
238 LOG.debug("Setting property " + propName
240 props.setProperty(propName, propVal);
243 } catch (Exception e) {
245 "Caught exception trying to convert value returned by "
246 + fromClass.getName() + "."
248 + "() to Properties entry", e);
250 } else if (isIpv6Address(returnType)) {
253 String propName = propNamePfx + "." + fieldName;
254 boolean isAccessible = m.isAccessible();
256 m.setAccessible(true);
258 Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
260 m.setAccessible(isAccessible);
263 if (retValue != null) {
264 propVal = retValue.getValue().toString();
265 LOG.debug("Setting property " + propName
267 props.setProperty(propName, propVal);
270 } catch (Exception e) {
272 "Caught exception trying to convert value returned by "
273 + fromClass.getName() + "."
275 + "() to Properties entry", e);
277 } else if (isIpAddress(returnType)) {
280 String propName = propNamePfx + "." + fieldName;
281 boolean isAccessible = m.isAccessible();
283 m.setAccessible(true);
285 IpAddress retValue = (IpAddress) m.invoke(fromObj);
287 m.setAccessible(isAccessible);
290 if (retValue != null) {
291 propVal = new String(retValue.getValue());
292 LOG.debug("Setting property " + propName
294 props.setProperty(propName, propVal);
297 } catch (Exception e) {
299 "Caught exception trying to convert value returned by "
300 + fromClass.getName() + "."
302 + "() to Properties entry", e);
304 } else if (isIpPrefix(returnType)) {
307 String propName = propNamePfx + "." + fieldName;
308 boolean isAccessible = m.isAccessible();
310 m.setAccessible(true);
312 IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
314 m.setAccessible(isAccessible);
317 if (retValue != null) {
318 propVal = new String(retValue.getValue());
319 LOG.debug("Setting property " + propName
321 props.setProperty(propName, propVal);
324 } catch (Exception e) {
326 "Caught exception trying to convert value returned by "
327 + fromClass.getName() + "."
329 + "() to Properties entry", e);
333 boolean isAccessible = m.isAccessible();
335 m.setAccessible(true);
337 Object retValue = m.invoke(fromObj);
339 if (retValue instanceof byte[]) {
340 LOG.trace(m.getName()+" returns a byte[]");
341 retValue = new String((byte[]) retValue, "UTF-8");
342 LOG.trace("Converted byte array "+propNamePfx+"."+fieldName+"to string "+ retValue );
345 m.setAccessible(isAccessible);
347 if (retValue != null) {
348 toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
350 } catch (Exception e) {
352 if (m.getName().equals("getKey")) {
353 LOG.trace("Caught "+e.getClass().getName()+" exception trying to convert results from getKey() - ignoring");
356 "Caught exception trying to convert Yang-generated class returned by"
357 + fromClass.getName() + "."
359 + "() to Properties entry", e);
363 } else if (returnType.equals(Class.class)) {
365 LOG.trace(m.getName()
366 + " returns a Class object - not interested");
368 } else if (List.class.isAssignableFrom(returnType)) {
370 // This getter method returns a list.
372 boolean isAccessible = m.isAccessible();
374 m.setAccessible(true);
376 Object retList = m.invoke(fromObj);
378 m.setAccessible(isAccessible);
380 // Figure out what type of elements are stored in this array.
381 Type paramType = m.getGenericReturnType();
382 Type elementType = ((ParameterizedType) paramType)
383 .getActualTypeArguments()[0];
384 toProperties(props, propNamePfx + "." + fieldName,
385 retList, (Class)elementType);
386 } catch (Exception e) {
388 "Caught exception trying to convert List returned by "
389 + fromClass.getName() + "."
391 + "() to Properties entry", e);
396 // Method returns something that is not a List and not
400 String propName = propNamePfx + "." + fieldName;
401 boolean isAccessible = m.isAccessible();
403 m.setAccessible(true);
405 Object propValObj = m.invoke(fromObj);
407 m.setAccessible(isAccessible);
410 if (propValObj != null) {
411 if (propValObj instanceof byte[]) {
412 LOG.trace(m.getName()+" returns a byte[]");
413 propVal = new String((byte[]) propValObj, "UTF-8");
414 LOG.trace("Converted byte array "+propNamePfx+"."+fieldName+"to string "+ propVal );
417 propVal = propValObj.toString();
419 LOG.debug("Setting property " + propName
421 props.setProperty(propName, propVal);
424 } catch (Exception e) {
425 if (m.getName().equals("getKey")) {
426 LOG.trace("Caught "+e.getClass().getName()+" exception trying to convert results from getKey() - ignoring");
429 "Caught exception trying to convert value returned by"
430 + fromClass.getName() + "."
432 + "() to Properties entry", e);
440 // End of method loop. If there was only one getter, named "getValue", then
441 // set value identified by "prefix" to that one value.
442 if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
443 LOG.trace("getValueFIX : "+ propNamePfx+" only has getValue() getter - setting "+propNamePfx+" = "+propVal);
444 props.setProperty(propNamePfx, propVal);
446 LOG.trace("getValueFIX : " + propNamePfx+" has "+numGetters+" getter(s), last one found was "+lastGetterName);
451 // Class is not yang generated and not a list
452 // It must be an element of a leaf list - set "prefix" to value
453 String fromVal = null;
454 if (fromObj instanceof byte[]) {
456 fromVal = new String((byte[]) fromObj, "UTF-8");
457 LOG.trace("Converted byte array "+pfx+"to string "+ fromVal );
458 } catch (Exception e) {
459 LOG.warn("Caught exception trying to convert "+pfx+" from byte[] to String", e);
460 fromVal = fromObj.toString();
464 fromVal = fromObj.toString();
466 LOG.debug("Setting property " + pfx
468 props.setProperty(pfx, fromVal);
474 public static Object toBuilder(Properties props, Object toObj) {
476 return (toBuilder(props, "", toObj));
479 public static List toList(Properties props, String pfx, List toObj,
483 boolean foundValue = false;
485 LOG.trace("Saving properties to List<" + elemType.getName()
488 if (props.contains(pfx+"_length")) {
490 int listLength = Integer.parseInt(props.getProperty(pfx+"_length"));
492 if (listLength > 0) {
493 maxIdx = listLength - 1;
495 } catch (Exception e) {
501 // Figure out array size
502 for (Object pNameObj : props.keySet()) {
503 String key = (String) pNameObj;
505 if (key.startsWith(pfx + "[")) {
506 String idxStr = key.substring(pfx.length() + 1);
507 int endloc = idxStr.indexOf("]");
509 idxStr = idxStr.substring(0, endloc);
513 int curIdx = Integer.parseInt(idxStr);
514 if (curIdx > maxIdx) {
517 } catch (Exception e) {
518 LOG.error("Illegal subscript in property " + key);
526 LOG.trace(pfx + " has max index of " + maxIdx);
527 for (int i = 0; i <= maxIdx; i++) {
529 String curBase = pfx + "[" + i + "]";
531 if (isYangGenerated(elemType)) {
532 String builderName = elemType.getName() + "Builder";
534 Class builderClass = Class.forName(builderName);
535 Object builderObj = builderClass.newInstance();
536 Method buildMethod = builderClass.getMethod("build");
537 builderObj = toBuilder(props, curBase, builderObj, true);
538 if (builderObj != null) {
539 LOG.trace("Calling " + builderObj.getClass().getName()
540 + "." + buildMethod.getName() + "()");
541 Object builtObj = buildMethod.invoke(builderObj);
546 } catch (ClassNotFoundException e) {
547 LOG.warn("Could not find builder class " + builderName, e);
548 } catch (Exception e) {
549 LOG.error("Caught exception trying to populate list from "
553 // Must be a leaf list
554 String curValue = props.getProperty(curBase, "");
558 if ((curValue != null) && (curValue.length() > 0)) {
573 public static Object toBuilder(Properties props, String pfx, Object toObj) {
574 return(toBuilder(props, pfx, toObj, false));
577 public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
578 Class toClass = toObj.getClass();
579 boolean foundValue = false;
581 LOG.trace("Saving properties to " + toClass.getName() + " class from "
586 if (isYangGenerated(toClass)) {
587 // Class is yang generated.
588 LOG.trace(toClass.getName() + " is a Yang-generated class");
590 String propNamePfx = null;
595 if ((pfx != null) && (pfx.length() > 0)) {
596 propNamePfx = pfx + "."
597 + toLowerHyphen(toClass.getSimpleName());
599 propNamePfx = toLowerHyphen(toClass.getSimpleName());
602 if (propNamePfx.endsWith("-builder")) {
603 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
604 - "-builder".length());
607 if (propNamePfx.endsWith("-impl")) {
608 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
613 if (toObj instanceof Identifier) {
614 LOG.trace(toClass.getName() + " is a Key - skipping");
618 // Iterate through getter methods to figure out values we need to
621 for (Method m : toClass.getMethods()) {
623 Class paramTypes[] = m.getParameterTypes();
624 Class paramClass = paramTypes[0];
626 String fieldName = toLowerHyphen(m.getName().substring(3));
627 fieldName = fieldName.substring(0, 1).toLowerCase()
628 + fieldName.substring(1);
630 String propName = propNamePfx + "." + fieldName;
632 String paramValue = props.getProperty(propName);
633 if (paramValue == null) {
634 LOG.trace(propName + " is unset");
636 LOG.trace(propName + " = " + paramValue);
639 // Is the return type a yang generated class?
640 if (isYangGenerated(paramClass)) {
642 if (paramClass.isEnum()) {
644 LOG.trace(m.getName() + " expects an Enum");
645 // Param type is a typedef.
646 if ((paramValue != null) && (paramValue.length() > 0)) {
647 Object paramObj = null;
650 paramObj = Enum.valueOf(paramClass,
651 toUpperCamelCase(paramValue));
652 } catch (Exception e) {
654 "Caught exception trying to convert field "
655 + propName + " to enum "
656 + paramClass.getName(), e);
660 boolean isAccessible = m.isAccessible();
662 m.setAccessible(true);
666 + toObj.getClass().getName() + "."
667 + m.getName() + "(" + paramValue
669 m.invoke(toObj, paramObj);
672 m.setAccessible(isAccessible);
676 } catch (Exception e) {
678 "Caught exception trying to create Yang-generated enum expected by"
682 + "() from Properties entry",
688 String simpleName = paramClass.getSimpleName();
690 if ("Ipv4Address".equals(simpleName)
691 || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) {
693 if ((paramValue != null) && (paramValue.length() > 0)) {
695 IpAddress ipAddr = IpAddressBuilder
696 .getDefaultInstance(paramValue);
699 if ("Ipv4Address".equals(simpleName))
701 m.invoke(toObj, ipAddr.getIpv4Address());
703 else if ("Ipv6Address".equals(simpleName))
705 m.invoke(toObj, ipAddr.getIpv6Address());
710 m.invoke(toObj, ipAddr);
713 } catch (Exception e) {
715 "Caught exception calling "
716 + toClass.getName() + "."
718 + paramValue + ")", e);
723 boolean isAccessible = m.isAccessible();
725 m.setAccessible(true);
728 + toObj.getClass().getName()
729 + "." + m.getName() + "("
731 m.invoke(toObj, paramValue);
733 m.setAccessible(isAccessible);
737 } catch (Exception e) {
739 "Caught exception trying to call "
743 + "() with Properties entry",
747 } else if ("IpPrefix".equals(simpleName)) {
748 if ((paramValue != null) && (paramValue.length() > 0)) {
750 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
751 m.invoke(toObj, ipPrefix);
753 } catch (Exception e) {
755 "Caught exception calling "
756 + toClass.getName() + "."
758 + paramValue + ")", e);
762 // setter expects a yang-generated class. Need
764 // create a builder to set it.
766 String builderName = paramClass.getName()
768 Class builderClass = null;
769 Object builderObj = null;
770 Object paramObj = null;
772 Object constObj = null;
774 LOG.trace(m.getName()
775 + " expects a yang-generated class - looking for builder "
778 builderClass = Class.forName(builderName);
779 builderObj = builderClass.newInstance();
780 paramObj = toBuilder(props, propNamePfx,
782 } catch (ClassNotFoundException e) {
784 if (paramValue == null) {
786 boolean isAccessible = m
789 m.setAccessible(true);
794 + m.getName() + "(null)");
795 m.invoke(toObj, new Object[]{null});
797 m.setAccessible(isAccessible);
801 } catch (Exception e1) {
803 "Caught exception trying to cally"
807 + "() with Properties entry",
812 // See if I can find a constructor I
815 Constructor[] constructors = paramClass
817 // Is there a String constructor?
818 for (Constructor c : constructors) {
820 .getParameterTypes();
822 && (cParms.length == 1)) {
824 .isAssignableFrom(cParms[0])) {
826 .newInstance(paramValue);
831 if (constObj == null) {
832 // Is there a Long constructor?
833 for (Constructor c : constructors) {
835 .getParameterTypes();
837 && (cParms.length == 1)) {
839 .isAssignableFrom(cParms[0])) {
842 .parseLong(paramValue));
849 if (constObj == null) {
851 // Last chance - see if
852 // parameter class has a static
854 // getDefaultInstance(String)
856 Method gm = paramClass
858 "getDefaultInstance",
864 .isStatic(gmodifier)) {
866 // getDefaultInstance(String)
867 paramObj = gm.invoke(
872 } catch (Exception gme) {
878 } catch (Exception e1) {
880 "Could not find a suitable constructor for "
886 if (constObj == null) {
887 LOG.warn("Could not find builder class "
889 + " and could not find a String or Long constructor or static getDefaultInstance(String) - trying just to set passing paramValue");
893 } catch (Exception e) {
895 "Caught exception trying to create builder "
899 if (paramObj != null) {
903 Method buildMethod = builderClass
906 + paramObj.getClass().getName()
907 + "." + buildMethod.getName()
909 Object builtObj = buildMethod
912 boolean isAccessible = m.isAccessible();
914 m.setAccessible(true);
918 + toObj.getClass().getName()
919 + "." + m.getName() + "()");
920 m.invoke(toObj, builtObj);
922 m.setAccessible(isAccessible);
926 } catch (Exception e) {
928 "Caught exception trying to set Yang-generated class expected by"
932 + "() from Properties entry",
937 boolean isAccessible = m.isAccessible();
939 m.setAccessible(true);
942 if (constObj != null) {
948 + constObj.toString() + ")");
949 m.invoke(toObj, constObj);
956 m.invoke(toObj, paramValue);
960 m.setAccessible(isAccessible);
964 } catch (Exception e) {
966 "Caught exception trying to convert value returned by"
970 + "() to Properties entry",
978 // Setter's argument is not a yang-generated class. See
981 if (List.class.isAssignableFrom(paramClass)) {
983 LOG.trace("Parameter class " + paramClass.getName()
986 // Figure out what type of args are in List and pass
989 Type paramType = m.getGenericParameterTypes()[0];
990 Type elementType = ((ParameterizedType) paramType)
991 .getActualTypeArguments()[0];
992 Object paramObj = new LinkedList();
994 paramObj = toList(props, propName,
995 (List) paramObj, (Class) elementType);
996 } catch (Exception e) {
997 LOG.error("Caught exception trying to create list expected as argument to "
998 + toClass.getName() + "." + m.getName());
1001 if (paramObj != null) {
1003 boolean isAccessible = m.isAccessible();
1004 if (!isAccessible) {
1005 m.setAccessible(true);
1007 LOG.trace("Calling "
1008 + toObj.getClass().getName() + "."
1009 + m.getName() + "(" + paramValue
1011 m.invoke(toObj, paramObj);
1012 if (!isAccessible) {
1013 m.setAccessible(isAccessible);
1017 } catch (Exception e) {
1019 "Caught exception trying to convert List returned by"
1020 + toClass.getName() + "."
1022 + "() to Properties entry",
1028 // Setter expects something that is not a List and
1029 // not yang-generated. Just pass the parameter value
1031 LOG.trace("Parameter class "
1032 + paramClass.getName()
1033 + " is not a yang-generated class or a List");
1035 if ((paramValue != null) && (paramValue.length() > 0)) {
1037 Object constObj = null;
1040 // See if I can find a constructor I can use
1041 Constructor[] constructors = paramClass
1043 // Is there a String constructor?
1044 for (Constructor c : constructors) {
1045 Class[] cParms = c.getParameterTypes();
1046 if ((cParms != null)
1047 && (cParms.length == 1)) {
1049 .isAssignableFrom(cParms[0])) {
1051 .newInstance(paramValue);
1056 if (constObj == null) {
1057 // Is there a Long constructor?
1058 for (Constructor c : constructors) {
1060 .getParameterTypes();
1061 if ((cParms != null)
1062 && (cParms.length == 1)) {
1064 .isAssignableFrom(cParms[0])) {
1067 .parseLong(paramValue));
1074 if (constObj != null) {
1076 LOG.trace("Calling "
1081 m.invoke(toObj, constObj);
1083 } catch (Exception e2) {
1085 "Caught exception trying to call "
1090 boolean isAccessible = m
1092 if (!isAccessible) {
1093 m.setAccessible(true);
1095 LOG.trace("Calling "
1099 + paramValue + ")");
1100 m.invoke(toObj, paramValue);
1101 if (!isAccessible) {
1102 m.setAccessible(isAccessible);
1106 } catch (Exception e) {
1108 "Caught exception trying to convert value returned by"
1112 + "() to Properties entry",
1116 } catch (Exception e1) {
1118 "Could not find a suitable constructor for "
1119 + paramClass.getName(), e1);
1126 } // End of section handling "setter" method
1127 } // End of loop through Methods
1128 } // End of section handling yang-generated class
1137 public static void printPropertyList(PrintStream pstr, String pfx,
1139 boolean foundValue = false;
1141 LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
1143 if (isYangGenerated(toClass)
1144 && (!Identifier.class.isAssignableFrom(toClass))) {
1145 // Class is yang generated.
1146 LOG.trace(toClass.getName() + " is a Yang-generated class");
1148 if (toClass.getName().endsWith("Key")) {
1149 if (Identifier.class.isAssignableFrom(toClass)) {
1150 LOG.trace(Identifier.class.getName()
1151 + " is assignable from " + toClass.getName());
1154 LOG.trace(Identifier.class.getName()
1155 + " is NOT assignable from " + toClass.getName());
1159 String propNamePfx = null;
1160 if (pfx.endsWith("]")) {
1164 if ((pfx != null) && (pfx.length() > 0)) {
1165 propNamePfx = pfx + "."
1166 + toLowerHyphen(toClass.getSimpleName());
1168 propNamePfx = toLowerHyphen(toClass.getSimpleName());
1171 if (propNamePfx.endsWith("-builder")) {
1172 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
1173 - "-builder".length());
1176 if (propNamePfx.endsWith("-impl")) {
1177 propNamePfx = propNamePfx.substring(0, propNamePfx.length()
1178 - "-impl".length());
1182 // Iterate through getter methods to figure out values we need to
1185 for (Method m : toClass.getMethods()) {
1186 LOG.trace("Is " + m.getName() + " method a getter?");
1188 LOG.trace(m.getName() + " is a getter");
1189 Class returnClass = m.getReturnType();
1191 String fieldName = toLowerHyphen(m.getName().substring(3));
1192 fieldName = fieldName.substring(0, 1).toLowerCase()
1193 + fieldName.substring(1);
1195 String propName = propNamePfx + "." + fieldName;
1197 // Is the return type a yang generated class?
1198 if (isYangGenerated(returnClass)) {
1200 if (returnClass.isEnum()) {
1202 LOG.trace(m.getName() + " is an Enum");
1203 pstr.print("\n\n * " + propName);
1207 String simpleName = returnClass.getSimpleName();
1209 if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)) {
1210 LOG.trace(m.getName()+" is an "+simpleName);
1211 pstr.print("\n\n * " + propName);
1213 printPropertyList(pstr, propNamePfx, returnClass);
1219 // Setter's argument is not a yang-generated class. See
1222 if (List.class.isAssignableFrom(returnClass)) {
1224 LOG.trace("Parameter class "
1225 + returnClass.getName() + " is a List");
1227 // Figure out what type of args are in List and pass
1228 // that to toList().
1230 Type returnType = m.getGenericReturnType();
1231 Type elementType = ((ParameterizedType) returnType)
1232 .getActualTypeArguments()[0];
1233 Class elementClass = (Class) elementType;
1234 LOG.trace("Calling printPropertyList on list type ("
1235 + elementClass.getName()
1239 + toClass.getName() + ")");
1244 + toLowerHyphen(elementClass
1245 .getSimpleName()) + "[]",
1248 } else if (!returnClass.equals(Class.class)) {
1250 // Setter expects something that is not a List and
1251 // not yang-generated. Just pass the parameter value
1253 LOG.trace("Parameter class "
1254 + returnClass.getName()
1255 + " is not a yang-generated class or a List");
1257 pstr.print("\n\n * " + propName);
1261 } // End of section handling "setter" method
1262 } // End of loop through Methods
1263 } // End of section handling yang-generated class
1267 public static boolean isYangGenerated(Class c) {
1271 return (c.getName().startsWith("org.opendaylight.yang.gen."));
1275 public static boolean isIpPrefix(Class c) {
1280 String simpleName = c.getSimpleName();
1281 return ("IpPrefix".equals(simpleName)) ;
1286 public static boolean isIpv4Address(Class c) {
1291 String simpleName = c.getSimpleName();
1292 return ("Ipv4Address".equals(simpleName)) ;
1295 public static boolean isIpv6Address(Class c) {
1300 String simpleName = c.getSimpleName();
1301 return ("Ipv6Address".equals(simpleName)) ;
1304 public static boolean isIpAddress(Class c) {
1309 String simpleName = c.getSimpleName();
1310 return ("IpAddress".equals(simpleName)) ;
1313 public static String toLowerHyphen(String inStr) {
1314 if (inStr == null) {
1318 String str = inStr.substring(0, 1).toLowerCase();
1319 if (inStr.length() > 1) {
1320 str = str + inStr.substring(1);
1323 String regex = "(([a-z0-9])([A-Z]))";
1324 String replacement = "$2-$3";
1326 String retval = str.replaceAll(regex, replacement).toLowerCase();
1328 LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
1332 public static String toUpperCamelCase(String inStr) {
1333 if (inStr == null) {
1335 } else if (inStr.length() == 0) {
1339 String[] terms = inStr.split("-");
1340 StringBuffer sbuff = new StringBuffer();
1341 // Check if string begins with a digit
1342 if (Character.isDigit(inStr.charAt(0))) {
1345 for (String term : terms) {
1346 sbuff.append(term.substring(0, 1).toUpperCase());
1347 if (term.length() > 1) {
1348 sbuff.append(term.substring(1));
1351 return (sbuff.toString());
1355 public static boolean isGetter(Method m) {
1360 if (Modifier.isPublic(m.getModifiers())
1361 && (m.getParameterTypes().length == 0)) {
1362 if (m.getName().matches("^get[A-Z].*")
1363 && !m.getReturnType().equals(void.class)) {
1364 if (!"getClass".equals(m.getName())) {
1369 if (m.getName().matches("^get[A-Z].*")
1370 && m.getReturnType().equals(boolean.class)) {
1374 if (m.getName().matches("^is[A-Z].*")
1375 && m.getReturnType().equals(Boolean.class)) {
1383 public static boolean isSetter(Method m) {
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])) {