import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.FileDescriptor; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.LinkedList; import java.util.List; import java.util.Properties; import java.util.Arrays; import java.util.ArrayList; import java.io.*; import javax.json.*; import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.CaseFormat; public class PrintYangToProp { private static final Logger LOG = LoggerFactory.getLogger(PrintYangToProp.class); public static final String PROPERTIES_FILE="/opt/bvc/controller/configuration/flowred.properties"; private static Properties properties; static { // Trick class loader into loading builders. Some of // these will be needed later by Reflection classes, but need // to explicitly "new" them here to get class loader to load them. /* ServiceInformationBuilder b2 = new ServiceInformationBuilder(); ServiceDataBuilder b3 = new ServiceDataBuilder(); SdncRequestHeaderBuilder b4 = new SdncRequestHeaderBuilder(); RequestInformationBuilder b6 = new RequestInformationBuilder(); FlowredGroupInformationDataBuilder b29 = new FlowredGroupInformationDataBuilder(); FlowredInformationDataBuilder b48 = new FlowredInformationDataBuilder(); OperStatusBuilder b41 = new OperStatusBuilder(); */ } public static void loadProperties() { /* File file = new File(PROPERTIES_FILE); properties = new Properties(); InputStream input = null; if (file.isFile() && file.canRead()) { try { input = new FileInputStream(file); properties.load(input); LOG.info("Loaded properties from " + PROPERTIES_FILE ); } catch (Exception e) { LOG.error("Failed to load properties " + PROPERTIES_FILE +"\n",e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { LOG.error("Failed to close properties file " + PROPERTIES_FILE +"\n",e); } } } } */ } public static Properties toProperties(Properties props, Object fromObj) { Class fromClass = null; if (fromObj != null) { fromClass = fromObj.getClass(); } return (toProperties(props, "", fromObj, fromClass)); } public static Properties toProperties(Properties props, String pfx, Object fromObj) { Class fromClass = null; if (fromObj != null) { fromClass = fromObj.getClass(); } return(toProperties(props, pfx, fromObj, fromClass)); } public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) { if (fromObj == null) { return (props); } String simpleName = fromClass.getSimpleName(); //LOG.debug("Extracting properties from " + fromClass.getName() // + " class"); if (fromObj instanceof List) { // Class is a List. List should contain yang-generated classes. //LOG.debug(fromClass.getName() + " is a List"); List fromList = (List) fromObj; for (int i = 0; i < fromList.size(); i++) { toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass); } props.setProperty(pfx + "_length", "" + fromList.size()); } else if (isYangGenerated(fromClass)) { // Class is yang generated. //LOG.debug(fromClass.getName() + " is a Yang-generated class"); String propNamePfx = null; // If called from a list (so prefix ends in ']'), don't // add class name again if (pfx.endsWith("]")) { propNamePfx = pfx; } else { if ((pfx != null) && (pfx.length() > 0)) { propNamePfx = pfx ; } else { propNamePfx = toLowerHyphen(fromClass.getSimpleName()); } if (propNamePfx.endsWith("-builder")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length()); } if (propNamePfx.endsWith("-impl")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); } } // Iterate through getter methods to figure out values we need to // save from for (Method m : fromClass.getMethods()) { // LOG.debug("Checking " + m.getName() + " method"); if (isGetter(m)) { // LOG.debug(m.getName() + " is a getter"); Class returnType = m.getReturnType(); String fieldName = toLowerHyphen(m.getName().substring(3)); if(m != null && m.getName().matches("^is[A-Z].*")){ fieldName = toLowerHyphen(m.getName().substring(2)); } fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); // Is the return type a yang generated class? if (isYangGenerated(returnType)) { // Is it an enum? if (returnType.isEnum()) { // Return type is a typedef. Save its value. try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Object retValue = m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } if (retValue != null) { String propName = propNamePfx + "." + fieldName; String propVal = retValue.toString(); String yangProp = "yang." + fieldName + "." + propVal; if ( properties.containsKey(yangProp)) { propVal = properties.getProperty(yangProp); //LOG.debug("Adjusting property " + yangProp + " " + propVal); } //LOG.debug("Setting property " + propName // + " to " + propVal); props.setProperty(propName, propVal); } } catch (Exception e) { LOG.error( "Caught exception trying to convert Yang-generated enum returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } else if (isIpv4Address(returnType)) { // Save its value try { String propName = propNamePfx + "." + fieldName; boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } if (retValue != null) { String propVal = retValue.getValue().toString(); //LOG.debug("Setting property " + propName // + " to " + propVal); props.setProperty(propName, propVal); } } catch (Exception e) { LOG.error( "Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } else if (isIpv6Address(returnType)) { // Save its value try { String propName = propNamePfx + "." + fieldName; boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } if (retValue != null) { String propVal = retValue.getValue().toString(); //LOG.debug("Setting property " + propName // + " to " + propVal); props.setProperty(propName, propVal); } } catch (Exception e) { LOG.error( "Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } else { try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Object retValue = m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } if (retValue != null) { toProperties(props, propNamePfx + "." + fieldName, retValue, returnType); } } catch (Exception e) { LOG.error( "Caught exception trying to convert Yang-generated class returned by" + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } } else if (returnType.equals(Class.class)) { //LOG.debug(m.getName() // + " returns a Class object - not interested"); } else if (List.class.isAssignableFrom(returnType)) { // This getter method returns a list. try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Object retList = m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } // Figure out what type of elements are stored in this array. Type paramType = m.getGenericReturnType(); Type elementType = ((ParameterizedType) paramType) .getActualTypeArguments()[0]; toProperties(props, propNamePfx + "." + fieldName, retList, (Class)elementType); } catch (Exception e) { LOG.error( "Caught exception trying to convert List returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } else { // Method returns something that is not a List and not // yang-generated. // Save its value try { String propName = propNamePfx + "." + fieldName; boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } Object propValObj = m.invoke(fromObj); if (!isAccessible) { m.setAccessible(isAccessible); } if (propValObj != null) { String propVal = propValObj.toString(); //LOG.debug("Setting property " + propName // + " to " + propVal); props.setProperty(propName, propVal); } } catch (Exception e) { LOG.error( "Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); } } } } } else { // Class is not yang generated and not a list // Do nothing. } return (props); } public static Object toBuilder(Properties props, Object toObj) { return (toBuilder(props, "", toObj)); } public static List toList(Properties props, String pfx, List toObj, Class elemType) { int maxIdx = -1; boolean foundValue = false; //LOG.debug("Saving properties to List<" + elemType.getName() // + "> from " + pfx); // Figure out array size for (Object pNameObj : props.keySet()) { String key = (String) pNameObj; if (key.startsWith(pfx + "[")) { String idxStr = key.substring(pfx.length() + 1); int endloc = idxStr.indexOf("]"); if (endloc != -1) { idxStr = idxStr.substring(0, endloc); } try { int curIdx = Integer.parseInt(idxStr); if (curIdx > maxIdx) { maxIdx = curIdx; } } catch (Exception e) { LOG.error("Illegal subscript in property " + key); } } } //LOG.debug(pfx + " has max index of " + maxIdx); for (int i = 0; i <= maxIdx; i++) { String curBase = pfx + "[" + i + "]"; if (isYangGenerated(elemType)) { String builderName = elemType.getName() + "Builder"; try { Class builderClass = Class.forName(builderName); Object builderObj = builderClass.newInstance(); Method buildMethod = builderClass.getMethod("build"); builderObj = toBuilder(props, curBase, builderObj, true); if (builderObj != null) { //LOG.debug("Calling " + builderObj.getClass().getName() // + "." + buildMethod.getName() + "()"); Object builtObj = buildMethod.invoke(builderObj); toObj.add(builtObj); foundValue = true; } } catch (ClassNotFoundException e) { LOG.warn("Could not find builder class " + builderName, e); } catch (Exception e) { LOG.error("Caught exception trying to populate list from " + pfx); } } } if (foundValue) { return (toObj); } else { return (null); } } public static Object toBuilder(Properties props, String pfx, Object toObj) { return(toBuilder(props, pfx, toObj, false)); } public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) { Class toClass = toObj.getClass(); boolean foundValue = false; //LOG.debug("Saving properties to " + toClass.getName() + " class from " // + pfx); Ipv4Address addr; if (isYangGenerated(toClass)) { // Class is yang generated. //LOG.debug(toClass.getName() + " is a Yang-generated class"); String propNamePfx = null; if (preservePfx) { propNamePfx = pfx; } else { if ((pfx != null) && (pfx.length() > 0)) { propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); } else { propNamePfx = toLowerHyphen(toClass.getSimpleName()); } if (propNamePfx.endsWith("-builder")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length()); } if (propNamePfx.endsWith("-impl")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); } } if (toObj instanceof Identifier) { //LOG.debug(toClass.getName() + " is a Key - skipping"); return (toObj); } // Iterate through getter methods to figure out values we need to // set for (Method m : toClass.getMethods()) { // LOG.debug("Is " + m.getName() + " method a setter?"); if (isSetter(m)) { // LOG.debug(m.getName() + " is a setter"); Class paramTypes[] = m.getParameterTypes(); Class paramClass = paramTypes[0]; String fieldName = toLowerHyphen(m.getName().substring(3)); fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); String propName = propNamePfx + "." + fieldName; String paramValue = props.getProperty(propName); if (paramValue == null) { //LOG.debug(propName + " is unset"); } else { //LOG.debug(propName + " = " + paramValue); } // Is the return type a yang generated class? if (isYangGenerated(paramClass)) { // Is it an enum? if (paramClass.isEnum()) { //LOG.debug(m.getName() + " expects an Enum"); // Param type is a typedef. if (paramValue != null) { Object paramObj = null; try { paramObj = Enum.valueOf(paramClass, toUpperCamelCase(paramValue)); } catch (Exception e) { LOG.error( "Caught exception trying to convert field " + propName + " to enum " + paramClass.getName(), e); } try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } //LOG.debug("Calling " // + toObj.getClass().getName() + "." // + m.getName() + "(" + paramValue // + ")"); m.invoke(toObj, paramObj); if (!isAccessible) { m.setAccessible(isAccessible); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception trying to create Yang-generated enum expected by" + toClass.getName() + "." + m.getName() + "() from Properties entry", e); } } } else { String simpleName = paramClass.getSimpleName(); if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)) { if (paramValue != null) { try { IpAddress ipAddr = IpAddressBuilder .getDefaultInstance(paramValue); if ("Ipv4Address".equals(simpleName)) { m.invoke(toObj, ipAddr.getIpv4Address()); } else { m.invoke(toObj, ipAddr.getIpv6Address()); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception calling " + toClass.getName() + "." + m.getName() + "(" + paramValue + ")", e); } } } else { // setter expects a yang-generated class. Need // to // create a builder to set it. String builderName = paramClass.getName() + "Builder"; Class builderClass = null; Object builderObj = null; Object paramObj = null; //LOG.debug(m.getName() // + " expects a yang-generated class - looking for builder " // + builderName); try { builderClass = Class.forName(builderName); builderObj = builderClass.newInstance(); paramObj = toBuilder(props, propNamePfx, builderObj); } catch (ClassNotFoundException e) { Object constObj = null; try { // See if I can find a constructor I can // use Constructor[] constructors = paramClass .getConstructors(); // Is there a String constructor? for (Constructor c : constructors) { Class[] cParms = c .getParameterTypes(); if ((cParms != null) && (cParms.length == 1)) { if (String.class .isAssignableFrom(cParms[0])) { constObj = c .newInstance(paramValue); } } } if (constObj == null) { // Is there a Long constructor? for (Constructor c : constructors) { Class[] cParms = c .getParameterTypes(); if ((cParms != null) && (cParms.length == 1)) { if (Long.class .isAssignableFrom(cParms[0])) { constObj = c .newInstance(Long .parseLong(paramValue)); } } } } if (constObj != null) { try { m.invoke(toObj, constObj); foundValue = true; } catch (Exception e2) { LOG.error( "Caught exception trying to call " + m.getName(), e2); } } } catch (Exception e1) { LOG.warn( "Could not find a suitable constructor for " + paramClass.getName(), e1); } if (paramObj == null) { LOG.warn("Could not find builder class " + builderName + " and could not find a String or Long constructor - trying just to set passing paramValue"); } } catch (Exception e) { LOG.error( "Caught exception trying to create builder " + builderName, e); } if (paramObj != null) { try { Method buildMethod = builderClass .getMethod("build"); //LOG.debug("Calling " // + paramObj.getClass().getName() // + "." + buildMethod.getName() // + "()"); Object builtObj = buildMethod .invoke(paramObj); boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } //LOG.debug("Calling " // + toObj.getClass().getName() // + "." + m.getName() + "()"); m.invoke(toObj, builtObj); if (!isAccessible) { m.setAccessible(isAccessible); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception trying to set Yang-generated class expected by" + toClass.getName() + "." + m.getName() + "() from Properties entry", e); } } else { try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } //LOG.debug("Calling " // + toObj.getClass().getName() // + "." + m.getName() + "(" // + paramValue + ")"); m.invoke(toObj, paramValue); if (!isAccessible) { m.setAccessible(isAccessible); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e); } } } } } else { // Setter's argument is not a yang-generated class. See // if it is a List. if (List.class.isAssignableFrom(paramClass)) { //LOG.debug("Parameter class " + paramClass.getName() // + " is a List"); // Figure out what type of args are in List and pass // that to toList(). Type paramType = m.getGenericParameterTypes()[0]; Type elementType = ((ParameterizedType) paramType) .getActualTypeArguments()[0]; Object paramObj = new LinkedList(); try { paramObj = toList(props, propName, (List) paramObj, (Class) elementType); } catch (Exception e) { LOG.error("Caught exception trying to create list expected as argument to " + toClass.getName() + "." + m.getName()); } if (paramObj != null) { try { boolean isAccessible = m.isAccessible(); if (!isAccessible) { m.setAccessible(true); } //LOG.debug("Calling " // + toObj.getClass().getName() + "." // + m.getName() + "(" + paramValue // + ")"); m.invoke(toObj, paramObj); if (!isAccessible) { m.setAccessible(isAccessible); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception trying to convert List returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e); } } } else { // Setter expects something that is not a List and // not yang-generated. Just pass the parameter value //LOG.debug("Parameter class " // + paramClass.getName() // + " is not a yang-generated class or a List"); if (paramValue != null) { Object constObj = null; try { // See if I can find a constructor I can use Constructor[] constructors = paramClass .getConstructors(); // Is there a String constructor? for (Constructor c : constructors) { Class[] cParms = c.getParameterTypes(); if ((cParms != null) && (cParms.length == 1)) { if (String.class .isAssignableFrom(cParms[0])) { constObj = c .newInstance(paramValue); } } } if (constObj == null) { // Is there a Long constructor? for (Constructor c : constructors) { Class[] cParms = c .getParameterTypes(); if ((cParms != null) && (cParms.length == 1)) { if (Long.class .isAssignableFrom(cParms[0])) { constObj = c .newInstance(Long .parseLong(paramValue)); } } } } if (constObj != null) { try { //LOG.debug("Calling " // + toObj.getClass() // .getName() + "." // + m.getName() + "(" // + constObj + ")"); m.invoke(toObj, constObj); foundValue = true; } catch (Exception e2) { LOG.error( "Caught exception trying to call " + m.getName(), e2); } } else { try { boolean isAccessible = m .isAccessible(); if (!isAccessible) { m.setAccessible(true); } //LOG.debug("Calling " // + toObj.getClass() // .getName() + "." // + m.getName() + "(" // + paramValue + ")"); m.invoke(toObj, paramValue); if (!isAccessible) { m.setAccessible(isAccessible); } foundValue = true; } catch (Exception e) { LOG.error( "Caught exception trying to convert value returned by" + toClass.getName() + "." + m.getName() + "() to Properties entry", e); } } } catch (Exception e1) { LOG.warn( "Could not find a suitable constructor for " + paramClass.getName(), e1); } /* * try { boolean isAccessible = * m.isAccessible(); if (!isAccessible) { * m.setAccessible(true); } LOG.debug("Calling " * + toObj.getClass().getName() + "." + * m.getName() + "(" + paramValue + ")"); * m.invoke(toObj, paramValue); if * (!isAccessible) { * m.setAccessible(isAccessible); } foundValue = * true; * * } catch (Exception e) { LOG.error( * "Caught exception trying to convert value returned by" * + toClass.getName() + "." + m.getName() + * "() to Properties entry", e); } */ } } } } // End of section handling "setter" method } // End of loop through Methods } // End of section handling yang-generated class if (foundValue) { return (toObj); } else { return (null); } } /* public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) { boolean foundValue = false; //LOG.debug("Analyzing " + toClass.getName() + " class : pfx " + pfx); if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) { // Class is yang generated. //LOG.debug(toClass.getName() + " is a Yang-generated class"); if (toClass.getName().endsWith("Key")) { if (Identifier.class.isAssignableFrom(toClass)) { //LOG.debug(Identifier.class.getName() // + " is assignable from " + toClass.getName()); } else { //LOG.debug(Identifier.class.getName() // + " is NOT assignable from " + toClass.getName()); } } String propNamePfx = null; if (pfx.endsWith("]")) { propNamePfx = pfx; } else { if ((pfx != null) && (pfx.length() > 0)) { propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); } else { propNamePfx = toLowerHyphen(toClass.getSimpleName()); } if (propNamePfx.endsWith("-builder")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length()); } if (propNamePfx.endsWith("-impl")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); } } // Iterate through getter methods to figure out values we need to // set for (Method m : toClass.getMethods()) { //LOG.debug("Is " + m.getName() + " method a getter?"); if (isGetter(m)) { //LOG.debug(m.getName() + " is a getter"); Class returnClass = m.getReturnType(); String fieldName = toLowerHyphen(m.getName().substring(3)); fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); String propName = propNamePfx + "." + fieldName; // Is the return type a yang generated class? if (isYangGenerated(returnClass)) { // Is it an enum? if (returnClass.isEnum()) { //System.out.println(returnClass.getSimpleName()); //System.out.println(Arrays.asList(returnClass.getEnumConstants())); //LOG.debug(m.getName() + " is an Enum"); pstr.print("\n" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\n"); } else { String simpleName = returnClass.getSimpleName(); if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)) { //LOG.debug(m.getName()+" is an "+simpleName); pstr.print("\n" + propName + ":" + simpleName + "\n"); } else { printPropertyList(pstr, propNamePfx, returnClass); } } } else { // Setter's argument is not a yang-generated class. See // if it is a List. if (List.class.isAssignableFrom(returnClass)) { //LOG.debug("Parameter class " //+ returnClass.getName() + " is a List"); // Figure out what type of args are in List and pass // that to toList(). Type returnType = m.getGenericReturnType(); Type elementType = ((ParameterizedType) returnType) .getActualTypeArguments()[0]; Class elementClass = (Class) elementType; //LOG.debug("Calling printPropertyList on list type (" //+ elementClass.getName() //+ "), pfx is (" // + pfx // + "), toClass is (" // + toClass.getName() + ")"); printPropertyList( pstr, propNamePfx + "." + toLowerHyphen(elementClass .getSimpleName()) + "[]", elementClass); } else if (!returnClass.equals(Class.class)) { // Setter expects something that is not a List and // not yang-generated. Just pass the parameter value //LOG.debug("Parameter class " // + returnClass.getName() // + " is not a yang-generated class or a List"); String className=returnClass.getName(); //"org.opendaylight.yangtools.yang.binding.Identifier" int nClassNameIndex = className.lastIndexOf('.'); String nClassName = className; if(nClassNameIndex != -1){ nClassName=className.substring(nClassNameIndex+1); } pstr.print("\n" + propName +":" + nClassName +"\n"); } } } // End of section handling "setter" method } // End of loop through Methods } // End of section handling yang-generated class } */ public static Properties prop = new Properties(); public static ArrayList propList = new ArrayList(); public static Properties getProperties(PrintStream pstr, String pfx, Class toClass) { boolean foundValue = false; //LOG.debug("Analyzing " + toClass.getName() + " class : pfx " + pfx); if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) { // Class is yang generated. //LOG.debug(toClass.getName() + " is a Yang-generated class"); if (toClass.getName().endsWith("Key")) { if (Identifier.class.isAssignableFrom(toClass)) { //LOG.debug(Identifier.class.getName() // + " is assignable from " + toClass.getName()); } else { //LOG.debug(Identifier.class.getName() // + " is NOT assignable from " + toClass.getName()); } } String propNamePfx = null; if (pfx.endsWith("]")) { propNamePfx = pfx; }else if(pfx.indexOf(".CLASS_FOUND") != -1){ pfx = pfx.replace(".CLASS_FOUND",""); propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); } else { if ((pfx != null) && (pfx.length() > 0)) { propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); } else { propNamePfx = toLowerHyphen(toClass.getSimpleName()); } if (propNamePfx.endsWith("-builder")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-builder".length()); } if (propNamePfx.endsWith("-impl")) { propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); } } // Iterate through getter methods to figure out values we need to // set for (Method m : toClass.getMethods()) { //LOG.debug("Is " + m.getName() + " method a getter?"); if (isGetter(m)) { // LOG.debug(m.getName() + " is a getter"); Class returnClass = m.getReturnType(); String fieldName = toLowerHyphen(m.getName().substring(3)); if(m != null && m.getName().matches("^is[A-Z].*")){ fieldName = toLowerHyphen(m.getName().substring(2)); } fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); String propName = propNamePfx + "." + fieldName; //System.out.println("****" + propName); // Is the return type a yang generated class? if (isYangGenerated(returnClass)) { // Is it an enum? if (returnClass.isEnum()) { //LOG.debug(m.getName() + " is an Enum"); //pstr.print("\n" + propName); //pstr.print("\n" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\n"); pstr.print("\"" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\","); prop.setProperty(propName,""); propList.add(propName); } else { String simpleName = returnClass.getSimpleName(); //System.out.println("simpleName:" + simpleName); if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) { //LOG.debug(m.getName()+" is an "+simpleName); //pstr.print("\n" + propName); //pstr.print("\n" + propName + ":" + simpleName + "\n"); pstr.print("\"" + propName + ":" + simpleName + "\","); prop.setProperty(propName,""); propList.add(propName); } else { boolean isString = false; boolean isNumber = false; boolean isBoolean = false; boolean isIdentifier = false; //System.out.println("simpleName:" + simpleName); //System.out.println("propName:" + propName); for(Method mthd : returnClass.getMethods()){ String methodName = mthd.getName(); //System.out.println("methodName:" + methodName); if(methodName.equals("getValue")){ Class retType = mthd.getReturnType(); //System.out.println("retType:" + retType); isString = String.class.isAssignableFrom(retType); isNumber = Number.class.isAssignableFrom(retType); isBoolean = Boolean.class.isAssignableFrom(retType); isIdentifier = Identifier.class.isAssignableFrom(retType); //System.out.println("isString:" + isString); //System.out.println("isNumber:" + isNumber); //System.out.println("isNumber:" + isNumber); break; } } if(isString){ pstr.print("\"" + propName + ":String\","); prop.setProperty(propName,""); propList.add(propName); }else if(isNumber){ pstr.print("\"" + propName + ":Number\","); prop.setProperty(propName,""); propList.add(propName); }else if(isBoolean){ pstr.print("\"" + propName + ":Boolean\","); prop.setProperty(propName,""); propList.add(propName); }else if(isIdentifier){ //System.out.println("isIdentifier"); //isIdentifer so skipping continue; }else{ /* System.out.println("fieldName:" + fieldName); System.out.println("simpleName:" + simpleName); System.out.println("returnClass:" + returnClass); System.out.println("pstr:" + pstr); System.out.println("propNamePfx:" + propNamePfx); */ getProperties(pstr, propNamePfx + ".CLASS_FOUND", returnClass); } } } } else { // Setter's argument is not a yang-generated class. See // if it is a List. if (List.class.isAssignableFrom(returnClass)) { //LOG.debug("Parameter class " // + returnClass.getName() + " is a List"); // Figure out what type of args are in List and pass // that to toList(). Type returnType = m.getGenericReturnType(); Type elementType = ((ParameterizedType) returnType) .getActualTypeArguments()[0]; Class elementClass = (Class) elementType; //LOG.debug("Calling printPropertyList on list type (" //+ elementClass.getName() // + "), pfx is (" // + pfx // + "), toClass is (" // + toClass.getName() + ")"); //System.out.println("List propNamePfx:" + propNamePfx+ "." + toLowerHyphen(elementClass.getSimpleName()) + "[]"); if(String.class.isAssignableFrom(elementClass)){ pstr.print("\"" + propName + ":[String,String,...]\","); prop.setProperty(propName,""); propList.add(propName); }else if(Number.class.isAssignableFrom(elementClass)){ pstr.print("\"" + propName + ":[Number,Number,...]\","); prop.setProperty(propName,""); propList.add(propName); }else if(Boolean.class.isAssignableFrom(elementClass)){ pstr.print("\"" + propName + ":[Boolean,Boolean,...]\","); prop.setProperty(propName,""); propList.add(propName); }else if(Identifier.class.isAssignableFrom(elementClass)){ continue; }else{ getProperties( pstr, propNamePfx + "." + toLowerHyphen(elementClass .getSimpleName()) + "[]", elementClass); } } else if (!returnClass.equals(Class.class)) { // Setter expects something that is not a List and // not yang-generated. Just pass the parameter value //LOG.debug("Parameter class " // + returnClass.getName() // + " is not a yang-generated class or a List"); //pstr.print("\n" + propName); String className=returnClass.getName(); int nClassNameIndex = className.lastIndexOf('.'); String nClassName = className; if(nClassNameIndex != -1){ nClassName=className.substring(nClassNameIndex+1); } boolean isString = String.class.isAssignableFrom(returnClass); boolean isNumber = Number.class.isAssignableFrom(returnClass); boolean isBoolean = Boolean.class.isAssignableFrom(returnClass); //pstr.print("\n" + propName +":" + nClassName +"\n"); boolean isIdentifier = Identifier.class.isAssignableFrom(returnClass); if(!isIdentifier && !nClassName.equals("[C")){ if(isNumber){ pstr.print("\"" + propName +":Number\","); }else if(isBoolean){ pstr.print("\"" + propName +":Boolean\","); }else{ if(nClassName.equals("[B")){ pstr.print("\"" + propName +":Binary\","); }else{ pstr.print("\"" + propName +":" + nClassName +"\","); } } prop.setProperty(propName,""); propList.add(propName); } } } } // End of section handling "setter" method } // End of loop through Methods } // End of section handling yang-generated class return prop; } public static boolean isYangGenerated(Class c) { if (c == null) { return (false); } else { //System.out.println(c.getName()); return (c.getName().startsWith("org.opendaylight.yang.gen.")); } } public static boolean isIpv4Address(Class c) { if (c == null ) { return (false); } String simpleName = c.getSimpleName(); return ("Ipv4Address".equals(simpleName)) ; } public static boolean isIpv6Address(Class c) { if (c == null ) { return (false); } String simpleName = c.getSimpleName(); return ("Ipv6Address".equals(simpleName)) ; } public static String toLowerHyphen(String inStr) { if (inStr == null) { return (null); } String str = inStr.substring(0, 1).toLowerCase(); if (inStr.length() > 1) { str = str + inStr.substring(1); } String regex = "(([a-z0-9])([A-Z]))"; String replacement = "$2-$3"; String retval = str.replaceAll(regex, replacement).toLowerCase(); //LOG.debug("Converting " + inStr + " => " + str + " => " + retval); return (retval); } public static String toUpperCamelCase(String inStr) { if (inStr == null) { return (null); } String[] terms = inStr.split("-"); StringBuffer sbuff = new StringBuffer(); // Check if string begins with a digit if (Character.isDigit(inStr.charAt(0))) { sbuff.append('_'); } for (String term : terms) { sbuff.append(term.substring(0, 1).toUpperCase()); if (term.length() > 1) { sbuff.append(term.substring(1)); } } return (sbuff.toString()); } public static boolean isGetter(Method m) { //System.out.println(m); if (m == null) { return (false); } if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) { if ((m.getName().matches("^is[A-Z].*") || m.getName().matches("^get[A-Z].*")) && m.getReturnType().equals(Boolean.class)) { return (true); } if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) { return (true); } } return (false); } public static boolean isSetter(Method m) { if (m == null) { return (false); } if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) { if (m.getName().matches("^set[A-Z].*")) { Class[] paramTypes = m.getParameterTypes(); if (paramTypes[0].isAssignableFrom(Identifier.class) || Identifier.class.isAssignableFrom(paramTypes[0])) { return (false); } else { return (true); } } } return (false); } public static void main(String[] args){ try{ PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out)); PrintYangToProp printYangToProp = new PrintYangToProp(); String className = args[0]; //ClassLoader classLoader = PrintYangToProp.class.getClassLoader(); //Class aClass = classLoader.loadClass(className); Class cl = Class.forName(className); //printPropertyList(ps,"",cl); //JsonObject jsonObj = Json.createObjectBuilder().build(); Properties p = getProperties(ps,"",cl); //System.out.println(p); }catch(Exception e){ e.printStackTrace(); } } }