📄 main.java
字号:
/* $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.<p>
*
* 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:
* <A HREF="http://jakarta.apache.org/log4j/doc/download.html">log4j.jar</A>
* (from jakarta.apache.org), and the GNU LGPL-ed
* <A HREF="http://www.urbanophile.com/arenn/hacking/download.html">java-getopt-1.0.8.jar</A>
* published by Aaron M. Renn.
*
* The tool's usage is simple:
* <pre>
* 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
* </pre>
*
* 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.
* <pre>
* -Dlog4j.configuration=./log.properties
* </pre>
*
* @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("<ctor>", 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[<directory>]");
System.out.println(" --Destination=[<directory>]");
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 <module-name>=<package-name>");
System.out.println(" -P<module-name>=<package-name>");
System.out.println(" --Package=<module-name>=<package-name>");
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 <tt>true</tt> or <tt>false</tt> 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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -