package codegen; import static CIAPI.Java.logging.Log.debug; import static CIAPI.Java.logging.Log.error; import static CIAPI.Java.logging.Log.info; import static CIAPI.Java.logging.Log.trace; import static CIAPI.Java.logging.Log.warn; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import codegen.modelobjects.DTO; /** * Main class for running stuff * * @author Justin Nelson */ public class CodeGenMain { /** * Stuff...It's a main...what do you expect? * * @param args */ public static void main(String[] args) throws ClassNotFoundException, IOException { info("Beginning the process of generating code"); if (args.length == 0 || args[0].matches("(-h|-H|--help)") || args.length % 2 == 1) { debug("Given arguments did not match the expected arguments"); CodeGenMain.printUsage(); return; } List<ClParam> params = parseParams(args); String outputLocation = CodeGenMain.generateCode(params); if (outputLocation != null) { info("Success! Generated code!: " + outputLocation); } else { warn("Code was not generated"); } } public static void main2(String[] args) throws FileNotFoundException, ClassNotFoundException { SchemaReader rdr = new SchemaReader(new FileInputStream("files/smdFiles/schema_new.js"), new FileInputStream( "files/smdFiles/smd.js"), "files/code_replacement_rules"); List<DTO> dtos = rdr.getAllModelItems(); for (DTO d : dtos) { System.out.println(d); } } /** * Uses the specific params to print the usage instructions to standard out */ private static void printUsage() { String usage = "Please specify the following arguments:\n" + SpecificParams.toUsageString(); System.out.println(usage); } /** * Given a set of command line parameters, generate the code using a SchemaReader. * * @param params * the command line args after they've been parsed * @throws URISyntaxException * @throws IOException * @throws ParserConfigurationException * @throws SAXException * @throws ClassNotFoundException */ public static String generateCode(List<ClParam> params) throws ClassNotFoundException, IOException { CodeGenConfig conf = parseClParams(params); SchemaReader.generateCode(conf); return conf.getSaveLocation(); } private static CodeGenConfig parseClParams(List<ClParam> parms) { if (parms.size() < 3 && parms.size() != 1) { error(new IllegalArgumentException("You must provide the 4 location parameters or a config file.")); } // Find all of the required parameters String schemaLocation = null; String smdLocation = null; String saveLocation = null; String replacementDirectory = null; String configLocation = null; for (ClParam p : parms) { if (p.option.equals("-sch")) { schemaLocation = p.value; } else if (p.option.equals("-smd")) { smdLocation = p.value; } else if (p.option.equals("-l")) { saveLocation = p.value; } else if (p.option.equals("-t")) { } else if (p.option.equals("-r")) { replacementDirectory = p.value; } else if (p.option.equals("-c")) { configLocation = p.value; } } // If a config file was supplied, we will use the values from that if (configLocation != null) { CodeGenConfig conf = CodeGenConfig.loadFile(configLocation); return conf; } // If any of the other values are null, then we have a problem if (schemaLocation == null || smdLocation == null || saveLocation == null || replacementDirectory == null) { error("Did not find all required parameters"); printUsage(); return null; } return new CodeGenConfig(smdLocation, schemaLocation, replacementDirectory, saveLocation); } public static InputStream openFileOrUrl(String path) throws IOException { if (path.startsWith("http")) { debug("Attempting to open url: " + path); URL url = new URL(path); return url.openStream(); } else { debug("Attempting to open local file: " + path); return new FileInputStream(new File(path)); } } /** * Parses params into objects. * * @param array * command line arguments from main * @return a list of ClParam objects that represent the parameters passed into main */ private static List<ClParam> parseParams(String[] array) { List<ClParam> ret = new ArrayList<ClParam>(); for (int i = 0; i < array.length; i += 2) { ret.add(new ClParam(array[i], array[i + 1])); } trace("Parsed " + ret.size() + " parameters from the command line."); return ret; } /** * The specific parameters we need for generating code * * @author Justin Nelson */ static enum SpecificParams { CONFIG_LOCATION("-c", "Where the code gen config file is located. Use this parameter, or all of the rest."), SCHEMA_URI( "-sch", "The local file or URL location of the Schema descriptor"), SMD_URI("-smd", "The local file or URL location of the SMD descriptor"), SAVE_LOCATION("-l", "The location to save the generated code"), REPLACEMNT_FILE_DIR("-r", "The directory where your replacement files are located."); public final String option; public final String description; private SpecificParams(String option, String description) { this.option = option; this.description = description; } /** * Will combine the switch and the description of it's behavior and return a pretty string * * @return what the given {@link SpecificParams} is used for. */ public static String toUsageString() { String ret = ""; for (SpecificParams p : values()) { ret += "\t" + p.option + " <" + p.description + ">\n"; } return ret; } /** * Will find a {@link SpecificParams} that matches the given option. * * @param option * the option to match * @return the {@link SpecificParams} matching the option. Or <code>null</code> if no matches are found. */ public static SpecificParams fromOption(String option) { for (SpecificParams p : values()) { if (p.option.equals(option)) { return p; } } warn("Could not parse generic option: " + option); return null; } } /** * A class representing a generic command line paramter. It has 2 parts, an option (-l, -smd) and a value. * * @author Justin Nelson * */ static class ClParam { public final String option; public final String value; public ClParam(String option, String value) { this.option = option; this.value = value; checkValues(); } /** * Given the generic parameter will try to find the matching specific parameter. * * @return */ public SpecificParams toSpecificParam() { return SpecificParams.fromOption(option); } private void checkValues() { if (!option.startsWith("-")) { throw new IllegalArgumentException("The parameter '" + option + "' is not a valid switch."); } } } }