2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 ONAP
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.ccsdk.sli.core.sli.provider;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.PrintStream;
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.Method;
30 import java.lang.reflect.Modifier;
31 import java.lang.reflect.ParameterizedType;
32 import java.lang.reflect.Type;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.Properties;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
43 import org.opendaylight.yangtools.yang.binding.Identifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 public class MdsalHelper {
49 private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
50 private static Properties yangMappingProperties = new Properties();
53 public static void setProperties(Properties input) {
54 setYangMappingProperties(input);
57 public static void setYangMappingProperties(Properties properties) {
58 for (Object propNameObj : properties.keySet()) {
59 String propName = (String) propNameObj;
60 MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
64 public static void loadProperties(String propertiesFile) {
65 File file = new File(propertiesFile);
66 Properties properties = new Properties();
67 InputStream input = null;
68 if (file.isFile() && file.canRead()) {
70 input = new FileInputStream(file);
71 properties.load(input);
72 MdsalHelper.setYangMappingProperties(properties);
73 LOG.info("Loaded properties from " + propertiesFile);
74 } catch (Exception e) {
75 LOG.error("Failed to load properties " + propertiesFile + "\n", e);
80 } catch (IOException e) {
81 LOG.error("Failed to close properties file " + propertiesFile + "\n", e);
86 LOG.error("Failed to load the properties file " + propertiesFile + "\n");
87 LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
91 public static Properties toProperties(Properties props, Object fromObj) {
92 Class fromClass = null;
94 if (fromObj != null) {
95 fromClass = fromObj.getClass();
97 return (toProperties(props, "", fromObj, fromClass));
100 public static Properties toProperties(Properties props, String pfx, Object fromObj) {
101 Class fromClass = null;
103 if (fromObj != null) {
104 fromClass = fromObj.getClass();
107 return (toProperties(props, pfx, fromObj, fromClass));
110 public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
112 if (fromObj == null) {
116 String simpleName = fromClass.getSimpleName();
118 LOG.trace("Extracting properties from " + fromClass.getName() + " class");
119 if (fromObj instanceof List) {
121 // Class is a List. List should contain yang-generated classes.
122 LOG.trace(fromClass.getName() + " is a List");
124 List fromList = (List) fromObj;
126 for (int i = 0; i < fromList.size(); i++) {
127 toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
129 props.setProperty(pfx + "_length", "" + fromList.size());
131 } else if (isYangGenerated(fromClass)) {
132 // Class is yang generated.
133 LOG.trace(fromClass.getName() + " is a Yang-generated class");
135 String propNamePfx = null;
137 // If called from a list (so prefix ends in ']'), don't
138 // add class name again
139 if (pfx.endsWith("]")) {
142 if ((pfx != null) && (pfx.length() > 0)) {
145 propNamePfx = toLowerHyphen(fromClass.getSimpleName());
148 if (propNamePfx.endsWith("-builder")) {
149 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
152 if (propNamePfx.endsWith("-impl")) {
153 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
157 // Iterate through getter methods to figure out values we need to
161 String lastGetterName = null;
162 String propVal = null;
164 for (Method m : fromClass.getMethods()) {
168 lastGetterName = m.getName();
170 Class returnType = m.getReturnType();
172 if (m.getName().startsWith("get")) {
173 fieldName = toLowerHyphen(m.getName().substring(3));
176 fieldName = toLowerHyphen(m.getName().substring(2));
179 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
181 // Is the return type a yang generated class?
182 if (isYangGenerated(returnType)) {
184 if (returnType.isEnum()) {
185 // Return type is a typedef. Save its value.
187 boolean isAccessible = m.isAccessible();
189 m.setAccessible(true);
192 Object retValue = m.invoke(fromObj);
195 m.setAccessible(isAccessible);
197 if (retValue != null) {
198 String propName = propNamePfx + "." + fieldName;
199 propVal = retValue.toString();
200 props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
202 } catch (Exception e) {
203 LOG.error("Caught exception trying to convert Yang-generated enum returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
205 } else if (isIpv4Address(returnType)) {
208 String propName = propNamePfx + "." + fieldName;
209 boolean isAccessible = m.isAccessible();
211 m.setAccessible(true);
213 Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
215 m.setAccessible(isAccessible);
218 if (retValue != null) {
219 propVal = retValue.getValue().toString();
220 LOG.debug("Setting property " + propName + " to " + propVal);
221 props.setProperty(propName, propVal);
224 } catch (Exception e) {
225 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
227 } else if (isIpv6Address(returnType)) {
230 String propName = propNamePfx + "." + fieldName;
231 boolean isAccessible = m.isAccessible();
233 m.setAccessible(true);
235 Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
237 m.setAccessible(isAccessible);
240 if (retValue != null) {
241 propVal = retValue.getValue().toString();
242 LOG.debug("Setting property " + propName + " to " + propVal);
243 props.setProperty(propName, propVal);
246 } catch (Exception e) {
247 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
249 } else if (isIpAddress(returnType)) {
252 String propName = propNamePfx + "." + fieldName;
253 boolean isAccessible = m.isAccessible();
255 m.setAccessible(true);
257 IpAddress retValue = (IpAddress) m.invoke(fromObj);
259 m.setAccessible(isAccessible);
262 if (retValue != null) {
263 propVal = new String(retValue.getValue());
264 LOG.debug("Setting property " + propName + " to " + propVal);
265 props.setProperty(propName, propVal);
268 } catch (Exception e) {
269 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
271 } else if (isIpPrefix(returnType)) {
274 String propName = propNamePfx + "." + fieldName;
275 boolean isAccessible = m.isAccessible();
277 m.setAccessible(true);
279 IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
281 m.setAccessible(isAccessible);
284 if (retValue != null) {
285 propVal = new String(retValue.getValue());
286 LOG.debug("Setting property " + propName + " to " + propVal);
287 props.setProperty(propName, propVal);
290 } catch (Exception e) {
291 LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
295 boolean isAccessible = m.isAccessible();
297 m.setAccessible(true);
299 Object retValue = m.invoke(fromObj);
301 if (retValue instanceof byte[]) {
302 LOG.trace(m.getName() + " returns a byte[]");
303 retValue = new String((byte[]) retValue, "UTF-8");
304 LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + retValue);
307 m.setAccessible(isAccessible);
309 if (retValue != null) {
310 toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
312 } catch (Exception e) {
314 if (m.getName().equals("getKey")) {
315 LOG.trace("Caught " + e.getClass().getName() + " exception trying to convert results from getKey() - ignoring");
317 LOG.error("Caught exception trying to convert Yang-generated class returned by" + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
321 } else if (returnType.equals(Class.class)) {
323 LOG.trace(m.getName() + " returns a Class object - not interested");
325 } else if (List.class.isAssignableFrom(returnType)) {
327 // This getter method returns a list.
329 boolean isAccessible = m.isAccessible();
331 m.setAccessible(true);
333 Object retList = m.invoke(fromObj);
335 m.setAccessible(isAccessible);
337 // Figure out what type of elements are stored in
339 Type paramType = m.getGenericReturnType();
340 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
341 toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType);
342 } catch (Exception e) {
343 LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
348 // Method returns something that is not a List and not
352 String propName = propNamePfx + "." + fieldName;
353 boolean isAccessible = m.isAccessible();
355 m.setAccessible(true);
357 Object propValObj = m.invoke(fromObj);
359 m.setAccessible(isAccessible);
362 if (propValObj != null) {
363 if (propValObj instanceof byte[]) {
364 LOG.trace(m.getName() + " returns a byte[]");
365 propVal = new String((byte[]) propValObj, "UTF-8");
366 LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + propVal);
369 propVal = propValObj.toString();
371 LOG.debug("Setting property " + propName + " to " + propVal);
372 props.setProperty(propName, propVal);
375 } catch (Exception e) {
376 if (m.getName().equals("getKey")) {
377 LOG.trace("Caught " + e.getClass().getName() + " exception trying to convert results from getKey() - ignoring");
379 LOG.error("Caught exception trying to convert value returned by" + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
387 // End of method loop. If there was only one getter, named
389 // set value identified by "prefix" to that one value.
390 if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
391 LOG.trace("getValueFIX : " + propNamePfx + " only has getValue() getter - setting " + propNamePfx + " = " + propVal);
392 props.setProperty(propNamePfx, propVal);
394 LOG.trace("getValueFIX : " + propNamePfx + " has " + numGetters + " getter(s), last one found was " + lastGetterName);
399 // Class is not yang generated and not a list
400 // It must be an element of a leaf list - set "prefix" to value
401 String fromVal = null;
402 if (fromObj instanceof byte[]) {
404 fromVal = new String((byte[]) fromObj, "UTF-8");
405 LOG.trace("Converted byte array " + pfx + "to string " + fromVal);
406 } catch (Exception e) {
407 LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
408 fromVal = fromObj.toString();
412 fromVal = fromObj.toString();
414 LOG.debug("Setting property " + pfx + " to " + fromVal);
415 props.setProperty(pfx, fromVal);
421 public static Object toBuilder(Properties props, Object toObj) {
423 return (toBuilder(props, "", toObj));
426 public static List toList(Properties props, String pfx, List toObj, Class elemType) {
429 boolean foundValue = false;
431 LOG.trace("Saving properties to List<" + elemType.getName() + "> from " + pfx);
433 if (props.contains(pfx + "_length")) {
435 int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
437 if (listLength > 0) {
438 maxIdx = listLength - 1;
440 } catch (Exception e) {
446 // Figure out array size
447 for (Object pNameObj : props.keySet()) {
448 String key = (String) pNameObj;
450 if (key.startsWith(pfx + "[")) {
451 String idxStr = key.substring(pfx.length() + 1);
452 int endloc = idxStr.indexOf("]");
454 idxStr = idxStr.substring(0, endloc);
458 int curIdx = Integer.parseInt(idxStr);
459 if (curIdx > maxIdx) {
462 } catch (Exception e) {
463 LOG.error("Illegal subscript in property " + key);
470 LOG.trace(pfx + " has max index of " + maxIdx);
471 for (int i = 0; i <= maxIdx; i++) {
473 String curBase = pfx + "[" + i + "]";
475 if (isYangGenerated(elemType)) {
476 String builderName = elemType.getName() + "Builder";
478 Class builderClass = Class.forName(builderName);
479 Object builderObj = builderClass.newInstance();
480 Method buildMethod = builderClass.getMethod("build");
481 builderObj = toBuilder(props, curBase, builderObj, true);
482 if (builderObj != null) {
483 LOG.trace("Calling " + builderObj.getClass().getName() + "." + buildMethod.getName() + "()");
484 Object builtObj = buildMethod.invoke(builderObj);
489 } catch (ClassNotFoundException e) {
490 LOG.warn("Could not find builder class " + builderName, e);
491 } catch (Exception e) {
492 LOG.error("Caught exception trying to populate list from " + pfx);
495 // Must be a leaf list
496 String curValue = props.getProperty(curBase, "");
500 if ((curValue != null) && (curValue.length() > 0)) {
515 public static Object toBuilder(Properties props, String pfx, Object toObj) {
516 return (toBuilder(props, pfx, toObj, false));
519 public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
520 Class toClass = toObj.getClass();
521 boolean foundValue = false;
523 LOG.trace("Saving properties to " + toClass.getName() + " class from " + pfx);
527 if (isYangGenerated(toClass)) {
528 // Class is yang generated.
529 LOG.trace(toClass.getName() + " is a Yang-generated class");
531 String propNamePfx = null;
536 if ((pfx != null) && (pfx.length() > 0)) {
537 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
539 propNamePfx = toLowerHyphen(toClass.getSimpleName());
542 if (propNamePfx.endsWith("-builder")) {
543 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
546 if (propNamePfx.endsWith("-impl")) {
547 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
551 if (toObj instanceof Identifier) {
552 LOG.trace(toClass.getName() + " is a Key - skipping");
556 // Iterate through getter methods to figure out values we need to
559 for (Method m : toClass.getMethods()) {
561 Class paramTypes[] = m.getParameterTypes();
562 Class paramClass = paramTypes[0];
564 String fieldName = toLowerHyphen(m.getName().substring(3));
565 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
567 String propName = propNamePfx + "." + fieldName;
569 String paramValue = props.getProperty(propName);
570 if (paramValue == null) {
571 LOG.trace(propName + " is unset");
573 LOG.trace(propName + " = " + paramValue);
576 // Is the return type a yang generated class?
577 if (isYangGenerated(paramClass)) {
579 if (paramClass.isEnum()) {
581 LOG.trace(m.getName() + " expects an Enum");
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 " + paramClass.getName(), e);
593 boolean isAccessible = m.isAccessible();
595 m.setAccessible(true);
598 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
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" + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
612 String simpleName = paramClass.getSimpleName();
614 if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) {
616 if ((paramValue != null) && (paramValue.length() > 0)) {
618 IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
620 if ("Ipv4Address".equals(simpleName)) {
621 m.invoke(toObj, ipAddr.getIpv4Address());
622 } else if ("Ipv6Address".equals(simpleName)) {
623 m.invoke(toObj, ipAddr.getIpv6Address());
626 m.invoke(toObj, ipAddr);
629 } catch (Exception e) {
630 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + "(" + paramValue + ")", e);
635 boolean isAccessible = m.isAccessible();
637 m.setAccessible(true);
639 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
640 m.invoke(toObj, paramValue);
642 m.setAccessible(isAccessible);
646 } catch (Exception e) {
647 LOG.error("Caught exception trying to call " + toClass.getName() + "." + m.getName() + "() with Properties entry", e);
650 } else if ("IpPrefix".equals(simpleName)) {
651 if ((paramValue != null) && (paramValue.length() > 0)) {
653 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
654 m.invoke(toObj, ipPrefix);
656 } catch (Exception e) {
657 LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + "(" + paramValue + ")", e);
661 // setter expects a yang-generated class. Need
663 // create a builder to set it.
665 String builderName = paramClass.getName() + "Builder";
666 Class builderClass = null;
667 Object builderObj = null;
668 Object paramObj = null;
670 Object constObj = null;
672 LOG.trace(m.getName() + " expects a yang-generated class - looking for builder " + builderName);
674 builderClass = Class.forName(builderName);
675 builderObj = builderClass.newInstance();
676 paramObj = toBuilder(props, propNamePfx, builderObj);
677 } catch (ClassNotFoundException e) {
679 if (paramValue == null) {
681 boolean isAccessible = m.isAccessible();
683 m.setAccessible(true);
685 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(null)");
686 m.invoke(toObj, new Object[] { null });
688 m.setAccessible(isAccessible);
692 } catch (Exception e1) {
693 LOG.error("Caught exception trying to cally" + toClass.getName() + "." + m.getName() + "() with Properties entry", e1);
697 // See if I can find a constructor I
700 Constructor[] constructors = paramClass.getConstructors();
701 // Is there a String constructor?
702 for (Constructor c : constructors) {
703 Class[] cParms = c.getParameterTypes();
704 if ((cParms != null) && (cParms.length == 1)) {
705 if (String.class.isAssignableFrom(cParms[0])) {
706 constObj = c.newInstance(paramValue);
711 if (constObj == null) {
712 // Is there a Long constructor?
713 for (Constructor c : constructors) {
714 Class[] cParms = c.getParameterTypes();
715 if ((cParms != null) && (cParms.length == 1)) {
716 if (Long.class.isAssignableFrom(cParms[0])) {
717 constObj = c.newInstance(Long.parseLong(paramValue));
724 if (constObj == null) {
726 // Last chance - see if
727 // parameter class has a static
729 // getDefaultInstance(String)
731 Method gm = paramClass.getMethod("getDefaultInstance", String.class);
733 int gmodifier = gm.getModifiers();
734 if (Modifier.isStatic(gmodifier)) {
736 // getDefaultInstance(String)
737 paramObj = gm.invoke(null, paramValue);
740 } catch (Exception gme) {
745 } catch (Exception e1) {
746 LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
749 if (constObj == null) {
750 LOG.warn("Could not find builder class " + builderName + " and could not find a String or Long constructor or static getDefaultInstance(String) - trying just to set passing paramValue");
754 } catch (Exception e) {
755 LOG.error("Caught exception trying to create builder " + builderName, e);
758 if (paramObj != null) {
762 Method buildMethod = builderClass.getMethod("build");
763 LOG.trace("Calling " + paramObj.getClass().getName() + "." + buildMethod.getName() + "()");
764 Object builtObj = buildMethod.invoke(paramObj);
766 boolean isAccessible = m.isAccessible();
768 m.setAccessible(true);
771 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "()");
772 m.invoke(toObj, builtObj);
774 m.setAccessible(isAccessible);
778 } catch (Exception e) {
779 LOG.error("Caught exception trying to set Yang-generated class expected by" + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
783 boolean isAccessible = m.isAccessible();
785 m.setAccessible(true);
788 if (constObj != null) {
790 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + constObj.toString() + ")");
791 m.invoke(toObj, constObj);
793 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
794 m.invoke(toObj, paramValue);
798 m.setAccessible(isAccessible);
802 } catch (Exception e) {
803 LOG.error("Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
810 // Setter's argument is not a yang-generated class. See
813 if (List.class.isAssignableFrom(paramClass)) {
815 LOG.trace("Parameter class " + paramClass.getName() + " is a List");
817 // Figure out what type of args are in List and pass
820 Type paramType = m.getGenericParameterTypes()[0];
821 Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
822 Object paramObj = new LinkedList();
824 paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
825 } catch (Exception e) {
826 LOG.error("Caught exception trying to create list expected as argument to " + toClass.getName() + "." + m.getName());
829 if (paramObj != null) {
831 boolean isAccessible = m.isAccessible();
833 m.setAccessible(true);
835 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
836 m.invoke(toObj, paramObj);
838 m.setAccessible(isAccessible);
842 } catch (Exception e) {
843 LOG.error("Caught exception trying to convert List returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
848 // Setter expects something that is not a List and
849 // not yang-generated. Just pass the parameter value
851 LOG.trace("Parameter class " + paramClass.getName() + " is not a yang-generated class or a List");
853 if ((paramValue != null) && (paramValue.length() > 0)) {
855 Object constObj = null;
858 // See if I can find a constructor I can use
859 Constructor[] constructors = paramClass.getConstructors();
860 // Is there a String constructor?
861 for (Constructor c : constructors) {
862 Class[] cParms = c.getParameterTypes();
863 if ((cParms != null) && (cParms.length == 1)) {
864 if (String.class.isAssignableFrom(cParms[0])) {
865 constObj = c.newInstance(paramValue);
870 if (constObj == null) {
871 // Is there a Long constructor?
872 for (Constructor c : constructors) {
873 Class[] cParms = c.getParameterTypes();
874 if ((cParms != null) && (cParms.length == 1)) {
875 if (Long.class.isAssignableFrom(cParms[0])) {
876 constObj = c.newInstance(Long.parseLong(paramValue));
883 if (constObj != null) {
885 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + constObj + ")");
886 m.invoke(toObj, constObj);
888 } catch (Exception e2) {
889 LOG.error("Caught exception trying to call " + m.getName(), e2);
893 boolean isAccessible = m.isAccessible();
895 m.setAccessible(true);
897 LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + paramValue + ")");
898 m.invoke(toObj, paramValue);
900 m.setAccessible(isAccessible);
904 } catch (Exception e) {
905 LOG.error("Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
908 } catch (Exception e1) {
909 LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
915 } // End of section handling "setter" method
916 } // End of loop through Methods
917 } // End of section handling yang-generated class
926 public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
927 boolean foundValue = false;
929 LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
931 if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
932 // Class is yang generated.
933 LOG.trace(toClass.getName() + " is a Yang-generated class");
935 if (toClass.getName().endsWith("Key")) {
936 if (Identifier.class.isAssignableFrom(toClass)) {
937 LOG.trace(Identifier.class.getName() + " is assignable from " + toClass.getName());
940 LOG.trace(Identifier.class.getName() + " is NOT assignable from " + toClass.getName());
944 String propNamePfx = null;
945 if (pfx.endsWith("]")) {
949 if ((pfx != null) && (pfx.length() > 0)) {
950 propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
952 propNamePfx = toLowerHyphen(toClass.getSimpleName());
955 if (propNamePfx.endsWith("-builder")) {
956 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length());
959 if (propNamePfx.endsWith("-impl")) {
960 propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
964 // Iterate through getter methods to figure out values we need to
967 for (Method m : toClass.getMethods()) {
968 LOG.trace("Is " + m.getName() + " method a getter?");
970 LOG.trace(m.getName() + " is a getter");
971 Class returnClass = m.getReturnType();
973 String fieldName = toLowerHyphen(m.getName().substring(3));
974 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
976 String propName = propNamePfx + "." + fieldName;
978 // Is the return type a yang generated class?
979 if (isYangGenerated(returnClass)) {
981 if (returnClass.isEnum()) {
983 LOG.trace(m.getName() + " is an Enum");
984 pstr.print("\n\n * " + propName);
988 String simpleName = returnClass.getSimpleName();
990 if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)) {
991 LOG.trace(m.getName() + " is an " + simpleName);
992 pstr.print("\n\n * " + propName);
994 printPropertyList(pstr, propNamePfx, returnClass);
1000 // Setter's argument is not a yang-generated class. See
1003 if (List.class.isAssignableFrom(returnClass)) {
1005 LOG.trace("Parameter class " + returnClass.getName() + " is a List");
1007 // Figure out what type of args are in List and pass
1008 // that to toList().
1010 Type returnType = m.getGenericReturnType();
1011 Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
1012 Class elementClass = (Class) elementType;
1013 LOG.trace("Calling printPropertyList on list type (" + elementClass.getName() + "), pfx is (" + pfx + "), toClass is (" + toClass.getName() + ")");
1014 printPropertyList(pstr, propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]", elementClass);
1016 } else if (!returnClass.equals(Class.class)) {
1018 // Setter expects something that is not a List and
1019 // not yang-generated. Just pass the parameter value
1021 LOG.trace("Parameter class " + returnClass.getName() + " is not a yang-generated class or a List");
1023 pstr.print("\n\n * " + propName);
1027 } // End of section handling "setter" method
1028 } // End of loop through Methods
1029 } // End of section handling yang-generated class
1033 public static boolean isYangGenerated(Class c) {
1037 return (c.getName().startsWith("org.opendaylight.yang.gen."));
1041 public static boolean isIpPrefix(Class c) {
1046 String simpleName = c.getSimpleName();
1047 return ("IpPrefix".equals(simpleName));
1050 public static boolean isIpv4Address(Class c) {
1055 String simpleName = c.getSimpleName();
1056 return ("Ipv4Address".equals(simpleName));
1059 public static boolean isIpv6Address(Class c) {
1064 String simpleName = c.getSimpleName();
1065 return ("Ipv6Address".equals(simpleName));
1068 public static boolean isIpAddress(Class c) {
1073 String simpleName = c.getSimpleName();
1074 return ("IpAddress".equals(simpleName));
1077 public static String toLowerHyphen(String inStr) {
1078 if (inStr == null) {
1082 String str = inStr.substring(0, 1).toLowerCase();
1083 if (inStr.length() > 1) {
1084 str = str + inStr.substring(1);
1087 String regex = "(([a-z0-9])([A-Z]))";
1088 String replacement = "$2-$3";
1090 String retval = str.replaceAll(regex, replacement).toLowerCase();
1092 LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
1096 //This is called when mapping the yang value back to a valid java enumeration
1097 public static String toJavaEnum(String inStr) {
1098 if (inStr == null) {
1100 } else if (inStr.length() == 0) {
1104 //This will strip out all periods, which cannot be in a java enum
1105 inStr = inStr.replaceAll("\\.", "");
1107 String[] terms = inStr.split("-");
1108 StringBuffer sbuff = new StringBuffer();
1110 //appends an _ if the string starts with a digit to make it a valid java enum
1111 if (Character.isDigit(inStr.charAt(0))) {
1114 //If the string contains hyphens it will convert the string to upperCamelCase without hyphens
1115 for (String term : terms) {
1116 sbuff.append(term.substring(0, 1).toUpperCase());
1117 if (term.length() > 1) {
1118 sbuff.append(term.substring(1));
1121 return (sbuff.toString());
1125 public static boolean isGetter(Method m) {
1130 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
1131 if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
1132 if (!"getClass".equals(m.getName())) {
1137 if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
1141 if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
1149 public static boolean isSetter(Method m) {
1154 if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
1155 if (m.getName().matches("^set[A-Z].*")) {
1156 Class[] paramTypes = m.getParameterTypes();
1157 if (paramTypes[0].isAssignableFrom(Identifier.class) || Identifier.class.isAssignableFrom(paramTypes[0])) {
1169 public static String getFullPropertiesPath(String propertiesFileName) {
1170 return "/opt/bvc/controller/configuration/" + propertiesFileName;
1173 //This is called when mapping a valid java enumeration back to the yang model value
1174 public static String mapEnumeratedValue(String propertyName, String propertyValue) {
1175 LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
1176 String mappingKey = "yang." + propertyName + "." + propertyValue;
1177 if (yangMappingProperties.containsKey(mappingKey)) {
1178 return (yangMappingProperties.getProperty(mappingKey));
1180 LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
1181 return propertyValue;