📄 generator.java
字号:
out(" public "+className+"("+superclass+" value) {");
out(" super(value);");
out(" }");
out();
out(" /**");
out(" * Constructs a new instance of this type with a designated Name and an ");
out(" * initial value.");
out(" *");
out(" * @param name the designated Name for this new instance.");
out(" * @param value the initial value of this instance.");
out(" */");
out(" public "+className+"(String name, "+superclass+" value) {");
out(" super(name, value);");
out(" }");
out();
out(" /**");
out(" * Constructs a new instance of this type given its Name, Tag and initial");
out(" * values.");
out(" *");
out(" * @param name the designated Name for this new instance.");
out(" * @param tag the specific tag for this instance.");
out(" * @param value the initial value for this instance.");
out(" */");
out(" public "+className+"(String name, Tag tag, "+superclass+" value) {");
out(" super(name, tag, value);");
out(" }");
out();
outBeginAttributes();
cat.info("<== outUpperConstructors()");
}
private void outBeginAttributes() {
cat.info("==> outBeginAttributes()");
out(" // Constants and variables");
out(" // -------------------------------------------------------------------------");
out();
cat.info("<== outBeginAttributes()");
}
private void outAttribute(String className, String var, String literal) {
cat.info("==> outAttribute("+String.valueOf(className)+", "+String.valueOf(var)+", "+String.valueOf(literal)+")");
StringBuffer sb = new StringBuffer(" public static final ");
sb.append(className).append(" ").append(var)
.append(" = new ").append(className).append("(")
.append("\"").append(var).append("\", ")
.append(literal)
.append(");");
out(sb.toString());
cat.info("<== outAttribute()");
}
/**
* Generates Java source code for a CHOICE ASN.1 construct.
*
* @param data a LinkedList containing the CHOICE alternatives.
*/
private void generateChoice(LinkedList data) {
cat.info("==> generateChoice()");
generateCompound(data);
// generate convenience isXXX() methods
out(" // CHOICE-specific convenience methods");
out(" // -------------------------------------------------------------------------");
out();
int i = 0;
for (Iterator ei = data.iterator(); ei.hasNext(); i++) {
NodeInfo ed = (NodeInfo) ei.next();
String lower = toJava(ed.getElementName());
String type = ed.getElementType();
String superclass = superclassFromType(type);
String proper = properFromLower(lower);
out(" /**");
out(" * Returns true iff this CHOICE instance has been decoded, and its (only)");
out(" * concrete alternative is the designated one. False otherwise.");
out(" *");
out(" * @return true iff this CHOICE instance has been decoded, and its (only)");
out(" * concrete alternative is the designated one. False otherwise.");
out(" */");
out(" public boolean is"+proper+"() {");
out(" return !get"+proper+"().isBlank();");
out(" }");
}
cat.info("<== generateChoice()");
}
private void generateCompound(String type) {
cat.info("==> generateCompound("+String.valueOf(type)+")");
LinkedList data = new LinkedList();
String name = type.substring(0, 1).toLowerCase() + type.substring(1);
data.add(new NodeInfo(name, type, null, null));
generateCompound(data);
cat.info("<== generateCompound()");
}
private void generateCompound(LinkedList data) {
cat.info("==> generateCompound(LinkedList)");
Iterator ei;
out();
out(" // Over-loaded implementation of methods defined in superclass");
out(" // -------------------------------------------------------------------------");
out();
// generate components declarations
out(" protected void initInternal() {");
out(" super.initInternal();");
out();
for (ei = data.iterator(); ei.hasNext(); ) {
NodeInfo ed = (NodeInfo) ei.next();
String asnLower = ed.getElementName();
String lower = toJava(asnLower);
String type = ed.getElementType();
String superclass = superclassFromType(type);
String tag = ed.getTagValue();
StringBuffer sb = new StringBuffer();
sb.append(" IType ").append(lower).append(" = new ")
.append(superclass).append("(\"").append(asnLower).append("\"");
if (tag != null)
sb.append(", ").append(tag);
//---
Node ets = ed.getTypeSpecs();
if (ets != null && (ets instanceof ADefaultElementTypeSuf)) {
Node v = ((ADefaultElementTypeSuf) ets).getValue();
String tc = String.valueOf(v).trim();
sb.append(", ").append(superclass).append(".").append(tc);
}
//---
sb.append(");");
out(sb.toString());
//---
if (ets != null
&& ((ets instanceof AOptionalElementTypeSuf)
|| (ets instanceof ADefaultElementTypeSuf))) {
sb = new StringBuffer();
sb.append(" ").append(lower).append(".optional(true);");
out(sb.toString());
}
sb = new StringBuffer();
sb.append(" components.add(").append(lower).append(");");
out(sb.toString());
}
out(" }");
out();
// generate accessors
out(" // Accessor methods");
out(" // -------------------------------------------------------------------------");
out();
int i = 0;
for (ei = data.iterator(); ei.hasNext(); i++) {
NodeInfo ed = (NodeInfo) ei.next();
String lower = ed.getElementName();
String type = ed.getElementType();
String superclass = superclassFromType(type);
String proper = toJava(properFromLower(lower));
out(" public "+superclass+" get"+proper+"() {");
out(" return ("+superclass+") components.get("+i+");");
out(" }");
out();
out(" public void set"+proper+"("+superclass+" obj) {");
out(" "+superclass+" it = get"+proper+"();");
out(" it.value(obj.value());");
out(" components.set("+i+", it);");
out(" }");
out();
}
cat.info("<== generateCompound()");
}
/**
* Generates a convenience interface Java source file, grouping all defined
* OIDs in the designated ASN.1 module name.<p>
*
* The name of the generate file is <tt>Module</tt> to be located in the
* designated destination directory, and belonging to a resolved package
* name (from the designated map). If such a file already exists it is
* over-written with just a warning printed to trace/debug output stream.
*
* @param destination the directory where generated files will be stored.
* @param module the name of the ASN.1 module, which will become the name of
* the package containg the new classes.
* @param dict a <tt>java.util.Map</tt> that maps package names to ASN.1
* module names. If a module name is not found in this map, then the same
* name string will be used as the name of its enclosing package.
* @exception IOException if an I/O error occurs during (a) the creation of
* a new file (that will contain generated code) or its parent directory,
* (b) the construction of a FileWriter object wrapping a new file, or
* (c) the process of generating the code per-se.
*/
private void generateModule(File destination, String module, Map dict)
throws IOException {
File f = setupVars(destination, module, dict, "Module");
activate(new PrintWriter(new FileWriter(f)));
outBeginClass(this.pkgName);
// the Module as a Java interface
// out("public interface Module {");
//
// Map oids = ast.getOIDs(module);
// Set keys = oids.keySet();
// for (Iterator it = keys.iterator(); it.hasNext(); ) {
// String name = (String) it.next();
// String value = (String) oids.get(name);
// out();
// out(" // OID "+name);
// name = name.toUpperCase();
// name = name.replace('-', '_');
// out(" ObjectIdentifier "+name+" = ObjectIdentifier.getInstance(\""+value+"\");");
// }
// or as a static class. this is preferred since no transformation of
// the name is necessary. user just refers to the ASN.1 specs file!
// on the other hand, we already transform the specs so this argument
// is not infallible.
out("public final class Module {");
out();
out(" // Constants and variables");
out(" // -------------------------------------------------------------------------");
out();
out(" /** If module has explicit tagging (true) or not (false). */");
out(" public static final boolean EXPLICIT_TAGGING = "+String.valueOf(!ast.getImplicitTagging(module))+";");
out();
out(" /** The class Singleton. */");
out(" private static Module singleton = null;");
out();
out(" /**");
out(" * The Map containing the name and string representations of OIDs defined.");
out(" * in this ASN.1 module.");
out(" */");
out(" private static java.util.Map map;");
out();
out(" // Constructor(s)");
out(" // -------------------------------------------------------------------------");
out();
out(" /** Trivial private constructor to enforce Singleton pattern. */");
out(" private Module() {");
out(" super();");
out();
out(" map = new java.util.HashMap();");
Map oids = ast.getOIDs(module);
Set keys = oids.keySet();
for (Iterator it = keys.iterator(); it.hasNext(); ) {
String name = (String) it.next();
out(" map.put(\""+name+"\", \""+(String) oids.get(name)+"\");");
}
out(" }");
out();
out(" // Class methods");
out(" // -------------------------------------------------------------------------");
out();
out(" /** @return the Singleton instance. */");
out(" public static synchronized Module instance() {");
out(" if (singleton == null)");
out(" singleton = new Module();");
out();
out(" return singleton;");
out(" }");
out();
out(" // Instance methods");
out(" // -------------------------------------------------------------------------");
out();
out(" /**");
out(" * @return the OID value for the designated user-defined OBJECT IDENTIFIER");
out(" * name.");
out(" */");
out(" public ObjectIdentifier getOID(String name) {");
out(" String oid = (String) map.get(name);");
out(" return ((oid == null) ? null : ObjectIdentifier.getInstance(oid));");
out(" }");
outEndClass();
passivate();
}
// other instance methods
// -------------------------------------------------------------------------
private void out() {
pw.println();
}
private void out(String s) {
pw.println(s);
}
/**
* Returns true if the given string is a permissible top-level ASN.1 type
* name; ie. it starts with an uppercase and does not contain dots.
*/
private boolean isPermissibleType(String type) {
return (Character.isUpperCase(type.charAt(0)) && type.indexOf(".") == -1);
}
private String superclassFromType(String type) {
String result;
if (type == null) result = "???";
else if (type.equals("BOOLEAN")) result = "ASNBoolean";
else if (type.equals("INTEGER")) result = "ASNInteger";
else if (type.equals("CHOICE")) result = "Choice";
else if (type.equals("BIT_STRING")) result = "BitString";
else if (type.equals("OCTET_STRING")) result = "OctetString";
else if (type.equals("NULL")) result = "Null";
else if (type.equals("OBJECT_IDENTIFIER")) result = "ObjectIdentifier";
else if (type.equals("SEQUENCE")) result = "Sequence";
else if (type.equals("SEQUENCE_OF")) result = "SequenceOf";
else if (type.equals("SET")) result = "Set";
else if (type.equals("SET_OF")) result = "SetOf";
else if (type.equals("PRINTABLE_STRING")) result = "PrintableString";
else if (type.equals("NUMERIC_STRING")) result = "NumericString";
else if (type.equals("T61_STRING")) result = "TeletexString";
else if (type.equals("VIDEOTEX_STRING")) result = "VideotexString";
else if (type.equals("IA5_STRING")) result = "IA5String";
else if (type.equals("GRAPHIC_STRING")) result = "GraphicString";
else if (type.equals("ISO646_STRING")) result = "VisibleString";
else if (type.equals("GENERAL_STRING")) result = "GeneralString";
else if (type.equals("UNIVERSAL_STRING")) result = "UniversalString";
else if (type.equals("BMP_STRING")) result = "BMPString";
else if (type.equals("UTC_TIME")) result = "UTCTime";
else if (type.equals("GENERALIZED_TIME")) result = "GeneralizedTime";
else if (type.equals("ANY")) result = "Any";
else result = type;
return result;
}
private String properFromLower(String lower) {
return (Character.toUpperCase(lower.charAt(0))+lower.substring(1));
}
private void generate(File destination, String module, Map dict, String type, Node n)
throws IOException {
File f = setupVars(destination, module, dict, type);
activate(new PrintWriter(new FileWriter(f)));
outBeginClass(this.pkgName);
state = GENERATING;
n.apply(this);
outEndClass();
passivate();
}
private File setupVars(File dir, String module, Map dict, String fileName)
throws IOException {
this.tag = null;
this.moduleName = module;
this.className = fileName;
this.pkgName = (String) dict.get(module);
if (this.pkgName == null)
this.pkgName = module;
cat.info("Generating java code for "+this.pkgName+"."+this.className);
File result = null;
String path = this.pkgName.replace('.', File.separatorChar);
File pkg = new File(dir, path);
pkg.mkdirs();
result = new File(pkg, this.className + ".java");
if (result.exists() && result.isFile()) {
cat.warn("Destination file "+result.getPath()+" already exists. Re-creating...");
result.delete();
result = new File(pkg, this.className + ".java");
}
result.createNewFile();
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -