001: /**
002: *
003: * © Copyright International Business Machines Corporation 2006.
004: * All rights reserved.
005: *
006: * The 'DefaultGenerator' class provides a default implementation of the
007: * 'SourceGenerator' interface.
008: *
009: * File : DefaultGenerator.java
010: * Created : 2006/03/02
011: *
012: * @author Rene Pawlitzek (rpa@zurich.ibm.com)
013: * @version 1.00, 2006/03/02
014: * @since JDK 1.3
015: *
016: * History : 2006/03/02, rpa, new file
017: * 2006/03/14, rpa, code review
018: *
019: */package com.ibm.hamlet.compiler;
020:
021: import java.io.*;
022: import java.util.*;
023: import com.ibm.hamlet.*;
024: import org.xml.sax.*;
025: import org.xml.sax.helpers.*;
026:
027: public class DefaultGenerator extends DefaultHandler implements
028: SourceGenerator {
029:
030: private static ReaderPool readerPool = new ReaderPool();
031:
032: private static final String IDENT = " ";
033:
034: private static final String REPEAT_TAG = "REPEAT"; // repeat
035: private static final String INCLUDE_TAG = "INCLUDE"; // include
036: private static final String REPLACE_TAG = "REPLACE"; // replace
037: private static final String ID_ATTRIBUTE = "ID"; // id
038:
039: private long attsVarNum, countVarNum, loopVarNum;
040: private boolean ignore;
041: private Stack stack;
042: private String ident = "";
043: private String chars, source;
044: private PrintStream out;
045: private StringBuffer buf;
046:
047: private static class LoopDesc {
048:
049: public String id;
050: public String var;
051:
052: public LoopDesc(String id, String var) {
053: this .id = id;
054: this .var = var;
055: } // LoopDesc
056:
057: } // LoopDesc
058:
059: public void perform(InputStream in, OutputStream out, String source)
060: throws Exception {
061: XMLReader reader = null;
062: try {
063: this .source = source;
064: this .out = new PrintStream(out);
065: reader = readerPool.getReader();
066: InputSource inputSource = new InputSource(in);
067: reader.setErrorHandler(this );
068: reader.setContentHandler(this );
069: reader.parse(inputSource);
070: } finally {
071: if (reader != null)
072: readerPool.returnReader(reader);
073: } // try
074: } // perform
075:
076: private void incIdent() {
077: ident += IDENT;
078: } // incIdent
079:
080: private void decIdent() {
081: ident = ident.substring(0, ident.length() - IDENT.length());
082: } // decIdent
083:
084: private String formatText(String text, String ident) {
085: StringBuffer buf = new StringBuffer();
086: for (int i = 0; i < text.length(); i++) {
087: char ch = text.charAt(i);
088: if (ch == '"') {
089: buf.append('\\');
090: buf.append(ch);
091: } else if (ch == '\n') {
092: buf.append("\\n\" + ");
093: buf.append(ch);
094: buf.append(ident);
095: buf.append("\"");
096: } else if (ch == '\r') {
097: // nop
098: } else {
099: buf.append(ch);
100: } // if
101: } // for
102: return buf.toString();
103: } // formatText
104:
105: private String getCall(String method, String id, String tag,
106: String attsVar) {
107: StringBuffer buf = new StringBuffer();
108: buf.append("handler.");
109: buf.append(method);
110: buf.append(" (");
111: if (id != null) {
112: buf.append("\"");
113: buf.append(id);
114: buf.append("\", ");
115: } else {
116: buf.append("null, ");
117: } // if
118: buf.append("\"");
119: buf.append(tag);
120: buf.append("\", ");
121: buf.append(attsVar);
122: buf.append(")");
123: return buf.toString();
124: } // getCall
125:
126: private void generateHeader(PrintStream out, String source) {
127: out.println("import java.io.*;");
128: out.println("import com.ibm.hamlet.*;");
129: out.println("import org.xml.sax.helpers.*;");
130: out.println();
131: out.print("public class ");
132: out.print(source);
133: out.println(" implements Template {");
134: out.println();
135: incIdent();
136: out.print(ident);
137: out
138: .println("public void serveDoc (PrintWriter writer, ContentHandler handler) throws Exception {");
139: incIdent();
140: } // generateHeader
141:
142: private void generateFooter(PrintStream out, String source) {
143: decIdent();
144: out.print(ident);
145: out.println("} // serveDoc");
146: decIdent();
147: out.println();
148: out.print("} // ");
149: out.println(source);
150: } // generateFooter
151:
152: private void generateText(PrintStream out, String text) {
153: out.print(ident);
154: out.println("writer.print (");
155: incIdent();
156: out.print(ident);
157: out.print("\"");
158: out.print(formatText(text, ident));
159: out.println("\"");
160: decIdent();
161: out.print(ident);
162: out.println(");");
163: } // generateText
164:
165: private String generateAttributes(PrintStream out, Attributes atts) {
166: String attsVar = "atts" + attsVarNum++;
167: out.print(ident);
168: out.print("AttributesImpl ");
169: out.print(attsVar);
170: out.println(" = new AttributesImpl ();");
171: for (int i = 0; i < atts.getLength(); i++) {
172: out.print(ident);
173: out.print(attsVar);
174: out.print(".addAttribute (");
175: out.print("\"");
176: out.print(atts.getURI(i));
177: out.print("\", ");
178: out.print("\"");
179: out.print(atts.getLocalName(i));
180: out.print("\", ");
181: out.print("\"");
182: out.print(atts.getQName(i));
183: out.print("\", ");
184: out.print("\"");
185: out.print(atts.getType(i));
186: out.print("\", ");
187: out.print("\"");
188: out.print(atts.getValue(i));
189: out.print("\"");
190: out.println(");");
191: } // for
192: return attsVar;
193: } // generateAttributes
194:
195: private void generateElementReplacement(PrintStream out,
196: Attributes atts) {
197: String attsVar = generateAttributes(out, atts);
198: String id = atts.getValue(ID_ATTRIBUTE);
199: String call = getCall("getElementReplacement", id, REPLACE_TAG,
200: attsVar);
201: out.print(ident);
202: out.print("writer.print (");
203: out.print(call);
204: out.println(");");
205: } // generateElementReplacement
206:
207: private void generateElementRepeatHeader(PrintStream out,
208: Attributes atts) {
209: String attsVar = generateAttributes(out, atts);
210: String loopVar = "loop" + loopVarNum++;
211: String countVar = "count" + countVarNum++;
212: String id = atts.getValue(ID_ATTRIBUTE);
213: String call = getCall("getElementRepeatCount", id, REPEAT_TAG,
214: attsVar);
215: out.print(ident);
216: out.print("int ");
217: out.print(countVar);
218: out.print(" = ");
219: out.print(call);
220: out.println(";");
221: out.print(ident);
222: out.print("for (int ");
223: out.print(loopVar);
224: out.print(" = 0; ");
225: out.print(loopVar);
226: out.print(" < ");
227: out.print(countVar);
228: out.print("; ");
229: out.print(loopVar);
230: out.println("++) {");
231: incIdent();
232: stack.push(new LoopDesc(id, attsVar));
233: } // generateElementRepeatHeader
234:
235: private void generateElementRepeatFooter(PrintStream out) {
236: LoopDesc loop = (LoopDesc) stack.pop();
237: String call = getCall("getElementRepeatCount", loop.id,
238: REPEAT_TAG, loop.var);
239: out.print(ident);
240: out.print("if (");
241: out.print(call);
242: out.println(" == 0)");
243: out.print(ident);
244: out.println(" break;");
245: decIdent();
246: out.print(ident);
247: out.println("} // for");
248: } // generateElementRepeatFooter
249:
250: private String generateElementAttributes(PrintStream out,
251: String localName, Attributes atts) {
252: String attsVar = generateAttributes(out, atts);
253: String id = atts.getValue(ID_ATTRIBUTE);
254: String call = getCall("getElementAttributes", id, localName,
255: attsVar);
256: out.print(ident);
257: out.print("RuntimeUtilities.printTag (writer, \"");
258: out.print(localName);
259: out.print("\", ");
260: out.print(call);
261: out.println(");");
262: return attsVar;
263: } // generateElementAttributes
264:
265: private void generateElementInclude(PrintStream out,
266: String localName, Attributes atts) {
267: String attsVar = generateAttributes(out, atts);
268: String id = atts.getValue(ID_ATTRIBUTE);
269: if (id != null)
270: attsVar = getCall("getElementAttributes", id, localName,
271: attsVar);
272: String call = getCall("getElementIncludeSource", id, localName,
273: attsVar);
274: out.print(ident);
275: out.print("RuntimeUtilities.printInclude (writer, ");
276: out.print(call);
277: out.println(");");
278: } // generateElementInclude
279:
280: /* ----- implementation of ContentHandler ----- */
281:
282: public void startDocument() throws SAXException {
283: stack = new Stack();
284: buf = new StringBuffer();
285: generateHeader(out, source);
286: } // startDocument
287:
288: public void endDocument() throws SAXException {
289: generateText(out, buf.toString());
290: generateFooter(out, source);
291: } // endDocument
292:
293: public void startElement(String namespaceURI, String localName,
294: String qName, Attributes atts) throws SAXException {
295:
296: // category.debug ("local name: " + localName + ", qname: " + qName);
297: if (REPEAT_TAG.equals(localName)) {
298: generateText(out, buf.toString());
299: generateElementRepeatHeader(out, atts);
300: buf = new StringBuffer();
301: } else if (REPLACE_TAG.equals(localName)) {
302: generateText(out, buf.toString());
303: String id = atts.getValue(ID_ATTRIBUTE);
304: if (id != null)
305: generateElementReplacement(out, atts);
306: buf = new StringBuffer();
307: ignore = true;
308: } else if (INCLUDE_TAG.equals(localName)) {
309: generateText(out, buf.toString());
310: generateElementInclude(out, localName, atts);
311: buf = new StringBuffer();
312: ignore = true;
313: } else {
314: String id = atts.getValue(ID_ATTRIBUTE);
315: if (id != null) {
316: generateText(out, buf.toString());
317: generateElementAttributes(out, localName, atts);
318: buf = new StringBuffer();
319: } else {
320: buf.append("<");
321: buf.append(localName);
322: for (int i = 0; i < atts.getLength(); i++) {
323: buf.append(" ");
324: buf.append(atts.getLocalName(i));
325: buf.append("=\"");
326: buf.append(atts.getValue(i));
327: buf.append("\"");
328: } // for
329: buf.append(">");
330: } // if
331: } // if
332:
333: } // startElement
334:
335: public void endElement(String namespaceURI, String localName,
336: String qName) throws SAXException {
337:
338: if (REPEAT_TAG.equals(localName)) {
339: generateText(out, buf.toString());
340: generateElementRepeatFooter(out);
341: buf = new StringBuffer();
342: } else if (REPLACE_TAG.equals(localName)
343: || INCLUDE_TAG.equals(localName)) {
344: ignore = false;
345: } else {
346: buf.append("</");
347: buf.append(localName);
348: buf.append(">");
349: } // if
350:
351: } // endElement
352:
353: public void characters(char[] ch, int start, int length)
354: throws SAXException {
355: chars = new String(ch, start, length);
356: if (!ignore)
357: buf.append(chars);
358: } // characters
359:
360: } // DefaultGenerator
361:
362: /* ----- End of File ----- */
|