KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ditchnet > jsp > util > JspResponseWriter


1 /*
2  * The contents of this file are subject to the GNU Lesser General Public
3  * License Version 2.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.gnu.org/copyleft/lesser.html
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * Developer:
13  * Todd Ditchendorf, todd@ditchnet.org
14  *
15  */

16
17 /**
18  * @author Todd Ditchendorf
19  * @since 2005-03-11
20  *
21  */

22
23 package org.ditchnet.jsp.util;
24
25 import java.io.Writer JavaDoc;
26 import java.io.StringWriter JavaDoc;
27 import org.ditchnet.xml.Xml;
28
29 /**
30  * A JSP-specific XML writing utility class meant to be used as an output
31  * buffer in a JSP tag handler subclass of
32  * {@link javax.servlet.jsp.tagext.SimpleTag}. This class should not be viewed
33  * as a general purpose XML writing utility class as several of it's methods
34  * make assumptions about the formatting of
35  * the output that make it's use in a JSP tag handler class more natural.
36  * Note that this class is not thread safe.
37  *
38  * @author Todd Ditchendorf
39  * @version 0.8
40  */

41 public final class JspResponseWriter {
42
43     private static final String JavaDoc LT = "<";
44     private static final String JavaDoc GT = ">";
45     private static final String JavaDoc COLON = ":";
46     private static final String JavaDoc SPACE = " ";
47     private static final String JavaDoc EQUALS = "=";
48     private static final String JavaDoc TAB_STOP = "\t";
49     private static final String JavaDoc LINE_BREAK = "\n";
50     private static final String JavaDoc SINGLE_QUOTE = "'";
51     private static final String JavaDoc DOUBLE_QUOTE = "\"";
52     private static final String JavaDoc OPEN_COMMENT = "<!-- ";
53     private static final String JavaDoc CLOSE_COMMENT = " -->";
54     private static final String JavaDoc FORWARD_SLASH = "/";
55
56     private StringWriter JavaDoc out = new StringWriter JavaDoc();
57
58     private boolean prettyPrinting = true;
59
60     private int tagDepth;
61     private volatile boolean elementTagIsOpen;
62     private volatile boolean elementIsEmpty;
63
64     /**
65      * Defualt constructor -- Sets pretty printing to 'on'.
66      *
67      */

68     public JspResponseWriter() {
69         this(true);
70     }
71     
72     /**
73      * Allows instanciating this writer with pretty printing turned off.
74      */

75     public JspResponseWriter(final boolean prettyPrinting) {
76         setPrettyPrinting(prettyPrinting);
77     }
78
79     /**
80      *
81      */

82     public StringBuffer JavaDoc getBuffer() {
83         return out.getBuffer();
84     }
85     
86     public Writer JavaDoc getWriter() {
87         return out;
88     }
89     
90     /**
91      * Set this writer to include line breaks and tabstops in the output
92      * for easier human-readable markup.
93      */

94     public void setPrettyPrinting(final boolean prettyPrinting) {
95         this.prettyPrinting = prettyPrinting;
96     }
97     
98     /**
99      * Check for pretty printing setting.
100      */

101     public boolean isPrettyPrinting() {
102         return prettyPrinting;
103     }
104     
105     private void prettyPrint() {
106         if (!isPrettyPrinting()) {
107             return;
108         }
109         lineBreak();
110         for (int i = 0; i < tagDepth; i++) {
111             tabStop();
112         }
113         tagDepth++;
114     }
115     
116     public void tabStop() {
117         closeOpenTagIfNecessary();
118         out.write(TAB_STOP);
119         elementIsEmpty = false;
120     }
121     
122     /**
123      * Start an XML element with a qualified name, up to and including the
124      * element name. Once this method has been called, clients can
125      * call the <code>writeAttribute()</code> or
126      * methods to add attributes and
127      * corresponding values. The starting element will be closed
128      * (that is, the trailing '>' character added)
129      * on any subsequent call to <code>startElement()</code>,
130      * <code>comment()</code>, lineBreak(),
131      * <code>text()</code>, <code>endElement()</code></p>
132      */

133     public void startElement(Xml.Tag qName) {
134         _startElement(qName.toString());
135     }
136     
137     /**
138      * Start an XML element with a namespace prefix and a localName.
139      */

140     public void startElement(String JavaDoc prefix, Xml.Tag localName) {
141         _startElement(prefix + COLON + localName);
142     }
143     
144     private void _startElement(final String JavaDoc name) {
145         closeOpenTagIfNecessary();
146         prettyPrint();
147         out.write(LT);
148         out.write(name);
149         elementTagIsOpen = true;
150         elementIsEmpty = true;
151     }
152     
153     /**
154      * End an XML element with a qualified name.
155      */

156     public void endElement(Xml.Tag qName) {
157         _endElement(qName.toString());
158     }
159     
160     /**
161      * End an XML element with a namespace prefix and a localName.
162      */

163     public void endElement(String JavaDoc prefix, Xml.Tag localName) {
164         _endElement(prefix + COLON + localName);
165     }
166     
167     private void _endElement(final String JavaDoc name) {
168         if (elementIsEmpty) {
169             out.write(SPACE);
170             out.write(FORWARD_SLASH);
171             out.write(GT);
172             elementIsEmpty = false;
173         } else {
174             if (isPrettyPrinting()) {
175                 lineBreak();
176             }
177             out.write(LT);
178             out.write(FORWARD_SLASH);
179             out.write(name);
180             out.write(GT);
181         }
182         elementTagIsOpen = false;
183         tagDepth--;
184     }
185     
186     /**
187      * This method exists for the convenience of the JSP author in manually
188      * controlling the pretty printing of the buffered output.
189      */

190     public void lineBreak() {
191         closeOpenTagIfNecessary();
192         out.write(LINE_BREAK);
193         elementIsEmpty = false;
194     }
195     
196     /**
197      * Write an attribute with qualified name and corresponding value.
198      * This method may only
199      * be called after a call to <code>startElement()</code>, and before the
200      * element has been closed.
201      *
202      * @exception <code>NullPointerException</code>
203      * @exception <code>IllegalStateException</code> if no element tag is
204      * currently open
205      */

206     public void attribute(Xml.Attr qName, String JavaDoc value) {
207         _attribute(qName.toString(),value);
208     }
209     
210     /**
211      * Write an attribute with this namespace prefix, and local name
212      * corresponding values. This method may only
213      * be called after a call to <code>startElement()</code>, and before the
214      * element has been closed.
215      *
216      * @exception <code>NullPointerException</code>
217      * @exception <code>IllegalStateException</code> if no element tag is
218      * currently open
219      */

220     public void attribute(String JavaDoc prefix, Xml.Attr localName, String JavaDoc value) {
221         _attribute(prefix + localName.toString(), value);
222     }
223     
224     private void _attribute(String JavaDoc qName, String JavaDoc value) {
225         if (!elementTagIsOpen) {
226             throw new IllegalStateException JavaDoc("Attempting to write attribute " +
227                                             " with no open element tag");
228         }
229         if (null == qName) {
230             throw new NullPointerException JavaDoc("Attempting to write attribute " +
231                                            " with no name");
232         }
233         out.write(SPACE);
234         out.write(qName);
235         out.write(EQUALS);
236         out.write(DOUBLE_QUOTE);
237         out.write(value);
238         out.write(DOUBLE_QUOTE);
239     }
240     
241     /**
242      * <p>Write an object, after converting it to a String (if necessary),
243      * and after performing any escaping appropriate for the markup language
244      * being rendered. If there is an open element that has been created
245      * by a call to <code>startElement()</code>, that element will be closed
246      * first.</p>
247      *
248      * @param text Text to be written
249      *
250      * @exception NullPointerException if <code>text</code>
251      * is <code>null</code>
252      */

253     public void text(Object JavaDoc text) {
254         if (null == text) {
255             throw new NullPointerException JavaDoc("Attempting to write null text");
256         }
257         closeOpenTagIfNecessary();
258         out.write(text.toString());
259         elementIsEmpty = false;
260     }
261     
262     /**
263      * <p>Write a comment containing the specified text, after converting
264      * that text to a String (if necessary), and after performing any escaping
265      * appropriate for the markup language being rendered. If there is
266      * an open element that has been created by a call to
267      * <code>startElement()</code>, that element will be closed first.</p>
268      *
269      * @param comment Text content of the comment
270      *
271      * @exception NullPointerException if <code>comment</code>
272      * is <code>null</code>
273      */

274     public void comment(Object JavaDoc comment) {
275         if (null == comment) {
276             throw new NullPointerException JavaDoc("Attempting to write null comment");
277         }
278         closeOpenTagIfNecessary();
279         out.write(OPEN_COMMENT);
280         out.write(comment.toString());
281         out.write(CLOSE_COMMENT);
282     }
283     
284     private void closeOpenTagIfNecessary() {
285         if (elementTagIsOpen) {
286             out.write(GT);
287             elementTagIsOpen = false;
288         }
289     }
290
291 }
292
293
Popular Tags