HTMLWriter.java revision 3170:dc017a37aac5
159191Skris/* 259191Skris * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 359191Skris * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 459191Skris * 559191Skris * This code is free software; you can redistribute it and/or modify it 659191Skris * under the terms of the GNU General Public License version 2 only, as 759191Skris * published by the Free Software Foundation. 859191Skris * 959191Skris * This code is distributed in the hope that it will be useful, but WITHOUT 1059191Skris * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1159191Skris * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1259191Skris * version 2 for more details (a copy is included in the LICENSE file that 1359191Skris * accompanied this code). 1459191Skris * 1559191Skris * You should have received a copy of the GNU General Public License version 1659191Skris * 2 along with this work; if not, write to the Free Software Foundation, 1759191Skris * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1859191Skris * 1959191Skris * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2059191Skris * or visit www.oracle.com if you need additional information or have any 2159191Skris * questions. 2259191Skris */ 2359191Skris 2459191Skrisimport java.io.BufferedWriter; 2559191Skrisimport java.io.File; 2659191Skrisimport java.io.IOException; 2759191Skrisimport java.io.Writer; 2859191Skrisimport java.net.URL; 2959191Skrisimport java.text.MessageFormat; 3059191Skrisimport java.util.ResourceBundle; 3159191Skris 3259191Skris/** 3359191Skris * A class to facilitate writing HTML via a stream. 3459191Skris */ 3559191Skrispublic class HTMLWriter 3659191Skris{ 3759191Skris /** 3859191Skris * Create an HTMLWriter object, using a default doctype for HTML 3.2. 3959191Skris * @param out a Writer to which to write the generated HTML 4059191Skris * @throws IOException if there is a problem writing to the underlying stream 4159191Skris */ 4259191Skris public HTMLWriter(Writer out) throws IOException { 4359191Skris this(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">"); 4459191Skris } 4559191Skris 4659191Skris /** 4759191Skris * Create an HTMLWriter object, using a specifed doctype header. 4859191Skris * @param out a Writer to which to write the generated HTML 4959191Skris * @param docType a string containing a doctype header for the HTML to be generetaed 5059191Skris * @throws IOException if there is a problem writing to the underlying stream 5159191Skris */ 5259191Skris public HTMLWriter(Writer out, String docType) throws IOException { 5359191Skris if (out instanceof BufferedWriter) 5459191Skris this.out = (BufferedWriter) out; 5559191Skris else 5659191Skris this.out = new BufferedWriter(out); 5759191Skris this.out.write(docType); 5859191Skris this.out.newLine(); 5959191Skris } 6059191Skris 6159191Skris /** 6259191Skris * Create an HTMLWriter object, using a specified bundle for localizing messages. 6359191Skris * @param out a Writer to which to write the generated HTML 6459191Skris * @param i18n a resource bundle to use to localize messages 6559191Skris * @throws IOException if there is a problem writing to the underlying stream 6659191Skris */ 6759191Skris public HTMLWriter(Writer out, ResourceBundle i18n) throws IOException { 6859191Skris this(out); 6959191Skris this.i18n = i18n; 7059191Skris } 7159191Skris 7259191Skris 7359191Skris /** 7459191Skris * Create an HTMLWriter object, using a specifed doctype header and 7559191Skris * using a specified bundle for l0calizing messages. 7659191Skris * @param out a Writer to which to write the generated HTML 7759191Skris * @param docType a string containing a doctype header for the HTML to be generetaed 7859191Skris * @param i18n a resource bundle to use to localize messages 7959191Skris * @throws IOException if there is a problem writing to the underlying stream 8059191Skris */ 8159191Skris public HTMLWriter(Writer out, String docType, ResourceBundle i18n) throws IOException { 8259191Skris this(out, docType); 8359191Skris this.i18n = i18n; 8459191Skris } 8559191Skris 8659191Skris /** 8759191Skris * Set the reource bundle to be used for localizing messages. 8859191Skris * @param i18n the resource bundle to be used for localizing messages 8959191Skris */ 9059191Skris public void setResourceBundle(ResourceBundle i18n) { 9159191Skris this.i18n = i18n; 9259191Skris } 9359191Skris 9459191Skris /** 9559191Skris * Flush the stream, and the underlying output stream. 9659191Skris * @throws IOException if there is a problem writing to the underlying stream 9759191Skris */ 9859191Skris public void flush() throws IOException { 9959191Skris out.flush(); 10059191Skris } 10159191Skris 10259191Skris /** 10359191Skris * Close the stream, and the underlying output stream. 10459191Skris * @throws IOException if there is a problem closing the underlying stream 10559191Skris */ 10659191Skris public void close() throws IOException { 10759191Skris out.close(); 10859191Skris } 10959191Skris 11059191Skris /** 11159191Skris * Write a newline to the underlying output stream. 11259191Skris * @throws IOException if there is a problem writing to the underlying stream 11359191Skris */ 11459191Skris public void newLine() throws IOException { 11559191Skris out.newLine(); 11659191Skris } 11759191Skris 11859191Skris /** 11959191Skris * Start an HTML tag. If a prior tag has been started, it will 12059191Skris * be closed first. Once a tag has been opened, attributes for the 12159191Skris * tag may be written out, followed by body content before finally 12259191Skris * ending the tag. 12359191Skris * @param tag the tag to be started 12459191Skris * @throws IOException if there is a problem writing to the underlying stream 12559191Skris * @see #writeAttr 12659191Skris * @see #write 12759191Skris * @see #endTag 12859191Skris */ 12959191Skris public void startTag(String tag) throws IOException { 13059191Skris if (state == IN_TAG) { 13159191Skris out.write(">"); 13259191Skris state = IN_BODY; 13359191Skris } 13459191Skris //newLine(); 13559191Skris out.write("<"); 13659191Skris out.write(tag); 13759191Skris state = IN_TAG; 13859191Skris } 13959191Skris 14059191Skris /** 14159191Skris * Finish an HTML tag. It is expected that a call to endTag will match 14259191Skris * a corresponding earlier call to startTag, but there is no formal check 14359191Skris * for this. 14459191Skris * @param tag the tag to be closed. 14559191Skris * @throws IOException if there is a problem writing to the underlying stream 14659191Skris */ 14759191Skris public void endTag(String tag) throws IOException { 14859191Skris if (state == IN_TAG) { 14959191Skris out.write(">"); 15059191Skris state = IN_BODY; 15159191Skris out.newLine(); 15259191Skris } 15359191Skris out.write("</"); 15459191Skris out.write(tag); 15559191Skris out.write(">"); 15659191Skris //out.newLine(); // PATCHED, jjg 15759191Skris state = IN_BODY; 15859191Skris } 15959191Skris 16059191Skris /** 16159191Skris * Finish an empty element tag, such as a META, BASE or LINK tag. 16259191Skris * This is expected to correspond with a startTag. 16359191Skris * @param tag the tag which is being closed. this is only useful for 16459191Skris * validation, it is not written out 16559191Skris * @throws IllegalStateException if this call does not follow startTag 16659191Skris * (stream is not currently inside a tag) 16759191Skris * @throws IOException if there is a problem writing to the underlying stream 16859191Skris */ 16959191Skris public void endEmptyTag(String tag) throws IOException { 17059191Skris if (state != IN_TAG) 17159191Skris throw new IllegalStateException(); 17259191Skris 17359191Skris out.write(">"); 17459191Skris state = IN_BODY; 17559191Skris out.newLine(); 17659191Skris } 17759191Skris 17859191Skris /** 17959191Skris * Write an attribute for a tag. A tag must previously have been started. 18059191Skris * All tag attributes must be written before any body text is written. 18159191Skris * The value will be quoted if necessary when writing it to the underlying 18259191Skris * stream. No check is made that the attribute is valid for the current tag. 18359191Skris * @param name the name of the attribute to be written 18459191Skris * @param value the value of the attribute to be written 18559191Skris * @throws IllegalStateException if the stream is not in a state to 18659191Skris * write attributes -- e.g. if this call does not follow startTag or other 18759191Skris * calls of writteAttr 18859191Skris * @throws IOException if there is a problem writing to the underlying stream 18959191Skris */ 19059191Skris public void writeAttr(String name, String value) throws IOException { 19159191Skris if (state != IN_TAG) 19259191Skris throw new IllegalStateException(); 19359191Skris 19459191Skris out.write(" "); 19559191Skris out.write(name); 19659191Skris out.write("="); 19759191Skris boolean alpha = true; 19859191Skris for (int i = 0; i < value.length() && alpha; i++) 19959191Skris alpha = Character.isLetter(value.charAt(i)); 20059191Skris if (!alpha) 20159191Skris out.write("\""); 20259191Skris out.write(value); 20359191Skris if (!alpha) 20459191Skris out.write("\""); 20559191Skris } 20659191Skris 20759191Skris /** 20859191Skris * Write an attribute for a tag. A tag must previously have been started. 20959191Skris * All tag attributes must be written before any body text is written. 21059191Skris * The value will be quoted if necessary when writing it to the underlying 21159191Skris * stream. No check is made that the attribute is valid for the current tag. 21259191Skris * @param name the name of the attribute to be written 21359191Skris * @param value the value of the attribute to be written 21459191Skris * @throws IllegalStateException if the stream is not in a state to 21559191Skris * write attributes -- e.g. if this call does not follow startTag or other 21659191Skris * calls of writteAttr 21759191Skris * @throws IOException if there is a problem writing to the underlying stream 21859191Skris */ 21959191Skris public void writeAttr(String name, int value) throws IOException { 22059191Skris writeAttr(name, Integer.toString(value)); 22159191Skris } 22259191Skris 22359191Skris /** 22459191Skris * Write a line of text, followed by a newline. 22559191Skris * The text will be escaped as necessary. 22659191Skris * @param text the text to be written. 22759191Skris * @throws IOException if there is a problem closing the underlying stream 22859191Skris */ 22959191Skris public void writeLine(String text) throws IOException { 23059191Skris write(text); 23159191Skris out.newLine(); 23259191Skris } 23359191Skris 23459191Skris /** 23559191Skris * Write body text, escaping it as necessary. 23659191Skris * If this call follows a call of startTag, the open tag will be 23759191Skris * closed -- meaning that no more attributes can be written until another 23859191Skris * tag is started. If the text value is null, the current tag will still 23959191Skris * be closed, but no other text will be written. 24059191Skris * @param text the text to be written, may be null or zero length. 24159191Skris * @throws IOException if there is a problem writing to the underlying stream 24259191Skris */ 24359191Skris public void write(String text) throws IOException { 24459191Skris if (state == IN_TAG) { 24559191Skris out.write(">"); 24659191Skris state = IN_BODY; 24759191Skris } 24859191Skris 24959191Skris if (text == null) 25059191Skris return; 25159191Skris 25259191Skris // check to see if there are any special characters 25359191Skris boolean specialChars = false; 25459191Skris for (int i = 0; i < text.length() && !specialChars; i++) { 25559191Skris switch (text.charAt(i)) { 25659191Skris case '<': case '>': case '&': 25759191Skris specialChars = true; 25859191Skris } 25959191Skris } 26059191Skris 26159191Skris // if there are special characters write the string character at a time; 26259191Skris // otherwise, write it out as is 26359191Skris if (specialChars) { 26459191Skris for (int i = 0; i < text.length(); i++) { 26559191Skris char c = text.charAt(i); 26659191Skris switch (c) { 26759191Skris case '<': out.write("<"); break; 26859191Skris case '>': out.write(">"); break; 26959191Skris case '&': out.write("&"); break; 27059191Skris default: out.write(c); 27159191Skris } 27259191Skris } 27359191Skris } 27459191Skris else 27559191Skris out.write(text); 27659191Skris } 27759191Skris 27859191Skris /** 27959191Skris * Write a basic HTML entity, such as or { . 28059191Skris * @param entity the entity to write 28159191Skris * @throws IOException if there is a problem writing to the underlying stream 28259191Skris */ 28359191Skris public void writeEntity(String entity) throws IOException { 28459191Skris if (state == IN_TAG) { 28559191Skris out.write(">"); 28659191Skris state = IN_BODY; 28759191Skris } 28859191Skris out.write(entity); 28959191Skris } 29059191Skris 29159191Skris /** 29259191Skris * Write an image tag, using a specified path for the image source attribute. 29359191Skris * @param imagePath the path for the image source 29459191Skris * @throws IOException if there is a problem closing the underlying stream 29559191Skris */ 29659191Skris public void writeImage(String imagePath) throws IOException { 29759191Skris startTag(IMAGE); 29859191Skris writeAttr(SRC, imagePath); 29959191Skris } 30059191Skris 30159191Skris /** 30259191Skris * Write an image tag, using a specified path for the image source attribute. 30359191Skris * @param imageURL the url for the image source 30459191Skris * @throws IOException if there is a problem closing the underlying stream 30559191Skris */ 30659191Skris public void writeImage(URL imageURL) throws IOException { 30759191Skris writeImage(imageURL.toString()); 30859191Skris } 30959191Skris 31059191Skris /** 31159191Skris * Write a hypertext link. 31259191Skris * @param anchor the target for the link 31359191Skris * @param body the body text for the link 31459191Skris * @throws IOException if there is a problem closing the underlying stream 31559191Skris */ 31659191Skris public void writeLink(String anchor, String body) throws IOException { 31759191Skris startTag(A); 31859191Skris writeAttr(HREF, anchor); 31959191Skris write(body); 32059191Skris endTag(A); 32159191Skris } 32259191Skris 32359191Skris /** 32459191Skris * Write a hypertext link. 32559191Skris * @param file the target for the link 32659191Skris * @param body the body text for the link 32759191Skris * @throws IOException if there is a problem closing the underlying stream 32859191Skris */ 32959191Skris public void writeLink(File file, String body) throws IOException { 33059191Skris startTag(A); 33159191Skris StringBuffer sb = new StringBuffer(); 33259191Skris String path = file.getPath().replace(File.separatorChar, '/'); 33359191Skris if (file.isAbsolute() && !path.startsWith("/")) 33459191Skris sb.append('/'); 33559191Skris sb.append(path); 33659191Skris writeAttr(HREF, sb.toString()); 33759191Skris write(body); 33859191Skris endTag(A); 33959191Skris } 34059191Skris 34159191Skris /** 34259191Skris * Write a hypertext link. 34359191Skris * @param file the target and body for the link 34459191Skris * @throws IOException if there is a problem closing the underlying stream 34559191Skris */ 34659191Skris public void writeLink(File file) throws IOException { 34759191Skris writeLink(file, file.getPath()); 34859191Skris } 34959191Skris 35059191Skris /** 35159191Skris * Write a hypertext link. 35259191Skris * @param url the target for the link 35359191Skris * @param body the body text for the link 35459191Skris * @throws IOException if there is a problem closing the underlying stream 35559191Skris */ 35659191Skris public void writeLink(URL url, String body) throws IOException { 35759191Skris startTag(A); 35859191Skris writeAttr(HREF, url.toString()); 35959191Skris write(body); 36059191Skris endTag(A); 36159191Skris } 36259191Skris 36359191Skris /** 36459191Skris * Write the destination marker for a hypertext link. 36559191Skris * @param anchor the destination marker for hypertext links 36659191Skris * @param body the body text for the marker 36759191Skris * @throws IOException if there is a problem closing the underlying stream 36859191Skris */ 36959191Skris public void writeLinkDestination(String anchor, String body) throws IOException { 37059191Skris startTag(A); 37159191Skris writeAttr(NAME, anchor); 37259191Skris write(body); 37359191Skris endTag(A); 37459191Skris } 37559191Skris 37659191Skris /** 37759191Skris * Write a parameter tag. 37859191Skris * @param name the name of the parameter 37959191Skris * @param value the value of the parameter 38059191Skris * @throws IOException if there is a problem closing the underlying stream 38159191Skris */ 38259191Skris public void writeParam(String name, String value) throws IOException { 38359191Skris startTag(PARAM); 38459191Skris writeAttr(NAME, name); 38559191Skris writeAttr(VALUE, value); 38659191Skris } 38759191Skris 38859191Skris /** 38959191Skris * Write a style attribute. 39059191Skris * @param value the value for the style atrtribute 39159191Skris * @throws IOException if there is a problem closing the underlying stream 39259191Skris */ 39359191Skris public void writeStyleAttr(String value) throws IOException { 39459191Skris writeAttr(STYLE, value); 39559191Skris } 39659191Skris 39759191Skris /** 39859191Skris * Write a localized message, using a specified resource bundle. 39959191Skris * @param i18n the resource bundle used to localize the message 40059191Skris * @param key the key for the message to be localized 40159191Skris * @throws IOException if there is a problem closing the underlying stream 40259191Skris */ 40359191Skris public void write(ResourceBundle i18n, String key) throws IOException { 40459191Skris write(getString(i18n, key)); 40559191Skris } 40659191Skris 40759191Skris /** 40859191Skris * Write a localized message, using a specified resource bundle. 40959191Skris * @param i18n the resource bundle used to localize the message 41059191Skris * @param key the key for the message to be localized 41159191Skris * @param arg an argument to be formatted into the localized message 41259191Skris * @throws IOException if there is a problem closing the underlying stream 41359191Skris */ 41459191Skris public void write(ResourceBundle i18n, String key, Object arg) throws IOException { 41559191Skris write(getString(i18n, key, arg)); 41659191Skris } 41759191Skris 41859191Skris /** 419100936Snectar * Write a localized message, using a specified resource bundle. 420100936Snectar * @param i18n the resource bundle used to localize the message 42159191Skris * @param key the key for the message to be localized 42259191Skris * @param args arguments to be formatted into the localized message 42359191Skris * @throws IOException if there is a problem closing the underlying stream 42459191Skris */ 42559191Skris public void write(ResourceBundle i18n, String key, Object[] args) throws IOException { 42659191Skris write(getString(i18n, key, args)); 42759191Skris } 42859191Skris 42959191Skris /** 43059191Skris * Write a localized message, using the default resource bundle. 43159191Skris * @param key the key for the message to be localized 43259191Skris * @throws IOException if there is a problem closing the underlying stream 43359191Skris */ 43459191Skris public void writeI18N(String key) throws IOException { 43559191Skris write(getString(i18n, key)); 43659191Skris } 43759191Skris 43859191Skris /** 43959191Skris * Write a localized message, using the default resource bundle. 44059191Skris * @param key the key for the message to be localized 44159191Skris * @param arg an argument to be formatted into the localized message 44259191Skris * @throws IOException if there is a problem closing the underlying stream 44359191Skris */ 44459191Skris public void writeI18N(String key, Object arg) throws IOException { 44559191Skris write(getString(i18n, key, arg)); 44659191Skris } 44759191Skris 44859191Skris /** 44959191Skris * Write a localized message, using the default resource bundle. 45059191Skris * @param key the key for the message to be localized 45159191Skris * @param args arguments to be formatted into the localized message 45259191Skris * @throws IOException if there is a problem closing the underlying stream 45359191Skris */ 45459191Skris public void writeI18N(String key, Object[] args) throws IOException { 45559191Skris write(getString(i18n, key, args)); 45659191Skris } 45759191Skris 45859191Skris private String getString(ResourceBundle rb, String key, Object... args) { 45959191Skris String s = rb.getString(key); 46059191Skris return MessageFormat.format(s, args); 46159191Skris } 46259191Skris 46359191Skris /** The HTML "a" tag. */ 46459191Skris public static final String A = "a"; 46559191Skris /** The HTML "align" attribute. */ 46659191Skris public static final String ALIGN = "align"; 46759191Skris /** The HTML "b" tag. */ 46859191Skris public static final String B = "b"; 46959191Skris /** The HTML "body" tag. */ 47059191Skris public static final String BODY = "body"; 47159191Skris /** The HTML "border" attribute. */ 47259191Skris public static final String BORDER = "border"; 47359191Skris /** The HTML "br" tag. */ 47459191Skris public static final String BR = "br"; 47559191Skris /** The HTML "class" attribute. */ 47659191Skris public static final String CLASS = "class"; 47759191Skris /** The HTML "classid" attribute. */ 47859191Skris public static final String CLASSID = "classid"; 47959191Skris /** The HTML "code" tag. */ 48059191Skris public static final String CODE = "code"; 48159191Skris /** The HTML "color" attribte. */ 48259191Skris public static final String COLOR = "color"; 48359191Skris /** The HTML "col" attribute value. */ 48459191Skris public static final String COL = "col"; 48559191Skris /** The HTML "dd" tag. */ 48659191Skris public static final String DD = "dd"; 48759191Skris /** The HTML "div" tag. */ 48859191Skris public static final String DIV = "div"; 48959191Skris /** The HTML "dl" tag. */ 49059191Skris public static final String DL = "dl"; 49159191Skris /** The HTML "dt" tag. */ 49259191Skris public static final String DT = "dt"; 49359191Skris /** The HTML "font" tag. */ 49459191Skris public static final String FONT = "font"; 49559191Skris /** The HTML "h1" tag. */ 49659191Skris public static final String H1 = "h1"; 49759191Skris /** The HTML "h2" tag. */ 49859191Skris public static final String H2 = "h2"; 49959191Skris /** The HTML "h3" tag. */ 50059191Skris public static final String H3 = "h3"; 50159191Skris /** The HTML "h4" tag. */ 50259191Skris public static final String H4 = "h4"; 50359191Skris /** The HTML "h5" tag. */ 50459191Skris public static final String H5 = "h5"; 50559191Skris /** The HTML "head" tag. */ 50659191Skris public static final String HEAD = "head"; 50759191Skris /** The HTML "href" attribute. */ 50859191Skris public static final String HREF = "href"; 50959191Skris /** The HTML "html" tag. */ 51059191Skris public static final String HTML = "html"; 51159191Skris /** The HTML "hr" tag. */ 51259191Skris public static final String HR = "hr"; 51359191Skris /** The HTML "i" tag. */ 51459191Skris public static final String I = "i"; 51559191Skris /** The HTML "id" tag. */ 51659191Skris public static final String ID = "id"; 51759191Skris /** The HTML "image" tag. */ 51859191Skris public static final String IMAGE = "image"; 51959191Skris /** The HTML "left" attribute value. */ 52059191Skris public static final String LEFT = "left"; 52159191Skris /** The HTML "li" tag. */ 52259191Skris public static final String LI = "li"; 52359191Skris /** The HTML "link" tag. */ 52459191Skris public static final String LINK = "link"; 52559191Skris /** The HTML "name" attribute. */ 52659191Skris public static final String NAME = "name"; 52759191Skris /** The HTML "object" tag. */ 52859191Skris public static final String OBJECT = "object"; 52959191Skris /** The HTML "p" tag. */ 53059191Skris public static final String PARAM = "param"; 53159191Skris /** The HTML "param" tag. */ 53259191Skris public static final String P = "p"; 53359191Skris /** The HTML "rel" attribute value. */ 53459191Skris public static final String REL = "rel"; 53559191Skris /** The HTML "right" attribute value. */ 53659191Skris public static final String RIGHT = "right"; 53759191Skris /** The HTML "row" attribute value. */ 53859191Skris public static final String ROW = "row"; 53959191Skris /** The HTML "script" tag. */ 54059191Skris public static final String SCRIPT = "script"; 54159191Skris /** The HTML "small" tag. */ 54259191Skris public static final String SMALL = "small"; 54359191Skris /** The HTML "span" tag. */ 54459191Skris public static final String SPAN = "span"; 54559191Skris /** The HTML "src" attribute. */ 54659191Skris public static final String SRC = "src"; 54759191Skris /** The HTML "scope" attribute. */ 54859191Skris public static final String SCOPE = "scope"; 54959191Skris /** The HTML "style" attribute. */ 55059191Skris public static final String STYLE = "style"; 55159191Skris /** The HTML "table" tag. */ 55259191Skris public static final String TABLE = "table"; 55359191Skris /** The HTML "td" tag. */ 55459191Skris public static final String TD = "td"; 55559191Skris /** The HTML type for JavaScript. */ 55659191Skris public static final String TEXT_JAVASCRIPT = "text/javascript"; 55759191Skris /** The HTML "title"attribute. */ 55859191Skris public static final String TITLE = "title"; 55959191Skris /** The HTML "th" tag. */ 56059191Skris public static final String TH = "th"; 56159191Skris /** The HTML "top" attribute value. */ 56259191Skris public static final String TOP = "top"; 56359191Skris /** The HTML "tr" tag. */ 56459191Skris public static final String TR = "tr"; 56559191Skris /** The HTML "type" attribute. */ 56659191Skris public static final String TYPE = "type"; 56759191Skris /** The HTML "ul" tag. */ 56859191Skris public static final String UL = "ul"; 56959191Skris /** The HTML "valign" attribute. */ 57059191Skris public static final String VALIGN = "valign"; 57159191Skris /** The HTML "value" attribute. */ 57259191Skris public static final String VALUE = "value"; 57359191Skris 57459191Skris 57559191Skris private BufferedWriter out; 57659191Skris private int state; 57759191Skris private ResourceBundle i18n; 57859191Skris private static final int IN_TAG = 1; 57959191Skris private static final int IN_BODY = 2; 58059191Skris} 58159191Skris