001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry;
016
017 import org.apache.tapestry.markup.Attribute;
018
019 /**
020 * Defines an object that can write markup (XML, HTML, XHTML) style output. A
021 * <code>IMarkupWriter</code> handles translation from unicode to the markup language (escaping
022 * characters such as '<' and '>' to their entity equivalents, '&lt;' and '&gt;') as
023 * well as assisting with nested elements, closing tags, etc.
024 *
025 * @author Howard Ship, David Solis
026 */
027
028 public interface IMarkupWriter
029 {
030 /**
031 * Writes an integer attribute into the currently open tag.
032 *
033 * @throws IllegalStateException
034 * if there is no open tag.
035 */
036
037 void attribute(String name, int value);
038
039 /**
040 * Writes a boolean attribute into the currently open tag.
041 *
042 * @throws IllegalStateException
043 * if there is no open tag.
044 * @since 3.0
045 */
046
047 void attribute(String name, boolean value);
048
049 /**
050 * Writes an attribute into the most recently opened tag. This must be called after
051 * {@link #begin(String)}and before any other kind of writing (which closes the tag).
052 * <p>
053 * The value may be null.
054 *
055 * @throws IllegalStateException
056 * if there is no open tag.
057 */
058
059 void attribute(String name, String value);
060
061 /**
062 * Similar to {@link #attribute(String, String)}but no escaping of invalid elements is done for
063 * the value.
064 *
065 * @throws IllegalStateException
066 * if there is no open tag.
067 * @since 3.0
068 */
069
070 void attributeRaw(String name, String value);
071
072 /**
073 * Appends an integer attribute to the current attribute with a matching
074 * <code>name</code> key, if one exists.
075 *
076 * @throws IllegalStateException
077 * if there is no open tag.
078 */
079
080 void appendAttribute(String name, int value);
081
082 /**
083 * Appends a boolean attribute into the currently open tag.
084 *
085 * @throws IllegalStateException
086 * if there is no open tag.
087 * @since 3.0
088 */
089
090 void appendAttribute(String name, boolean value);
091
092 /**
093 * Appends an attribute into the most recently opened tag. This must be called after
094 * {@link #begin(String)} and before any other kind of writing (which closes the tag).
095 * <p>
096 * The value may be null.
097 *
098 * @throws IllegalStateException
099 * if there is no open tag.
100 */
101
102 void appendAttribute(String name, String value);
103
104 /**
105 * Similar to {@link #attribute(String, String)} but no escaping of invalid elements is done for
106 * the value.
107 *
108 * @throws IllegalStateException
109 * if there is no open tag.
110 * @since 3.0
111 */
112
113 void appendAttributeRaw(String name, String value);
114
115 /**
116 * Checks if the current tag has an attribute keyed off of <code>name</code>.
117 *
118 * @param name
119 * The name of the attribute to check for existance of.
120 * @return
121 * True if the attribute exists, false otherwise.
122 * @throws IllegalStateException
123 * If there is no open tag.
124 */
125 boolean hasAttribute(String name);
126
127 /**
128 * Gets the attribute matching <code>name</code> from the current open
129 * tag, if it exists.
130 *
131 * @param name
132 * The attribute to get the value of by name.
133 * @return
134 * The attribute value, or null if it doesn't exist.
135 * @throws IllegalStateException
136 * If there is no open tag.
137 */
138 Attribute getAttribute(String name);
139
140 /**
141 * Removes the attribute specified with a matching <code>name</code> if
142 * one exists.
143 *
144 * @param name
145 * The attribute to remove.
146 * @return
147 * The removed attribute, null if one didn't exist.
148 * @throws IllegalStateException
149 * If there is no open tag.
150 */
151 Attribute removeAttribute(String name);
152
153 /**
154 * Removes all current attributes on the open tag, if any.
155 *
156 * @throws IllegalStateException
157 * If there is no open tag.
158 */
159 void clearAttributes();
160
161 /**
162 * Closes any existing tag then starts a new element. The new element is pushed onto the active
163 * element stack.
164 */
165
166 void begin(String name);
167
168 /**
169 * Starts an element that will not later be matched with an <code>end()</code> call. This is
170 * useful for elements that do not need closing tags.
171 */
172
173 void beginEmpty(String name);
174
175 /**
176 * Invokes checkError() on the <code>PrintWriter</code> used to format output.
177 */
178
179 boolean checkError();
180
181 /**
182 * Closes this <code>IMarkupWriter</code>. Close tags are written for any active elements.
183 * The <code>PrintWriter</code> is then sent <code>close()</code>. A nested writer will
184 * commit its buffer to its containing writer.
185 */
186
187 void close();
188
189 /**
190 * Closes the most recently opened element by writing the '>' that ends it. Once this is
191 * invoked, the <code>attribute()</code> methods may not be used until a new element is opened
192 * with {@link #begin(String)}or or {@link #beginEmpty(String)}.
193 */
194
195 void closeTag();
196
197 /**
198 * Writes an XML/HTML comment. Any open tag is first closed. The method takes care of providing
199 * the <code><!--</code> and <code>--></code>, and provides a blank line after the
200 * close of the comment.
201 * <p>
202 * <em>Most</em> characters are valid inside a comment, so no check of the contents is made
203 * (much like {@link #printRaw(String)}.
204 */
205
206 void comment(String value);
207
208 /**
209 * Ends the element most recently started by {@link #begin(String)}. The name of the tag is
210 * popped off of the active element stack and used to form an HTML close tag.
211 */
212
213 void end();
214
215 /**
216 * Ends the most recently started element with the given name. This will also end any other
217 * intermediate elements. This is very useful for easily ending a table or even an entire page.
218 */
219
220 void end(String name);
221
222 /**
223 * Forwards <code>flush()</code> to this <code>IMarkupWriter</code>'s
224 * <code>PrintWriter</code>.
225 */
226
227 void flush();
228
229 /**
230 * Returns a nested writer, one that accumulates its changes in a buffer. When the nested writer
231 * is closed, it writes its buffer of markup into its containing <code>IMarkupWriter</code>
232 * using {@link #printRaw(String)}.
233 */
234
235 NestedMarkupWriter getNestedWriter();
236
237 /**
238 * Version of {@link #print(char[], int, int, boolean)} that assumes filter is
239 * <em>enabled</em>.
240 */
241
242 void print(char[] data, int offset, int length);
243
244 /**
245 * The primary <code>print()</code> method, used by most other methods.
246 * <p>
247 * Prints the character array, first closing any open tag. Problematic characters ('<',
248 * '>' and '&') are converted to appropriate entities.
249 * <p>
250 * Does <em>nothing</em> if <code>data</code> is null.
251 * <p>
252 * Closes any open tag.
253 *
254 * @param data
255 * contains the characters to print, or null to not print anything
256 * @param offset
257 * offset into the array to start printing from
258 * @param length
259 * number of characters to print
260 * @param raw
261 * if true, filtering is disabled
262 * @since 4.0
263 */
264
265 void print(char[] data, int offset, int length, boolean raw);
266
267 /**
268 * Prints a single character, or its equivalent entity.
269 * <p>
270 * Closes any open tag.
271 */
272
273 void print(char value);
274
275 /**
276 * Prints an integer.
277 * <p>
278 * Closes any open tag.
279 */
280
281 void print(int value);
282
283 /**
284 * As with {@link #print(char[], int, int, boolean)}, but the data to print is defined by the
285 * String. Assumes filtering is <em>enabled</em>.
286 */
287
288 void print(String value);
289
290 /**
291 * As with {@link #print(char[], int, int, boolean)}, but the data to print is defined by the
292 * String.
293 */
294
295 void print(String value, boolean raw);
296
297 /**
298 * Closes the open tag (if any), then prints a line seperator to the output stream.
299 */
300
301 void println();
302
303 /**
304 * Version of {@link #print(char[], int, int, boolean)}that assumes filter is <em>enabled</em>.
305 */
306
307 void printRaw(char[] buffer, int offset, int length);
308
309 /**
310 * As with {@link #print(char[], int, int, boolean)}, but the data to print is defined by the
311 * String. Assumes filtering is <em>disabled</em>.
312 */
313
314 void printRaw(String value);
315
316 /**
317 * Returns the type of content generated by this response writer, as a MIME type.
318 */
319
320 String getContentType();
321 }