001: /*
002: * sqlc 1
003: * SQL Compiler
004: * Copyright (C) 2003 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz/products/sqlc/index.html
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.codegen;
024:
025: import java.io.File;
026: import java.io.FileWriter;
027: import java.io.IOException;
028: import java.io.Writer;
029: import java.util.HashMap;
030: import java.util.Iterator;
031: import java.util.Map;
032: import java.util.Properties;
033: import java.util.StringTokenizer;
034:
035: import org.apache.bcel.classfile.JavaClass;
036: import org.apache.bcel.generic.ClassGen;
037:
038: /**
039: * Stores generated class files in a specified directory and creates HTML documenation.
040: * @author Pavel Vlasov
041: * @version $Revision: 1.5 $
042: */
043: public class HtmlDocConsumer implements DocumentingConsumer {
044: private File classDir;
045: private File docDir;
046: private Writer indexWriter;
047:
048: final Map writerMap = new HashMap();
049:
050: /**
051: * Construcotor
052: * @param classDir Output directory for generated classes. Mandatory.
053: * @param docDir Output directory for HTML documentation. Optional (can be null).
054: * @param indexName Name of index file.
055: * @throws GenerationException
056: */
057: public HtmlDocConsumer(File classDir, File docDir, String indexName)
058: throws GenerationException {
059: if (classDir == null) {
060: throw new GenerationException("Class directory is null");
061: }
062: if (!classDir.isDirectory()) {
063: throw new GenerationException(classDir.getAbsolutePath()
064: + " is not a directory");
065: }
066: if (docDir != null && !docDir.isDirectory()) {
067: throw new GenerationException(docDir.getAbsolutePath()
068: + " is not a directory");
069: }
070: this .classDir = classDir;
071: this .docDir = docDir;
072:
073: if (docDir != null) {
074: try {
075: indexWriter = new FileWriter(
076: new File(docDir, indexName));
077: indexWriter
078: .write("<HTML><BODY><H1>Generated classes</H1><TABLE border='1'><TR><TH>Class</TH><TH>Description</TH></TR>");
079: } catch (IOException e) {
080: throw new GenerationException(
081: "Cannot write index.html: " + e, e);
082: }
083: }
084: }
085:
086: private GenerationListener listener;
087:
088: public void consume(JavaClass javaClass) throws GenerationException {
089: try {
090: javaClass.dump(new File(classDir, javaClass.getClassName()
091: .replace('.', File.separatorChar)
092: + ".class"));
093: closeWriter(javaClass.getClassName());
094: } catch (IOException e) {
095: throw new GenerationException(
096: "Cannot save generated file: " + e, e);
097: }
098: }
099:
100: private void closeWriter(String className) {
101: Writer writer = (Writer) writerMap.remove(className);
102: if (writer != null) {
103: try {
104: writer.write("</BODY></HTML>");
105: writer.close();
106: } catch (IOException e) {
107: throw new DocumentingException(
108: "Cannot close documentation for class "
109: + className + ": " + e, e);
110: }
111: }
112: }
113:
114: public GenerationListener getListener() {
115: if (listener == null && docDir != null) {
116: listener = new GenerationListener() {
117:
118: public void onClass(ClassGen classGen,
119: String description) {
120: String className = classGen.getClassName();
121: try {
122: indexWriter.write("<TR><TD><a href='");
123: indexWriter.write(className);
124: indexWriter.write(".html'>");
125: indexWriter.write(className);
126: indexWriter.write("</a></TD><TD>");
127: writeEscaped(description, indexWriter);
128: indexWriter.write("</TD></TR>");
129:
130: Writer w = new FileWriter(new File(docDir,
131: className + ".html"));
132: writerMap.put(className, w);
133: w.write("<HTML><BODY><H1>");
134: w.write(className);
135: w.write("</H1>");
136: writeEscaped(description, w);
137: w
138: .write("<H2>Methods</H2><TABLE border='1'><TR><TH>Signature</TH><TH>Description</TH></TR>");
139: } catch (IOException e) {
140: throw new DocumentingException(
141: "Cannot document class " + className
142: + ": " + e, e);
143: }
144: }
145:
146: /**
147: * @param description
148: * @param indexWriter
149: * @throws IOException
150: */
151: private void writeEscaped(String description,
152: final Writer indexWriter) throws IOException {
153: StringTokenizer st = new StringTokenizer(
154: description, "<>", true);
155: while (st.hasMoreTokens()) {
156: String t = st.nextToken();
157: if ("<".equals(t)) {
158: indexWriter.write("<");
159: } else if (">".equals(t)) {
160: indexWriter.write(">");
161: } else {
162: indexWriter.write(t);
163: }
164: }
165: }
166:
167: public void onMethod(String className,
168: String signature, String description,
169: Properties attributes) {
170: Writer w = selectWriter(className);
171: try {
172: w.write("<TR><TD>");
173: w.write(signature);
174: w.write("</TD><TD>");
175: writeEscaped(description, w);
176: w.write("</TD>");
177: // Attributes ignored
178: } catch (IOException e) {
179: throw new DocumentingException(
180: "Cannot document method " + signature
181: + " in class " + className
182: + ": " + e, e);
183: }
184: }
185:
186: public void onField(String className, String signature,
187: String description, Properties attributes) {
188: Writer w = selectWriter(className);
189: try {
190: w.write("<TR><TD>");
191: w.write(signature);
192: w.write("</TD><TD>");
193: writeEscaped(description, w);
194: w.write("</TD>");
195: // Attributes ignored
196: } catch (IOException e) {
197: throw new DocumentingException(
198: "Cannot document method " + signature
199: + " in class " + className
200: + ": " + e, e);
201: }
202: }
203:
204: private Writer selectWriter(String className) {
205: return (Writer) writerMap.get(className);
206: }
207: };
208: }
209: return listener;
210: }
211:
212: /**
213: * Closes all files.
214: *
215: */
216: public void close() {
217: Iterator it = writerMap.keySet().iterator();
218: while (it.hasNext()) {
219: closeWriter((String) it.next());
220: }
221:
222: if (indexWriter != null) {
223: try {
224: indexWriter.write("</TABLE></BODY></HTML>");
225: indexWriter.close();
226: } catch (IOException e) {
227: throw new DocumentingException(
228: "Cannot close index file: " + e, e);
229: }
230: }
231: }
232:
233: }
|