001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. 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 distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.html; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.io.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.xml.*; 021 022/** 023 * Specialized writer for serializing HTML. 024 */ 025public class HtmlWriter extends XmlWriter { 026 027 /** 028 * Constructor. 029 * 030 * @param out The writer being wrapped. 031 * @param useWhitespace If <jk>true</jk>, tabs will be used in output. 032 * @param maxIndent The maximum indentation level. 033 * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized. 034 * @param quoteChar The quote character to use (i.e. <js>'\''</js> or <js>'"'</js>) 035 * @param uriResolver The URI resolver for resolving URIs to absolute or root-relative form. 036 */ 037 public HtmlWriter(Writer out, boolean useWhitespace, int maxIndent, boolean trimStrings, char quoteChar, 038 UriResolver uriResolver) { 039 super(out, useWhitespace, maxIndent, trimStrings, quoteChar, uriResolver, false, null); 040 } 041 042 043 //----------------------------------------------------------------------------------------------------------------- 044 // Overridden methods 045 //----------------------------------------------------------------------------------------------------------------- 046 047 @Override /* XmlSerializerWriter */ 048 public HtmlWriter text(Object o, boolean preserveWhitespace) throws IOException { 049 050 if (o == null) { 051 append("<null/>"); 052 return this; 053 } 054 String s = o.toString(); 055 if (s.isEmpty()) { 056 append("<sp/>"); 057 return this; 058 } 059 060 for (int i = 0; i < s.length(); i++) { 061 char test = s.charAt(i); 062 if (test == '&') 063 append("&"); 064 else if (test == '<') 065 append("<"); 066 else if (test == '>') 067 append(">"); 068 else if (test == '\n') 069 append(preserveWhitespace ? "\n" : "<br/>"); 070 else if (test == '\f') // XML 1.0 doesn't support form feeds or backslashes, so we have to invent something. 071 append(preserveWhitespace ? "\f" : "<ff/>"); 072 else if (test == '\b') 073 append(preserveWhitespace ? "\b" : "<bs/>"); 074 else if (test == '\t') 075 append(preserveWhitespace ? "\t" : "<sp> </sp>"); 076 else if ((i == 0 || i == s.length()-1) && Character.isWhitespace(test)) { 077 if (preserveWhitespace) 078 append(test); 079 else if (test == ' ') 080 append("<sp> </sp>"); 081 else 082 append("<sp>&#x").append(toHex4(test)).append(";</sp>"); 083 } 084 else if (Character.isISOControl(test)) 085 append("&#" + (int) test + ";"); 086 else 087 append(test); 088 } 089 090 return this; 091 } 092 093 @Override /* XmlSerializerWriter */ 094 public HtmlWriter oTag(String ns, String name, boolean needsEncoding) throws IOException { 095 super.oTag(ns, name, needsEncoding); 096 return this; 097 } 098 099 @Override /* XmlSerializerWriter */ 100 public HtmlWriter oTag(String ns, String name) throws IOException { 101 super.oTag(ns, name); 102 return this; 103 } 104 105 @Override /* XmlSerializerWriter */ 106 public HtmlWriter oTag(String name) throws IOException { 107 super.oTag(name); 108 return this; 109 } 110 111 @Override /* XmlSerializerWriter */ 112 public HtmlWriter oTag(int indent, String ns, String name, boolean needsEncoding) throws IOException { 113 super.oTag(indent, ns, name, needsEncoding); 114 return this; 115 } 116 117 @Override /* XmlSerializerWriter */ 118 public HtmlWriter oTag(int indent, String ns, String name) throws IOException { 119 super.oTag(indent, ns, name); 120 return this; 121 } 122 123 @Override /* XmlSerializerWriter */ 124 public HtmlWriter oTag(int indent, String name) throws IOException { 125 super.oTag(indent, name); 126 return this; 127 } 128 129 @Override /* XmlSerializerWriter */ 130 public HtmlWriter tag(String ns, String name, boolean needsEncoding) throws IOException { 131 super.tag(ns, name, needsEncoding); 132 return this; 133 } 134 135 @Override /* XmlSerializerWriter */ 136 public HtmlWriter tag(String ns, String name) throws IOException { 137 super.tag(ns, name); 138 return this; 139 } 140 141 @Override /* XmlSerializerWriter */ 142 public HtmlWriter tag(String name) throws IOException { 143 super.tag(name); 144 return this; 145 } 146 147 @Override /* XmlSerializerWriter */ 148 public HtmlWriter tag(int indent, String name) throws IOException { 149 super.tag(indent, name); 150 return this; 151 } 152 153 @Override /* XmlSerializerWriter */ 154 public HtmlWriter tag(int indent, String ns, String name, boolean needsEncoding) throws IOException { 155 super.tag(indent, ns, name, needsEncoding); 156 return this; 157 } 158 159 @Override /* XmlSerializerWriter */ 160 public HtmlWriter tag(int indent, String ns, String name) throws IOException { 161 super.tag(indent, ns, name); 162 return this; 163 } 164 165 @Override /* XmlSerializerWriter */ 166 public HtmlWriter sTag(String ns, String name) throws IOException { 167 super.sTag(ns, name); 168 return this; 169 } 170 171 @Override /* XmlSerializerWriter */ 172 public HtmlWriter sTag(String ns, String name, boolean needsEncoding) throws IOException { 173 super.sTag(ns, name, needsEncoding); 174 return this; 175 } 176 177 @Override /* XmlSerializerWriter */ 178 public HtmlWriter sTag(int indent, String ns, String name) throws IOException { 179 super.sTag(indent, ns, name); 180 return this; 181 } 182 183 @Override /* XmlSerializerWriter */ 184 public HtmlWriter sTag(int indent, String name) throws IOException { 185 super.sTag(indent, name); 186 return this; 187 } 188 189 @Override /* XmlSerializerWriter */ 190 public HtmlWriter sTag(String name) throws IOException { 191 super.sTag(name); 192 return this; 193 } 194 195 @Override /* XmlSerializerWriter */ 196 public HtmlWriter sTag(int indent, String ns, String name, boolean needsEncoding) throws IOException { 197 super.sTag(indent, ns, name, needsEncoding); 198 return this; 199 } 200 201 @Override /* XmlSerializerWriter */ 202 public HtmlWriter eTag(String ns, String name) throws IOException { 203 super.eTag(ns, name); 204 return this; 205 } 206 207 @Override /* XmlSerializerWriter */ 208 public HtmlWriter eTag(String ns, String name, boolean needsEncoding) throws IOException { 209 super.eTag(ns, name, needsEncoding); 210 return this; 211 } 212 213 @Override /* XmlSerializerWriter */ 214 public HtmlWriter eTag(int indent, String ns, String name) throws IOException { 215 super.eTag(indent, ns, name); 216 return this; 217 } 218 219 @Override /* XmlSerializerWriter */ 220 public HtmlWriter eTag(int indent, String name) throws IOException { 221 super.eTag(indent, name); 222 return this; 223 } 224 225 @Override /* XmlSerializerWriter */ 226 public HtmlWriter eTag(String name) throws IOException { 227 super.eTag(name); 228 return this; 229 } 230 231 @Override /* XmlSerializerWriter */ 232 public HtmlWriter eTag(int indent, String ns, String name, boolean needsEncoding) throws IOException { 233 super.eTag(indent, ns, name, needsEncoding); 234 return this; 235 } 236 237 @Override /* XmlSerializerWriter */ 238 public HtmlWriter attr(String name, Object value) throws IOException { 239 super.attr(name, value); 240 return this; 241 } 242 243 @Override /* XmlSerializerWriter */ 244 public HtmlWriter attr(String ns, String name, Object value) throws IOException { 245 super.attr(ns, name, value); 246 return this; 247 } 248 249 @Override /* XmlSerializerWriter */ 250 public HtmlWriter attr(String ns, String name, Object value, boolean valNeedsEncoding) throws IOException { 251 super.attr(ns, name, value, valNeedsEncoding); 252 return this; 253 } 254 255 @Override /* XmlSerializerWriter */ 256 public HtmlWriter attr(String name, Object value, boolean valNeedsEncoding) throws IOException { 257 super.attr(null, name, value, valNeedsEncoding); 258 return this; 259 } 260 261 @Override /* XmlSerializerWriter */ 262 public HtmlWriter oAttr(String ns, String name) throws IOException { 263 super.oAttr(ns, name); 264 return this; 265 } 266 267 @Override /* SerializerWriter */ 268 public HtmlWriter cr(int depth) throws IOException { 269 if (depth > 0) 270 super.cr(depth); 271 return this; 272 } 273 274 @Override /* SerializerWriter */ 275 public HtmlWriter cre(int depth) throws IOException { 276 if (depth > 0) 277 super.cre(depth); 278 return this; 279 } 280 281 @Override /* SerializerWriter */ 282 public HtmlWriter appendln(int indent, String text) throws IOException { 283 super.appendln(indent, text); 284 return this; 285 } 286 287 @Override /* SerializerWriter */ 288 public HtmlWriter appendln(String text) throws IOException { 289 super.appendln(text); 290 return this; 291 } 292 293 @Override /* SerializerWriter */ 294 public HtmlWriter append(int indent, String text) throws IOException { 295 super.append(indent, text); 296 return this; 297 } 298 299 @Override /* SerializerWriter */ 300 public HtmlWriter append(int indent, char c) throws IOException { 301 super.append(indent, c); 302 return this; 303 } 304 305 @Override /* SerializerWriter */ 306 public HtmlWriter s() throws IOException { 307 super.s(); 308 return this; 309 } 310 311 @Override /* SerializerWriter */ 312 public HtmlWriter q() throws IOException { 313 super.q(); 314 return this; 315 } 316 317 @Override /* SerializerWriter */ 318 public HtmlWriter i(int indent) throws IOException { 319 super.i(indent); 320 return this; 321 } 322 323 @Override /* SerializerWriter */ 324 public HtmlWriter nl(int indent) throws IOException { 325 super.nl(indent); 326 return this; 327 } 328 329 @Override /* SerializerWriter */ 330 public HtmlWriter append(Object text) throws IOException { 331 super.append(text); 332 return this; 333 } 334 335 @Override /* SerializerWriter */ 336 public HtmlWriter append(String text) throws IOException { 337 super.append(text); 338 return this; 339 } 340 341 @Override /* SerializerWriter */ 342 public HtmlWriter append(char c) throws IOException { 343 super.append(c); 344 return this; 345 } 346}