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.onap.ccsdk.sli.core.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;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
45 import org.opendaylight.yangtools.yang.binding.Identifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 public class MdsalHelper {
51 private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
52 private static Properties yangMappingProperties = new Properties();
55 public static void setProperties(Properties input) {
56 setYangMappingProperties(input);
59 public static void setYangMappingProperties(Properties properties) {
60 for (Object propNameObj : properties.keySet()) {
61 String propName = (String) propNameObj;
62 MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
66 public static void loadProperties(String propertiesFile) {
67 File file = new File(propertiesFile);
68 Properties properties = new Properties();
69 if (file.isFile() && file.canRead()) {
70 try (InputStream input = new FileInputStream(file)) {
71 properties.load(input);
72 MdsalHelper.setYangMappingProperties(properties);
73 LOG.info("Loaded properties from " + propertiesFile);
74 } catch (Exception e) {
75 LOG.error("Failed to load properties " + propertiesFile + "\n", e);
78 LOG.error("Failed to load the properties file " + propertiesFile + "\n");
79 LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
83 public static Properties toProperties(Properties props, Object fromObj) {
84 Class fromClass = null;
86 if (fromObj != null) {
87 fromClass = fromObj.getClass();
89 return toProperties(props, "", fromObj, fromClass);
92 public static Properties toProperties(Properties props, String pfx, Object fromObj) {
93 Class fromClass = null;
95 if (fromObj != null) {
96 fromClass = fromObj.getClass();
99 return toProperties(props, pfx, fromObj, fromClass);
102 public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
104 if (fromObj == null) {
108 LOG.trace("Extracting properties from " + fromClass.getName() + " class");
109 if (fromObj instanceof List) {
111 // Class is a List. List should contain yang-generated classes.
112 LOG.trace(fromClass.getName() + " is a List");
114 List fromList = (List) fromObj;
116 for (int i = 0; i < fromList.size(); i++) {
117 toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
119 props.setProperty(pfx + "_length", Integer.toString(fromList.size()));
121 } else if (isYangGenerated(fromClass)) {
122 // Class is yang generated.
123 LOG.trace(fromClass.getName() + " is a Yang-generated class");
125 String propNamePfx = null;
127 // If called from a list (so prefix ends in ']'), don't
128 // add class name again
129 if (pfx.endsWith("]")) {
132 if ((pfx != null) && (pfx.length() > 0)) {
135 propNamePfx = toLowerHyphen(fromClass.getSimpleName());
138 if (propNamePfx.endsWith("-builder")) {
139 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
142 if (propNamePfx.endsWith("-impl")) {
143 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
147 // Iterate through getter methods to figure out values we need to
151 String lastGetterName = null;
152 String propVal = null;
154 for (Method m : fromClass.getMethods()) {
158 lastGetterName = m.getName();
160 Class returnType = m.getReturnType();
162 if (m.getName().startsWith("get")) {
163 fieldName = toLowerHyphen(m.getName().substring(3));
166 fieldName = toLowerHyphen(m.getName().substring(2));
169 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
171 // Is the return type a yang generated class?
172 if (isYangGenerated(returnType)) {
174 if (returnType.isEnum()) {
175 // Return type is a typedef. Save its value.
177 boolean isAccessible = m.isAccessible();
179 m.setAccessible(true);
182 Object retValue = m.invoke(fromObj);
185 m.setAccessible(isAccessible);
187 if (retValue != null) {
188 String propName = propNamePfx + "." + fieldName;
189 propVal = retValue.toString();
190 props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
192 } catch (Exception e) {
194 "Caught exception trying to convert Yang-generated enum returned by "
195 + fromClass.getName() + "." + m.getName() + "() to Properties entry",
198 } else if (isIpv4Address(returnType)) {
201 String propName = propNamePfx + "." + fieldName;
202 boolean isAccessible = m.isAccessible();
204 m.setAccessible(true);
206 Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
208 m.setAccessible(isAccessible);
211 if (retValue != null) {
212 propVal = retValue.getValue().toString();
213 LOG.debug("Setting property " + propName + " to " + propVal);
214 props.setProperty(propName, propVal);
217 } catch (Exception e) {
218 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
219 + "." + m.getName() + "() to Properties entry", e);
221 } else if (isIpv6Address(returnType)) {
224 String propName = propNamePfx + "." + fieldName;
225 boolean isAccessible = m.isAccessible();
227 m.setAccessible(true);
229 Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
231 m.setAccessible(isAccessible);
234 if (retValue != null) {
235 propVal = retValue.getValue().toString();
236 LOG.debug("Setting property " + propName + " to " + propVal);
237 props.setProperty(propName, propVal);
240 } catch (Exception e) {
241 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
242 + "." + m.getName() + "() to Properties entry", e);
244 } else if (isIpAddress(returnType)) {
247 String propName = propNamePfx + "." + fieldName;
248 boolean isAccessible = m.isAccessible();
250 m.setAccessible(true);
252 IpAddress retValue = (IpAddress) m.invoke(fromObj);
254 m.setAccessible(isAccessible);
257 if (retValue != null) {
258 propVal = new String(retValue.getValue());
259 LOG.debug("Setting property " + propName + " to " + propVal);
260 props.setProperty(propName, propVal);
263 } catch (Exception e) {
264 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
265 + "." + m.getName() + "() to Properties entry", e);
267 } else if (isIpPrefix(returnType)) {
270 String propName = propNamePfx + "." + fieldName;
271 boolean isAccessible = m.isAccessible();
273 m.setAccessible(true);
275 IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
277 m.setAccessible(isAccessible);
280 if (retValue != null) {
281 propVal = new String(retValue.getValue());
282 LOG.debug("Setting property " + propName + " to " + propVal);
283 props.setProperty(propName, propVal);
286 } catch (Exception e) {
287 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
288 + "." + m.getName() + "() to Properties entry", e);
290 } else if (isPortNumber(returnType)) {
293 String propName = propNamePfx + "." + fieldName;
294 boolean isAccessible = m.isAccessible();
296 m.setAccessible(true);
298 PortNumber retValue = (PortNumber) m.invoke(fromObj);
300 m.setAccessible(isAccessible);
303 if (retValue != null) {
304 propVal = "" + retValue.getValue();
305 LOG.debug("Setting property " + propName + " to " + propVal);
306 props.setProperty(propName, propVal);
309 } catch (Exception e) {
310 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
311 + "." + m.getName() + "() to Properties entry", e);
313 } else if (isDscp(returnType)) {
316 String propName = propNamePfx + "." + fieldName;
317 boolean isAccessible = m.isAccessible();
319 m.setAccessible(true);
321 Dscp retValue = (Dscp) m.invoke(fromObj);
323 m.setAccessible(isAccessible);
326 if (retValue != null) {
327 propVal = "" + retValue.getValue();
328 LOG.debug("Setting property " + propName + " to " + propVal);
329 props.setProperty(propName, propVal);
332 } catch (Exception e) {
333 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
334 + "." + m.getName() + "() to Properties entry", e);
338 boolean isAccessible = m.isAccessible();
340 m.setAccessible(true);
342 Object retValue = m.invoke(fromObj);
344 if (retValue instanceof byte[]) {
345 LOG.trace(m.getName() + " returns a byte[]");
346 retValue = new String((byte[]) retValue, "UTF-8");
347 LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string "
351 m.setAccessible(isAccessible);
353 if (retValue != null) {
354 toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
356 } catch (Exception e) {
358 if (m.getName().equals("getKey")) {
359 LOG.trace("Caught " + e.getClass().getName()
360 + " exception trying to convert results from getKey() - ignoring");
362 LOG.error("Caught exception trying to convert Yang-generated class returned by"
363 + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
367 } else if (returnType.equals(Class.class)) {
369 LOG.trace(m.getName() + " returns a Class object - not interested");
371 } else if (List.class.isAssignableFrom(returnType)) {
373 // This getter method returns a list.
375 boolean isAccessible = m.isAccessible();
377 m.setAccessible(true);
379 Object retList = m.invoke(fromObj);
381 m.setAccessible(isAccessible);
383 // Figure out what type of elements are stored in
385 Type paramType = m.getGenericReturnType();
386 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
387 toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType);
388 } catch (Exception e) {
389 LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "."
390 + m.getName() + "() to Properties entry", e);
395 // Method returns something that is not a List and not
399 String propName = propNamePfx + "." + fieldName;
400 boolean isAccessible = m.isAccessible();
402 m.setAccessible(true);
404 Object propValObj = m.invoke(fromObj);
406 m.setAccessible(isAccessible);
409 if (propValObj != null) {
410 if (propValObj instanceof byte[]) {
411 LOG.trace(m.getName() + " returns a byte[]");
412 propVal = new String((byte[]) propValObj, "UTF-8");
413 LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string "
417 propVal = propValObj.toString();
419 LOG.debug("Setting property " + propName + " to " + propVal);
420 props.setProperty(propName, propVal);
423 } catch (Exception e) {
424 if (m.getName().equals("getKey")) {
425 LOG.trace("Caught " + e.getClass().getName()
426 + " exception trying to convert results from getKey() - ignoring");
428 LOG.error("Caught exception trying to convert value returned by" + fromClass.getName()
429 + "." + m.getName() + "() to Properties entry", e);
437 // End of method loop. If there was only one getter, named
439 // set value identified by "prefix" to that one value.
440 if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
441 LOG.trace("getValueFIX : " + propNamePfx + " only has getValue() getter - setting " + propNamePfx
443 props.setProperty(propNamePfx, propVal);
445 LOG.trace("getValueFIX : " + propNamePfx + " has " + numGetters + " getter(s), last one found was "
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 + " to " + fromVal);
467 props.setProperty(pfx, fromVal);
473 public static Object toBuilder(Properties props, Object toObj) {
475 return (toBuilder(props, "", toObj));
478 public static List toList(Properties props, String pfx, List toObj, Class elemType) {
481 boolean foundValue = false;
483 LOG.trace("Saving properties to List<" + elemType.getName() + "> from " + pfx);
485 if (props.contains(pfx + "_length")) {
487 int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
489 if (listLength > 0) {
490 maxIdx = listLength - 1;
492 } catch (NumberFormatException e) {
493 LOG.info("Invalid input for length ", e);
498 // Figure out array size
499 for (Object pNameObj : props.keySet()) {
500 String key = (String) pNameObj;
502 if (key.startsWith(pfx + "[")) {
503 String idxStr = key.substring(pfx.length() + 1);
504 int endloc = idxStr.indexOf("]");
506 idxStr = idxStr.substring(0, endloc);
510 int curIdx = Integer.parseInt(idxStr);
511 if (curIdx > maxIdx) {
514 } catch (Exception e) {
515 LOG.error("Illegal subscript in property {}", key, e);
522 LOG.trace(pfx + " has max index of " + maxIdx);
523 for (int i = 0; i <= maxIdx; i++) {
525 String curBase = pfx + "[" + i + "]";
527 if (isYangGenerated(elemType)) {
528 String builderName = elemType.getName() + "Builder";
530 Class builderClass = Class.forName(builderName);
531 Object builderObj = builderClass.newInstance();
532 Method buildMethod = builderClass.getMethod("build");
533 builderObj = toBuilder(props, curBase, builderObj, true);
534 if (builderObj != null) {
535 LOG.trace("Calling " + builderObj.getClass().getName() + "." + buildMethod.getName() + "()");
536 Object builtObj = buildMethod.invoke(builderObj);
541 } catch (ClassNotFoundException e) {
542 LOG.warn("Could not find builder class {}", builderName, e);
543 } catch (Exception e) {
544 LOG.error("Caught exception trying to populate list from {}", pfx, e);
547 // Must be a leaf list
548 String curValue = props.getProperty(curBase, "");
552 if ((curValue != null) && (curValue.length() > 0)) {
567 public static Object toBuilder(Properties props, String pfx, Object toObj) {
568 return (toBuilder(props, pfx, toObj, false));
571 public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
572 Class toClass = toObj.getClass();
573 boolean foundValue = false;
575 LOG.trace("Saving properties to " + toClass.getName() + " class from " + pfx);
579 if (isYangGenerated(toClass)) {
580 // Class is yang generated.
581 LOG.trace(toClass.getName() + " is a Yang-generated class");
583 String propNamePfx = null;
588 if ((pfx != null) && (pfx.length() > 0)) {
589 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
591 propNamePfx = toLowerHyphen(toClass.getSimpleName());
594 if (propNamePfx.endsWith("-builder")) {
595 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
598 if (propNamePfx.endsWith("-impl")) {
599 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
603 if (toObj instanceof Identifier) {
604 LOG.trace(toClass.getName() + " is a Key - skipping");
608 // Iterate through getter methods to figure out values we need to
611 for (Method m : toClass.getMethods()) {
613 Class paramTypes[] = m.getParameterTypes();
614 Class paramClass = paramTypes[0];
616 String fieldName = toLowerHyphen(m.getName().substring(3));
617 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
619 String propName = propNamePfx + "." + fieldName;
621 String paramValue = props.getProperty(propName);
622 if (paramValue == null) {
623 LOG.trace(propName + " is unset");
624 } else if ("".equals(paramValue)) {
625 LOG.trace(propName + " was set to the empty string, setting it to null");
628 LOG.trace(propName + " = " + paramValue);
631 // Is the return type a yang generated class?
632 if (isYangGenerated(paramClass)) {
634 if (paramClass.isEnum()) {
636 LOG.trace(m.getName() + " expects an Enum");
637 // Param type is a typedef.
638 if ((paramValue != null) && (paramValue.length() > 0)) {
639 Object paramObj = null;
642 paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
643 } catch (Exception e) {
644 LOG.error("Caught exception trying to convert field " + propName + " to enum "
645 + paramClass.getName(), e);
649 boolean isAccessible = m.isAccessible();
651 m.setAccessible(true);
654 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
656 m.invoke(toObj, paramObj);
659 m.setAccessible(isAccessible);
663 } catch (Exception e) {
664 LOG.error("Caught exception trying to create Yang-generated enum expected by"
665 + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
670 String simpleName = paramClass.getSimpleName();
672 if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)
673 || "IpAddress".equals(simpleName)) {
675 if ((paramValue != null) && (paramValue.length() > 0)) {
677 IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
679 if ("Ipv4Address".equals(simpleName)) {
680 m.invoke(toObj, ipAddr.getIpv4Address());
681 } else if ("Ipv6Address".equals(simpleName)) {
682 m.invoke(toObj, ipAddr.getIpv6Address());
685 m.invoke(toObj, ipAddr);
688 } catch (Exception e) {
689 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
690 + "(" + paramValue + ")", e);
695 boolean isAccessible = m.isAccessible();
697 m.setAccessible(true);
699 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
701 m.invoke(toObj, paramValue);
703 m.setAccessible(isAccessible);
707 } catch (Exception e) {
708 LOG.error("Caught exception trying to call " + toClass.getName() + "."
709 + m.getName() + "() with Properties entry", e);
712 } else if ("IpPrefix".equals(simpleName)) {
713 if ((paramValue != null) && (paramValue.length() > 0)) {
715 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
716 m.invoke(toObj, ipPrefix);
718 } catch (Exception e) {
719 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
720 + "(" + paramValue + ")", e);
723 } else if ("PortNumber".equals(simpleName)) {
724 if ((paramValue != null) && (paramValue.length() > 0)) {
726 PortNumber portNumber = PortNumber.getDefaultInstance(paramValue);
727 m.invoke(toObj, portNumber);
729 } catch (Exception e) {
730 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
731 + "(" + paramValue + ")", e);
734 } else if ("Dscp".equals(simpleName)) {
735 if ((paramValue != null) && (paramValue.length() > 0)) {
737 Dscp dscp = Dscp.getDefaultInstance(paramValue);
738 m.invoke(toObj, dscp);
740 } catch (Exception e) {
741 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
742 + "(" + paramValue + ")", e);
746 // setter expects a yang-generated class. Need
748 // create a builder to set it.
750 String builderName = paramClass.getName() + "Builder";
751 Class builderClass = null;
752 Object builderObj = null;
753 Object paramObj = null;
755 Object constObj = null;
757 LOG.trace(m.getName() + " expects a yang-generated class - looking for builder "
760 builderClass = Class.forName(builderName);
761 builderObj = builderClass.newInstance();
762 paramObj = toBuilder(props, propNamePfx, builderObj);
763 } catch (ClassNotFoundException e) {
764 LOG.info("Builder class {} not found ", builderName, e);
765 if (paramValue == null) {
767 boolean isAccessible = m.isAccessible();
769 m.setAccessible(true);
771 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName()
773 m.invoke(toObj, new Object[] {null});
775 m.setAccessible(isAccessible);
779 } catch (Exception e1) {
780 LOG.error("Caught exception trying to cally" + toClass.getName() + "."
781 + m.getName() + "() with Properties entry", e1);
785 // See if I can find a constructor I
788 Constructor[] constructors = paramClass.getConstructors();
789 // Is there a String constructor?
790 for (Constructor c : constructors) {
791 Class[] cParms = c.getParameterTypes();
792 if ((cParms != null) && (cParms.length == 1)) {
793 if (String.class.isAssignableFrom(cParms[0])) {
794 constObj = c.newInstance(paramValue);
799 if (constObj == null) {
800 // Is there a Long constructor?
801 for (Constructor c : constructors) {
802 Class[] cParms = c.getParameterTypes();
803 if ((cParms != null) && (cParms.length == 1)) {
804 if (Long.class.isAssignableFrom(cParms[0])) {
805 constObj = c.newInstance(Long.parseLong(paramValue));
812 if (constObj == null) {
814 // Last chance - see if
815 // parameter class has a static
817 // getDefaultInstance(String)
820 paramClass.getMethod("getDefaultInstance", String.class);
822 int gmodifier = gm.getModifiers();
823 if (Modifier.isStatic(gmodifier)) {
825 // getDefaultInstance(String)
826 paramObj = gm.invoke(null, paramValue);
829 } catch (Exception gme) {
830 LOG.info("Unable to find static method getDefaultInstance for "
831 + "class {}", paramClass.getSimpleName(), gme);
835 } catch (Exception e1) {
837 "Could not find a suitable constructor for " + paramClass.getName(),
841 if (constObj == null) {
842 LOG.warn("Could not find builder class " + builderName
843 + " and could not find a String or Long constructor or static "
844 + "getDefaultInstance(String) - trying just to set passing paramValue");
848 } catch (Exception e) {
849 LOG.error("Caught exception trying to create builder " + builderName, e);
852 if (paramObj != null && builderClass != null) {
855 Method buildMethod = builderClass.getMethod("build");
856 LOG.trace("Calling " + paramObj.getClass().getName() + "."
857 + buildMethod.getName() + "()");
858 Object builtObj = buildMethod.invoke(paramObj);
860 boolean isAccessible = m.isAccessible();
862 m.setAccessible(true);
865 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "()");
866 m.invoke(toObj, builtObj);
868 m.setAccessible(isAccessible);
872 } catch (Exception e) {
873 LOG.error("Caught exception trying to set Yang-generated class expected by"
874 + toClass.getName() + "." + m.getName() + "() from Properties entry",
879 boolean isAccessible = m.isAccessible();
881 m.setAccessible(true);
884 if (constObj != null) {
886 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
887 + constObj.toString() + ")");
888 m.invoke(toObj, constObj);
890 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
892 m.invoke(toObj, paramValue);
896 m.setAccessible(isAccessible);
900 } catch (Exception e) {
901 LOG.error("Caught exception trying to convert value returned by"
902 + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
909 // Setter's argument is not a yang-generated class. See
912 if (List.class.isAssignableFrom(paramClass)) {
914 LOG.trace("Parameter class " + paramClass.getName() + " is a List");
916 // Figure out what type of args are in List and pass
919 Type paramType = m.getGenericParameterTypes()[0];
920 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
921 Object paramObj = new LinkedList();
923 paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
924 } catch (Exception e) {
925 LOG.error("Caught exception trying to create list expected as argument to {}.{}",
926 toClass.getName(), m.getName(), e);
929 if (paramObj != null) {
931 boolean isAccessible = m.isAccessible();
933 m.setAccessible(true);
935 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
937 m.invoke(toObj, paramObj);
939 m.setAccessible(isAccessible);
943 } catch (Exception e) {
944 LOG.error("Caught exception trying to convert List returned by" + toClass.getName()
945 + "." + m.getName() + "() to Properties entry", e);
950 // Setter expects something that is not a List and
951 // not yang-generated. Just pass the parameter value
953 LOG.trace("Parameter class " + paramClass.getName()
954 + " is not a yang-generated class or a List");
956 if ((paramValue != null) && (paramValue.length() > 0)) {
958 Object constObj = null;
961 // See if I can find a constructor I can use
962 Constructor[] constructors = paramClass.getConstructors();
963 // Is there a String constructor?
964 for (Constructor c : constructors) {
965 Class[] cParms = c.getParameterTypes();
966 if ((cParms != null) && (cParms.length == 1)) {
967 if (String.class.isAssignableFrom(cParms[0])) {
968 constObj = c.newInstance(paramValue);
973 if (constObj == null) {
974 // Is there a Long constructor?
975 for (Constructor c : constructors) {
976 Class[] cParms = c.getParameterTypes();
977 if ((cParms != null) && (cParms.length == 1)) {
978 if (Long.class.isAssignableFrom(cParms[0])) {
979 constObj = c.newInstance(Long.parseLong(paramValue));
986 if (constObj != null) {
988 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
990 m.invoke(toObj, constObj);
992 } catch (Exception e2) {
993 LOG.error("Caught exception trying to call " + m.getName(), e2);
997 boolean isAccessible = m.isAccessible();
999 m.setAccessible(true);
1001 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "("
1002 + paramValue + ")");
1003 m.invoke(toObj, paramValue);
1004 if (!isAccessible) {
1005 m.setAccessible(isAccessible);
1009 } catch (Exception e) {
1010 LOG.error("Caught exception trying to convert value returned by"
1011 + toClass.getName() + "." + m.getName() + "() to Properties entry",
1015 } catch (Exception e1) {
1016 LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
1022 } // End of section handling "setter" method
1023 } // End of loop through Methods
1024 } // End of section handling yang-generated class
1033 public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
1034 boolean foundValue = false;
1036 LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
1038 if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
1039 // Class is yang generated.
1040 LOG.trace(toClass.getName() + " is a Yang-generated class");
1042 if (toClass.getName().endsWith("Key")) {
1043 if (Identifier.class.isAssignableFrom(toClass)) {
1044 LOG.trace(Identifier.class.getName() + " is assignable from " + toClass.getName());
1047 LOG.trace(Identifier.class.getName() + " is NOT assignable from " + toClass.getName());
1051 String propNamePfx = null;
1052 if (pfx.endsWith("]")) {
1056 if ((pfx != null) && (pfx.length() > 0)) {
1057 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
1059 propNamePfx = toLowerHyphen(toClass.getSimpleName());
1062 if (propNamePfx.endsWith("-builder")) {
1063 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
1066 if (propNamePfx.endsWith("-impl")) {
1067 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
1071 // Iterate through getter methods to figure out values we need to
1074 for (Method m : toClass.getMethods()) {
1075 LOG.trace("Is " + m.getName() + " method a getter?");
1077 LOG.trace(m.getName() + " is a getter");
1078 Class returnClass = m.getReturnType();
1080 String fieldName = toLowerHyphen(m.getName().substring(3));
1081 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
1083 String propName = propNamePfx + "." + fieldName;
1085 // Is the return type a yang generated class?
1086 if (isYangGenerated(returnClass)) {
1088 if (returnClass.isEnum()) {
1090 LOG.trace(m.getName() + " is an Enum");
1091 pstr.print("\n\n * " + propName);
1095 String simpleName = returnClass.getSimpleName();
1097 if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)
1098 || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)
1099 || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
1100 LOG.trace(m.getName() + " is an " + simpleName);
1101 pstr.print("\n\n * " + propName);
1103 printPropertyList(pstr, propNamePfx, returnClass);
1109 // Setter's argument is not a yang-generated class. See
1112 if (List.class.isAssignableFrom(returnClass)) {
1114 LOG.trace("Parameter class " + returnClass.getName() + " is a List");
1116 // Figure out what type of args are in List and pass
1117 // that to toList().
1119 Type returnType = m.getGenericReturnType();
1120 Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
1121 Class elementClass = (Class) elementType;
1122 LOG.trace("Calling printPropertyList on list type (" + elementClass.getName()
1123 + "), pfx is (" + pfx + "), toClass is (" + toClass.getName() + ")");
1124 printPropertyList(pstr,
1125 propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]",
1128 } else if (!returnClass.equals(Class.class)) {
1130 // Setter expects something that is not a List and
1131 // not yang-generated. Just pass the parameter value
1133 LOG.trace("Parameter class " + returnClass.getName()
1134 + " is not a yang-generated class or a List");
1136 pstr.print("\n\n * " + propName);
1139 } // End of section handling "setter" method
1140 } // End of loop through Methods
1141 } // End of section handling yang-generated class
1145 public static boolean isYangGenerated(Class c) {
1149 return (c.getName().startsWith("org.opendaylight.yang.gen."));
1153 public static boolean isIpPrefix(Class c) {
1158 if (!isIetfInet(c)) {
1161 String simpleName = c.getSimpleName();
1162 return ("IpPrefix".equals(simpleName));
1165 public static boolean isIpv4Address(Class c) {
1170 if (!isIetfInet(c)) {
1173 String simpleName = c.getSimpleName();
1174 return ("Ipv4Address".equals(simpleName));
1177 public static boolean isIpv6Address(Class c) {
1182 if (!isIetfInet(c)) {
1185 String simpleName = c.getSimpleName();
1186 return ("Ipv6Address".equals(simpleName));
1189 public static boolean isIpAddress(Class c) {
1194 if (!isIetfInet(c)) {
1197 String simpleName = c.getSimpleName();
1198 return ("IpAddress".equals(simpleName));
1201 public static boolean isPortNumber(Class c) {
1206 if (!isIetfInet(c)) {
1210 String simpleName = c.getSimpleName();
1211 return ("PortNumber".equals(simpleName));
1214 public static boolean isDscp(Class c) {
1219 if (!isIetfInet(c)) {
1222 String simpleName = c.getSimpleName();
1223 return ("Dscp".equals(simpleName));
1226 public static boolean isIetfInet(Class c) {
1228 Package p = c.getPackage();
1230 String pkgName = p.getName();
1232 if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) {
1240 public static String toLowerHyphen(String inStr) {
1241 if (inStr == null) {
1245 String str = inStr.substring(0, 1).toLowerCase();
1246 if (inStr.length() > 1) {
1247 str = str + inStr.substring(1);
1250 String regex = "(([a-z0-9])([A-Z]))";
1251 String replacement = "$2-$3";
1253 String retval = str.replaceAll(regex, replacement).toLowerCase();
1255 LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
1259 // This is called when mapping the yang value back to a valid java enumeration
1260 public static String toJavaEnum(String inStr) {
1261 if (inStr == null) {
1263 } else if (inStr.length() == 0) {
1267 // This will strip out all periods, which cannot be in a java enum
1268 inStr = inStr.replaceAll("\\.", "");
1270 String[] terms = inStr.split("-");
1271 StringBuffer sbuff = new StringBuffer();
1273 // appends an _ if the string starts with a digit to make it a valid java enum
1274 if (Character.isDigit(inStr.charAt(0))) {
1277 // If the string contains hyphens it will convert the string to upperCamelCase without hyphens
1278 for (String term : terms) {
1279 sbuff.append(term.substring(0, 1).toUpperCase());
1280 if (term.length() > 1) {
1281 sbuff.append(term.substring(1));
1284 return (sbuff.toString());
1288 public static boolean isGetter(Method m) {
1293 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
1294 if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
1295 if (!"getClass".equals(m.getName())) {
1300 if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
1304 if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
1312 public static boolean isSetter(Method m) {
1317 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
1318 if (m.getName().matches("^set[A-Z].*")) {
1319 Class[] paramTypes = m.getParameterTypes();
1320 if (paramTypes[0].isAssignableFrom(Identifier.class)
1321 || Identifier.class.isAssignableFrom(paramTypes[0])) {
1333 public static String getFullPropertiesPath(String propertiesFileName) {
1334 return "/opt/bvc/controller/configuration/" + propertiesFileName;
1337 // This is called when mapping a valid java enumeration back to the yang model value
1338 public static String mapEnumeratedValue(String propertyName, String propertyValue) {
1339 LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
1340 String mappingKey = "yang." + propertyName + "." + propertyValue;
1341 if (yangMappingProperties.containsKey(mappingKey)) {
1342 return (yangMappingProperties.getProperty(mappingKey));
1344 LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
1345 return propertyValue;