www.pudn.com > cryptix-asn1-0.1.11.zip > Main.java, change:2001-07-01,size:14286b
/* $Id: Main.java,v 1.5 2001/06/30 20:53:31 raif Exp $ * * Copyright (C) 1997-2001 The Cryptix Foundation Limited. All rights reserved. * * Use, modification, copying and distribution of this software is subject to * the terms and conditions of the Cryptix General Licence. You should have * received a copy of the Cryptix General Licence along with this library; if * not, you can download a copy from http://www.cryptix.org/ */ package cryptix.asn1.tool; import cryptix.asn1.lexer.Lexer; import cryptix.asn1.node.Node; import cryptix.asn1.parser.Parser; import org.apache.log4j.Category; import gnu.getopt.Getopt; import gnu.getopt.LongOpt; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.PushbackReader; import java.util.ArrayList; import java.util.Date; import java.util.Hashtable; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; /** * A command line tool class for generating Java classes from one or more user * defined ASN.1 specification file(s). It is also the main class in the * executable jar (normally named cryptix-asn1.jar) included in the * distribution of this toolkit.* * To run this tool you need to have two additional jar files that must be * present in the same directory as the executable jar file that contains this * class: * log4j.jar * (from jakarta.apache.org), and the GNU LGPL-ed * java-getopt-1.0.8.jar * published by Aaron M. Renn. * * The tool's usage is simple: *
* java [java-options] cryptix.asn1.tools.Main [options] [--] specification... * Or * java -jar [java-options] cryptix-asn1.jar [options] [--] specification... * * Where java-options are those described in the java tool documentation, * and where options are: * -h * --help * To display this text. * -g * --gui * Display the parsed AST in a Swing frame, without generating Java * classes. * -D[<directory>] * --Destination=[<directory>] * The name of the destination directory for generated sources. * If unspecified, then the user's current directory is assumed. * -P <module-name>=<package-name> * -P<module-name>=<package-name> * --Package=<module-name>=<package-name> * The name of a package to map an ASN.1 module name to. This may * be repeated as many times as required. If no mapping is found, * the ASN.1 module name will be used as the package name. * specification * A non-empty, space separated, list of ASN.1 specifications * file(s) to process. * * Example: * java -jar cryptix-asn1.jar \ * -Dtmp \ * -P CryptixUsefulDefinitions=cryptix.asn1.common \ * -P PKCS-6=cryptix.asn1.pkc6 \ * cryptix.asn pkcs7 ** * For debugging, this tool uses the Log4J framework and classes. To pass the * log4j configuration information to the log4j framework, use the -D option * with a suitable value for the "log4j.configuration" key; eg. ** -Dlog4j.configuration=./log.properties ** * @version $Revision: 1.5 $ * @author Raif S. Naffah */ public class Main { // Constants and variables // ------------------------------------------------------------------------- private static Category cat = Category.getInstance(Main.class); /** The command line options. */ private static final LongOpt[] CLO = { new LongOpt("gui", LongOpt.NO_ARGUMENT, null, 'g'), new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'), new LongOpt("Destination", LongOpt.OPTIONAL_ARGUMENT, null, 'D'), new LongOpt("Package", LongOpt.REQUIRED_ARGUMENT, null, 'P') }; /** The destination directory for generated java files. */ private String destination; /** The names of file(s) to compile. */ private String[] definitions; /** The ASN.1 module to java package name mappings. */ private Hashtable dict; /** Indicates if this instance should 'swing' the AST. */ private boolean swing; /** The JFrame instance to use when the swing option is requested. */ private JFrame treeFrame; /** Indicates if this instance has valid options or not. */ private boolean valid; // Constructor(s) // ------------------------------------------------------------------------- /** Trivial private constructor to enforce usage through main(). */ private Main(String[] args) { super(); // initialise default values destination = System.getProperty("user.dir"); definitions = null; dict = new Hashtable(); valid = false; // parse command line arguments, if error get out try { valid = parseArgs(args); } catch (Exception x) { cat.error("", x); System.exit(1); } // if break in options, print usage if (!valid) printUsage(); } // Class methods // ------------------------------------------------------------------------- /** * The main method. * * @param args see class comments above. */ public static final void main(String[] args) { cat.info("Started on "+String.valueOf(new Date())); long t = -System.currentTimeMillis(); Main compiler = new Main(args); if (compiler.valid) compiler.invoke(); t += System.currentTimeMillis(); cat.info("Finished. Process lasted "+String.valueOf(t)+"ms..."); } /** Prints the command line options to System.out. */ private static final void printUsage() { System.out.println(); System.out.println("Cryptix ASN.1 Kit ASN.1-to-Java compiler"); System.out.println("Copyright (C) 1997-2001 The Cryptix Foundation Limited."); System.out.println("All rights reserved."); System.out.println(); System.out.println("$Revision: 1.5 $".replace('$', ' ').substring(1)); System.out.println("$Date: 2001/06/30 20:53:31 $".replace('$', ' ').substring(1)); System.out.println(); System.out.println("Usage:"); System.out.println(" java -jar [java-options] cryptix-asn1.jar [options] [--] specification..."); System.out.println("or"); System.out.println(" java [java-options] "+Main.class.getName()+" [options] [--] specification..."); System.out.println(); System.out.println("Where java-options are those described in the java tool documentation,"); System.out.println("and where options are:"); System.out.println(" -h"); System.out.println(" --help"); System.out.println(" Prints this text."); System.out.println(" -g"); System.out.println(" --gui"); System.out.println(" Display the parsed AST in a Swing frame, without generating Java"); System.out.println(" classes."); System.out.println(" -D[ ]"); System.out.println(" --Destination=[ ]"); System.out.println(" The name of the destination directory for generated sources."); System.out.println(" If unspecified, then the current directory is assumed."); System.out.println(" -P = "); System.out.println(" -P = "); System.out.println(" --Package= = "); System.out.println(" The name of a package to map an ASN.1 module name to. This may"); System.out.println(" be repeated as many times as required. If no mapping is found,"); System.out.println(" the ASN.1 module name will be used as the package name."); System.out.println(" specification"); System.out.println(" A non-empty, space separated, list of ASN.1 specifications"); System.out.println(" file(s) to process."); System.out.println(); System.out.println("Example:"); System.out.println(" java -jar cryptix-asn1.jar \\"); System.out.println(" -Dtmp \\"); System.out.println(" -P CryptixUsefulDefinitions=cryptix.asn1.common \\"); System.out.println(" -P PKCS-6=cryptix.asn1.pkc6 \\"); System.out.println(" cryptix.asn pkcs6"); System.out.println(); } // Instance methods // ------------------------------------------------------------------------- /** * @return true or false to notify the caller that further * processing is required or not respectively. * @params the list or args. * @exception RuntimeException if an option is missing or incorrect. */ private boolean parseArgs(String[] args) { Getopt g = new Getopt(this.getClass().getName(), args, "-:ghD::P:", CLO); g.setOpterr(false); int c; String arg; ArrayList inFiles = new ArrayList(); while ((c = g.getopt()) != -1) switch (c) { // error handling case '?': throw new RuntimeException("Invalid option. May be missing space after --"); case ':': cat.error("Stuffed option "+String.valueOf(g.getOptopt())); break; case 0: cat.debug("Long option "+String.valueOf(g.getOptarg())); break; case 1: arg = g.getOptarg(); cat.debug("Non-optional argument \""+arg+"\""); inFiles.add(arg); break; case 'g': swing = true; break; case 'h': return false; case 'D': arg = g.getOptarg(); cat.debug("Destination argument: \""+String.valueOf(arg)+"\""); destination = arg; break; case 'P': arg = g.getOptarg(); cat.debug("Package argument: \""+arg+"\""); int j = arg.indexOf("="); if (j == -1) throw new RuntimeException("Missing '=' in a Package option value. Malformed -P option value"); String modName = arg.substring(0, j); String pkgName = arg.substring(j+1); dict.put(modName, pkgName); break; default: throw new RuntimeException("Unknown option: '"+String.valueOf((char) c)+"'"); } // the [remaining] spec file(s) int i = g.getOptind(); int limit = args.length - i; while (limit-- > 0) inFiles.add(args[i++]); limit = inFiles.size(); if (limit < 1) throw new RuntimeException("Missing specification file"); definitions = new String[inFiles.size()]; inFiles.toArray(definitions); cat.info("Destination directory = "+destination); cat.info("Package name mappings = "+String.valueOf(dict)); cat.info("Display AST = "+String.valueOf(swing)); cat.info("Specification file(s) = "+String.valueOf(inFiles)); cat.info(""); return true; } /** Processes all specification(s) based on some command line options. */ private void invoke() { for (int i = 0; i < definitions.length; i++) compile(definitions[i]); } /** Compiles 1 specification file. */ private void compile(String asnFile) { File f = new File(asnFile); if (!f.isFile()) { String msg = "File "+f.getAbsolutePath()+" does not exist"; cat.error(msg); throw new RuntimeException(msg); } String asn = f.getAbsolutePath(); Node ast = null; cat.info(""); cat.info("Parsing ASN.1 specification in \""+asn+"\"..."); try { Lexer lexer = new Lexer( new PushbackReader( new BufferedReader( new FileReader(f), 4096))); Parser parser = new Parser(lexer); ast = parser.parse(); // parse the asn.1 specs cat.info(ast); } catch (Exception x) { cat.error("compile("+String.valueOf(asnFile)+")", x); throw new RuntimeException("Error while parsing ASN.1 specifications"); } cat.info(""); cat.info("Printing ASN.1 specifications defined in \""+asn+"\"..."); try { ast.apply(new PrintWalker()); } catch (Exception x) { cat.error("compile("+String.valueOf(asnFile)+")", x); throw new RuntimeException("Error while printing ASN.1 specifications"); } cat.info(""); cat.info("Interpreting ASN.1 specifications defined in \""+asn+"\"..."); Interpreter ai = new Interpreter(); try { ast.apply(ai); // interpret the asn.1 specs } catch (Exception x) { cat.error("compile("+String.valueOf(asnFile)+")", x); throw new RuntimeException("Error while interpreting ASN.1 specifications"); } cat.info(""); try { File dir = new File(destination); cat.info("Generating java source"); Generator generator = new Generator(ai); generator.generate(dir, dict); } catch (Exception x) { cat.error("compile("+String.valueOf(asnFile)+")", x); throw new RuntimeException("Error while generating Java source"); } if (swing) try { DisplayTree gui = new DisplayTree(); ast.apply(gui); treeFrame = gui.getTreeFrame(); treeFrame.addWindowListener( new WindowAdapter() { public void windowClosed(WindowEvent x) { hideFrame(); } } ); treeFrame.show(); } catch (Exception x) { cat.error("compile("+String.valueOf(asnFile)+")", x); throw new RuntimeException("Error while displaying ASN.1 specifications"); } } private void hideFrame() { treeFrame.hide(); System.exit(0); } }