001: package org.antlr.stringtemplate;
002:
003: import org.antlr.stringtemplate.language.*;
004:
005: import java.util.*;
006: import java.io.Reader;
007:
008: /** A group interface is like a group without the template implementations;
009: * there are just template names/argument-lists like this:
010: *
011: * interface foo;
012: * class(name,fields);
013: * method(name,args,body);
014: *
015: */
016: public class StringTemplateGroupInterface {
017: /** What is the group name */
018: protected String name;
019:
020: /** Maps template name to TemplateDefinition object */
021: protected Map templates = new LinkedHashMap();
022:
023: /** Are we derived from another group? Templates not found in this group
024: * will be searched for in the superGroup recursively.
025: */
026: protected StringTemplateGroupInterface super Interface = null;
027:
028: /** Where to report errors. All string templates in this group
029: * use this error handler by default.
030: */
031: protected StringTemplateErrorListener listener = DEFAULT_ERROR_LISTENER;
032:
033: public static StringTemplateErrorListener DEFAULT_ERROR_LISTENER = new StringTemplateErrorListener() {
034: public void error(String s, Throwable e) {
035: System.err.println(s);
036: if (e != null) {
037: e.printStackTrace(System.err);
038: }
039: }
040:
041: public void warning(String s) {
042: System.out.println(s);
043: }
044: };
045:
046: /** All the info we need to track for a template defined in an interface */
047: static class TemplateDefinition {
048: public String name;
049: public LinkedHashMap formalArgs; // LinkedHashMap<FormalArgument>
050: public boolean optional = false;
051:
052: public TemplateDefinition(String name,
053: LinkedHashMap formalArgs, boolean optional) {
054: this .name = name;
055: this .formalArgs = formalArgs;
056: this .optional = optional;
057: }
058: }
059:
060: public StringTemplateGroupInterface(Reader r) {
061: this (r, DEFAULT_ERROR_LISTENER,
062: (StringTemplateGroupInterface) null);
063: }
064:
065: public StringTemplateGroupInterface(Reader r,
066: StringTemplateErrorListener errors) {
067: this (r, errors, (StringTemplateGroupInterface) null);
068: }
069:
070: /** Create an interface from the input stream */
071: public StringTemplateGroupInterface(Reader r,
072: StringTemplateErrorListener errors,
073: StringTemplateGroupInterface super Interface) {
074: this .listener = errors;
075: setSuperInterface(super Interface);
076: parseInterface(r);
077: }
078:
079: public StringTemplateGroupInterface getSuperInterface() {
080: return super Interface;
081: }
082:
083: public void setSuperInterface(
084: StringTemplateGroupInterface super Interface) {
085: this .super Interface = super Interface;
086: }
087:
088: protected void parseInterface(Reader r) {
089: try {
090: InterfaceLexer lexer = new InterfaceLexer(r);
091: InterfaceParser parser = new InterfaceParser(lexer);
092: parser.groupInterface(this );
093: //System.out.println("read interface\n"+this.toString());
094: } catch (Exception e) {
095: String name = "<unknown>";
096: if (getName() != null) {
097: name = getName();
098: }
099: error("problem parsing group " + name + ": " + e, e);
100: }
101: }
102:
103: public void defineTemplate(String name, LinkedHashMap formalArgs,
104: boolean optional) {
105: TemplateDefinition d = new TemplateDefinition(name, formalArgs,
106: optional);
107: templates.put(d.name, d);
108: }
109:
110: /** Return a list of all template names missing from group that are defined
111: * in this interface. Return null if all is well.
112: */
113: public List getMissingTemplates(StringTemplateGroup group) {
114: List missing = new ArrayList();
115: for (Iterator it = templates.keySet().iterator(); it.hasNext();) {
116: String name = (String) it.next();
117: TemplateDefinition d = (TemplateDefinition) templates
118: .get(name);
119: if (!d.optional && !group.isDefined(d.name)) {
120: missing.add(d.name);
121: }
122: }
123: if (missing.size() == 0) {
124: missing = null;
125: }
126: return missing;
127: }
128:
129: /** Return a list of all template sigs that are present in the group, but
130: * that have wrong formal argument lists. Return null if all is well.
131: */
132: public List getMismatchedTemplates(StringTemplateGroup group) {
133: List mismatched = new ArrayList();
134: for (Iterator it = templates.keySet().iterator(); it.hasNext();) {
135: String name = (String) it.next();
136: TemplateDefinition d = (TemplateDefinition) templates
137: .get(name);
138: if (group.isDefined(d.name)) {
139: StringTemplate defST = group
140: .getTemplateDefinition(d.name);
141: Map formalArgs = defST.getFormalArguments();
142: boolean ack = false;
143: if ((d.formalArgs != null && formalArgs == null)
144: || (d.formalArgs == null && formalArgs != null)
145: || d.formalArgs.size() != formalArgs.size()) {
146: ack = true;
147: }
148: if (!ack) {
149: for (Iterator it2 = formalArgs.keySet().iterator(); it2
150: .hasNext();) {
151: String argName = (String) it2.next();
152: if (d.formalArgs.get(argName) == null) {
153: ack = true;
154: break;
155: }
156: }
157: }
158: if (ack) {
159: //System.out.println(d.formalArgs+"!="+formalArgs);
160: mismatched.add(getTemplateSignature(d));
161: }
162: }
163: }
164: if (mismatched.size() == 0) {
165: mismatched = null;
166: }
167: return mismatched;
168: }
169:
170: public String getName() {
171: return name;
172: }
173:
174: public void setName(String name) {
175: this .name = name;
176: }
177:
178: public void error(String msg) {
179: error(msg, null);
180: }
181:
182: public void error(String msg, Exception e) {
183: if (listener != null) {
184: listener.error(msg, e);
185: } else {
186: System.err.println("StringTemplate: " + msg);
187: if (e != null) {
188: e.printStackTrace();
189: }
190: }
191: }
192:
193: public String toString() {
194: StringBuffer buf = new StringBuffer();
195: buf.append("interface ");
196: buf.append(getName());
197: buf.append(";\n");
198: for (Iterator it = templates.keySet().iterator(); it.hasNext();) {
199: String name = (String) it.next();
200: TemplateDefinition d = (TemplateDefinition) templates
201: .get(name);
202: buf.append(getTemplateSignature(d));
203: buf.append(";\n");
204: }
205: return buf.toString();
206: }
207:
208: protected String getTemplateSignature(TemplateDefinition d) {
209: StringBuffer buf = new StringBuffer();
210: if (d.optional) {
211: buf.append("optional ");
212: }
213: buf.append(d.name);
214: if (d.formalArgs != null) {
215: StringBuffer args = new StringBuffer();
216: args.append('(');
217: int i = 1;
218: for (Iterator it = d.formalArgs.keySet().iterator(); it
219: .hasNext();) {
220: String name = (String) it.next();
221: if (i > 1) {
222: args.append(", ");
223: }
224: args.append(name);
225: i++;
226: }
227: args.append(')');
228: buf.append(args);
229: } else {
230: buf.append("()");
231: }
232: return buf.toString();
233: }
234: }
|