2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
24 package org.onap.ccsdk.sli.core.sli.provider;
27 import java.io.FileInputStream;
28 import java.io.InputStream;
29 import java.io.PrintStream;
30 import java.lang.reflect.Constructor;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.lang.reflect.ParameterizedType;
34 import java.lang.reflect.Type;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Properties;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
46 import org.opendaylight.yangtools.yang.binding.Identifier;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class MdsalHelper {
52 private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
53 private static Properties yangMappingProperties = new Properties();
54 private static final String IP_ADDRESS="IpAddress";
55 private static final String IPV4_ADDRESS="Ipv4Address";
56 private static final String IPV6_ADDRESS="Ipv6Address";
58 private static final String IP_PREFIX="IpPrefix";
59 private static final String SETTING_PROPERTY="Setting property ";
60 private static final String BUILDER="-builder";
63 public static void setProperties(Properties input) {
64 setYangMappingProperties(input);
68 public static void setYangMappingProperties(Properties properties) {
69 for (Object propNameObj : properties.keySet()) {
70 String propName = (String) propNameObj;
71 MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
76 public static void loadProperties(String propertiesFile) {
77 File file = new File(propertiesFile);
78 Properties properties = new Properties();
79 if (file.isFile() && file.canRead()) {
80 try (InputStream input = new FileInputStream(file)) {
81 properties.load(input);
82 MdsalHelper.setYangMappingProperties(properties);
83 LOG.info("Loaded properties from " + propertiesFile);
84 } catch (Exception e) {
85 LOG.error("Failed to load properties " + propertiesFile + "\n", e);
88 LOG.error("Failed to load the properties file " + propertiesFile + "\n");
89 LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
93 public static Properties toProperties(Properties props, Object fromObj) {
94 return toProperties(props, fromObj, false);
97 public static Properties toProperties(Properties props, Object fromObj, Boolean useLegacyEnumerationMapping) {
98 Class fromClass = null;
100 if (fromObj != null) {
101 fromClass = fromObj.getClass();
103 return toProperties(props, "", fromObj, fromClass, useLegacyEnumerationMapping);
106 public static Properties toProperties(Properties props, String pfx, Object fromObj) {
107 return toProperties(props, pfx, fromObj, false);
110 public static Properties toProperties(Properties props, String pfx, Object fromObj, Boolean useLegacyEnumerationMapping) {
111 Class fromClass = null;
113 if (fromObj != null) {
114 fromClass = fromObj.getClass();
117 return toProperties(props, pfx, fromObj, fromClass, useLegacyEnumerationMapping);
120 public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
121 return toProperties(props, pfx, fromObj, fromClass, false);
124 public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass, Boolean useLegacyEnumerationMapping) {
126 if (fromObj == null) {
129 String simpleTypeName = fromObj.getClass().getTypeName();
130 simpleTypeName = simpleTypeName.substring(simpleTypeName.lastIndexOf(".") + 1);
132 if (classHasSpecialHandling(simpleTypeName)) {
135 Method m = fromClass.getMethod(getStringValueMethod(simpleTypeName), null);
136 boolean isAccessible = m.isAccessible();
138 m.setAccessible(true);
140 Object retValue = m.invoke(fromObj);
141 if (retValue != null) {
142 String propVal = null;
143 if (IP_ADDRESS.equals(simpleTypeName) || IP_PREFIX.equals(simpleTypeName)
144 || IPV4_ADDRESS.equals(simpleTypeName) || IPV6_ADDRESS.equals(simpleTypeName)) {
145 propVal = (String) retValue;
146 } else if ("Dscp".equals(simpleTypeName)) {
147 propVal = String.valueOf((short) retValue);
148 } else if ("PortNumber".equals(simpleTypeName)) {
149 propVal = String.valueOf((Integer) retValue);
151 LOG.debug(SETTING_PROPERTY + pfx + " to " + propVal);
152 props.setProperty(pfx, propVal);
154 } catch (Exception e) {
155 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
156 + ".getValue() to Properties entry", e);
158 } else if (fromObj instanceof List) {
159 List fromList = (List) fromObj;
161 for (int i = 0; i < fromList.size(); i++) {
162 toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass, useLegacyEnumerationMapping);
164 props.setProperty(pfx + "_length", Integer.toString(fromList.size()));
166 } else if (isYangGenerated(fromClass)) {
167 // Class is yang generated.
169 String propNamePfx = null;
171 // If called from a list (so prefix ends in ']'), don't
172 // add class name again
173 if (pfx.endsWith("]")) {
176 if ((pfx != null) && (pfx.length() > 0)) {
179 propNamePfx = toLowerHyphen(fromClass.getSimpleName());
182 if (propNamePfx.endsWith(BUILDER)) {
183 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
186 if (propNamePfx.endsWith("-impl")) {
187 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
191 // Iterate through getter methods to figure out values we need to
195 String lastGetterName = null;
196 String propVal = null;
198 for (Method m : fromClass.getMethods()) {
202 lastGetterName = m.getName();
204 Class returnType = m.getReturnType();
206 if (m.getName().startsWith("get")) {
207 fieldName = toLowerHyphen(m.getName().substring(3));
210 fieldName = toLowerHyphen(m.getName().substring(2));
213 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
215 // Is the return type a yang generated class?
216 if (isYangGenerated(returnType)) {
218 if (returnType.isEnum()) {
219 // Return type is a typedef. Save its value.
221 boolean isAccessible = m.isAccessible();
223 m.setAccessible(true);
226 Object retValue = m.invoke(fromObj);
229 m.setAccessible(isAccessible);
231 if (retValue != null) {
232 String propName = propNamePfx + "." + fieldName;
233 if (useLegacyEnumerationMapping) {
234 propVal = retValue.toString();
235 props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
237 Method method = retValue.getClass().getMethod("getName");
238 String yangValue = (String) method.invoke(retValue);
239 props.setProperty(propName, yangValue);
243 } catch (Exception e) {
245 "Caught exception trying to convert Yang-generated enum returned by "
246 + fromClass.getName() + "." + m.getName() + "() to Properties entry",
251 boolean isAccessible = m.isAccessible();
253 m.setAccessible(true);
255 Object retValue = m.invoke(fromObj);
257 if (retValue instanceof byte[]) {
258 retValue = new String((byte[]) retValue, "UTF-8");
261 m.setAccessible(isAccessible);
263 if (retValue != null) {
264 toProperties(props, propNamePfx + "." + fieldName, retValue, returnType, useLegacyEnumerationMapping);
266 } catch (Exception e) {
268 if (m.getName().equals("getKey")) {
269 LOG.trace("Caught " + e.getClass().getName()
270 + " exception trying to convert results from getKey() - ignoring");
272 LOG.error("Caught exception trying to convert Yang-generated class returned by"
273 + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
277 } else if (returnType.equals(Class.class)) {
279 } else if (List.class.isAssignableFrom(returnType)) {
281 // This getter method returns a list.
283 boolean isAccessible = m.isAccessible();
285 m.setAccessible(true);
287 Object retList = m.invoke(fromObj);
289 m.setAccessible(isAccessible);
291 // Figure out what type of elements are stored in
293 Type paramType = m.getGenericReturnType();
294 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
295 toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType, useLegacyEnumerationMapping);
296 } catch (Exception e) {
297 LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "."
298 + m.getName() + "() to Properties entry", e);
303 // Method returns something that is not a List and not
307 String propName = propNamePfx + "." + fieldName;
308 boolean isAccessible = m.isAccessible();
310 m.setAccessible(true);
312 Object propValObj = m.invoke(fromObj);
314 m.setAccessible(isAccessible);
317 if (propValObj != null) {
318 if (propValObj instanceof byte[]) {
319 propVal = new String((byte[]) propValObj, "UTF-8");
321 propVal = propValObj.toString();
323 LOG.debug(SETTING_PROPERTY + propName + " to " + propVal);
324 props.setProperty(propName, propVal);
327 } catch (Exception e) {
328 if (m.getName().equals("getKey")) {
329 LOG.trace("Caught " + e.getClass().getName()
330 + " exception trying to convert results from getKey() - ignoring");
332 LOG.error("Caught exception trying to convert value returned by" + fromClass.getName()
333 + "." + m.getName() + "() to Properties entry", e);
341 // End of method loop. If there was only one getter, named
343 // set value identified by "prefix" to that one value.
344 if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
345 LOG.trace("getValueFIX : " + propNamePfx + " only has getValue() getter - setting " + propNamePfx
347 props.setProperty(propNamePfx, propVal);
349 LOG.trace("getValueFIX : " + propNamePfx + " has " + numGetters + " getter(s), last one found was "
355 // Class is not yang generated and not a list
356 // It must be an element of a leaf list - set "prefix" to value
357 String fromVal = null;
358 if (fromObj instanceof byte[]) {
360 fromVal = new String((byte[]) fromObj, "UTF-8");
361 } catch (Exception e) {
362 LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
363 fromVal = fromObj.toString();
367 fromVal = fromObj.toString();
369 LOG.debug(SETTING_PROPERTY + pfx + " to " + fromVal);
370 props.setProperty(pfx, fromVal);
376 public static Object toBuilder(Properties props, Object toObj) {
378 return (toBuilder(props, "", toObj));
381 public static List toList(Properties props, String pfx, List toObj, Class elemType) {
384 boolean foundValue = false;
386 if (props.containsKey(pfx + "_length")) {
388 int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
390 if (listLength > 0) {
391 maxIdx = listLength - 1;
393 } catch (NumberFormatException e) {
394 LOG.info("Invalid input for length ", e);
398 String arrayKey = pfx + "[";
399 int arrayKeyLength = arrayKey.length();
401 // Figure out array size
402 for (Object pNameObj : props.keySet()) {
403 String key = (String) pNameObj;
405 if (key.startsWith(arrayKey)) {
406 String idxStr = key.substring(arrayKeyLength);
407 int endloc = idxStr.indexOf("]");
409 idxStr = idxStr.substring(0, endloc);
412 int curIdx = Integer.parseInt(idxStr);
413 if (curIdx > maxIdx) {
416 } catch (Exception e) {
417 LOG.error("Illegal subscript in property {}", key, e);
424 for (int i = 0; i <= maxIdx; i++) {
426 String curBase = pfx + "[" + i + "]";
428 if (isYangGenerated(elemType)) {
430 if (isIpAddress(elemType)) {
432 String curValue = props.getProperty(curBase, "");
434 if ((curValue != null) && (curValue.length() > 0)) {
435 toObj.add(IpAddressBuilder.getDefaultInstance(curValue));
438 } else if (isIpv4Address(elemType)) {
439 String curValue = props.getProperty(curBase, "");
441 if ((curValue != null) && (curValue.length() > 0)) {
442 toObj.add(new Ipv4Address(curValue));
446 } else if (isIpv6Address(elemType)) {
447 String curValue = props.getProperty(curBase, "");
449 if ((curValue != null) && (curValue.length() > 0)) {
450 toObj.add(new Ipv6Address(curValue));
453 } else if (isIpPrefix(elemType)) {
455 String curValue = props.getProperty(curBase, "");
457 if ((curValue != null) && (curValue.length() > 0)) {
458 toObj.add(IpPrefixBuilder.getDefaultInstance(curValue));
461 } else if (isPortNumber(elemType)) {
463 String curValue = props.getProperty(curBase, "");
465 if ((curValue != null) && (curValue.length() > 0)) {
466 toObj.add(PortNumber.getDefaultInstance(curValue));
469 } else if (isDscp(elemType)) {
471 String curValue = props.getProperty(curBase, "");
473 if ((curValue != null) && (curValue.length() > 0)) {
474 toObj.add(Dscp.getDefaultInstance(curValue));
478 String builderName = elemType.getName() + "Builder";
480 Class builderClass = Class.forName(builderName);
481 Object builderObj = builderClass.newInstance();
482 Method buildMethod = builderClass.getMethod("build");
483 builderObj = toBuilder(props, curBase, builderObj, true);
484 if (builderObj != null) {
485 Object builtObj = buildMethod.invoke(builderObj);
490 } catch (ClassNotFoundException e) {
491 LOG.warn("Could not find builder class {}", builderName, e);
492 } catch (Exception e) {
493 LOG.error("Caught exception trying to populate list from {}", pfx, e);
497 // Must be a leaf list
498 String curValue = props.getProperty(curBase, "");
502 if ((curValue != null) && (curValue.length() > 0)) {
517 public static Object toBuilder(Properties props, String pfx, Object toObj) {
518 return (toBuilder(props, pfx, toObj, false));
521 public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
523 Class toClass = toObj.getClass();
524 boolean foundValue = false;
528 if (isYangGenerated(toClass)) {
529 // Class is yang generated.
530 String propNamePfx = null;
535 if ((pfx != null) && (pfx.length() > 0)) {
536 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
538 propNamePfx = toLowerHyphen(toClass.getSimpleName());
541 if (propNamePfx.endsWith(BUILDER)) {
542 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
545 if (propNamePfx.endsWith("-impl")) {
546 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
550 if (toObj instanceof Identifier) {
554 // Iterate through getter methods to figure out values we need to
557 for (Method m : toClass.getMethods()) {
559 Class paramTypes[] = m.getParameterTypes();
560 Class paramClass = paramTypes[0];
562 String fieldName = toLowerHyphen(m.getName().substring(3));
563 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
565 String propName = propNamePfx + "." + fieldName;
567 String paramValue = props.getProperty(propName);
568 if (paramValue == null) {
570 } else if ("".equals(paramValue)) {
571 LOG.trace(propName + " was set to the empty string, setting it to null");
577 // Is the return type a yang generated class?
578 if (isYangGenerated(paramClass)) {
580 if (paramClass.isEnum()) {
582 // Param type is a typedef.
583 if ((paramValue != null) && (paramValue.length() > 0)) {
584 Object paramObj = null;
587 paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
588 } catch (Exception e) {
589 LOG.error("Caught exception trying to convert field " + propName + " to enum "
590 + paramClass.getName(), e);
594 boolean isAccessible = m.isAccessible();
596 m.setAccessible(true);
599 m.invoke(toObj, paramObj);
602 m.setAccessible(isAccessible);
606 } catch (Exception e) {
607 LOG.error("Caught exception trying to create Yang-generated enum expected by"
608 + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
613 String simpleName = paramClass.getSimpleName();
615 if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
616 || IP_ADDRESS.equals(simpleName)) {
619 if ((paramValue != null) && (paramValue.length() > 0)) {
621 IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
623 if (IPV4_ADDRESS.equals(simpleName)) {
624 m.invoke(toObj, ipAddr.getIpv4Address());
625 } else if (IPV6_ADDRESS.equals(simpleName)) {
626 m.invoke(toObj, ipAddr.getIpv6Address());
629 m.invoke(toObj, ipAddr);
632 } catch (Exception e) {
633 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
634 + "(" + paramValue + ")", e);
639 boolean isAccessible = m.isAccessible();
641 m.setAccessible(true);
644 m.invoke(toObj, paramValue);
646 m.setAccessible(isAccessible);
650 } catch (Exception e) {
651 LOG.error("Caught exception trying to call " + toClass.getName() + "."
652 + m.getName() + "() with Properties entry", e);
655 } else if (IP_PREFIX.equals(simpleName)) {
656 if ((paramValue != null) && (paramValue.length() > 0)) {
658 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
659 m.invoke(toObj, ipPrefix);
661 } catch (Exception e) {
662 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
663 + "(" + paramValue + ")", e);
666 } else if ("PortNumber".equals(simpleName)) {
667 if ((paramValue != null) && (paramValue.length() > 0)) {
669 PortNumber portNumber = PortNumber.getDefaultInstance(paramValue);
670 m.invoke(toObj, portNumber);
672 } catch (Exception e) {
673 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
674 + "(" + paramValue + ")", e);
677 } else if ("Dscp".equals(simpleName)) {
678 if ((paramValue != null) && (paramValue.length() > 0)) {
680 Dscp dscp = Dscp.getDefaultInstance(paramValue);
681 m.invoke(toObj, dscp);
683 } catch (Exception e) {
684 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
685 + "(" + paramValue + ")", e);
689 // setter expects a yang-generated class. Need
691 // create a builder to set it.
693 String builderName = paramClass.getName() + "Builder";
694 Class builderClass = null;
695 Object builderObj = null;
696 Object paramObj = null;
698 Object constObj = null;
701 builderClass = Class.forName(builderName);
702 builderObj = builderClass.newInstance();
703 paramObj = toBuilder(props, propNamePfx, builderObj);
704 } catch (ClassNotFoundException e) {
705 LOG.info("Builder class {} not found ", builderName, e);
706 if (paramValue == null) {
708 boolean isAccessible = m.isAccessible();
710 m.setAccessible(true);
713 m.invoke(toObj, new Object[] { null });
715 m.setAccessible(isAccessible);
719 } catch (Exception e1) {
720 LOG.error("Caught exception trying to cally" + toClass.getName() + "."
721 + m.getName() + "() with Properties entry", e1);
725 // See if I can find a constructor I
728 Constructor[] constructors = paramClass.getConstructors();
729 // Is there a String constructor?
730 for (Constructor c : constructors) {
731 Class[] cParms = c.getParameterTypes();
732 if ((cParms != null) && (cParms.length == 1)) {
733 if (String.class.isAssignableFrom(cParms[0])) {
734 constObj = c.newInstance(paramValue);
739 if (constObj == null) {
740 // Is there a Long constructor?
741 for (Constructor c : constructors) {
742 Class[] cParms = c.getParameterTypes();
743 if ((cParms != null) && (cParms.length == 1)) {
744 if (Long.class.isAssignableFrom(cParms[0])) {
745 constObj = c.newInstance(Long.parseLong(paramValue));
752 if (constObj == null) {
754 // Last chance - see if
755 // parameter class has a static
757 // getDefaultInstance(String)
760 paramClass.getMethod("getDefaultInstance", String.class);
762 int gmodifier = gm.getModifiers();
763 if (Modifier.isStatic(gmodifier)) {
765 // getDefaultInstance(String)
766 paramObj = gm.invoke(null, paramValue);
769 } catch (Exception gme) {
770 LOG.info("Unable to find static method getDefaultInstance for "
771 + "class {}", paramClass.getSimpleName(), gme);
775 } catch (Exception e1) {
777 "Could not find a suitable constructor for " + paramClass.getName(),
781 if (constObj == null) {
782 LOG.warn("Could not find builder class " + builderName
783 + " and could not find a String or Long constructor or static "
784 + "getDefaultInstance(String) - trying just to set passing paramValue");
788 } catch (Exception e) {
789 LOG.error("Caught exception trying to create builder " + builderName, e);
792 if (paramObj != null && builderClass != null) {
795 Method buildMethod = builderClass.getMethod("build");
797 Object builtObj = buildMethod.invoke(paramObj);
799 boolean isAccessible = m.isAccessible();
801 m.setAccessible(true);
804 m.invoke(toObj, builtObj);
806 m.setAccessible(isAccessible);
810 } catch (Exception e) {
811 LOG.error("Caught exception trying to set Yang-generated class expected by"
812 + toClass.getName() + "." + m.getName() + "() from Properties entry",
817 boolean isAccessible = m.isAccessible();
819 m.setAccessible(true);
822 if (constObj != null) {
823 m.invoke(toObj, constObj);
825 m.invoke(toObj, paramValue);
828 m.setAccessible(isAccessible);
832 } catch (Exception e) {
833 LOG.error("Caught exception trying to convert value returned by"
834 + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
841 // Setter's argument is not a yang-generated class. See
844 if (List.class.isAssignableFrom(paramClass)) {
845 // Figure out what type of args are in List and pass
848 Type paramType = m.getGenericParameterTypes()[0];
849 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
850 Object paramObj = new LinkedList();
852 paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
853 } catch (Exception e) {
854 LOG.error("Caught exception trying to create list expected as argument to {}.{}",
855 toClass.getName(), m.getName(), e);
858 if (paramObj != null) {
860 boolean isAccessible = m.isAccessible();
862 m.setAccessible(true);
864 m.invoke(toObj, paramObj);
866 m.setAccessible(isAccessible);
870 } catch (Exception e) {
871 LOG.error("Caught exception trying to convert List returned by" + toClass.getName()
872 + "." + m.getName() + "() to Properties entry", e);
877 // Setter expects something that is not a List and
878 // not yang-generated. Just pass the parameter value
879 if ((paramValue != null) && (paramValue.length() > 0)) {
881 Object constObj = null;
884 // See if I can find a constructor I can use
885 Constructor[] constructors = paramClass.getConstructors();
886 // Is there a String constructor?
887 for (Constructor c : constructors) {
888 Class[] cParms = c.getParameterTypes();
889 if ((cParms != null) && (cParms.length == 1)) {
890 if (String.class.isAssignableFrom(cParms[0])) {
891 constObj = c.newInstance(paramValue);
896 if (constObj == null) {
897 // Is there a Long constructor?
898 for (Constructor c : constructors) {
899 Class[] cParms = c.getParameterTypes();
900 if ((cParms != null) && (cParms.length == 1)) {
901 if (Long.class.isAssignableFrom(cParms[0])) {
902 constObj = c.newInstance(Long.parseLong(paramValue));
909 if (constObj != null) {
911 m.invoke(toObj, constObj);
913 } catch (Exception e2) {
914 LOG.error("Caught exception trying to call " + m.getName(), e2);
918 boolean isAccessible = m.isAccessible();
920 m.setAccessible(true);
922 m.invoke(toObj, paramValue);
924 m.setAccessible(isAccessible);
928 } catch (Exception e) {
929 LOG.error("Caught exception trying to convert value returned by"
930 + toClass.getName() + "." + m.getName() + "() to Properties entry",
934 } catch (Exception e1) {
935 LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
941 } // End of section handling "setter" method
942 } // End of loop through Methods
943 } // End of section handling yang-generated class
952 private static boolean classHasSpecialHandling(String simpleName) {
953 if (IP_ADDRESS.equals(simpleName) || IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
954 || IP_PREFIX.equals(simpleName) || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
960 private static String getStringValueMethod(String simpleName){
961 if (IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)) {
962 return("stringValue");
968 public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
969 boolean foundValue = false;
971 if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
972 // Class is yang generated.
973 String propNamePfx = null;
974 if (pfx.endsWith("]")) {
978 if ((pfx != null) && (pfx.length() > 0)) {
979 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
981 propNamePfx = toLowerHyphen(toClass.getSimpleName());
984 if (propNamePfx.endsWith(BUILDER)) {
985 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
988 if (propNamePfx.endsWith("-impl")) {
989 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
993 // Iterate through getter methods to figure out values we need to
996 for (Method m : toClass.getMethods()) {
998 Class returnClass = m.getReturnType();
1000 String fieldName = toLowerHyphen(m.getName().substring(3));
1001 if (fieldName != null) {
1002 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
1006 String propName = propNamePfx + "." + fieldName;
1008 // Is the return type a yang generated class?
1009 if (isYangGenerated(returnClass)) {
1011 if (returnClass.isEnum()) {
1012 pstr.print("\n\n * " + propName);
1015 String simpleName = returnClass.getSimpleName();
1017 if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
1018 || IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)
1019 || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
1020 pstr.print("\n\n * " + propName);
1022 printPropertyList(pstr, propNamePfx, returnClass);
1028 // Setter's argument is not a yang-generated class. See
1031 if (List.class.isAssignableFrom(returnClass)) {
1032 // Figure out what type of args are in List and pass
1033 // that to toList().
1035 Type returnType = m.getGenericReturnType();
1036 Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
1037 Class elementClass = (Class) elementType;
1038 printPropertyList(pstr,
1039 propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]",
1042 } else if (!returnClass.equals(Class.class)) {
1044 // Setter expects something that is not a List and
1045 // not yang-generated. Just pass the parameter value
1046 pstr.print("\n\n * " + propName);
1049 } // End of section handling "setter" method
1050 } // End of loop through Methods
1051 } // End of section handling yang-generated class
1055 public static boolean isYangGenerated(Class c) {
1057 return (c.getName().startsWith("org.opendaylight.yang.gen."));
1062 public static boolean isIpPrefix(Class c) {
1067 if (!isIetfInet(c)) {
1070 String simpleName = c.getSimpleName();
1071 return (IP_PREFIX.equals(simpleName));
1074 public static boolean isIpv4Address(Class c) {
1079 if (!isIetfInet(c)) {
1082 String simpleName = c.getSimpleName();
1083 return (IPV4_ADDRESS.equals(simpleName));
1086 public static boolean isIpv6Address(Class c) {
1091 if (!isIetfInet(c)) {
1094 String simpleName = c.getSimpleName();
1095 return (IPV6_ADDRESS.equals(simpleName));
1098 public static boolean isIpAddress(Class c) {
1103 if (!isIetfInet(c)) {
1106 String simpleName = c.getSimpleName();
1107 return (IP_ADDRESS.equals(simpleName));
1110 public static boolean isPortNumber(Class c) {
1115 if (!isIetfInet(c)) {
1119 String simpleName = c.getSimpleName();
1120 return ("PortNumber".equals(simpleName));
1123 public static boolean isDscp(Class c) {
1128 if (!isIetfInet(c)) {
1131 String simpleName = c.getSimpleName();
1132 return ("Dscp".equals(simpleName));
1135 public static boolean isIetfInet(Class c) {
1137 Package p = c.getPackage();
1139 String pkgName = p.getName();
1141 if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) {
1149 public static String toLowerHyphen(String inStr) {
1150 if (inStr == null) {
1154 String str = inStr.substring(0, 1).toLowerCase();
1155 if (inStr.length() > 1) {
1156 str = str + inStr.substring(1);
1159 String regex = "(([a-z0-9])([A-Z]))";
1160 String replacement = "$2-$3";
1162 String retval = str.replaceAll(regex, replacement).toLowerCase();
1167 // This is called when mapping the yang value back to a valid java enumeration
1168 public static String toJavaEnum(String inStr) {
1169 if (inStr == null) {
1171 } else if (inStr.length() == 0) {
1175 // This is needed for enums containing under scores
1176 inStr = inStr.replaceAll("_", "");
1178 // This will strip out all periods, which cannot be in a java enum
1179 inStr = inStr.replaceAll("\\.", "");
1181 // This is needed for enums containing spaces
1182 inStr = inStr.replaceAll(" ", "");
1184 String[] terms = inStr.split("-");
1185 StringBuffer sbuff = new StringBuffer();
1187 // appends an _ if the string starts with a digit to make it a valid java enum
1188 if (Character.isDigit(inStr.charAt(0))) {
1191 // If the string contains hyphens it will convert the string to upperCamelCase without hyphens
1192 for (String term : terms) {
1193 sbuff.append(term.substring(0, 1).toUpperCase());
1194 if (term.length() > 1) {
1195 sbuff.append(term.substring(1));
1198 return (sbuff.toString());
1202 public static boolean isGetter(Method m) {
1207 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
1208 if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
1209 if (!"getClass".equals(m.getName())) {
1214 if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
1218 if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
1226 public static boolean isSetter(Method m) {
1231 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
1232 if (m.getName().matches("^set[A-Z].*")) {
1233 Class[] paramTypes = m.getParameterTypes();
1234 if (paramTypes[0].isAssignableFrom(Identifier.class)
1235 || Identifier.class.isAssignableFrom(paramTypes[0])) {
1248 public static String getFullPropertiesPath(String propertiesFileName) {
1249 String karafHome = System.getProperty("karaf.home","/opt/lsc/controller");
1250 return karafHome + "/configuration/" + propertiesFileName;
1253 // This is called when mapping a valid java enumeration back to the yang model value
1255 public static String mapEnumeratedValue(String propertyName, String propertyValue) {
1256 LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
1257 String mappingKey = "yang." + propertyName + "." + propertyValue;
1258 if (yangMappingProperties.containsKey(mappingKey)) {
1259 return (yangMappingProperties.getProperty(mappingKey));
1261 LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
1262 return propertyValue;