Java tutorial
/* File: com.miistwo.pa.action.EnquiryActionBean.java * * XYCommon - Utility * Licensed Material - Property of XYBASE. * Copyright (C) 2011 PT. XYBASE Indonesia. All rights reserved. * * Version 0.1 */ package com.xybase.utils; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.lang.reflect.Method; import java.security.MessageDigest; import java.util.*; /** * Provides miscellaneous Form, String and Stream utility methods. * * <p>Revision Information:<br/><i> * $Date$<br/> * $Revision$<br/> * $LastChangedBy$ * </i></p> * * @author Malcolm Edgar */ public class StringUtils { /** Hexadecimal characters for MD5 encoding. */ private static final char[] HEXADECIMAL = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * Character used to separate username and password in persistent cookies. * 0x13 == "Device Control 3" non-printing ASCII char. Unlikely to appear * in a username */ private static final char DELIMITER = 0x13; /* * "Tweakable" parameters for the cookie encoding. NOTE: changing these *and recompiling this class will essentially invalidate old cookies. */ private final static char ENCODE_CHAR_OFFSET1 = 'C'; private final static char ENCODE_CHAR_OFFSET2 = 'i'; /** * 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 --> } // --------------------------------------------------------- Public Methods /** * Return a new XML Document for the given input stream. * * @param inputStream the input stream * @return new XML Document * @throws RuntimeException if a parsing error occurs */ public static Document buildDocument(InputStream inputStream) { return buildDocument(inputStream, null); } /** * Return a new XML Document for the given input stream and XML entity * resolver. * * @param inputStream the input stream * @param entityResolver the XML entity resolver * @return new XML Document * @throws RuntimeException if a parsing error occurs */ public static Document buildDocument(InputStream inputStream, EntityResolver entityResolver) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); if (entityResolver != null) { builder.setEntityResolver(entityResolver); } return builder.parse(inputStream); } catch (Exception ex) { throw new RuntimeException("Error parsing XML", ex); } } /** * Close the given input stream and ignore any exceptions thrown. * * @param stream the input stream to close. */ public static void close(InputStream stream) { if (stream != null) { try { stream.close(); } catch (IOException ex) { // Ignore. } } } /** * Close the given output stream and ignore any exceptions thrown. * * @param stream the output stream to close. */ public static void close(OutputStream stream) { if (stream != null) { try { stream.close(); } catch (IOException ex) { // Ignore. } } } /** * Close the given reader and ignore any exceptions thrown. * * @param reader the reader to close. */ public static void close(Reader reader) { if (reader != null) { try { reader.close(); } catch (IOException ioe) { // Ignore } } } /** * Invalidate the specified cookie and delete it from the response object. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param request the servlet request * @param response the servlet response * @param cookieName The name of the cookie you want to delete * @param path of the path the cookie you want to delete */ public static void invalidateCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String path) { setCookie(request, response, cookieName, null, 0, path); } /** * Invalidate the specified cookie and delete it from the response object. Deletes only cookies mapped * against the root "/" path. Otherwise use * {@link #invalidateCookie(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, String, String)} * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @see #invalidateCookie(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, String, String) * * @param request the servlet request * @param response the servlet response * @param cookieName The name of the cookie you want to delete. */ public static void invalidateCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) { invalidateCookie(request, response, cookieName, "/"); } /** * Returns the specified Cookie object, or null if the cookie does not exist. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param request the servlet request * @param name the name of the cookie * @return the Cookie object if it exists, otherwise null */ public static Cookie getCookie(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); if (cookies == null || name == null || name.length() == 0) { return null; } //Otherwise, we have to do a linear scan for the cookie. for (Cookie cooky : cookies) { if (cooky.getName().equals(name)) { return cooky; } } return null; } /** * Sets the given cookie values in the servlet response. * <p/> * This will also put the cookie in a list of cookies to send with this request's response * (so that in case of a redirect occurring down the chain, the first filter * will always try to set this cookie again) * <p/> * The cookie secure flag is set if the request is secure. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param request the servlet request * @param response the servlet response * @param name the cookie name * @param value the cookie value * @param maxAge the maximum age of the cookie in seconds. A negative * value will expire the cookie at the end of the session, while 0 will delete * the cookie. * @param path the cookie path * @return the Cookie object created and set in the response */ public static Cookie setCookie(HttpServletRequest request, HttpServletResponse response, String name, String value, int maxAge, String path) { Cookie cookie = new Cookie(name, value); cookie.setMaxAge(maxAge); cookie.setPath(path); cookie.setSecure(request.isSecure()); response.addCookie(cookie); return cookie; } /** * Returns the value of the specified cookie as a String. If the cookie * does not exist, the method returns null. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param request the servlet request * @param name the name of the cookie * @return the value of the cookie, or null if the cookie does not exist. */ public static String getCookieValue(HttpServletRequest request, String name) { Cookie cookie = getCookie(request, name); if (cookie != null) { return cookie.getValue(); } return null; } /** * Builds a cookie string containing a username and password. * <p/> * Note: with open source this is not really secure, but it prevents users * from snooping the cookie file of others and by changing the XOR mask and * character offsets, you can easily tweak results. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param username the username * @param password the password * @param xorMask the XOR mask to encrypt the value with, must be same as * as the value used to decrypt the cookie password * @return String encoding the input parameters, an empty string if one of * the arguments equals <code>null</code> */ public static String encodePasswordCookie(String username, String password, int xorMask) { String encoding = new String(new char[] { DELIMITER, ENCODE_CHAR_OFFSET1, ENCODE_CHAR_OFFSET2 }); return encodePasswordCookie(username, password, encoding, xorMask); } /** * Builds a cookie string containing a username and password, using offsets * to customize the encoding. * <p/> * Note: with open source this is not really secure, but it prevents users * from snooping the cookie file of others and by changing the XOR mask and * character offsets, you can easily tweak results. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param username the username * @param password the password * @param encoding a String used to customize cookie encoding (only the first 3 characters are used) * @param xorMask the XOR mask to encrypt the value with, must be same as * as the value used to decrypt the cookie password * @return String encoding the input parameters, an empty string if one of * the arguments equals <code>null</code>. */ public static String encodePasswordCookie(String username, String password, String encoding, int xorMask) { StringBuffer buf = new StringBuffer(); if (username != null && password != null) { char offset1 = (encoding != null && encoding.length() > 1) ? encoding.charAt(1) : ENCODE_CHAR_OFFSET1; char offset2 = (encoding != null && encoding.length() > 2) ? encoding.charAt(2) : ENCODE_CHAR_OFFSET2; byte[] bytes = (username + DELIMITER + password).getBytes(); int b; for (int n = 0; n < bytes.length; n++) { b = bytes[n] ^ (xorMask + n); buf.append((char) (offset1 + (b & 0x0F))); buf.append((char) (offset2 + ((b >> 4) & 0x0F))); } } return buf.toString(); } /** * Decodes a cookie string containing a username and password. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param cookieVal the encoded cookie username and password value * @param xorMask the XOR mask to decrypt the value with, must be same as * as the value used to encrypt the cookie password * @return String[] containing the username at index 0 and the password at * index 1, or <code>{ null, null }</code> if cookieVal equals * <code>null</code> or the empty string. */ public static String[] decodePasswordCookie(String cookieVal, int xorMask) { String encoding = new String(new char[] { DELIMITER, ENCODE_CHAR_OFFSET1, ENCODE_CHAR_OFFSET2 }); return decodePasswordCookie(cookieVal, encoding, xorMask); } /** * Decodes a cookie string containing a username and password. * <p/> * This method was derived from Atlassian <tt>CookieUtils</tt> method of * the same name, release under the Apache License. * * @param cookieVal the encoded cookie username and password value * @param encoding a String used to customize cookie encoding (only the first 3 characters are used) * - should be the same string you used to encode the cookie! * @param xorMask the XOR mask to decrypt the value with, must be same as * as the value used to encrypt the cookie password * @return String[] containing the username at index 0 and the password at * index 1, or <code>{ null, null }</code> if cookieVal equals * <code>null</code> or the empty string. */ public static String[] decodePasswordCookie(String cookieVal, String encoding, int xorMask) { // Check that the cookie value isn't null or zero-length if (cookieVal == null || cookieVal.length() <= 0) { return null; } char offset1 = (encoding != null && encoding.length() > 1) ? encoding.charAt(1) : ENCODE_CHAR_OFFSET1; char offset2 = (encoding != null && encoding.length() > 2) ? encoding.charAt(2) : ENCODE_CHAR_OFFSET2; // Decode the cookie value char[] chars = cookieVal.toCharArray(); byte[] bytes = new byte[chars.length / 2]; int b; for (int n = 0, m = 0; n < bytes.length; n++) { b = chars[m++] - offset1; b |= (chars[m++] - offset2) << 4; bytes[n] = (byte) (b ^ (xorMask + n)); } cookieVal = new String(bytes); int pos = cookieVal.indexOf(DELIMITER); String username = (pos < 0) ? "" : cookieVal.substring(0, pos); String password = (pos < 0) ? "" : cookieVal.substring(pos + 1); return new String[] { username, password }; } /** * Return a HTML escaped string for the given string value. * * @param value the string value to escape * @return the HTML escaped string value */ public static String escapeHtml(String value) { if (requiresHtmlEscape(value)) { HtmlStringBuffer buffer = new HtmlStringBuffer(value.length() * 2); buffer.appendEscaped(value); return buffer.toString(); } else { return value; } } /** * Return the value string limited to maxlength characters. If the string * gets curtailed, "..." is appended to it. * <p/> * Adapted from Velocity Tools Formatter. * * @param value the string value to limit the length of * @param maxlength the maximum string length * @return a length limited string */ public static String limitLength(String value, int maxlength) { return limitLength(value, maxlength, "..."); } /** * Return the value string limited to maxlength characters. If the string * gets curtailed and the suffix parameter is appended to it. * <p/> * Adapted from Velocity Tools Formatter. * * @param value the string value to limit the length of * @param maxlength the maximum string length * @param suffix the suffix to append to the length limited string * @return a length limited string */ public static String limitLength(String value, int maxlength, String suffix) { String ret = value; if (value.length() > maxlength) { ret = value.substring(0, maxlength - suffix.length()) + suffix; } return ret; } /** * Return an ordered map of request parameters from the given request. * * @param request the servlet request to obtain request parameters from * @return the ordered map of request parameters */ @SuppressWarnings("unchecked") public static Map<String, String> getRequestParameters(HttpServletRequest request) { TreeMap<String, String> requestParams = new TreeMap<String, String>(); Enumeration paramNames = request.getParameterNames(); while (paramNames.hasMoreElements()) { String name = paramNames.nextElement().toString(); String[] values = request.getParameterValues(name); HtmlStringBuffer valsBuffer = new HtmlStringBuffer(32); if (values.length == 1) { valsBuffer.append(values[0]); } else { for (int i = 0; i < values.length; i++) { if (i == 0) { valsBuffer.append("["); } valsBuffer.append(values[i]); if (i == values.length - 1) { valsBuffer.append("]"); } else { valsBuffer.append(","); } } } requestParams.put(name, valsBuffer.toString()); } return requestParams; } /** * Return the page resource path from the request. For example: * <pre class="codeHtml"> * <span class="blue">http://www.mycorp.com/banking/secure/login.htm</span> -> <span class="red">/secure/login.htm</span> </pre> * * @param request the page servlet request * @return the page resource path from the request */ public static String getResourcePath(HttpServletRequest request) { // Adapted from VelocityViewServlet.handleRequest() method: // If we get here from RequestDispatcher.include(), getServletPath() // will return the original (wrong) URI requested. The following // special attribute holds the correct path. See section 8.3 of the // Servlet 2.3 specification. String path = (String) request.getAttribute("javax.servlet.include.servlet_path"); // Also take into account the PathInfo stated on // SRV.4.4 Request Path Elements. String info = (String) request.getAttribute("javax.servlet.include.path_info"); if (path == null) { path = request.getServletPath(); info = request.getPathInfo(); } if (info != null) { path += info; } return path; } /** * Return the getter method name for the given property name. * * @param property the property name * @return the getter method name for the given property name. */ public static String toGetterName(String property) { HtmlStringBuffer buffer = new HtmlStringBuffer(property.length() + 3); buffer.append("get"); buffer.append(Character.toUpperCase(property.charAt(0))); buffer.append(property.substring(1)); return buffer.toString(); } /** * Return the is getter method name for the given property name. * * @param property the property name * @return the is getter method name for the given property name. */ public static String toIsGetterName(String property) { HtmlStringBuffer buffer = new HtmlStringBuffer(property.length() + 3); buffer.append("is"); buffer.append(Character.toUpperCase(property.charAt(0))); buffer.append(property.substring(1)); return buffer.toString(); } /** * Return a field label string from the given field name. For example: * <pre class="codeHtml"> * <span class="blue">faxNumber</span> -> <span class="red">Fax Number</span> </pre> * * @param name the field name * @return a field label string from the given field name */ public static String toLabel(String name) { if (name == null) { throw new IllegalArgumentException("Null name parameter"); } HtmlStringBuffer buffer = new HtmlStringBuffer(); for (int i = 0, size = name.length(); i < size; i++) { char aChar = name.charAt(i); if (i == 0) { buffer.append(Character.toUpperCase(aChar)); } else { buffer.append(aChar); if (i < name.length() - 1) { char nextChar = name.charAt(i + 1); if (Character.isLowerCase(aChar) && (Character.isUpperCase(nextChar) || Character.isDigit(nextChar))) { buffer.append(" "); } } } } return buffer.toString(); } /** * Return an 32 char MD5 encoded string from the given plain text. * The returned value is MD5 hash compatible with Tomcat catalina Realm. * <p/> * Adapted from <tt>org.apache.catalina.util.MD5Encoder</tt> * * @param plaintext the plain text value to encode * @return encoded MD5 string */ public static String toMD5Hash(String plaintext) { if (plaintext == null) { throw new IllegalArgumentException("Null plaintext parameter"); } try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(plaintext.getBytes("UTF-8")); byte[] binaryData = md.digest(); char[] buffer = new char[32]; for (int i = 0; i < 16; i++) { int low = (int) (binaryData[i] & 0x0f); int high = (int) ((binaryData[i] & 0xf0) >> 4); buffer[i * 2] = HEXADECIMAL[high]; buffer[i * 2 + 1] = HEXADECIMAL[low]; } return new String(buffer); } catch (Exception e) { throw new RuntimeException(e); } } /** * Return a field name string from the given field label. * <p/> * A label of " OK do it!" is returned as "okDoIt". Any &nbsp; * characters will also be removed. * <p/> * A label of "customerSelect" is returned as "customerSelect". * * @param label the field label or caption * @return a field name string from the given field label */ public static String toName(String label) { if (label == null) { throw new IllegalArgumentException("Null label parameter"); } boolean doneFirstLetter = false; boolean lastCharBlank = false; boolean hasWhiteSpace = (label.indexOf(' ') != -1); HtmlStringBuffer buffer = new HtmlStringBuffer(label.length()); for (int i = 0, size = label.length(); i < size; i++) { char aChar = label.charAt(i); if (aChar != ' ') { if (Character.isJavaIdentifierPart(aChar)) { if (lastCharBlank) { if (doneFirstLetter) { buffer.append(Character.toUpperCase(aChar)); lastCharBlank = false; } else { buffer.append(Character.toLowerCase(aChar)); lastCharBlank = false; doneFirstLetter = true; } } else { if (doneFirstLetter) { if (hasWhiteSpace) { buffer.append(Character.toLowerCase(aChar)); } else { buffer.append(aChar); } } else { buffer.append(Character.toLowerCase(aChar)); doneFirstLetter = true; } } } } else { lastCharBlank = true; } } return buffer.toString(); } /** * Return the setter method name for the given property name. * * @param property the property name * @return the setter method name for the given property name. */ public static String toSetterName(String property) { HtmlStringBuffer buffer = new HtmlStringBuffer(property.length() + 3); buffer.append("set"); buffer.append(Character.toUpperCase(property.charAt(0))); buffer.append(property.substring(1)); return buffer.toString(); } public static String splitByUpperCase(String name, boolean isUpperCase) { StringBuilder builder = new StringBuilder(); boolean lastUpperCase = true; for (int i = 0, size = name.length(); i < size; i++) { char ch = name.charAt(i); if (Character.isUpperCase(ch)) { if (!lastUpperCase) { builder.append('_'); } } builder.append(ch); lastUpperCase = Character.isUpperCase(ch); } if (isUpperCase) { return builder.toString().toUpperCase(); } return builder.toString().toLowerCase(); } // -------------------------------------------------------- Package Methods /** * 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 requiresEscape(char aChar) { return (int) aChar < HTML_ENTITIES.length - 1 && HTML_ENTITIES[((int) aChar)] != null; } /** * Return the HTML escaped string for the given character value. * * @param aChar the character value to escape * @return the HTML escaped string for the given character value */ static String escapeChar(char aChar) { return (int) aChar < HTML_ENTITIES.length - 1 && HTML_ENTITIES[((int) aChar)] != null ? HTML_ENTITIES[((int) aChar)] : String.valueOf(aChar); } // -------------------------------------------------------- Private Methods @SuppressWarnings("unchecked") public static Set getObjectPropertyNames(Object object) { if (object instanceof Map) { return ((Map) object).keySet(); } HashSet hashSet = new HashSet(); Method[] methods = object.getClass().getMethods(); for (Method method : methods) { String methodName = method.getName(); if (methodName.startsWith("get") && methodName.length() > 3) { String propertyName = "" + Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); hashSet.add(propertyName); } if (methodName.startsWith("is") && methodName.length() > 2) { String propertyName = "" + Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3); hashSet.add(propertyName); } if (methodName.startsWith("set") && methodName.length() > 3) { String propertyName = "" + Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); hashSet.add(propertyName); } } return hashSet; } /** * 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 */ private static boolean requiresHtmlEscape(String value) { if (value == null) { return false; } int length = value.length(); for (int i = 0; i < length; i++) { if (requiresEscape(value.charAt(i))) { return true; } } return false; } /** * Convert a string to a valid camel case string * * @param inputString the input string to convert to camel case * @param firstCharacterUppercase when true first word will be converted to upper case as well * @return camel case of the input */ public static String getCamelCaseString(String inputString, boolean firstCharacterUppercase) { StringBuilder sb = new StringBuilder(); boolean nextUpperCase = false; for (int i = 0; i < inputString.length(); i++) { char c = inputString.charAt(i); switch (c) { case '_': case '-': case '@': case '$': case '#': case ' ': if (sb.length() > 0) { nextUpperCase = true; } break; default: if (nextUpperCase) { sb.append(Character.toUpperCase(c)); nextUpperCase = false; } else { sb.append(Character.toLowerCase(c)); } break; } } if (firstCharacterUppercase) { sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); } return sb.toString(); } /** * Join contents of a collection with a delimiter returning a joined string. * * @param s Collection to join * @param delimiter delimiter to seperate each item in collection * @return joined string */ public static String join(Collection s, String delimiter) { StringBuilder buffer = new StringBuilder(); Iterator iter = s.iterator(); while (iter.hasNext()) { buffer.append(iter.next()); if (iter.hasNext()) { buffer.append(delimiter); } } return buffer.toString(); } }