001: package de.java2html.converter;
002:
003: import java.io.BufferedWriter;
004: import java.io.IOException;
005: import java.text.MessageFormat;
006:
007: import de.java2html.Version;
008: import de.java2html.javasource.JavaSource;
009: import de.java2html.javasource.JavaSourceIterator;
010: import de.java2html.javasource.JavaSourceRun;
011: import de.java2html.javasource.JavaSourceType;
012: import de.java2html.options.HorizontalAlignment;
013: import de.java2html.options.IHorizontalAlignmentVisitor;
014: import de.java2html.options.JavaSourceConversionOptions;
015: import de.java2html.options.JavaSourceStyleEntry;
016: import de.java2html.options.JavaSourceStyleTable;
017: import de.java2html.util.HtmlUtilities;
018: import de.java2html.util.StringHolder;
019:
020: /**
021: * Algorithm and stuff for converting a
022: * {@link de.java2html.javasource.JavaSource} object to to a HTML string
023: * representation.
024: *
025: * The result is XHTML1.0 Transitional compliant.
026: *
027: * For questions, suggestions, bug-reports, enhancement-requests etc. I may be
028: * contacted at: <a href="mailto:markus@jave.de">markus@jave.de</a>
029: *
030: * The Java2html home page is located at: <a href="http://www.java2html.de">
031: * http://www.java2html.de</a>
032: *
033: * @author <a href="mailto:markus@jave.de">Markus Gebhard</a>
034: *
035: * Copyright (C) Markus Gebhard 2000-2002
036: *
037: * This program is free software; you can redistribute it and/or modify it
038: * under the terms of the GNU General Public License as published by the Free
039: * Software Foundation; either version 2 of the License, or (at your option)
040: * any later version.
041: *
042: * This program is distributed in the hope that it will be useful, but WITHOUT
043: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
044: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
045: * more details.
046: *
047: * You should have received a copy of the GNU General Public License along with
048: * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
049: * Place - Suite 330, Boston, MA 02111-1307, USA.
050: */
051: public class JavaSource2HTMLConverter extends
052: AbstractJavaSourceConverter {
053: /**
054: * Flag indication whether html output contains a link to the
055: * Java2Html-Homepage or not.
056: *
057: * @deprecated As of Jan 2, 2004 (Markus Gebhard) replaced by
058: * {@link de.java2html.options.JavaSourceConversionOptions#setShowJava2HtmlLink(boolean)}
059: */
060: public static boolean java2HtmlHomepageLinkEnabled = false;
061:
062: /**
063: * Site header for a html page. Is not used by this class, but can be used
064: * from outside to add it to one or more converted
065: */
066: private final static String HTML_SITE_HEADER = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
067: // "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"
068: // \"http://www.w3.org/TR/html4/loose.dtd\">\n"
069: + "<html><head>\n"
070: + "<title>{0}</title>\n"
071: + " <style type=\"text/css\">\n"
072: + " <!--code '{' font-family: Courier New, Courier; font-size: 10pt; margin: 0px; '}'-->\n"
073: + " </style>\n"
074: + " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n"
075: + "</head><body>\n";
076:
077: /**
078: * Site footer for a html page. Is not used by this class, but can be used
079: * from outside to add it to one or more converted
080: */
081: private final static String HTML_SITE_FOOTER = "\n</body></html>";
082:
083: /** Block seperator for between two blocks of converted source code */
084: private final static String HTML_BLOCK_SEPARATOR = "<p />\n";
085:
086: /** HTML-Header for a block (!) of converted code */
087: private final static String HTML_BLOCK_HEADER = "\n\n"
088: + "<!-- ======================================================== -->\n"
089: + "<!-- = Java Sourcecode to HTML automatically converted code = -->\n"
090: + "<!-- = "
091: + Version.getJava2HtmlConverterTitle()
092: + " "
093: + Version.getBuildDate()
094: + " by Markus Gebhard markus@jave.de = -->\n"
095: + "<!-- = Further information: http://www.java2html.de = -->\n"
096: + "<div align=\"{0}\" class=\"java\">\n"
097: + "<table border=\"{1}\" cellpadding=\"3\" "
098: + "cellspacing=\"0\" bgcolor=\"{2}\">\n";
099:
100: /** HTML-code for before the headline */
101: private final static String HTML_HEAD_START = " <!-- start headline -->\n"
102: + " <tr>\n"
103: + " <td colspan=\"2\">\n"
104: + " <center><font size=\"+2\">\n" + " <code><b>\n";
105:
106: /** HTML-code for after the headline */
107: private final static String HTML_HEAD_END = " </b></code>\n"
108: + " </font></center>\n" + " </td>\n" + " </tr>\n"
109: + " <!-- end headline -->\n";
110:
111: /**
112: * HTML-code for before the second column (contaning the converted source
113: * code)
114: */
115: private final static String HTML_COL2_START = " <!-- start source code -->\n"
116: + " <td nowrap=\"nowrap\" valign=\"top\" align=\"left\">\n"
117: + " <code>\n";
118:
119: /**
120: * HTML-code for after the second column (contaning the converted source
121: * code)
122: */
123: private final static String HTML_COL2_END = "</code>\n" + " \n"
124: + " </td>\n" + " <!-- end source code -->\n";
125:
126: /**
127: * HTML-code for the bottom line (containing a little link to the
128: * java2html-homepage). Can be disabled by setting
129: * {@link #java2HtmlHomepageLinkEnabled}
130: */
131: private final static String HTML_LINK = " <!-- start Java2Html link -->\n"
132: + " <tr>\n"
133: + " <td align=\"right\">\n"
134: + "<small>\n"
135: + "<a href=\"http://www.java2html.de\" target=\"_blank\">Java2html</a>\n"
136: + "</small>\n"
137: + " </td>\n"
138: + " </tr>\n"
139: + " <!-- end Java2Html link -->\n";
140:
141: /** HTML-code for after the end of the block */
142: private final static String HTML_BLOCK_FOOTER =
143: //"\n"+ sieht schoener aus, wenn kein Zeilenumbruch mehr!
144: "</table>\n"
145: + "</div>\n"
146: + "<!-- = END of automatically generated HTML code = -->\n"
147: + "<!-- ======================================================== -->\n\n";
148:
149: /**
150: * The html representation of the colors used for different source
151: */
152:
153: private int lineCifferCount;
154:
155: public JavaSource2HTMLConverter() {
156: super (new ConverterMetaData("html",
157: "XHTML 1.0 Transitional (inlined fonts)", "html"));
158: }
159:
160: public String getDocumentHeader(
161: JavaSourceConversionOptions options, String title) {
162: if (title == null) {
163: title = ""; //$NON-NLS-1$
164: }
165: return MessageFormat.format(HTML_SITE_HEADER,
166: new Object[] { title });
167: }
168:
169: public String getDocumentFooter(JavaSourceConversionOptions options) {
170: return HTML_SITE_FOOTER;
171: }
172:
173: public String getBlockSeparator(JavaSourceConversionOptions options) {
174: return HTML_BLOCK_SEPARATOR;
175: }
176:
177: public void convert(JavaSource source,
178: JavaSourceConversionOptions options, BufferedWriter writer)
179: throws IOException {
180: if (source == null) {
181: throw new IllegalStateException(
182: "Trying to write out converted code without having source set.");
183: }
184:
185: //Header
186: String alignValue = getHtmlAlignValue(options
187: .getHorizontalAlignment());
188: String bgcolorValue = options.getStyleTable().get(
189: JavaSourceType.BACKGROUND).getHtmlColor();
190: String borderValue = options.isShowTableBorder() ? "2" : "0";
191:
192: writer
193: .write(MessageFormat.format(HTML_BLOCK_HEADER,
194: new Object[] { alignValue, borderValue,
195: bgcolorValue }));
196:
197: if (options.isShowFileName() && source.getFileName() != null) {
198: writeFileName(source, writer);
199: }
200:
201: writer.write(" <tr>");
202: writer.newLine();
203:
204: writeSourceCode(source, options, writer);
205:
206: writer.write(" </tr>");
207: writer.newLine();
208:
209: //5) Footer with link to web site
210: if (options.isShowJava2HtmlLink()
211: || java2HtmlHomepageLinkEnabled) {
212: writer.write(HTML_LINK);
213: }
214: writer.write(HTML_BLOCK_FOOTER);
215: }
216:
217: private String getHtmlAlignValue(HorizontalAlignment alignment) {
218: final StringHolder stringHolder = new StringHolder();
219: alignment.accept(new IHorizontalAlignmentVisitor() {
220: public void visitLeftAlignment(
221: HorizontalAlignment horizontalAlignment) {
222: stringHolder.setValue("left");
223: }
224:
225: public void visitRightAlignment(
226: HorizontalAlignment horizontalAlignment) {
227: stringHolder.setValue("right");
228: }
229:
230: public void visitCenterAlignment(
231: HorizontalAlignment horizontalAlignment) {
232: stringHolder.setValue("center");
233: }
234: });
235: return stringHolder.getValue();
236: }
237:
238: private void writeFileName(JavaSource source, BufferedWriter writer)
239: throws IOException {
240: writer.write(HTML_HEAD_START);
241: writer.write(source.getFileName());
242: writer.newLine();
243: writer.write(HTML_HEAD_END);
244: }
245:
246: private void writeSourceCode(JavaSource source,
247: JavaSourceConversionOptions options, BufferedWriter writer)
248: throws IOException {
249: writer.write(HTML_COL2_START);
250:
251: lineCifferCount = String.valueOf(source.getLineCount())
252: .length();
253:
254: JavaSourceIterator iterator = source.getIterator();
255: int lineNumber = 1;
256: while (iterator.hasNext()) {
257: JavaSourceRun run = iterator.getNext();
258:
259: if (run.isAtStartOfLine()) {
260: if (options.isAddLineAnchors()) {
261: writeLineAnchorStart(options, writer, lineNumber);
262: }
263: if (options.isShowLineNumbers()) {
264: writeLineNumber(options, writer, lineNumber);
265: }
266: if (options.isAddLineAnchors()) {
267: writeLineAnchorEnd(writer);
268: }
269: lineNumber++;
270: }
271:
272: toHTML(options.getStyleTable(), run, writer);
273: if (run.isAtEndOfLine() && iterator.hasNext()) {
274: writer.write("<br />");
275: writer.newLine();
276: }
277: }
278: writer.write(HTML_COL2_END);
279: }
280:
281: private void writeLineAnchorEnd(BufferedWriter writer)
282: throws IOException {
283: writer.write("</a>");
284: }
285:
286: private void writeLineAnchorStart(
287: JavaSourceConversionOptions options, BufferedWriter writer,
288: int lineNumber) throws IOException {
289: writer.write("<a name=\"");
290: writer.write(options.getLineAnchorPrefix() + lineNumber);
291: writer.write("\">");
292: }
293:
294: private void writeLineNumber(JavaSourceConversionOptions options,
295: BufferedWriter writer, int lineNo) throws IOException {
296: JavaSourceStyleEntry styleEntry = options.getStyleTable().get(
297: JavaSourceType.LINE_NUMBERS);
298: writeStyleStart(writer, styleEntry);
299:
300: String lineNumber = String.valueOf(lineNo);
301: int cifferCount = lineCifferCount - lineNumber.length();
302: while (cifferCount > 0) {
303: writer.write('0');
304: --cifferCount;
305: }
306:
307: writer.write(lineNumber);
308: writeStyleEnd(writer, styleEntry);
309: writer.write(" ");
310: }
311:
312: private void toHTML(JavaSourceStyleTable styleTable,
313: JavaSourceRun run, BufferedWriter writer)
314: throws IOException {
315: // result.append(htmlColors[sourceTypes[start]]);
316: JavaSourceStyleEntry style = styleTable.get(run.getType());
317:
318: writeStyleStart(writer, style);
319:
320: String t = HtmlUtilities.encode(run.getCode(), "\n ");
321:
322: for (int i = 0; i < t.length(); ++i) {
323: char ch = t.charAt(i);
324: if (ch == ' ') {
325: writer.write(" ");
326: } else {
327: writer.write(ch);
328: }
329: }
330:
331: writeStyleEnd(writer, style);
332: }
333:
334: private void writeStyleStart(BufferedWriter writer,
335: JavaSourceStyleEntry style) throws IOException {
336: writer.write("<font color=\"" + style.getHtmlColor() + "\">");
337: if (style.isBold()) {
338: writer.write("<b>");
339: }
340: if (style.isItalic()) {
341: writer.write("<i>");
342: }
343: }
344:
345: private void writeStyleEnd(BufferedWriter writer,
346: JavaSourceStyleEntry style) throws IOException {
347: if (style.isItalic()) {
348: writer.write("</i>");
349: }
350: if (style.isBold()) {
351: writer.write("</b>");
352: }
353: writer.write("</font>");
354: }
355: }
|