001: /*
002: * Copyright (c) 1998-2004 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Sam
027: */
028:
029: package com.caucho.widget;
030:
031: import com.caucho.portal.generic.FastPrintWriter;
032: import com.caucho.util.L10N;
033:
034: import java.io.IOException;
035: import java.io.Writer;
036: import java.util.logging.Logger;
037:
038: public class WidgetWriter extends FastPrintWriter {
039: private static L10N L = new L10N(WidgetWriter.class);
040:
041: static protected final Logger log = Logger
042: .getLogger(WidgetWriter.class.getName());
043:
044: private boolean _isCompact;
045: private boolean _closeElementNeeded;
046: private boolean _closeElementNewline;
047:
048: public WidgetWriter(Writer writer) throws IOException {
049: super (writer);
050: }
051:
052: /**
053: * If true do not print unnecessary newlines, default false.
054: */
055: public void setCompact(boolean compact) {
056: _isCompact = compact;
057: }
058:
059: /**
060: * Write the '%gt;' of an element if needed, but do not flush the underlying
061: * writer.
062: */
063: public void flush() {
064: closeElementIfNeeded();
065: }
066:
067: public void startElement(String name) throws IOException {
068: startElement(name, false);
069: }
070:
071: /**
072: * @param name the name of the element
073: * @param newline write a newline after starting the element, unless
074: * compact rendering has been set.
075: */
076: public void startElement(String name, boolean newline)
077: throws IOException {
078: closeElementIfNeeded();
079:
080: write('<');
081: write(name);
082:
083: _closeElementNeeded = true;
084: _closeElementNewline = newline;
085: }
086:
087: public void writeAttribute(String name, Object value)
088: throws IOException {
089: write(' ');
090: writeEscaped(name);
091: write("=\"");
092:
093: writeEscaped(value);
094: write('\"');
095: }
096:
097: public void writeAttribute(String name, WidgetURL url)
098: throws IOException {
099: write(' ');
100: write(name);
101: write("=\"");
102:
103: write(url.toString());
104: write('\"');
105: }
106:
107: public void writeComment(Object comment) throws IOException {
108: closeElementIfNeeded();
109:
110: write("<!--");
111: writeEscaped(comment.toString());
112: write("-->");
113: }
114:
115: /**
116: * Write the toString() of the object, escaping as needed
117: */
118: public void writeText(Object object) throws IOException {
119: closeElementIfNeeded();
120:
121: String string = object.toString();
122: int len = string.length();
123:
124: for (int i = 0; i < len; i++) {
125: writeEscaped(string.charAt(i));
126: }
127: }
128:
129: /**
130: * Write the char[], escaping as needed
131: */
132: public void writeText(char buf[]) throws IOException {
133: closeElementIfNeeded();
134:
135: int endIndex = buf.length;
136:
137: for (int i = 0; i < endIndex; i++) {
138: writeEscaped(buf[i]);
139: }
140: }
141:
142: /**
143: * Write the char[], escaping as needed
144: */
145: public void writeText(char buf[], int offset, int length)
146: throws IOException {
147: closeElementIfNeeded();
148:
149: int endIndex = offset + length;
150:
151: for (int i = offset; i < endIndex; i++) {
152: writeEscaped(buf[i]);
153: }
154: }
155:
156: public void writeText(char ch) throws IOException {
157: closeElementIfNeeded();
158:
159: writeEscaped(ch);
160: }
161:
162: public void endElement(String name) throws IOException {
163: endElement(name, false);
164: }
165:
166: /**
167: * @param name the name of the element
168: * @param newline write a newline after closing the element, unless
169: * compact rendering has been set
170: */
171: public void endElement(String name, boolean newline)
172: throws IOException {
173: closeElementIfNeeded();
174:
175: write("</");
176: write(name);
177: write(">");
178:
179: if (newline)
180: printlnUnlessCompact();
181: }
182:
183: public void close() {
184: closeElementIfNeeded();
185:
186: super .close();
187: }
188:
189: protected void closeElementIfNeeded() {
190: if (_closeElementNeeded) {
191: _closeElementNeeded = false;
192: write('>');
193:
194: if (_closeElementNewline) {
195: printlnUnlessCompact();
196: _closeElementNewline = false;
197: }
198: }
199: }
200:
201: private void printlnUnlessCompact() {
202: if (!_isCompact)
203: println();
204: }
205:
206: private void writeEscaped(Object object) throws IOException {
207: String string = object.toString();
208:
209: int len = string.length();
210:
211: for (int i = 0; i < len; i++) {
212: writeEscaped(string.charAt(i));
213: }
214: }
215:
216: private void writeEscaped(char ch) throws IOException {
217: switch (ch) {
218: case '<':
219: write("<");
220: break;
221: case '>':
222: write(">");
223: break;
224: case '&':
225: write("&");
226: break;
227: case '\"':
228: write(""");
229: break;
230: case '\'':
231: write("’");
232: break;
233: default:
234: write(ch);
235: }
236: }
237: }
|