diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index 1e68f8bd219..06e488133c6 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -28,10 +28,14 @@ import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Properties; +import java.util.TreeMap; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -48,20 +52,20 @@ import com.google.gson.annotations.SerializedName; import com.thoughtworks.xstream.XStream; public class ApiXmlDocWriter { - public static final Logger s_logger = Logger - .getLogger(ApiXmlDocWriter.class.getName()); + public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName()); private static final short DOMAIN_ADMIN_COMMAND = 2; private static final short USER_COMMAND = 8; - private static Properties all_api_commands = new Properties(); - private static Properties domain_admin_api_commands = new Properties(); - private static Properties regular_user_api_commands = new Properties(); - + private static LinkedHashMap all_api_commands = new LinkedHashMap(); + private static LinkedHashMap domain_admin_api_commands = new LinkedHashMap(); + private static LinkedHashMap regular_user_api_commands = new LinkedHashMap(); + private static TreeMap all_api_commands_sorted = new TreeMap(); + private static TreeMap domain_admin_api_commands_sorted = new TreeMap(); + private static TreeMap regular_user_api_commands_sorted = new TreeMap(); private static String dirName=""; public static void main (String[] args) { - Properties preProcessedCommands = new Properties(); - Enumeration command = null; + LinkedProperties preProcessedCommands = new LinkedProperties(); String[] fileNames = null; List argsList = Arrays.asList(args); @@ -95,9 +99,11 @@ public class ApiXmlDocWriter { } } + Iterator propertiesIterator = preProcessedCommands.keys.iterator(); //Get command classes and response object classes - for (Object key : preProcessedCommands.keySet()) { - String preProcessedCommand = preProcessedCommands.getProperty((String)key); + while (propertiesIterator.hasNext()) { + String key = (String)propertiesIterator.next(); + String preProcessedCommand = preProcessedCommands.getProperty(key); String[] commandParts = preProcessedCommand.split(";"); String commandName = commandParts[0]; all_api_commands.put(key, commandName); @@ -111,7 +117,9 @@ public class ApiXmlDocWriter { } } - command = all_api_commands.propertyNames(); + all_api_commands_sorted.putAll(all_api_commands); + domain_admin_api_commands_sorted.putAll(domain_admin_api_commands); + regular_user_api_commands_sorted.putAll(regular_user_api_commands); try { //Create object writer @@ -128,101 +136,62 @@ public class ApiXmlDocWriter { ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/commands.xml"), "commands"); ObjectOutputStream rootAdmin = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "rootAdminSummary.xml"), "commands"); - ObjectOutputStream outDomainAdmin = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummary.xml"), "commands"); + ObjectOutputStream rootAdminSorted = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "rootAdminSummarySorted.xml"), "commands"); + ObjectOutputStream domainAdmin = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummary.xml"), "commands"); + ObjectOutputStream outDomainAdminSorted = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummarySorted.xml"), "commands"); ObjectOutputStream regularUser = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/regularUserSummary.xml"), "commands"); + ObjectOutputStream regularUserSorted = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/regularUserSummarySorted.xml"), "commands"); - while (command.hasMoreElements()) { + //Write commands in the order they are represented in commands.properties.in file + Iterator it = all_api_commands.keySet().iterator(); + while (it.hasNext()) { ObjectOutputStream singleCommandOs = null; - String key = (String) command.nextElement(); - Class clas = Class.forName(all_api_commands.getProperty(key)); - ArrayList request = new ArrayList(); - ArrayList response = new ArrayList(); + String key = (String)it.next(); - //Create a new command, set name and description - Command apiCommand = new Command(); - apiCommand.setName(key); - - - Implementation impl = (Implementation)clas.getAnnotation(Implementation.class); - if (impl == null) - impl = (Implementation)clas.getSuperclass().getAnnotation(Implementation.class); - String commandDescription = impl.description(); - if (commandDescription != null) - apiCommand.setDescription(commandDescription); - else - System.out.println("Command " + apiCommand.getName() + " misses description"); - - //Get request parameters - Field[] fields = clas.getDeclaredFields(); - - //Get fields from superclass - Class superClass = clas.getSuperclass(); - String superName = superClass.getName(); - if (!superName.equals(BaseCmd.class.getName()) && !superName.equals(BaseAsyncCmd.class.getName()) && !superName.equals(BaseAsyncCreateCmd.class.getName())) { - Field[] superClassFields = superClass.getDeclaredFields(); - if (superClassFields != null && !superClass.getName().equals(BaseListCmd.class.getName())) { - Field[] tmpFields = new Field[fields.length + superClassFields.length]; - System.arraycopy(fields, 0, tmpFields, 0, fields.length); - System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length); - fields = tmpFields; - } - superClass = superClass.getSuperclass(); - } - - for (Field f : fields) { - Parameter parameterAnnotation = f.getAnnotation(Parameter.class); - if (parameterAnnotation != null) { - Argument reqArg = new Argument(parameterAnnotation.name()); - reqArg.setRequired(parameterAnnotation.required()); - if (!parameterAnnotation.description().isEmpty() && parameterAnnotation.expose()) - reqArg.setDescription(parameterAnnotation.description()); - else if (parameterAnnotation.expose()) { - //System.out.println("Description is missing for the parameter " + parameterAnnotation.name() + " of the command " + apiCommand.getName() ); - } - request.add(reqArg); - } - } - - Class responseClas = impl.responseObject(); - - //Get response parameters - Field[] responseFields = responseClas.getDeclaredFields(); - for (Field responseField : responseFields) { - SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class); - Param descAnnotation = responseField.getAnnotation(Param.class); - Argument respArg = new Argument(nameAnnotation.value()); - if (descAnnotation != null) - respArg.setDescription(descAnnotation.description()); - response.add(respArg); - } - - apiCommand.setRequest(request); - apiCommand.setResponse(response); - - //Write command to xml file - out.writeObject(apiCommand); - rootAdmin.writeObject(apiCommand); - - //Write single command to xml file + //Write admin commands + writeCommand(out, key); + writeCommand(rootAdmin, key); + + //Write single commands to separate xml files singleCommandOs = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + key + ".xml"), "command"); if (domain_admin_api_commands.containsKey(key)){ - outDomainAdmin.writeObject(apiCommand); + writeCommand(domainAdmin, key); singleCommandOs = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + key + ".xml"), "command"); } if (regular_user_api_commands.containsKey(key)){ singleCommandOs = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/" + key + ".xml"), "command"); - regularUser.writeObject(apiCommand); + writeCommand(regularUser, key); } - singleCommandOs.writeObject(apiCommand); + writeCommand(singleCommandOs, key); singleCommandOs.close(); } + //Write sorted commands + it = all_api_commands_sorted.keySet().iterator(); + while (it.hasNext()) { + String key = (String)it.next(); + + writeCommand(rootAdminSorted, key); + + + if (domain_admin_api_commands.containsKey(key)){ + writeCommand(outDomainAdminSorted, key); + } + + if (regular_user_api_commands.containsKey(key)){ + writeCommand(regularUserSorted, key); + } + } + out.close(); rootAdmin.close(); - outDomainAdmin.close(); + rootAdminSorted.close(); + domainAdmin.close(); + outDomainAdminSorted.close(); regularUser.close(); + regularUserSorted.close(); //gzip directory with xml doc zipDir(dirName + "xmldoc.zip", xmlDocDir); @@ -236,6 +205,76 @@ public class ApiXmlDocWriter { } } + + private static void writeCommand(ObjectOutputStream out, String command) throws ClassNotFoundException, IOException{ + Class clas = Class.forName(all_api_commands.get(command)); + ArrayList request = new ArrayList(); + ArrayList response = new ArrayList(); + + //Create a new command, set name and description + Command apiCommand = new Command(); + apiCommand.setName(command); + + + Implementation impl = (Implementation)clas.getAnnotation(Implementation.class); + if (impl == null) + impl = (Implementation)clas.getSuperclass().getAnnotation(Implementation.class); + String commandDescription = impl.description(); + if (commandDescription != null) + apiCommand.setDescription(commandDescription); + else + System.out.println("Command " + apiCommand.getName() + " misses description"); + + //Get request parameters + Field[] fields = clas.getDeclaredFields(); + + //Get fields from superclass + Class superClass = clas.getSuperclass(); + String superName = superClass.getName(); + if (!superName.equals(BaseCmd.class.getName()) && !superName.equals(BaseAsyncCmd.class.getName()) && !superName.equals(BaseAsyncCreateCmd.class.getName())) { + Field[] superClassFields = superClass.getDeclaredFields(); + if (superClassFields != null && !superClass.getName().equals(BaseListCmd.class.getName())) { + Field[] tmpFields = new Field[fields.length + superClassFields.length]; + System.arraycopy(fields, 0, tmpFields, 0, fields.length); + System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length); + fields = tmpFields; + } + superClass = superClass.getSuperclass(); + } + + for (Field f : fields) { + Parameter parameterAnnotation = f.getAnnotation(Parameter.class); + if (parameterAnnotation != null) { + Argument reqArg = new Argument(parameterAnnotation.name()); + reqArg.setRequired(parameterAnnotation.required()); + if (!parameterAnnotation.description().isEmpty() && parameterAnnotation.expose()) + reqArg.setDescription(parameterAnnotation.description()); + else if (parameterAnnotation.expose()) { + //System.out.println("Description is missing for the parameter " + parameterAnnotation.name() + " of the command " + apiCommand.getName() ); + } + request.add(reqArg); + } + } + + Class responseClas = impl.responseObject(); + + //Get response parameters + Field[] responseFields = responseClas.getDeclaredFields(); + for (Field responseField : responseFields) { + SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class); + Param descAnnotation = responseField.getAnnotation(Param.class); + Argument respArg = new Argument(nameAnnotation.value()); + if (descAnnotation != null) + respArg.setDescription(descAnnotation.description()); + response.add(respArg); + } + + apiCommand.setRequest(request); + apiCommand.setResponse(response); + + out.writeObject(apiCommand); + } + private static void zipDir(String zipFileName, String dir) throws Exception { File dirObj = new File(dir); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName)); @@ -273,4 +312,20 @@ public class ApiXmlDocWriter { } dir.delete(); } + + + private static class LinkedProperties extends Properties { + private final LinkedList keys = new LinkedList(); + + public Enumeration keys() { + return Collections.enumeration(keys); + } + + public Object put(Object key, Object value) { + //System.out.println("Adding key" + key); + keys.add(key); + return super.put(key, value); + } + } + } \ No newline at end of file