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