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.common.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 * 025 * <h5 class='section'>See Also:</h5><ul> 026 * <li class='link'><a class="doclink" href="../../../../index.html#jm.HtmlDetails">HTML Details</a> 027 028 * </ul> 029 */ 030public class HtmlWriter extends XmlWriter { 031 032 /** 033 * Constructor. 034 * 035 * @param out The writer being wrapped. 036 * @param useWhitespace If <jk>true</jk>, tabs will be used in output. 037 * @param maxIndent The maximum indentation level. 038 * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized. 039 * @param quoteChar The quote character to use (i.e. <js>'\''</js> or <js>'"'</js>) 040 * @param uriResolver The URI resolver for resolving URIs to absolute or root-relative form. 041 */ 042 public HtmlWriter(Writer out, boolean useWhitespace, int maxIndent, boolean trimStrings, char quoteChar, 043 UriResolver uriResolver) { 044 super(out, useWhitespace, maxIndent, trimStrings, quoteChar, uriResolver, false, null); 045 } 046 047 /** 048 * Copy constructor. 049 * 050 * @param w Writer being copied. 051 */ 052 public HtmlWriter(HtmlWriter w) { 053 super(w); 054 } 055 056 //----------------------------------------------------------------------------------------------------------------- 057 // Overridden methods 058 //----------------------------------------------------------------------------------------------------------------- 059 060 @Override /* XmlSerializerWriter */ 061 public HtmlWriter text(Object o, boolean preserveWhitespace) { 062 063 if (o == null) { 064 append("<null/>"); 065 return this; 066 } 067 String s = o.toString(); 068 if (s.isEmpty()) { 069 append("<sp/>"); 070 return this; 071 } 072 073 for (int i = 0; i < s.length(); i++) { 074 char test = s.charAt(i); 075 if (test == '&') 076 append("&"); 077 else if (test == '<') 078 append("<"); 079 else if (test == '>') 080 append(">"); 081 else if (test == '\n') 082 append(preserveWhitespace ? "\n" : "<br/>"); 083 else if (test == '\f') // XML 1.0 doesn't support form feeds or backslashes, so we have to invent something. 084 append(preserveWhitespace ? "\f" : "<ff/>"); 085 else if (test == '\b') 086 append(preserveWhitespace ? "\b" : "<bs/>"); 087 else if (test == '\t') 088 append(preserveWhitespace ? "\t" : "<sp> </sp>"); 089 else if ((i == 0 || i == s.length()-1) && Character.isWhitespace(test)) { 090 if (preserveWhitespace) 091 w(test); 092 else if (test == ' ') 093 append("<sp> </sp>"); 094 else 095 append("<sp>&#x").append(toHex4(test)).append(";</sp>"); 096 } 097 else if (Character.isISOControl(test)) 098 append("&#" + (int) test + ";"); 099 else 100 w(test); 101 } 102 103 return this; 104 } 105 106 // <FluentSetters> 107 108 @Override /* XmlSerializerWriter */ 109 public HtmlWriter oTag(String ns, String name, boolean needsEncoding) { 110 super.oTag(ns, name, needsEncoding); 111 return this; 112 } 113 114 @Override /* XmlSerializerWriter */ 115 public HtmlWriter oTag(String ns, String name) { 116 super.oTag(ns, name); 117 return this; 118 } 119 120 @Override /* XmlSerializerWriter */ 121 public HtmlWriter oTag(String name) { 122 super.oTag(name); 123 return this; 124 } 125 126 @Override /* XmlSerializerWriter */ 127 public HtmlWriter oTag(int indent, String ns, String name, boolean needsEncoding) { 128 super.oTag(indent, ns, name, needsEncoding); 129 return this; 130 } 131 132 @Override /* XmlSerializerWriter */ 133 public HtmlWriter oTag(int indent, String ns, String name) { 134 super.oTag(indent, ns, name); 135 return this; 136 } 137 138 @Override /* XmlSerializerWriter */ 139 public HtmlWriter oTag(int indent, String name) { 140 super.oTag(indent, name); 141 return this; 142 } 143 144 @Override /* XmlSerializerWriter */ 145 public HtmlWriter tag(String ns, String name, boolean needsEncoding) { 146 super.tag(ns, name, needsEncoding); 147 return this; 148 } 149 150 @Override /* XmlSerializerWriter */ 151 public HtmlWriter tag(String ns, String name) { 152 super.tag(ns, name); 153 return this; 154 } 155 156 @Override /* XmlSerializerWriter */ 157 public HtmlWriter tag(String name) { 158 super.tag(name); 159 return this; 160 } 161 162 @Override /* XmlSerializerWriter */ 163 public HtmlWriter tag(int indent, String name) { 164 super.tag(indent, name); 165 return this; 166 } 167 168 @Override /* XmlSerializerWriter */ 169 public HtmlWriter tag(int indent, String ns, String name, boolean needsEncoding) { 170 super.tag(indent, ns, name, needsEncoding); 171 return this; 172 } 173 174 @Override /* XmlSerializerWriter */ 175 public HtmlWriter tag(int indent, String ns, String name) { 176 super.tag(indent, ns, name); 177 return this; 178 } 179 180 @Override /* XmlSerializerWriter */ 181 public HtmlWriter sTag(String ns, String name) { 182 super.sTag(ns, name); 183 return this; 184 } 185 186 @Override /* XmlSerializerWriter */ 187 public HtmlWriter sTag(String ns, String name, boolean needsEncoding) { 188 super.sTag(ns, name, needsEncoding); 189 return this; 190 } 191 192 @Override /* XmlSerializerWriter */ 193 public HtmlWriter sTag(int indent, String ns, String name) { 194 super.sTag(indent, ns, name); 195 return this; 196 } 197 198 @Override /* XmlSerializerWriter */ 199 public HtmlWriter sTag(int indent, String name) { 200 super.sTag(indent, name); 201 return this; 202 } 203 204 @Override /* XmlSerializerWriter */ 205 public HtmlWriter sTag(String name) { 206 super.sTag(name); 207 return this; 208 } 209 210 @Override /* XmlSerializerWriter */ 211 public HtmlWriter sTag(int indent, String ns, String name, boolean needsEncoding) { 212 super.sTag(indent, ns, name, needsEncoding); 213 return this; 214 } 215 216 @Override /* XmlSerializerWriter */ 217 public HtmlWriter eTag(String ns, String name) { 218 super.eTag(ns, name); 219 return this; 220 } 221 222 @Override /* XmlSerializerWriter */ 223 public HtmlWriter eTag(String ns, String name, boolean needsEncoding) { 224 super.eTag(ns, name, needsEncoding); 225 return this; 226 } 227 228 @Override /* XmlSerializerWriter */ 229 public HtmlWriter eTag(int indent, String ns, String name) { 230 super.eTag(indent, ns, name); 231 return this; 232 } 233 234 @Override /* XmlSerializerWriter */ 235 public HtmlWriter eTag(int indent, String name) { 236 super.eTag(indent, name); 237 return this; 238 } 239 240 @Override /* XmlSerializerWriter */ 241 public HtmlWriter eTag(String name) { 242 super.eTag(name); 243 return this; 244 } 245 246 @Override /* XmlSerializerWriter */ 247 public HtmlWriter eTag(int indent, String ns, String name, boolean needsEncoding) { 248 super.eTag(indent, ns, name, needsEncoding); 249 return this; 250 } 251 252 @Override /* XmlSerializerWriter */ 253 public HtmlWriter attr(String name, Object value) { 254 super.attr(name, value); 255 return this; 256 } 257 258 @Override /* XmlSerializerWriter */ 259 public HtmlWriter attr(String ns, String name, Object value) { 260 super.attr(ns, name, value); 261 return this; 262 } 263 264 @Override /* XmlSerializerWriter */ 265 public HtmlWriter attr(String ns, String name, Object value, boolean valNeedsEncoding) { 266 super.attr(ns, name, value, valNeedsEncoding); 267 return this; 268 } 269 270 @Override /* XmlSerializerWriter */ 271 public HtmlWriter attr(String name, Object value, boolean valNeedsEncoding) { 272 super.attr(null, name, value, valNeedsEncoding); 273 return this; 274 } 275 276 @Override /* XmlSerializerWriter */ 277 public HtmlWriter oAttr(String ns, String name) { 278 super.oAttr(ns, name); 279 return this; 280 } 281 282 @Override /* SerializerWriter */ 283 public HtmlWriter cr(int depth) { 284 if (depth > 0) 285 super.cr(depth); 286 return this; 287 } 288 289 @Override /* SerializerWriter */ 290 public HtmlWriter cre(int depth) { 291 if (depth > 0) 292 super.cre(depth); 293 return this; 294 } 295 296 @Override /* SerializerWriter */ 297 public HtmlWriter appendln(int indent, String text) { 298 super.appendln(indent, text); 299 return this; 300 } 301 302 @Override /* SerializerWriter */ 303 public HtmlWriter appendln(String text) { 304 super.appendln(text); 305 return this; 306 } 307 308 @Override /* SerializerWriter */ 309 public HtmlWriter append(int indent, String text) { 310 super.append(indent, text); 311 return this; 312 } 313 314 @Override /* SerializerWriter */ 315 public HtmlWriter append(int indent, char c) { 316 super.append(indent, c); 317 return this; 318 } 319 320 @Override /* SerializerWriter */ 321 public HtmlWriter s() { 322 super.s(); 323 return this; 324 } 325 326 @Override /* SerializerWriter */ 327 public HtmlWriter q() { 328 super.q(); 329 return this; 330 } 331 332 @Override /* SerializerWriter */ 333 public HtmlWriter i(int indent) { 334 super.i(indent); 335 return this; 336 } 337 338 @Override /* SerializerWriter */ 339 public HtmlWriter nl(int indent) { 340 super.nl(indent); 341 return this; 342 } 343 344 @Override /* SerializerWriter */ 345 public HtmlWriter append(Object text) { 346 super.append(text); 347 return this; 348 } 349 350 @Override /* SerializerWriter */ 351 public HtmlWriter append(String text) { 352 super.append(text); 353 return this; 354 } 355 356 @Override /* SerializerWriter */ 357 public HtmlWriter append(char c) { 358 super.append(c); 359 return this; 360 } 361 362 // </FluentSetters> 363}