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 }