Java tutorial
package com.edgardleal.util.html; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; /** * Provides a HTML element StringBuffer for rendering, automatically escaping * string values. HTMLStringBuffer is used by Click controls for HTML rendering. * <p/> * For example the following code: * * <pre class="codeJava"> * <span class="kw">public</span> String toString() { * HTMLStringBuffer buffer = <span class="kw">new</span> HTMLStringBuffer(); * * buffer.elementStart(<span class="st">"input"</span>); * buffer.appendAttribute(<span class="st">"type"</span>, <span class="st">"text"</span>); * buffer.appendAttribute(<span class="st">"name"</span>, getName()); * buffer.appendAttribute(<span class="st">"value"</span>, getValue()); * buffer.elementEnd(); * * <span class="kw">return</span> buffer.toString(); * } * </pre> * * Would render: * * <pre class="codeHtml"> * <input type="text" name="address" value="23 Holt's Street"/> * </pre> * * <h4>Synchronization</h4> * * To improve performance in Click's thread safe environment this class does not * synchronize append operations. Internally this class uses a character buffer * adapted from the JDK 1.5 <tt>AbstractStringBuilder</tt>. */ public class HTMLStringBuffer { // -------------------------------------------------------------- Constants /** JavaScript attribute names. */ static final String[] JS_ATTRIBUTES = { "onload", "onunload", "onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover", "onmousemove", "onmouseout", "onfocus", "onblur", "onkeypress", "onkeydown", "onkeyup", "onsubmit", "onreset", "onselect", "onchange" }; /** * The array of escaped XML character values, indexed on char value. * <p/> * XML entities values were derived from Jakarta Commons Lang * <tt>org.apache.commons.lang.Entities</tt> class. */ private static final String[] XML_ENTITIES = new String[63]; static { XML_ENTITIES[34] = """; // " - double-quote XML_ENTITIES[38] = "&"; // & - ampersand XML_ENTITIES[39] = "'"; // ' - quote XML_ENTITIES[60] = "<"; // < - less-than XML_ENTITIES[62] = ">"; // > - greater-than }; // ----------------------------------------------------- Instance Variables /** The character storage array. */ protected char[] characters; /** The count is the number of characters used. */ protected int count; /** * The array of escaped HTML character values, indexed on char value. * <p/> * HTML entities values were derived from Jakarta Commons Lang * <tt>org.apache.commons.lang.Entities</tt> class. */ private static final String[] HTML_ENTITIES = new String[9999]; static { HTML_ENTITIES[34] = """; // " - double-quote HTML_ENTITIES[38] = "&"; // & - ampersand HTML_ENTITIES[60] = "<"; // < - less-than HTML_ENTITIES[62] = ">"; // > - greater-than HTML_ENTITIES[160] = " "; // non-breaking space HTML_ENTITIES[161] = "¡"; // inverted exclamation mark HTML_ENTITIES[162] = "¢"; // cent sign HTML_ENTITIES[163] = "£"; // pound sign HTML_ENTITIES[164] = "¤"; // currency sign HTML_ENTITIES[165] = "¥"; // yen sign = yuan sign HTML_ENTITIES[166] = "¦"; // broken bar = broken vertical bar HTML_ENTITIES[167] = "§"; // section sign HTML_ENTITIES[168] = "¨"; // diaeresis = spacing diaeresis HTML_ENTITIES[169] = "©"; // copyright sign HTML_ENTITIES[170] = "ª"; // feminine ordinal indicator HTML_ENTITIES[171] = "«"; // left-pointing double angle quotation // mark = left pointing guillemet HTML_ENTITIES[172] = "¬"; // not sign HTML_ENTITIES[173] = "­"; // soft hyphen = discretionary hyphen HTML_ENTITIES[174] = "®"; // registered trademark sign HTML_ENTITIES[175] = "¯"; // macron = spacing macron = overline = // APL overbar HTML_ENTITIES[176] = "°"; // degree sign HTML_ENTITIES[177] = "±"; // plus-minus sign = plus-or-minus sign HTML_ENTITIES[178] = "²"; // superscript two = superscript digit // two = squared HTML_ENTITIES[179] = "³"; // superscript three = superscript digit // three = cubed HTML_ENTITIES[180] = "´"; // acute accent = spacing acute HTML_ENTITIES[181] = "µ"; // micro sign HTML_ENTITIES[182] = "¶"; // pilcrow sign = paragraph sign HTML_ENTITIES[183] = "·"; // middle dot = Georgian comma = Greek // middle dot HTML_ENTITIES[184] = "¸"; // cedilla = spacing cedilla HTML_ENTITIES[185] = "¹"; // superscript one = superscript digit // one HTML_ENTITIES[186] = "º"; // masculine ordinal indicator HTML_ENTITIES[187] = "»"; // right-pointing double angle quotation // mark = right pointing guillemet HTML_ENTITIES[188] = "¼"; // vulgar fraction one quarter = // fraction one quarter HTML_ENTITIES[189] = "½"; // vulgar fraction one half = fraction // one half HTML_ENTITIES[190] = "¾"; // vulgar fraction three quarters = // fraction three quarters HTML_ENTITIES[191] = "¿"; // inverted question mark = turned // question mark HTML_ENTITIES[192] = "À"; // - uppercase A, grave accent HTML_ENTITIES[193] = "Á"; // - uppercase A, acute accent HTML_ENTITIES[194] = "Â"; // - uppercase A, circumflex // accent HTML_ENTITIES[195] = "Ã"; // - uppercase A, tilde HTML_ENTITIES[196] = "Ä"; // - uppercase A, umlaut HTML_ENTITIES[197] = "Å"; // - uppercase A, ring HTML_ENTITIES[198] = "Æ"; // - uppercase AE HTML_ENTITIES[199] = "Ç"; // - uppercase C, cedilla HTML_ENTITIES[200] = "È"; // - uppercase E, grave accent HTML_ENTITIES[201] = "É"; // - uppercase E, acute accent HTML_ENTITIES[202] = "Ê"; // - uppercase E, circumflex accent HTML_ENTITIES[203] = "Ë"; // - uppercase E, umlaut HTML_ENTITIES[204] = "Ì"; // - uppercase I, grave accent HTML_ENTITIES[205] = "Í"; // - uppercase I, acute accent HTML_ENTITIES[206] = "Î"; // - uppercase I, circumflex accent HTML_ENTITIES[207] = "Ï"; // - uppercase I, umlaut HTML_ENTITIES[208] = "Ð"; // - uppercase Eth, Icelandic HTML_ENTITIES[209] = "Ñ"; // - uppercase N, tilde HTML_ENTITIES[210] = "Ò"; // - uppercase O, grave accent HTML_ENTITIES[211] = "Ó"; // - uppercase O, acute accent HTML_ENTITIES[212] = "Ô"; // ? - uppercase O, circumflex // accent HTML_ENTITIES[213] = "Õ"; // - uppercase O, tilde HTML_ENTITIES[214] = "Ö"; // - uppercase O, umlaut HTML_ENTITIES[215] = "×"; // multiplication sign HTML_ENTITIES[216] = "Ø"; // - uppercase O, slash HTML_ENTITIES[217] = "Ù"; // - uppercase U, grave accent HTML_ENTITIES[218] = "Ú"; // - uppercase U, acute accent HTML_ENTITIES[219] = "Û"; // - uppercase U, circumflex // accent HTML_ENTITIES[220] = "Ü"; // - uppercase U, umlaut HTML_ENTITIES[221] = "Ý"; // - uppercase Y, acute accent HTML_ENTITIES[222] = "Þ"; // - uppercase THORN, Icelandic HTML_ENTITIES[223] = "ß"; // - lowercase sharps, German HTML_ENTITIES[224] = "à"; // - lowercase a, grave accent HTML_ENTITIES[225] = "á"; // - lowercase a, acute accent HTML_ENTITIES[226] = "â"; // - lowercase a, circumflex accent HTML_ENTITIES[227] = "ã"; // - lowercase a, tilde HTML_ENTITIES[228] = "ä"; // - lowercase a, umlaut HTML_ENTITIES[229] = "å"; // - lowercase a, ring HTML_ENTITIES[230] = "æ"; // - lowercase ae HTML_ENTITIES[231] = "ç"; // - lowercase c, cedilla HTML_ENTITIES[232] = "è"; // - lowercase e, grave accent HTML_ENTITIES[233] = "é"; // - lowercase e, acute accent HTML_ENTITIES[234] = "ê"; // - lowercase e, circumflex accent HTML_ENTITIES[235] = "ë"; // - lowercase e, umlaut HTML_ENTITIES[236] = "ì"; // - lowercase i, grave accent HTML_ENTITIES[237] = "í"; // - lowercase i, acute accent HTML_ENTITIES[238] = "î"; // - lowercase i, circumflex accent HTML_ENTITIES[239] = "ï"; // - lowercase i, umlaut HTML_ENTITIES[240] = "ð"; // - lowercase eth, Icelandic HTML_ENTITIES[241] = "ñ"; // - lowercase n, tilde HTML_ENTITIES[242] = "ò"; // - lowercase o, grave accent HTML_ENTITIES[243] = "ó"; // - lowercase o, acute accent HTML_ENTITIES[244] = "ô"; // - lowercase o, circumflex accent HTML_ENTITIES[245] = "õ"; // - lowercase o, tilde HTML_ENTITIES[246] = "ö"; // - lowercase o, umlaut HTML_ENTITIES[247] = "÷"; // division sign HTML_ENTITIES[248] = "ø"; // - lowercase o, slash HTML_ENTITIES[249] = "ù"; // - lowercase u, grave accent HTML_ENTITIES[250] = "ú"; // - lowercase u, acute accent HTML_ENTITIES[251] = "û"; // - lowercase u, circumflex accent HTML_ENTITIES[252] = "ü"; // - lowercase u, umlaut HTML_ENTITIES[253] = "ý"; // - lowercase y, acute accent HTML_ENTITIES[254] = "þ"; // - lowercase thorn, Icelandic HTML_ENTITIES[255] = "ÿ"; // - lowercase y, umlaut // http://www.w3.org/TR/REC-html40/sgml/entities.html // <!-- Latin Extended-B --> HTML_ENTITIES[402] = "ƒ"; // latin small f with hook = function= // florin, U+0192 ISOtech --> // <!-- Greek --> HTML_ENTITIES[913] = "Α"; // greek capital letter alpha, U+0391 // --> HTML_ENTITIES[914] = "Β"; // greek capital letter beta, U+0392 --> HTML_ENTITIES[915] = "Γ"; // greek capital letter gamma,U+0393 // ISOgrk3 --> HTML_ENTITIES[916] = "Δ"; // greek capital letter delta,U+0394 // ISOgrk3 --> HTML_ENTITIES[917] = "Ε"; // greek capital letter epsilon, // U+0395 --> HTML_ENTITIES[918] = "Ζ"; // greek capital letter zeta, U+0396 --> HTML_ENTITIES[919] = "Η"; // greek capital letter eta, U+0397 --> HTML_ENTITIES[920] = "Θ"; // greek capital letter theta,U+0398 // ISOgrk3 --> HTML_ENTITIES[921] = "Ι"; // greek capital letter iota, U+0399 --> HTML_ENTITIES[922] = "Κ"; // greek capital letter kappa, U+039A // --> HTML_ENTITIES[923] = "Λ"; // greek capital letter lambda,U+039B // ISOgrk3 --> HTML_ENTITIES[924] = "Μ"; // greek capital letter mu, U+039C --> HTML_ENTITIES[925] = "Ν"; // greek capital letter nu, U+039D --> HTML_ENTITIES[926] = "Ξ"; // greek capital letter xi, U+039E ISOgrk3 // --> HTML_ENTITIES[927] = "Ο"; // greek capital letter omicron, // U+039F --> HTML_ENTITIES[928] = "Π"; // greek capital letter pi, U+03A0 ISOgrk3 // --> HTML_ENTITIES[929] = "Ρ"; // greek capital letter rho, U+03A1 --> // <!-- there is no Sigmaf, and no U+03A2 character either --> HTML_ENTITIES[931] = "Σ"; // greek capital letter sigma,U+03A3 // ISOgrk3 --> HTML_ENTITIES[932] = "Τ"; // greek capital letter tau, U+03A4 --> HTML_ENTITIES[933] = "Υ"; // greek capital letter upsilon,U+03A5 // ISOgrk3 --> HTML_ENTITIES[934] = "Φ"; // greek capital letter phi,U+03A6 ISOgrk3 // --> HTML_ENTITIES[935] = "Χ"; // greek capital letter chi, U+03A7 --> HTML_ENTITIES[936] = "Ψ"; // greek capital letter psi,U+03A8 ISOgrk3 // --> HTML_ENTITIES[937] = "Ω"; // greek capital letter omega,U+03A9 // ISOgrk3 --> HTML_ENTITIES[945] = "α"; // greek small letter alpha,U+03B1 // ISOgrk3 --> HTML_ENTITIES[946] = "β"; // greek small letter beta, U+03B2 // ISOgrk3 --> HTML_ENTITIES[947] = "γ"; // greek small letter gamma,U+03B3 // ISOgrk3 --> HTML_ENTITIES[948] = "δ"; // greek small letter delta,U+03B4 // ISOgrk3 --> HTML_ENTITIES[949] = "ε"; // greek small letter epsilon,U+03B5 // ISOgrk3 --> HTML_ENTITIES[950] = "ζ"; // greek small letter zeta, U+03B6 // ISOgrk3 --> HTML_ENTITIES[951] = "η"; // greek small letter eta, U+03B7 ISOgrk3 // --> HTML_ENTITIES[952] = "θ"; // greek small letter theta,U+03B8 // ISOgrk3 --> HTML_ENTITIES[953] = "ι"; // greek small letter iota, U+03B9 // ISOgrk3 --> HTML_ENTITIES[954] = "κ"; // greek small letter kappa,U+03BA // ISOgrk3 --> HTML_ENTITIES[955] = "λ"; // greek small letter lambda,U+03BB // ISOgrk3 --> HTML_ENTITIES[956] = "μ"; // greek small letter mu, U+03BC ISOgrk3 // --> HTML_ENTITIES[957] = "ν"; // greek small letter nu, U+03BD ISOgrk3 // --> HTML_ENTITIES[958] = "ξ"; // greek small letter xi, U+03BE ISOgrk3 // --> HTML_ENTITIES[959] = "ο"; // greek small letter omicron, U+03BF // NEW --> HTML_ENTITIES[960] = "π"; // greek small letter pi, U+03C0 ISOgrk3 // --> HTML_ENTITIES[961] = "ρ"; // greek small letter rho, U+03C1 ISOgrk3 // --> HTML_ENTITIES[962] = "ς"; // greek small letter final // sigma,U+03C2 ISOgrk3 --> HTML_ENTITIES[963] = "σ"; // greek small letter sigma,U+03C3 // ISOgrk3 --> HTML_ENTITIES[964] = "τ"; // greek small letter tau, U+03C4 ISOgrk3 // --> HTML_ENTITIES[965] = "υ"; // greek small letter upsilon,U+03C5 // ISOgrk3 --> HTML_ENTITIES[966] = "φ"; // greek small letter phi, U+03C6 ISOgrk3 // --> HTML_ENTITIES[967] = "χ"; // greek small letter chi, U+03C7 ISOgrk3 // --> HTML_ENTITIES[968] = "ψ"; // greek small letter psi, U+03C8 ISOgrk3 // --> HTML_ENTITIES[969] = "ω"; // greek small letter omega,U+03C9 // ISOgrk3 --> HTML_ENTITIES[977] = "ϑ"; // greek small letter theta // symbol,U+03D1 NEW --> HTML_ENTITIES[978] = "ϒ"; // greek upsilon with hook symbol,U+03D2 // NEW --> HTML_ENTITIES[982] = "ϖ"; // greek pi symbol, U+03D6 ISOgrk3 --> // <!-- General Punctuation --> HTML_ENTITIES[8226] = "•"; // bullet = black small circle,U+2022 // ISOpub --> // <!-- bullet is NOT the same as bullet operator, U+2219 --> HTML_ENTITIES[8230] = "…"; // horizontal ellipsis = three dot // leader,U+2026 ISOpub --> HTML_ENTITIES[8242] = "′"; // prime = minutes = feet, U+2032 // ISOtech --> HTML_ENTITIES[8243] = "″"; // double prime = seconds = // inches,U+2033 ISOtech --> HTML_ENTITIES[8254] = "‾"; // overline = spacing overscore,U+203E // NEW --> HTML_ENTITIES[8260] = "⁄"; // fraction slash, U+2044 NEW --> // <!-- Letterlike Symbols --> HTML_ENTITIES[8472] = "℘"; // script capital P = power set= // Weierstrass p, U+2118 ISOamso --> HTML_ENTITIES[8465] = "ℑ"; // blackletter capital I = imaginary // part,U+2111 ISOamso --> HTML_ENTITIES[8476] = "ℜ"; // blackletter capital R = real part // symbol,U+211C ISOamso --> HTML_ENTITIES[8482] = "™"; // trade mark sign, U+2122 ISOnum --> HTML_ENTITIES[8501] = "ℵ"; // alef symbol = first transfinite // cardinal,U+2135 NEW --> // <!-- alef symbol is NOT the same as hebrew letter alef,U+05D0 // although the same glyph could be used to depict both characters --> // <!-- Arrows --> HTML_ENTITIES[8592] = "←"; // leftwards arrow, U+2190 ISOnum --> HTML_ENTITIES[8593] = "↑"; // upwards arrow, U+2191 ISOnum--> HTML_ENTITIES[8594] = "→"; // rightwards arrow, U+2192 ISOnum --> HTML_ENTITIES[8595] = "↓"; // downwards arrow, U+2193 ISOnum --> HTML_ENTITIES[8596] = "↔"; // left right arrow, U+2194 ISOamsa --> HTML_ENTITIES[8629] = "↵"; // downwards arrow with corner // leftwards= carriage return, // U+21B5 NEW --> HTML_ENTITIES[8656] = "⇐"; // leftwards double arrow, U+21D0 // ISOtech --> // <!-- ISO 10646 does not say that lArr is the same as the 'is implied // by' arrowbut also does not have any other character for that // function. So ? lArr canbe used for 'is implied by' as ISOtech // suggests --> HTML_ENTITIES[8657] = "⇑"; // upwards double arrow, U+21D1 ISOamsa // --> HTML_ENTITIES[8658] = "⇒"; // rightwards double arrow,U+21D2 // ISOtech --> // <!-- ISO 10646 does not say this is the 'implies' character but does // not have another character with this function so ?rArr can be used // for 'implies' as ISOtech suggests --> HTML_ENTITIES[8659] = "⇓"; // downwards double arrow, U+21D3 // ISOamsa --> HTML_ENTITIES[8660] = "⇔"; // left right double arrow,U+21D4 // ISOamsa --> // <!-- Mathematical Operators --> HTML_ENTITIES[8704] = "∀"; // for all, U+2200 ISOtech --> HTML_ENTITIES[8706] = "∂"; // partial differential, U+2202 ISOtech // --> HTML_ENTITIES[8707] = "∃"; // there exists, U+2203 ISOtech --> HTML_ENTITIES[8709] = "∅"; // empty set = null set = // diameter,U+2205 ISOamso --> HTML_ENTITIES[8711] = "∇"; // nabla = backward difference,U+2207 // ISOtech --> HTML_ENTITIES[8712] = "∈"; // element of, U+2208 ISOtech --> HTML_ENTITIES[8713] = "∉"; // not an element of, U+2209 ISOtech // --> HTML_ENTITIES[8715] = "∋"; // contains as member, U+220B ISOtech --> // <!-- should there be a more memorable name than 'ni'? --> HTML_ENTITIES[8719] = "∏"; // n-ary product = product sign,U+220F // ISOamsb --> // <!-- prod is NOT the same character as U+03A0 'greek capital letter // pi' though the same glyph might be used for both --> HTML_ENTITIES[8721] = "∑"; // n-ary summation, U+2211 ISOamsb --> // <!-- sum is NOT the same character as U+03A3 'greek capital letter // sigma' though the same glyph might be used for both --> HTML_ENTITIES[8722] = "−"; // minus sign, U+2212 ISOtech --> HTML_ENTITIES[8727] = "∗"; // asterisk operator, U+2217 ISOtech // --> HTML_ENTITIES[8730] = "√"; // square root = radical sign,U+221A // ISOtech --> HTML_ENTITIES[8733] = "∝"; // proportional to, U+221D ISOtech --> HTML_ENTITIES[8734] = "∞"; // infinity, U+221E ISOtech --> HTML_ENTITIES[8736] = "∠"; // angle, U+2220 ISOamso --> HTML_ENTITIES[8743] = "∧"; // logical and = wedge, U+2227 ISOtech // --> HTML_ENTITIES[8744] = "∨"; // logical or = vee, U+2228 ISOtech --> HTML_ENTITIES[8745] = "∩"; // intersection = cap, U+2229 ISOtech --> HTML_ENTITIES[8746] = "∪"; // union = cup, U+222A ISOtech --> HTML_ENTITIES[8747] = "∫"; // integral, U+222B ISOtech --> HTML_ENTITIES[8756] = "∴"; // therefore, U+2234 ISOtech --> HTML_ENTITIES[8764] = "∼"; // tilde operator = varies with = similar // to,U+223C ISOtech --> // <!-- tilde operator is NOT the same character as the tilde, // U+007E,although the same glyph might be used to represent both --> HTML_ENTITIES[8773] = "≅"; // approximately equal to, U+2245 // ISOtech --> HTML_ENTITIES[8776] = "≈"; // almost equal to = asymptotic // to,U+2248 ISOamsr --> HTML_ENTITIES[8800] = "≠"; // not equal to, U+2260 ISOtech --> HTML_ENTITIES[8801] = "≡"; // identical to, U+2261 ISOtech --> HTML_ENTITIES[8804] = "≤"; // less-than or equal to, U+2264 ISOtech // --> HTML_ENTITIES[8805] = "≥"; // greater-than or equal to,U+2265 ISOtech // --> HTML_ENTITIES[8834] = "⊂"; // subset of, U+2282 ISOtech --> HTML_ENTITIES[8835] = "⊃"; // superset of, U+2283 ISOtech --> // <!-- note that nsup, 'not a superset of, U+2283' is not covered by // the Symbol font encoding and is not included. Should it be, for // symmetry?It is in ISOamsn --> <!ENTITY nsub"; 8836 //not a subset of, // U+2284 ISOamsn --> HTML_ENTITIES[8838] = "⊆"; // subset of or equal to, U+2286 ISOtech // --> HTML_ENTITIES[8839] = "⊇"; // superset of or equal to,U+2287 // ISOtech --> HTML_ENTITIES[8853] = "⊕"; // circled plus = direct sum,U+2295 // ISOamsb --> HTML_ENTITIES[8855] = "⊗"; // circled times = vector // product,U+2297 ISOamsb --> HTML_ENTITIES[8869] = "⊥"; // up tack = orthogonal to = // perpendicular,U+22A5 ISOtech --> HTML_ENTITIES[8901] = "⋅"; // dot operator, U+22C5 ISOamsb --> // <!-- dot operator is NOT the same character as U+00B7 middle dot --> // <!-- Miscellaneous Technical --> HTML_ENTITIES[8968] = "⌈"; // left ceiling = apl upstile,U+2308 // ISOamsc --> HTML_ENTITIES[8969] = "⌉"; // right ceiling, U+2309 ISOamsc --> HTML_ENTITIES[8970] = "⌊"; // left floor = apl downstile,U+230A // ISOamsc --> HTML_ENTITIES[8971] = "⌋"; // right floor, U+230B ISOamsc --> HTML_ENTITIES[9001] = "⟨"; // left-pointing angle bracket = // bra,U+2329 ISOtech --> // <!-- lang is NOT the same character as U+003C 'less than' or U+2039 // 'single left-pointing angle quotation mark' --> HTML_ENTITIES[9002] = "⟩"; // right-pointing angle bracket = // ket,U+232A ISOtech --> // <!-- rang is NOT the same character as U+003E 'greater than' or // U+203A 'single right-pointing angle quotation mark' --> // <!-- Geometric Shapes --> HTML_ENTITIES[9674] = "◊"; // lozenge, U+25CA ISOpub --> // <!-- Miscellaneous Symbols --> HTML_ENTITIES[9824] = "♠"; // black spade suit, U+2660 ISOpub --> // <!-- black here seems to mean filled as opposed to hollow --> HTML_ENTITIES[9827] = "♣"; // black club suit = shamrock,U+2663 // ISOpub --> HTML_ENTITIES[9829] = "♥"; // black heart suit = valentine,U+2665 // ISOpub --> HTML_ENTITIES[9830] = "♦"; // black diamond suit, U+2666 ISOpub // --> // <!-- Latin Extended-A --> HTML_ENTITIES[338] = "Œ"; // -- latin capital ligature OE,U+0152 // ISOlat2 --> HTML_ENTITIES[339] = "œ"; // -- latin small ligature oe, U+0153 // ISOlat2 --> // <!-- ligature is a misnomer, this is a separate character in some // languages --> HTML_ENTITIES[352] = "Š"; // -- latin capital letter S with // caron,U+0160 ISOlat2 --> HTML_ENTITIES[353] = "š"; // -- latin small letter s with // caron,U+0161 ISOlat2 --> HTML_ENTITIES[376] = "Ÿ"; // -- latin capital letter Y with // diaeresis,U+0178 ISOlat2 --> // <!-- Spacing Modifier Letters --> HTML_ENTITIES[710] = "ˆ"; // -- modifier letter circumflex // accent,U+02C6 ISOpub --> HTML_ENTITIES[732] = "˜"; // small tilde, U+02DC ISOdia --> // <!-- General Punctuation --> HTML_ENTITIES[8194] = " "; // en space, U+2002 ISOpub --> HTML_ENTITIES[8195] = " "; // em space, U+2003 ISOpub --> HTML_ENTITIES[8201] = " "; // thin space, U+2009 ISOpub --> HTML_ENTITIES[8204] = "‌"; // zero width non-joiner,U+200C NEW RFC // 2070 --> HTML_ENTITIES[8205] = "‍"; // zero width joiner, U+200D NEW RFC 2070 // --> HTML_ENTITIES[8206] = "‎"; // left-to-right mark, U+200E NEW RFC // 2070 --> HTML_ENTITIES[8207] = "‏"; // right-to-left mark, U+200F NEW RFC // 2070 --> HTML_ENTITIES[8211] = "–"; // en dash, U+2013 ISOpub --> HTML_ENTITIES[8212] = "—"; // em dash, U+2014 ISOpub --> HTML_ENTITIES[8216] = "‘"; // left single quotation mark,U+2018 // ISOnum --> HTML_ENTITIES[8217] = "’"; // right single quotation mark,U+2019 // ISOnum --> HTML_ENTITIES[8218] = "‚"; // single low-9 quotation mark, U+201A // NEW --> HTML_ENTITIES[8220] = "“"; // left double quotation mark,U+201C // ISOnum --> HTML_ENTITIES[8221] = "”"; // right double quotation mark,U+201D // ISOnum --> HTML_ENTITIES[8222] = "„"; // double low-9 quotation mark, U+201E // NEW --> HTML_ENTITIES[8224] = "†"; // dagger, U+2020 ISOpub --> HTML_ENTITIES[8225] = "‡"; // double dagger, U+2021 ISOpub --> HTML_ENTITIES[8240] = "‰"; // per mille sign, U+2030 ISOtech --> HTML_ENTITIES[8249] = "‹"; // single left-pointing angle // quotation mark,U+2039 ISO // proposed --> // <!-- lsaquo is proposed but not yet ISO standardized --> HTML_ENTITIES[8250] = "›"; // single right-pointing angle // quotation mark,U+203A ISO // proposed --> // <!-- rsaquo is proposed but not yet ISO standardized --> HTML_ENTITIES[8364] = "€"; // -- euro sign, U+20AC NEW --> }; // ----------------------------------------------------------- Constructors /** * Create a new HTML StringBuffer with the specified initial capacity. * * @param length * the initial capacity */ public HTMLStringBuffer(int length) { characters = new char[length]; } /** * Create a new HTML StringBuffer with an initial capacity of 128 * characters. */ public HTMLStringBuffer() { characters = new char[128]; } // --------------------------------------------------------- Public Methods /** * Append the double value to the buffer. * * @param value * the double value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(double value) { append(String.valueOf(value)); return this; } /** * Append the char value to the buffer. * * @param value * the char value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(char value) { int newcount = count + 1; if (newcount > characters.length) { expandCapacity(newcount); } characters[count++] = value; return this; } /** * Append the integer value to the buffer. * * @param value * the integer value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(int value) { append(String.valueOf(value)); return this; } /** * Append the long value to the buffer. * * @param value * the long value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(long value) { append(String.valueOf(value)); return this; } /** * Append the raw object value of the given object to the buffer. * * @param value * the object value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(Object value) { String string = String.valueOf(value); int length = string.length(); int newCount = count + length; if (newCount > characters.length) { expandCapacity(newCount); } string.getChars(0, length, characters, count); count = newCount; return this; } /** * Append the raw string value of the given object to the buffer. * * @param value * the string value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer append(String value) { String string = (value != null) ? value : "null"; int length = string.length(); int newCount = count + length; if (newCount > characters.length) { expandCapacity(newCount); } string.getChars(0, length, characters, count); count = newCount; return this; } /** * Append the given value to the buffer and escape its value. The following * characters are escaped: <, >, ", ', &. * * @param value * the object value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if the value is null */ public HTMLStringBuffer appendEscaped(Object value) { if (value == null) { throw new IllegalArgumentException("Null value parameter"); } String string = value.toString(); boolean requiresEscape = false; for (int i = 0, size = string.length(); i < size; i++) { if (requiresEscape(string.charAt(i))) { requiresEscape = true; break; } } if (requiresEscape) { appendEscapeString(string, this); } else { append(string); } return this; } /** * Append the escaped string for the given character value to the buffer. * The following characters are escaped: <, >, ", ', &. * * @param value * the String value to escape * @param buffer * the string buffer to append the escaped value to */ public void appendEscapeString(String value, HTMLStringBuffer buffer) { char aChar; for (int i = 0, size = value.length(); i < size; i++) { aChar = value.charAt(i); int index = aChar; if (index < XML_ENTITIES.length && XML_ENTITIES[index] != null) { buffer.append(XML_ENTITIES[index]); } else { buffer.append(aChar); } } } /** * Return true if the given character requires escaping. The following * characters are escaped: <, >, ", ', &. * * @param aChar * the character value to test * @return true if the given character requires escaping */ public boolean requiresEscape(char aChar) { int index = aChar; if (index < XML_ENTITIES.length) { return XML_ENTITIES[index] != null; } else { return false; } } /** * Append the given HTML attribute name and value to the string buffer, and * do not escape the attribute value. * <p/> * For example: * * <pre class="javaCode"> * appendAttribute(<span class="st">"size"</span>, 10) <span class="green">-></span> <span class="st">size="10"</span> * </pre> * * @param name * the HTML attribute name * @param value * the HTML attribute value * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if name is null */ public HTMLStringBuffer appendAttribute(String name, Object value) { if (name == null) { throw new IllegalArgumentException("Null name parameter"); } if (value != null) { append(" "); append(name); append("=\""); append(value); append("\""); } return this; } /** * Append the given attribute name and value to the buffer, if the value is * not null. * <p/> * For example: * * <pre class="javaCode"> * appendAttribute(<span class="st">"class"</span>, <span class="st">"required"</span>) <span class="green">-></span> <span class="st">class="required"</span> * </pre> * * The attribute value will be escaped. The following characters are * escaped: <, >, ", ', &. * <p/> * If the attribute name is a JavaScript event handler the value will not be * escaped. * * @param name * the HTML attribute name * @param value * the object value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if name is null */ public HTMLStringBuffer appendAttributeEscaped(String name, Object value) { if (name == null) { throw new IllegalArgumentException("Null name parameter"); } if (value != null) { append(" "); append(name); append("=\""); if (isJavaScriptAttribute(name)) { append(value); } else { appendEscaped(value.toString()); } append("\""); } return this; } /** * Append the given HTML attribute name and value to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * appendAttribute(<span class="st">"size"</span>, 10) <span class="green">-></span> <span class="st">size="10"</span> * </pre> * * @param name * the HTML attribute name * @param value * the HTML attribute value * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if name is null */ public HTMLStringBuffer appendAttribute(String name, int value) { if (name == null) { throw new IllegalArgumentException("Null name parameter"); } append(" "); append(name); append("=\""); append(value); append("\""); return this; } /** * Append the HTML "disabled" attribute to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * appendAttributeDisabled() <span class="green">-></span> <span class="st">disabled="disabled"</span> * </pre> * * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer appendAttributeDisabled() { append(" disabled=\"disabled\""); return this; } /** * Append the HTML "readonly" attribute to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * appendAttributeReadonly() <span class="green">-></span> <span class="st">readonly="readonly"</span> * </pre> * * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer appendAttributeReadonly() { append(" readonly=\"readonly\""); return this; } /** * Append the given map of attribute names and values to the string buffer. * * @param attributes * the map of attribute names and values * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if attributes is null */ public HTMLStringBuffer appendAttributes(Map<String, String> attributes) { if (attributes == null) { throw new IllegalArgumentException("Null attributes parameter"); } for (Map.Entry<String, String> entry : attributes.entrySet()) { String name = entry.getKey(); if (!name.equals("id")) { appendAttributeEscaped(name, entry.getValue()); } } return this; } /** * Append the given map of CSS style name and value pairs as a style * attribute to the string buffer. * * @param attributes * the map of CSS style names and values * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if attributes is null */ public HTMLStringBuffer appendStyleAttributes(Map<String, String> attributes) { if (attributes == null) { throw new IllegalArgumentException("Null attributes parameter"); } if (!attributes.isEmpty()) { append(" style=\""); for (Map.Entry<String, String> entry : attributes.entrySet()) { append(entry.getKey()); append(":"); append(entry.getValue()); append(";"); } append("\""); } return this; } /** * Append a HTML element end to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * elementEnd(<span class="st">"textarea"</span>) <span class="green">-></span> <span class="st"></textarea></span> * </pre> * * @param name * the HTML element name to end * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if name is null */ public HTMLStringBuffer elementEnd(String name) { if (name == null) { throw new IllegalArgumentException("Null name parameter"); } append("</"); append(name); append(">"); return this; } /** * Append a HTML element end to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * closeTag() <span class="green">-></span> <span class="st">></span> * </pre> * * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer closeTag() { append(">"); return this; } /** * Append a HTML element end to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * elementEnd() <span class="green">-></span> <span class="st">/></span> * </pre> * * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer elementEnd() { append("/>"); return this; } /** * Append a HTML element start to the string buffer. * <p/> * For example: * * <pre class="javaCode"> * elementStart(<span class="st">"input"</span>) <span class="green">-></span> <span class="st"><input</span> * </pre> * * @param name * the HTML element name to start * @return a reference to this <tt>HTMLStringBuffer</tt> object */ public HTMLStringBuffer elementStart(String name) { append("<"); append(name); return this; } /** * Return true if the given attribute name is a JavaScript attribute, or * false otherwise. * * @param name * the HTML attribute name to test * @return true if the HTML attribute is a JavaScript attribute */ public boolean isJavaScriptAttribute(String name) { if (name.length() < 6 || name.length() > 11) { return false; } if (!name.startsWith("on")) { return false; } for (String jsAttribute : JS_ATTRIBUTES) { if (jsAttribute.equalsIgnoreCase(name)) { return true; } } return false; } /** * Return the length of the string buffer. * * @return the length of the string buffer */ public int length() { return count; } /** * @see Object#toString() * * @return a string representation of the string buffer */ @Override public String toString() { return new String(characters, 0, count); } // ------------------------------------------------------ Protected Methods /** * Ensures that the capacity is at least equal to the specified minimum. If * the current capacity is less than the argument, then a new internal array * is allocated with greater capacity. The new capacity is the larger of: * <ul> * <li>The <code>minimumCapacity</code> argument. * <li>Twice the old capacity, plus <code>2</code>. * </ul> * If the <code>minimumCapacity</code> argument is non-positive, this method * takes no action and simply returns. * * @param minimumCapacity * the minimum desired capacity */ protected void expandCapacity(int minimumCapacity) { int newCapacity = (characters.length + 1) * 2; if (newCapacity < 0) { newCapacity = Integer.MAX_VALUE; } else if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } char newValue[] = new char[newCapacity]; System.arraycopy(characters, 0, newValue, 0, count); characters = newValue; } // Private Package Methods ------------------------------------------------ /** * Append the given value to the buffer and HTML escape its value. * * @param value * the object value to append * @return a reference to this <tt>HTMLStringBuffer</tt> object * @throws IllegalArgumentException * if the value is null */ HTMLStringBuffer appendHtmlEscaped(Object value) { if (value == null) { throw new IllegalArgumentException("Null value parameter"); } String string = value.toString(); boolean requiresEscape = false; for (int i = 0, size = string.length(); i < size; i++) { if (requiresHtmlEscape(string.charAt(i))) { requiresEscape = true; break; } } if (requiresEscape) { appendHtmlEscapeString(string, this); } else { append(value); } return this; } /** * Return true if the given character requires HTML escaping. * * @param aChar * the character value to test * @return true if the given character requires HTML escaping */ static boolean requiresHtmlEscape(char aChar) { int index = aChar; if (index < HTML_ENTITIES.length) { return HTML_ENTITIES[index] != null; } else { return false; } } /** * Return true if the given string requires HTML escaping of characters. * * @param value * the string value to test * @return true if the given string requires HTML escaping of characters */ static boolean requiresHtmlEscape(String value) { if (value == null) { return false; } int length = value.length(); for (int i = 0; i < length; i++) { if (requiresHtmlEscape(value.charAt(i))) { return true; } } return false; } /** * Append the HTML escaped string for the given character value to the * buffer. * * @param value * the String value to escape * @param buffer * the string buffer to append the escaped value to */ static void appendHtmlEscapeString(String value, HTMLStringBuffer buffer) { char aChar; for (int i = 0, size = value.length(); i < size; i++) { aChar = value.charAt(i); int index = aChar; if (index < HTML_ENTITIES.length && HTML_ENTITIES[index] != null) { buffer.append(HTML_ENTITIES[index]); } else { buffer.append(aChar); } } } }