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 props.setProperty(propNamePfx, propVal);
348 // Class is not yang generated and not a list
349 // It must be an element of a leaf list - set "prefix" to value
350 String fromVal = null;
351 if (fromObj instanceof byte[]) {
353 fromVal = new String((byte[]) fromObj, "UTF-8");
354 } catch (Exception e) {
355 LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
356 fromVal = fromObj.toString();
360 fromVal = fromObj.toString();
362 LOG.debug(SETTING_PROPERTY + pfx + " to " + fromVal);
363 props.setProperty(pfx, fromVal);
369 public static Object toBuilder(Properties props, Object toObj) {
371 return (toBuilder(props, "", toObj));
374 public static List toList(Properties props, String pfx, List toObj, Class elemType) {
377 boolean foundValue = false;
379 if (props.containsKey(pfx + "_length")) {
381 int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
383 if (listLength > 0) {
384 maxIdx = listLength - 1;
386 } catch (NumberFormatException e) {
387 LOG.info("Invalid input for length ", e);
391 String arrayKey = pfx + "[";
392 int arrayKeyLength = arrayKey.length();
394 // Figure out array size
395 for (Object pNameObj : props.keySet()) {
396 String key = (String) pNameObj;
398 if (key.startsWith(arrayKey)) {
399 String idxStr = key.substring(arrayKeyLength);
400 int endloc = idxStr.indexOf("]");
402 idxStr = idxStr.substring(0, endloc);
405 int curIdx = Integer.parseInt(idxStr);
406 if (curIdx > maxIdx) {
409 } catch (Exception e) {
410 LOG.error("Illegal subscript in property {}", key, e);
417 for (int i = 0; i <= maxIdx; i++) {
419 String curBase = pfx + "[" + i + "]";
421 if (isYangGenerated(elemType)) {
423 if (isIpAddress(elemType)) {
425 String curValue = props.getProperty(curBase, "");
427 if ((curValue != null) && (curValue.length() > 0)) {
428 toObj.add(IpAddressBuilder.getDefaultInstance(curValue));
431 } else if (isIpv4Address(elemType)) {
432 String curValue = props.getProperty(curBase, "");
434 if ((curValue != null) && (curValue.length() > 0)) {
435 toObj.add(new Ipv4Address(curValue));
439 } else if (isIpv6Address(elemType)) {
440 String curValue = props.getProperty(curBase, "");
442 if ((curValue != null) && (curValue.length() > 0)) {
443 toObj.add(new Ipv6Address(curValue));
446 } else if (isIpPrefix(elemType)) {
448 String curValue = props.getProperty(curBase, "");
450 if ((curValue != null) && (curValue.length() > 0)) {
451 toObj.add(IpPrefixBuilder.getDefaultInstance(curValue));
454 } else if (isPortNumber(elemType)) {
456 String curValue = props.getProperty(curBase, "");
458 if ((curValue != null) && (curValue.length() > 0)) {
459 toObj.add(PortNumber.getDefaultInstance(curValue));
462 } else if (isDscp(elemType)) {
464 String curValue = props.getProperty(curBase, "");
466 if ((curValue != null) && (curValue.length() > 0)) {
467 toObj.add(Dscp.getDefaultInstance(curValue));
471 String builderName = elemType.getName() + "Builder";
473 Class builderClass = Class.forName(builderName);
474 Object builderObj = builderClass.newInstance();
475 Method buildMethod = builderClass.getMethod("build");
476 builderObj = toBuilder(props, curBase, builderObj, true);
477 if (builderObj != null) {
478 Object builtObj = buildMethod.invoke(builderObj);
483 } catch (ClassNotFoundException e) {
484 LOG.warn("Could not find builder class {}", builderName, e);
485 } catch (Exception e) {
486 LOG.error("Caught exception trying to populate list from {}", pfx, e);
490 // Must be a leaf list
491 String curValue = props.getProperty(curBase, "");
495 if ((curValue != null) && (curValue.length() > 0)) {
510 public static Object toBuilder(Properties props, String pfx, Object toObj) {
511 return (toBuilder(props, pfx, toObj, false));
514 public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
516 Class toClass = toObj.getClass();
517 boolean foundValue = false;
521 if (isYangGenerated(toClass)) {
522 // Class is yang generated.
523 String propNamePfx = null;
528 if ((pfx != null) && (pfx.length() > 0)) {
529 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
531 propNamePfx = toLowerHyphen(toClass.getSimpleName());
534 if (propNamePfx.endsWith(BUILDER)) {
535 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
538 if (propNamePfx.endsWith("-impl")) {
539 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
543 if (toObj instanceof Identifier) {
547 // Iterate through getter methods to figure out values we need to
550 for (Method m : toClass.getMethods()) {
552 Class paramTypes[] = m.getParameterTypes();
553 Class paramClass = paramTypes[0];
555 String fieldName = toLowerHyphen(m.getName().substring(3));
556 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
558 String propName = propNamePfx + "." + fieldName;
560 String paramValue = props.getProperty(propName);
561 if (paramValue == null) {
563 } else if ("".equals(paramValue)) {
564 LOG.trace(propName + " was set to the empty string, setting it to null");
570 // Is the return type a yang generated class?
571 if (isYangGenerated(paramClass)) {
573 if (paramClass.isEnum()) {
575 // Param type is a typedef.
576 if ((paramValue != null) && (paramValue.length() > 0)) {
577 Object paramObj = null;
580 paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
581 } catch (Exception e) {
582 LOG.error("Caught exception trying to convert field " + propName + " to enum "
583 + paramClass.getName(), e);
587 boolean isAccessible = m.isAccessible();
589 m.setAccessible(true);
592 m.invoke(toObj, paramObj);
595 m.setAccessible(isAccessible);
599 } catch (Exception e) {
600 LOG.error("Caught exception trying to create Yang-generated enum expected by"
601 + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
606 String simpleName = paramClass.getSimpleName();
608 if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
609 || IP_ADDRESS.equals(simpleName)) {
612 if ((paramValue != null) && (paramValue.length() > 0)) {
614 IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
616 if (IPV4_ADDRESS.equals(simpleName)) {
617 m.invoke(toObj, ipAddr.getIpv4Address());
618 } else if (IPV6_ADDRESS.equals(simpleName)) {
619 m.invoke(toObj, ipAddr.getIpv6Address());
622 m.invoke(toObj, ipAddr);
625 } catch (Exception e) {
626 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
627 + "(" + paramValue + ")", e);
632 boolean isAccessible = m.isAccessible();
634 m.setAccessible(true);
637 m.invoke(toObj, paramValue);
639 m.setAccessible(isAccessible);
643 } catch (Exception e) {
644 LOG.error("Caught exception trying to call " + toClass.getName() + "."
645 + m.getName() + "() with Properties entry", e);
648 } else if (IP_PREFIX.equals(simpleName)) {
649 if ((paramValue != null) && (paramValue.length() > 0)) {
651 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
652 m.invoke(toObj, ipPrefix);
654 } catch (Exception e) {
655 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
656 + "(" + paramValue + ")", e);
659 } else if ("PortNumber".equals(simpleName)) {
660 if ((paramValue != null) && (paramValue.length() > 0)) {
662 PortNumber portNumber = PortNumber.getDefaultInstance(paramValue);
663 m.invoke(toObj, portNumber);
665 } catch (Exception e) {
666 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
667 + "(" + paramValue + ")", e);
670 } else if ("Dscp".equals(simpleName)) {
671 if ((paramValue != null) && (paramValue.length() > 0)) {
673 Dscp dscp = Dscp.getDefaultInstance(paramValue);
674 m.invoke(toObj, dscp);
676 } catch (Exception e) {
677 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
678 + "(" + paramValue + ")", e);
682 // setter expects a yang-generated class. Need
684 // create a builder to set it.
686 String builderName = paramClass.getName() + "Builder";
687 Class builderClass = null;
688 Object builderObj = null;
689 Object paramObj = null;
691 Object constObj = null;
694 builderClass = Class.forName(builderName);
695 builderObj = builderClass.newInstance();
696 paramObj = toBuilder(props, propNamePfx, builderObj);
697 } catch (ClassNotFoundException e) {
698 LOG.info("Builder class {} not found ", builderName, e);
699 if (paramValue == null) {
701 boolean isAccessible = m.isAccessible();
703 m.setAccessible(true);
706 m.invoke(toObj, new Object[] { null });
708 m.setAccessible(isAccessible);
712 } catch (Exception e1) {
713 LOG.error("Caught exception trying to cally" + toClass.getName() + "."
714 + m.getName() + "() with Properties entry", e1);
718 // See if I can find a constructor I
721 Constructor[] constructors = paramClass.getConstructors();
722 // Is there a String constructor?
723 for (Constructor c : constructors) {
724 Class[] cParms = c.getParameterTypes();
725 if ((cParms != null) && (cParms.length == 1)) {
726 if (String.class.isAssignableFrom(cParms[0])) {
727 constObj = c.newInstance(paramValue);
732 if (constObj == null) {
733 // Is there a Long constructor?
734 for (Constructor c : constructors) {
735 Class[] cParms = c.getParameterTypes();
736 if ((cParms != null) && (cParms.length == 1)) {
737 if (Long.class.isAssignableFrom(cParms[0])) {
738 constObj = c.newInstance(Long.parseLong(paramValue));
745 if (constObj == null) {
747 // Last chance - see if
748 // parameter class has a static
750 // getDefaultInstance(String)
753 paramClass.getMethod("getDefaultInstance", String.class);
755 int gmodifier = gm.getModifiers();
756 if (Modifier.isStatic(gmodifier)) {
758 // getDefaultInstance(String)
759 paramObj = gm.invoke(null, paramValue);
762 } catch (Exception gme) {
763 LOG.info("Unable to find static method getDefaultInstance for "
764 + "class {}", paramClass.getSimpleName(), gme);
768 } catch (Exception e1) {
770 "Could not find a suitable constructor for " + paramClass.getName(),
774 if (constObj == null) {
775 LOG.warn("Could not find builder class " + builderName
776 + " and could not find a String or Long constructor or static "
777 + "getDefaultInstance(String) - trying just to set passing paramValue");
781 } catch (Exception e) {
782 LOG.error("Caught exception trying to create builder " + builderName, e);
785 if (paramObj != null && builderClass != null) {
788 Method buildMethod = builderClass.getMethod("build");
790 Object builtObj = buildMethod.invoke(paramObj);
792 boolean isAccessible = m.isAccessible();
794 m.setAccessible(true);
797 m.invoke(toObj, builtObj);
799 m.setAccessible(isAccessible);
803 } catch (Exception e) {
804 LOG.error("Caught exception trying to set Yang-generated class expected by"
805 + toClass.getName() + "." + m.getName() + "() from Properties entry",
810 boolean isAccessible = m.isAccessible();
812 m.setAccessible(true);
815 if (constObj != null) {
816 m.invoke(toObj, constObj);
818 m.invoke(toObj, paramValue);
821 m.setAccessible(isAccessible);
825 } catch (Exception e) {
826 LOG.error("Caught exception trying to convert value returned by"
827 + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
834 // Setter's argument is not a yang-generated class. See
837 if (List.class.isAssignableFrom(paramClass)) {
838 // Figure out what type of args are in List and pass
841 Type paramType = m.getGenericParameterTypes()[0];
842 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
843 Object paramObj = new LinkedList();
845 paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
846 } catch (Exception e) {
847 LOG.error("Caught exception trying to create list expected as argument to {}.{}",
848 toClass.getName(), m.getName(), e);
851 if (paramObj != null) {
853 boolean isAccessible = m.isAccessible();
855 m.setAccessible(true);
857 m.invoke(toObj, paramObj);
859 m.setAccessible(isAccessible);
863 } catch (Exception e) {
864 LOG.error("Caught exception trying to convert List returned by" + toClass.getName()
865 + "." + m.getName() + "() to Properties entry", e);
870 // Setter expects something that is not a List and
871 // not yang-generated. Just pass the parameter value
872 if ((paramValue != null) && (paramValue.length() > 0)) {
874 Object constObj = null;
877 // See if I can find a constructor I can use
878 Constructor[] constructors = paramClass.getConstructors();
879 // Is there a String constructor?
880 for (Constructor c : constructors) {
881 Class[] cParms = c.getParameterTypes();
882 if ((cParms != null) && (cParms.length == 1)) {
883 if (String.class.isAssignableFrom(cParms[0])) {
884 constObj = c.newInstance(paramValue);
889 if (constObj == null) {
890 // Is there a Long constructor?
891 for (Constructor c : constructors) {
892 Class[] cParms = c.getParameterTypes();
893 if ((cParms != null) && (cParms.length == 1)) {
894 if (Long.class.isAssignableFrom(cParms[0])) {
895 constObj = c.newInstance(Long.parseLong(paramValue));
902 if (constObj != null) {
904 m.invoke(toObj, constObj);
906 } catch (Exception e2) {
907 LOG.error("Caught exception trying to call " + m.getName(), e2);
911 boolean isAccessible = m.isAccessible();
913 m.setAccessible(true);
915 m.invoke(toObj, paramValue);
917 m.setAccessible(isAccessible);
921 } catch (Exception e) {
922 LOG.error("Caught exception trying to convert value returned by"
923 + toClass.getName() + "." + m.getName() + "() to Properties entry",
927 } catch (Exception e1) {
928 LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
934 } // End of section handling "setter" method
935 } // End of loop through Methods
936 } // End of section handling yang-generated class
945 private static boolean classHasSpecialHandling(String simpleName) {
946 if (IP_ADDRESS.equals(simpleName) || IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
947 || IP_PREFIX.equals(simpleName) || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
953 private static String getStringValueMethod(String simpleName){
954 if (IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)) {
955 return("stringValue");
961 public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
962 boolean foundValue = false;
964 if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
965 // Class is yang generated.
966 String propNamePfx = null;
967 if (pfx.endsWith("]")) {
971 if ((pfx != null) && (pfx.length() > 0)) {
972 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
974 propNamePfx = toLowerHyphen(toClass.getSimpleName());
977 if (propNamePfx.endsWith(BUILDER)) {
978 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
981 if (propNamePfx.endsWith("-impl")) {
982 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
986 // Iterate through getter methods to figure out values we need to
989 for (Method m : toClass.getMethods()) {
991 Class returnClass = m.getReturnType();
993 String fieldName = toLowerHyphen(m.getName().substring(3));
994 if (fieldName != null) {
995 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
999 String propName = propNamePfx + "." + fieldName;
1001 // Is the return type a yang generated class?
1002 if (isYangGenerated(returnClass)) {
1004 if (returnClass.isEnum()) {
1005 pstr.print("\n\n * " + propName);
1008 String simpleName = returnClass.getSimpleName();
1010 if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
1011 || IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)
1012 || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
1013 pstr.print("\n\n * " + propName);
1015 printPropertyList(pstr, propNamePfx, returnClass);
1021 // Setter's argument is not a yang-generated class. See
1024 if (List.class.isAssignableFrom(returnClass)) {
1025 // Figure out what type of args are in List and pass
1026 // that to toList().
1028 Type returnType = m.getGenericReturnType();
1029 Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
1030 Class elementClass = (Class) elementType;
1031 printPropertyList(pstr,
1032 propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]",
1035 } else if (!returnClass.equals(Class.class)) {
1037 // Setter expects something that is not a List and
1038 // not yang-generated. Just pass the parameter value
1039 pstr.print("\n\n * " + propName);
1042 } // End of section handling "setter" method
1043 } // End of loop through Methods
1044 } // End of section handling yang-generated class
1048 public static boolean isYangGenerated(Class c) {
1050 return (c.getName().startsWith("org.opendaylight.yang.gen."));
1055 public static boolean isIpPrefix(Class c) {
1060 if (!isIetfInet(c)) {
1063 String simpleName = c.getSimpleName();
1064 return (IP_PREFIX.equals(simpleName));
1067 public static boolean isIpv4Address(Class c) {
1072 if (!isIetfInet(c)) {
1075 String simpleName = c.getSimpleName();
1076 return (IPV4_ADDRESS.equals(simpleName));
1079 public static boolean isIpv6Address(Class c) {
1084 if (!isIetfInet(c)) {
1087 String simpleName = c.getSimpleName();
1088 return (IPV6_ADDRESS.equals(simpleName));
1091 public static boolean isIpAddress(Class c) {
1096 if (!isIetfInet(c)) {
1099 String simpleName = c.getSimpleName();
1100 return (IP_ADDRESS.equals(simpleName));
1103 public static boolean isPortNumber(Class c) {
1108 if (!isIetfInet(c)) {
1112 String simpleName = c.getSimpleName();
1113 return ("PortNumber".equals(simpleName));
1116 public static boolean isDscp(Class c) {
1121 if (!isIetfInet(c)) {
1124 String simpleName = c.getSimpleName();
1125 return ("Dscp".equals(simpleName));
1128 public static boolean isIetfInet(Class c) {
1130 Package p = c.getPackage();
1132 String pkgName = p.getName();
1134 if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) {
1142 public static String toLowerHyphen(String inStr) {
1143 if (inStr == null) {
1147 String str = inStr.substring(0, 1).toLowerCase();
1148 if (inStr.length() > 1) {
1149 str = str + inStr.substring(1);
1152 String regex = "(([a-z0-9])([A-Z]))";
1153 String replacement = "$2-$3";
1155 String retval = str.replaceAll(regex, replacement).toLowerCase();
1160 // This is called when mapping the yang value back to a valid java enumeration
1161 public static String toJavaEnum(String inStr) {
1162 if (inStr == null) {
1164 } else if (inStr.length() == 0) {
1168 // This is needed for enums containing under scores
1169 inStr = inStr.replaceAll("_", "");
1171 // This will strip out all periods, which cannot be in a java enum
1172 inStr = inStr.replaceAll("\\.", "");
1174 // This is needed for enums containing spaces
1175 inStr = inStr.replaceAll(" ", "");
1177 String[] terms = inStr.split("-");
1178 StringBuffer sbuff = new StringBuffer();
1180 // appends an _ if the string starts with a digit to make it a valid java enum
1181 if (Character.isDigit(inStr.charAt(0))) {
1184 // If the string contains hyphens it will convert the string to upperCamelCase without hyphens
1185 for (String term : terms) {
1186 sbuff.append(term.substring(0, 1).toUpperCase());
1187 if (term.length() > 1) {
1188 sbuff.append(term.substring(1));
1191 return (sbuff.toString());
1195 public static boolean isGetter(Method m) {
1200 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
1201 if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
1202 if (!"getClass".equals(m.getName())) {
1207 if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
1211 if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
1219 public static boolean isSetter(Method m) {
1224 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
1225 if (m.getName().matches("^set[A-Z].*")) {
1226 Class[] paramTypes = m.getParameterTypes();
1227 if (paramTypes[0].isAssignableFrom(Identifier.class)
1228 || Identifier.class.isAssignableFrom(paramTypes[0])) {
1241 public static String getFullPropertiesPath(String propertiesFileName) {
1242 String karafHome = System.getProperty("karaf.home","/opt/lsc/controller");
1243 return karafHome + "/configuration/" + propertiesFileName;
1246 // This is called when mapping a valid java enumeration back to the yang model value
1248 public static String mapEnumeratedValue(String propertyName, String propertyValue) {
1249 LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
1250 String mappingKey = "yang." + propertyName + "." + propertyValue;
1251 if (yangMappingProperties.containsKey(mappingKey)) {
1252 return (yangMappingProperties.getProperty(mappingKey));
1254 LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
1255 return propertyValue;