/** * $Revision $ * $Date $ * * Copyright (C) 2005-2010 Jive Software. All rights reserved. * * Licensed 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. */ package org.jivesoftware.community.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.text.BreakIterator; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.net.QuotedPrintableCodec; import org.jivesoftware.util.*; public class StringUtils extends org.apache.commons.lang.StringUtils { private static final Logger Log = LoggerFactory.getLogger(StringUtils.class); private static final char QUOTE_ENCODE[] = """.toCharArray(); private static final char AMP_ENCODE[] = "&".toCharArray(); private static final char LT_ENCODE[] = "<".toCharArray(); private static final char GT_ENCODE[] = ">".toCharArray(); private static final char APOS_ENCODE[] = "'".toCharArray(); private static Pattern basicAddressPattern; private static Pattern validUserPattern; private static Pattern domainPattern; private static Pattern ipDomainPattern; private static Pattern tldPattern; private static final String EMAIL_DOMAINS = "com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi"; private static final Pattern WHITESPACE = Pattern.compile("(\\s| )*"); private static final Pattern URL_SAFE = Pattern.compile("([^0-9A-Za-z\\-\\_]+)"); private static final char HEX_ENC_CHARS[] = "abcdefABCDEF012345678".toCharArray(); private static MessageDigest digest = null; private static final char base[]; private static final int indexes[]; private static final char CA[]; private static final int IA[]; private static final BitSet allowed_query; private static SecureRandom randGen = new SecureRandom(); private static char numbersAndLetters[] = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); private static final char zeroArray[] = "0000000000000000000000000000000000000000000000000000000000000000".toCharArray(); public static final String OTHER_SAFE_CHARACTERS = "!'\",.?*@`~-+_=/\\:$"; private static char WS_ARRAY[]; private static Map HTML_ENTITY_MAP; private static final String PLAIN_ASCII = "AaEeIiOoUuAaEeIiOoUuYyAaEeIiOoUuYyAaOoAaEeIiOoUuYyAaCc"; private static final String UNICODE = "\300\340\310\350\314\354\322\362\331\371\301\341\311\351\315\355\323\363\332\372\335\375\302\342\312\352\316\356\324\364\333\373\u0176\u0177\303\343\325\365\304\344\313\353\317\357\326\366\334\374\u0178\377\305\345\307\347"; public static String getValidEmailDomains() { return "com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi"; } private StringUtils() { } public static String replace(String string, String oldString, String newString) { if(string == null) return null; if(newString == null) return string; int i = 0; if((i = string.indexOf(oldString, i)) >= 0) { char string2[] = string.toCharArray(); char newString2[] = newString.toCharArray(); int oLength = oldString.length(); StringBuffer buf = new StringBuffer(string2.length); buf.append(string2, 0, i).append(newString2); i += oLength; int j; for(j = i; (i = string.indexOf(oldString, i)) > 0; j = i) { buf.append(string2, j, i - j).append(newString2); i += oLength; } buf.append(string2, j, string2.length - j); return buf.toString(); } else { return string; } } public static String replaceIgnoreCase(String line, String oldString, String newString) { if(line == null) return null; String lcLine = line.toLowerCase(); String lcOldString = oldString.toLowerCase(); int i = 0; if((i = lcLine.indexOf(lcOldString, i)) >= 0) { char line2[] = line.toCharArray(); char newString2[] = newString.toCharArray(); int oLength = oldString.length(); StringBuffer buf = new StringBuffer(line2.length); buf.append(line2, 0, i).append(newString2); i += oLength; int j; for(j = i; (i = lcLine.indexOf(lcOldString, i)) > 0; j = i) { buf.append(line2, j, i - j).append(newString2); i += oLength; } buf.append(line2, j, line2.length - j); return buf.toString(); } else { return line; } } public static String replaceIgnoreCase(String line, String oldString, String newString, int count[]) { if(line == null) return null; String lcLine = line.toLowerCase(); String lcOldString = oldString.toLowerCase(); int i = 0; if((i = lcLine.indexOf(lcOldString, i)) >= 0) { int counter = 1; char line2[] = line.toCharArray(); char newString2[] = newString.toCharArray(); int oLength = oldString.length(); StringBuffer buf = new StringBuffer(line2.length); buf.append(line2, 0, i).append(newString2); i += oLength; int j; for(j = i; (i = lcLine.indexOf(lcOldString, i)) > 0; j = i) { counter++; buf.append(line2, j, i - j).append(newString2); i += oLength; } buf.append(line2, j, line2.length - j); count[0] = counter; return buf.toString(); } else { return line; } } public static String replace(String line, String oldString, String newString, int count[]) { if(line == null) return null; int i = 0; if((i = line.indexOf(oldString, i)) >= 0) { int counter = 1; char line2[] = line.toCharArray(); char newString2[] = newString.toCharArray(); int oLength = oldString.length(); StringBuffer buf = new StringBuffer(line2.length); buf.append(line2, 0, i).append(newString2); i += oLength; int j; for(j = i; (i = line.indexOf(oldString, i)) > 0; j = i) { counter++; buf.append(line2, j, i - j).append(newString2); i += oLength; } buf.append(line2, j, line2.length - j); count[0] = counter; return buf.toString(); } else { return line; } } public static String stripTags(String in) { if(in == null) return null; else return stripTags(in, false); } public static String stripTags(String in, boolean stripBRTag) { if(in == null) return null; int i = 0; int last = 0; char input[] = in.toCharArray(); int len = input.length; StringBuffer out = new StringBuffer((int)((double)len * 1.3D)); for(; i < len; i++) { char ch = input[i]; if(ch > '>') continue; if(ch == '<') { if(!stripBRTag && i + 3 < len && input[i + 1] == 'b' && input[i + 2] == 'r' && input[i + 3] == '>') { i += 3; continue; } if(i > last) { if(last > 0) out.append(" "); out.append(input, last, i - last); } last = i + 1; continue; } if(ch == '>') last = i + 1; } if(last == 0) return in; if(i > last) out.append(input, last, i - last); return out.toString(); } public static String escapeHTMLTags(String in) { if(in == null) return null; int i = 0; int last = 0; char input[] = in.toCharArray(); int len = input.length; StringBuffer out = new StringBuffer((int)((double)len * 1.3D)); for(; i < len; i++) { char ch = input[i]; if(ch > '>') continue; if(ch == '<') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(LT_ENCODE); continue; } if(ch == '>') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(GT_ENCODE); continue; } if(ch == '"') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(QUOTE_ENCODE); continue; } if(ch != '&') continue; if(i > last) out.append(input, last, i - last); last = i + 1; out.append(AMP_ENCODE); } if(last == 0) return in; if(i > last) out.append(input, last, i - last); return out.toString(); } public static synchronized String hash(String data) { if(digest == null) try { digest = MessageDigest.getInstance("MD5"); } catch(NoSuchAlgorithmException nsae) { Log.error("Failed to load the MD5 MessageDigest. Jive will be unable to function normally.", nsae); } try { digest.update(data.getBytes("utf-8")); } catch(UnsupportedEncodingException e) { Log.error(e.toString()); throw new UnsupportedOperationException((new StringBuilder()).append("Error computing hash: ").append(e.getMessage()).toString()); } return encodeHex(digest.digest()); } public static synchronized String hash(char data[]) { return hash(new String(data)); } public static String encodeHex(byte bytes[]) { return new String(Hex.encodeHex(bytes)); } public static byte[] decodeHex(String hex) { if(hex == null) return null; try { return Hex.decodeHex(hex.toCharArray()); } catch(DecoderException e) { Log.error(e.toString()); } return null; } public static String encodeBase64(String data) { byte bytes[] = null; try { bytes = data.getBytes("UTF-8"); } catch(UnsupportedEncodingException uee) { Log.error(uee.toString()); } return encodeBase64(bytes); } public static String decodeBase64(String data) { try { byte decoded[]; byte bytes[] = data.getBytes("UTF-8"); decoded = decodeBase64(bytes); if(decoded == null) return ""; return new String(decoded, "UTF-8"); } catch(Exception uee) { Log.error(uee.toString()); } return ""; } public static String encodeAlphaNumeric(long toEncode) { if(toEncode < 0L) throw new UnsupportedOperationException("Encoding of negative numbers is not supported"); if(toEncode == 0L) return "0"; StringBuffer buff = new StringBuffer(); for(; toEncode != 0L; toEncode /= base.length) buff.append(base[(int)(toEncode % (long)base.length)]); return buff.reverse().toString(); } public static long decodeAlphaNumeric(String encoded) { if(encoded.equals("0")) return 0L; StringBuffer buff = (new StringBuffer(encoded)).reverse(); long result = 0L; for(int i = 0; i < buff.length(); i++) { char current = buff.charAt(i); long currentVal = indexes[current]; result += currentVal * (long)Math.pow(base.length, i); } if(result < 0L) throw new IllegalArgumentException((new StringBuilder()).append("Input string ").append(encoded).append(" did not decode to a positive long value.").toString()); else return result; } public static String encodeBase64(byte data[]) { boolean lineSep = false; int sLen = data == null ? 0 : data.length; if(sLen == 0) return ""; int eLen = (sLen / 3) * 3; int cCnt = (sLen - 1) / 3 + 1 << 2; int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); char dArr[] = new char[dLen]; int s = 0; int d = 0; int cc = 0; do { if(s >= eLen) break; int i = (data[s++] & 0xff) << 16 | (data[s++] & 0xff) << 8 | data[s++] & 0xff; dArr[d++] = CA[i >>> 18 & 0x3f]; dArr[d++] = CA[i >>> 12 & 0x3f]; dArr[d++] = CA[i >>> 6 & 0x3f]; dArr[d++] = CA[i & 0x3f]; if(lineSep && ++cc == 19 && d < dLen - 2) { dArr[d++] = '\r'; dArr[d++] = '\n'; cc = 0; } } while(true); int left = sLen - eLen; if(left > 0) { int i = (data[eLen] & 0xff) << 10 | (left != 2 ? 0 : (data[sLen - 1] & 0xff) << 2); dArr[dLen - 4] = CA[i >> 12]; dArr[dLen - 3] = CA[i >>> 6 & 0x3f]; dArr[dLen - 2] = left != 2 ? '=' : CA[i & 0x3f]; dArr[dLen - 1] = '='; } return new String(dArr); } public static byte[] decodeBase64(byte bytes[]) { int sLen = bytes.length; int sepCnt = 0; for(int i = 0; i < sLen; i++) if(IA[bytes[i] & 0xff] < 0) sepCnt++; if((sLen - sepCnt) % 4 != 0) return null; int pad = 0; int i = sLen; do { if(i <= 1 || IA[bytes[--i] & 0xff] > 0) break; if(bytes[i] == 61) pad++; } while(true); int len = ((sLen - sepCnt) * 6 >> 3) - pad; byte dArr[] = new byte[len]; int s = 0; int d = 0; do { if(d >= len) break; i = 0; for(int j = 0; j < 4; j++) { int c = IA[bytes[s++] & 0xff]; if(c >= 0) i |= c << 18 - j * 6; else j--; } dArr[d++] = (byte)(i >> 16); if(d < len) { dArr[d++] = (byte)(i >> 8); if(d < len) dArr[d++] = (byte)i; } } while(true); return dArr; } public static String URLEncode(String original, String charset) throws UnsupportedEncodingException { if(original == null) return null; byte octets[]; try { octets = original.getBytes(charset); } catch(UnsupportedEncodingException error) { throw new UnsupportedEncodingException(); } StringBuffer buf = new StringBuffer(octets.length); byte arr$[] = octets; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { byte octet = arr$[i$]; char c = (char)octet; if(allowed_query.get(c)) { buf.append(c); } else { buf.append('%'); char hexadecimal = Character.forDigit(octet >> 4 & 0xf, 16); buf.append(Character.toUpperCase(hexadecimal)); hexadecimal = Character.forDigit(octet & 0xf, 16); buf.append(Character.toUpperCase(hexadecimal)); } } return buf.toString(); } public static String URLEncode(String string) { try { return URLEncoder.encode(string, "UTF-8"); } catch(UnsupportedEncodingException uee) { Log.warn("URL encoding failed." + uee); } return string; } public static String[] toLowerCaseWordArray(String text) { if(text == null || text.length() == 0) return new String[0]; ArrayList wordList = new ArrayList(); BreakIterator boundary = BreakIterator.getWordInstance(); boundary.setText(text); int start = 0; for(int end = boundary.next(); end != -1; end = boundary.next()) { String tmp = text.substring(start, end).trim(); tmp = replace(tmp, "+", ""); tmp = replace(tmp, "/", ""); tmp = replace(tmp, "\\", ""); tmp = replace(tmp, "#", ""); tmp = replace(tmp, "*", ""); tmp = replace(tmp, ")", ""); tmp = replace(tmp, "(", ""); tmp = replace(tmp, "&", ""); if(tmp.length() > 0) wordList.add(tmp); start = end; } return (String[])wordList.toArray(new String[wordList.size()]); } public static String randomString(int length) { if(length < 1) return null; char randBuffer[] = new char[length]; for(int i = 0; i < randBuffer.length; i++) randBuffer[i] = numbersAndLetters[randGen.nextInt(71)]; return new String(randBuffer); } public static String chop(String string, int length) { if(string == null) return null; if(length <= 0) throw new IllegalArgumentException("Length must be > 0"); if(string.length() <= length + 2) { return string; } else { StringBuffer buf = new StringBuffer(string.substring(0, length)); buf.append("..."); return buf.toString(); } } public static String chopAtWord(String string, int length, int minLength) { if(length < 2) throw new IllegalArgumentException((new StringBuilder()).append("Length specified (").append(length).append(") must be > 2").toString()); if(minLength >= length) throw new IllegalArgumentException("minLength must be smaller than length"); int sLength = string != null ? string.length() : -1; if(sLength < 1) return string; if(minLength != -1 && sLength < minLength) return string; if(minLength == -1 && sLength < length) return string; char charArray[] = string.toCharArray(); if(sLength > length) { sLength = length; for(int i = 0; i < sLength - 1; i++) { if(charArray[i] == '\r' && charArray[i + 1] == '\n') return string.substring(0, i + 1); if(charArray[i] == '\n') return string.substring(0, i); } if(charArray[sLength - 1] == '\n') return string.substring(0, sLength - 1); for(int i = sLength - 1; i > 0; i--) if(charArray[i] == ' ') return string.substring(0, i).trim(); } else if(minLength != -1 && sLength > minLength) { for(int i = 0; i < minLength; i++) if(charArray[i] == ' ') return string; } if(minLength > -1 && minLength <= string.length()) return string.substring(0, minLength); else return string.substring(0, length); } public static String chopAtWord(String string, int length) { return chopAtWord(string, length, -1); } public static String chopAtWordsAround(String input, String wordList[], int numChars) { if(input == null || "".equals(input.trim()) || wordList == null || wordList.length == 0 || numChars == 0) return ""; String lc = input.toLowerCase(); String arr$[] = wordList; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String aWordList = arr$[i$]; int pos = lc.indexOf(aWordList); if(pos > -1) { int beginIdx = pos - numChars; if(beginIdx < 0) beginIdx = 0; int endIdx = pos + numChars; if(endIdx > input.length() - 1) endIdx = input.length() - 1; char chars[]; for(chars = input.toCharArray(); beginIdx > 0 && chars[beginIdx] != ' ' && chars[beginIdx] != '\n' && chars[beginIdx] != '\r'; beginIdx--); for(; endIdx < input.length() && chars[endIdx] != ' ' && chars[endIdx] != '\n' && chars[endIdx] != '\r'; endIdx++); return input.substring(beginIdx, endIdx); } } return input.substring(0, input.length() < 200 ? input.length() : 200); } public static String wordWrap(String input, int width, Locale locale) { if(input == null) return ""; if(width < 5) return input; if(width >= input.length()) return input; if(locale == null) locale = JiveGlobals.getLocale(); StringBuffer buf = new StringBuffer(input); boolean endOfLine = false; int lineStart = 0; for(int i = 0; i < buf.length(); i++) { if(buf.charAt(i) == '\n') { lineStart = i + 1; endOfLine = true; } if(i <= (lineStart + width) - 1) continue; if(!endOfLine) { int limit = i - lineStart - 1; BreakIterator breaks = BreakIterator.getLineInstance(locale); breaks.setText(buf.substring(lineStart, i)); int end = breaks.last(); if(end == limit + 1 && !Character.isWhitespace(buf.charAt(lineStart + end))) end = breaks.preceding(end - 1); if(end != -1 && end == limit + 1) { buf.replace(lineStart + end, lineStart + end + 1, "\n"); lineStart += end; continue; } if(end != -1 && end != 0) { buf.insert(lineStart + end, '\n'); lineStart = lineStart + end + 1; } else { buf.insert(i, '\n'); lineStart = i + 1; } } else { buf.insert(i, '\n'); lineStart = i + 1; endOfLine = false; } } return buf.toString(); } public static String highlightWords(String string, String words[], String startHighlight, String endHighlight) { if(string == null || words == null || startHighlight == null || endHighlight == null) return null; StringBuffer regexp = new StringBuffer(); regexp.append("(?i)\\b("); for(int x = 0; x < words.length; x++) { words[x] = words[x].replaceAll("([\\$\\?\\|\\/\\.\\}\\{])", "\\\\$1"); regexp.append(words[x]); if(x != words.length - 1) regexp.append("|"); } regexp.append(")"); return string.replaceAll(regexp.toString(), (new StringBuilder()).append(startHighlight).append("$1").append(endHighlight).toString()); } public static String escapeForSQL(String string) { if(string == null) return null; if(string.length() == 0) return string; char input[] = string.toCharArray(); int i = 0; int last = 0; int len = input.length; StringBuffer out = null; for(; i < len; i++) { char ch = input[i]; if(ch != '\'') continue; if(out == null) out = new StringBuffer(len + 2); if(i > last) out.append(input, last, i - last); last = i + 1; out.append('\'').append('\''); } if(out == null) return string; if(i > last) out.append(input, last, i - last); return out.toString(); } public static String escapeForXML(String string) { if(string == null) return null; int i = 0; int last = 0; char input[] = string.toCharArray(); int len = input.length; StringBuffer out = new StringBuffer((int)((double)len * 1.3D)); for(; i < len; i++) { char ch = input[i]; if(ch > '>') continue; if(ch == '<') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(LT_ENCODE); continue; } if(ch == '>') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(GT_ENCODE); continue; } if(ch == '&') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(AMP_ENCODE); continue; } if(ch == '"') { if(i > last) out.append(input, last, i - last); last = i + 1; out.append(QUOTE_ENCODE); continue; } if(ch == '\n' || ch == '\r' || ch == '\t' || ch >= ' ') continue; if(i > last) out.append(input, last, i - last); last = i + 1; } if(last == 0) return string; if(i > last) out.append(input, last, i - last); return out.toString(); } public static String escapeEntitiesInXmlString(String xmlString) { xmlString = xmlString.replaceAll("&", String.valueOf(AMP_ENCODE)); return xmlString; } public static String unescapeFromXML(String string) { string = replace(string, "<", "<"); string = replace(string, ">", ">"); string = replace(string, """, "\""); return replace(string, "&", "&"); } public static String zeroPadString(String string, int length) { if(string == null || string.length() > length) { return string; } else { StringBuffer buf = new StringBuffer(length); buf.append(zeroArray, 0, length - string.length()).append(string); return buf.toString(); } } public static String dateToMillis(Date date) { return Long.toString(date.getTime()); } public static boolean isValidEmailAddress(String addr) { if(addr == null) return false; addr = addr.trim(); if(addr.length() == 0) return false; Matcher matcher = basicAddressPattern.matcher(addr); if(!matcher.matches()) return false; String userPart = matcher.group(1); String domainPart = matcher.group(2); matcher = validUserPattern.matcher(userPart); if(!matcher.matches()) return false; matcher = ipDomainPattern.matcher(domainPart); if(matcher.matches()) { for(int i = 1; i < 5; i++) { String num = matcher.group(i); if(num == null) return false; if(Integer.parseInt(num) > 254) return false; } return true; } matcher = domainPattern.matcher(domainPart); if(matcher.matches()) { String tld = matcher.group(matcher.groupCount()); matcher = tldPattern.matcher(tld); return tld.length() == 3 || matcher.matches(); } else { return "localhost".equals(domainPart); } } public static String removeIgnorableCharacters(String input) { if(input == null) return input; StringBuffer buf = new StringBuffer(); char chars[] = input.toCharArray(); int i = 0; for(int n = input.length(); i < n; i++) if(!Character.isIdentifierIgnorable(chars[i])) buf.append(chars[i]); return buf.toString(); } public static String getSpacer(String spacer, int num) { if(num <= 1) return spacer; if(spacer == null || "".equals(spacer)) return spacer; StringBuffer buf = new StringBuffer(spacer.length() * num); for(int i = 0; i < num; i++) buf.append(spacer); return buf.toString(); } public static String abbreviate(String str, int maxWidth) { if(null == str) return null; if(str.length() <= maxWidth) return str; else return (new StringBuilder()).append(chopAtWord(str, maxWidth)).append("...").toString(); } /** * @deprecated Method getTimeFromLong is deprecated */ public static String getTimeFromLong(long time) { return getTimeFromLong(time, 2); } /** * @deprecated Method getTimeFromLong is deprecated */ public static String getTimeFromLong(long time, int limit) { return (new DateUtils()).displayFriendly(time, limit); } public static boolean containsNonAlphanumeric(String str) { char testChars[] = str.toCharArray(); char arr$[] = testChars; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { char testChar = arr$[i$]; if(!Character.isLetterOrDigit(testChar)) return true; } return false; } public static String stripWhitespace(String str) { if(str == null) return null; Matcher matcher = WHITESPACE.matcher(str); StringBuffer buffer = new StringBuffer(); for(; matcher.find(); matcher.appendReplacement(buffer, "")); matcher.appendTail(buffer); return buffer.toString(); } public static boolean areEqualIgnoreCase(String s1, String s2) { if(s1 == null && s2 == null) return true; if(s1 != null) { s1 = s1.toLowerCase(); return s2 != null && s1.equals(s2.toLowerCase()); } else { return false; } } public static InputStream asStream(String data) { return new ByteArrayInputStream(data.getBytes()); } public static String removeTag(String s, String html) { return removeTag(s, new StringBuilder(html)).toString(); } private static StringBuilder removeSimpleTag(StringBuilder body, String tag) { return replaceAll(body, (new StringBuilder()).append("<").append(tag).append(" />").toString(), ""); } public static StringBuilder removeTag(String s, StringBuilder html) { String tagBegin = (new StringBuilder()).append("<").append(s).append(" ").toString(); String tagEnd = (new StringBuilder()).append("</").append(s).append(">").toString(); int start = html.indexOf(tagBegin); do { if(start == -1) break; int end = html.indexOf(tagEnd, start + 1); if(end != -1) { html.replace(start, end, ""); start = html.indexOf(tagBegin); } } while(true); return html; } public static StringBuilder removeTags(StringBuilder html, String tags[]) { String arr$[] = tags; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String tag = arr$[i$]; removeSimpleTag(html, tag); removeTag(tag, html); } return html; } private static String removeSimpleTag(String body, String tag) { String htmlTag = (new StringBuilder()).append("<").append(tag).append(" />").toString(); return body.replace(htmlTag, ""); } public static List occurs(String token, String s) { List locations = new ArrayList(); int i = 0; do { if(i == -1) break; i = s.indexOf(token, i); if(i != -1) { locations.add(Integer.valueOf(i)); i += token.length(); } } while(true); return locations; } public static String upperCaseFirstChar(String s) { String first = String.valueOf(s.charAt(0)); first = first.toUpperCase(); StringBuilder builder = new StringBuilder(); builder.append(first); builder.append(s.substring(1)); return builder.toString(); } public static boolean isWebSafeString(String str) { return isWebSafeString(str, "!'\",.?*@`~-+_=/\\:$"); } public static boolean isWebSafeString(String str, String otherSafeCharacters) { if(str == null) throw new NullPointerException("String to be tested cannot be null"); int sz = str.length(); for(int i = 0; i < sz; i++) { char iChar = str.charAt(i); if(Character.isLetterOrDigit(iChar) || Character.isSpaceChar(iChar)) continue; boolean found = false; int j = 0; do { if(j >= otherSafeCharacters.length()) break; char other = otherSafeCharacters.charAt(j); if(other == iChar) { found = true; break; } j++; } while(true); if(!found) return false; } return true; } public static String asString(List list) { if(list == null || list.isEmpty()) return ""; StringBuilder builder = new StringBuilder(); for(Iterator i$ = list.iterator(); i$.hasNext(); builder.append(",")) { long a = ((Long)i$.next()).longValue(); builder.append(a); } if(builder.charAt(builder.length() - 1) == ',') builder.deleteCharAt(builder.length() - 1); return builder.toString(); } public static List asList(String string) { if(string == null || "".equals(string)) return new ArrayList(); String tokens[] = string.split(","); ArrayList list = new ArrayList(); String arr$[] = tokens; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String t = arr$[i$]; try { long value = Long.parseLong(t); list.add(Long.valueOf(value)); } catch(NumberFormatException e) { } } return list; } public static String lowerFirstChar(String name) { String result = name; if(name != null && name.length() > 1) result = (new StringBuilder()).append(name.substring(0, 1).toLowerCase()).append(name.substring(1, name.length())).toString(); return result; } public static boolean isEqualToAnyOf(String s, String values[]) { String arr$[] = values; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String value = arr$[i$]; if(s.equals(value)) return true; } return false; } public static boolean isEqualToAnyOf(char c, char values[]) { char arr$[] = values; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { char value = arr$[i$]; if(c == value) return true; } return false; } public static boolean isEqualToAnyOfIgnoreCase(String s, String values[]) { s = s.toLowerCase(); String arr$[] = values; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String value = arr$[i$]; if(s.equals(value.toLowerCase())) return true; } return false; } public static String replaceAll(String text, String token, String repl) { return replaceAll(new StringBuilder(text), token, repl).toString(); } public static String join(List elements, String joinWith) { if(elements == null || elements.size() == 0) return null; StringBuilder buffer = new StringBuilder(56); for(Iterator i$ = elements.iterator(); i$.hasNext(); buffer.append(joinWith)) { String str = (String)i$.next(); buffer.append(str); } return buffer.toString(); } public static String join(String elements[], String joinWith) { if(elements == null || elements.length == 0) return null; StringBuilder buffer = new StringBuilder(56); String arr$[] = elements; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String str = arr$[i$]; buffer.append(str); buffer.append(joinWith); } return buffer.toString(); } public static StringBuilder replaceAll(StringBuilder text, String token, String repl) { int tokSize = token.length(); int i = 0; do { if(i == -1) break; i = text.indexOf(token, i); if(i != -1) { text.replace(i, i + tokSize, repl); i += repl.length(); } } while(true); return text; } public static String replaceAllKeys(String text, Map store) { StringBuilder stb = new StringBuilder(text); return replaceAllKeys(stb, store).toString(); } public static StringBuilder replaceAllKeys(StringBuilder stb, Map store) { List uuids = new ArrayList(store.keySet()); int loopCount = 0; label0: for(int maxLoops = uuids.size(); uuids.size() > 0 && loopCount < maxLoops; loopCount++) { Iterator i$ = store.keySet().iterator(); do { if(!i$.hasNext()) continue label0; String uuid = (String)i$.next(); String value = (String)store.get(uuid); int idx = stb.indexOf(uuid); if(idx != -1) { stb.replace(idx, idx + uuid.length(), value); uuids.remove(uuid); } } while(true); } return stb; } public static String replaceHtmlEntitiesWithValueOpt(String stb) { int size = stb.length(); StringReplacementHolder holder = new StringReplacementHolder(stb); int start = -1; for(int i = 0; i < size; i++) { if(start == -1 && stb.charAt(i) == '&') { start = i; continue; } if(isEqualToAnyOf(stb.charAt(i), new char[] { ' ', '\r', '\n' })) { start = -1; continue; } if(start == -1 || stb.charAt(i) != ';') continue; String key = stb.substring(start, i + 1); if(HTML_ENTITY_MAP.containsKey(key)) holder.addReplacement(start, i + 1, (String)HTML_ENTITY_MAP.get(key)); start = -1; } return holder.apply(); } public static String replaceHtmlEntitiesWithEmptyString(String stb) { Iterator i$ = HTML_ENTITY_MAP.keySet().iterator(); do { if(!i$.hasNext()) break; String key = (String)i$.next(); if(stb.contains(key)) stb = stb.replaceAll(key, ""); } while(true); i$ = HTML_ENTITY_MAP.values().iterator(); do { if(!i$.hasNext()) break; String value = (String)i$.next(); if(stb.contains(value)) stb = stb.replaceAll(value, ""); } while(true); return stb; } public static String getSpacer(char spacer, int num) { if(spacer == ' ' && num < WS_ARRAY.length) return new String(WS_ARRAY, 0, num); char space[] = new char[num]; for(int i = 0; i < space.length; i++) space[i] = spacer; return new String(space); } public static boolean startsWithAnyOf(String s, String values[]) { return startsWithAnyOf(s, ((Collection) (Arrays.asList(values)))); } public static boolean startsWithAnyOf(String s, Collection values) { if(s == null) return false; for(Iterator i$ = values.iterator(); i$.hasNext();) { String value = (String)i$.next(); if(s.startsWith(value)) return true; } return false; } public static Map createMap(Object keys[], Object values[]) { Map map = new HashMap(); if(keys.length != values.length) return map; for(int i = 0; i < keys.length; i++) map.put(keys[i], values[i]); return map; } public static boolean endsWithAnyOf(String s, String values[]) { return endsWithAnyOf(s, ((Collection) (Arrays.asList(values)))); } public static boolean endsWithAnyOf(String s, Collection values) { if(s == null) return false; for(Iterator i$ = values.iterator(); i$.hasNext();) { String value = (String)i$.next(); if(s.endsWith(value)) return true; } return false; } public static boolean containsAnyOf(String s, String values[]) { return containsAnyOf(s, ((Collection) (Arrays.asList(values)))); } public static boolean containsAnyOf(String s, Collection values) { if(s == null) return false; for(Iterator i$ = values.iterator(); i$.hasNext();) { String value = (String)i$.next(); if(s.contains(value)) return true; } return false; } public static String URLDecode(String original, String charset) { original = original.replace('+', ' '); int idx = original.indexOf('%'); if(idx != -1 && idx <= original.length() - 3 && isEqualToAnyOf(original.charAt(idx + 1), HEX_ENC_CHARS) && isEqualToAnyOf(original.charAt(idx + 2), HEX_ENC_CHARS)) try { String decoded = URLDecoder.decode(original, charset); return decoded.replace('+', ' '); } catch(Exception e) { e.printStackTrace(); } return original.replace('+', ' '); } public static String getShortDateFormat(Date date, Locale locale) { if(date == null) return ""; DateFormat shortDateFormat; if(locale != null) shortDateFormat = DateFormat.getDateInstance(3, locale); else shortDateFormat = DateFormat.getDateInstance(3); return shortDateFormat.format(date); } public static String setURLParameter(String url, String paramName, String paramValue) { Map urlParameters = new LinkedHashMap(); StringTokenizer queryStringTokenizer = new StringTokenizer(url, "?"); String baseURL = queryStringTokenizer.nextToken(); boolean isNewParameter = true; if(queryStringTokenizer.hasMoreTokens()) { String strQueryString = queryStringTokenizer.nextToken(); if(strQueryString != null) { for(StringTokenizer tokenizerNameValuePair = new StringTokenizer(strQueryString, "&"); tokenizerNameValuePair.hasMoreTokens();) try { String strNameValuePair = tokenizerNameValuePair.nextToken(); StringTokenizer tokenizerValue = new StringTokenizer(strNameValuePair, "="); String pName = tokenizerValue.nextToken(); String pValue = tokenizerValue.nextToken(); if(paramName.equals(pName)) { pValue = paramValue; isNewParameter = false; } urlParameters.put(pName, pValue); } catch(Throwable t) { } } } StringBuilder urlBuilder = (new StringBuilder(baseURL)).append("?"); Iterator params = urlParameters.keySet().iterator(); do { if(!params.hasNext()) break; String pName = (String)params.next(); String pValue = (String)urlParameters.get(pName); urlBuilder.append(pName).append("=").append(pValue); if(params.hasNext()) urlBuilder.append("&"); } while(true); if(isNewParameter) urlBuilder.append("&").append(paramName).append("=").append(paramValue); return urlBuilder.toString(); } public static boolean isASCIIURLSafe(String str) { return str != null && !"".equals(str.trim()) && !URL_SAFE.matcher(str).find(); } public static String makeURLSafe(String str) { return makeURLSafe(str, '-'); } public static String makeURLSafe(String str, char replacement) { if(str == null || !isASCIIURLSafe(String.valueOf(replacement))) return null; String trimmed = str.trim(); boolean ascii = str.trim().replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^A-Za-z\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).toLowerCase().replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0; if(ascii) { trimmed = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^0-9A-Za-z\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).toLowerCase(); if(trimmed.length() > 1 && (replacement == trimmed.charAt(0) || replacement == trimmed.charAt(trimmed.length() - 1))) { StringBuffer buf = new StringBuffer(trimmed); if(replacement == buf.charAt(0)) buf.deleteCharAt(0); if(replacement == buf.charAt(buf.length() - 1)) buf.deleteCharAt(buf.length() - 1); trimmed = buf.toString(); } } else { boolean hasLetters = str.trim().replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{L}\\p{Nd}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0; if(hasLetters) { trimmed = str.trim(); boolean cantLowercase = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{Lo}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)).replaceAll((new StringBuilder()).append("").append(replacement).toString(), "").replaceAll(" ", "").length() > 0; trimmed = trimmed.replaceAll((new StringBuilder()).append("([\\p{Punct}&&[^\\").append(replacement).append("]]+)").toString(), "").replaceAll((new StringBuilder()).append("([^\\p{L}\\p{Nd}\\").append(replacement).append("]+)").toString(), String.valueOf(replacement)); if(!cantLowercase) trimmed = trimmed.toLowerCase(); } else { trimmed = trimmed.toLowerCase(); } } return "".equals(trimmed) || "-".equals(trimmed) ? String.valueOf(Math.abs(str.hashCode())) : trimmed; } public static String encodeVCard(String toEncode) { return encodeVCard(toEncode, false); } public static String encodeVCard(String toEncode, boolean isQuotedPrintable) { if(toEncode == null) return toEncode; String quotedPrintable = toEncode.replace(";", "\\;"); if(isQuotedPrintable) { QuotedPrintableCodec codec = new QuotedPrintableCodec(); try { quotedPrintable = codec.encode(quotedPrintable); } catch(EncoderException e) { throw new RuntimeException("Error encoding vcard", e); } } return quotedPrintable; } public static char[] clearOutofRangeXmlChars(String text) { char chars[] = text.toCharArray(); for(int i = 0; i < chars.length; i++) if(chars[i] != '\t' && chars[i] != '\n' && chars[i] != '\r' && (chars[i] < ' ' || chars[i] > '\uD7FF') && (chars[i] < '\uE000' || chars[i] > '\uFFFD') && (chars[i] < '\0' || chars[i] > '\0')) chars[i] = ' '; return chars; } public static String[] slice(String source[], int start, int end) { if(source == null) return null; if(start == end) return new String[0]; int e = Math.max(start, end); e = Math.min(e, source.length); int s = Math.min(start, end); String newArray[] = new String[e - s]; int i = 0; for(; s < e; s++) newArray[i++] = source[s]; return newArray; } public static String[] slice(String source[], int start) { if(source == null) return null; else return slice(source, start, source.length); } public static boolean isNullOrEmpty(String test) { return test == null || test.equals(""); } public static String convertNonAscii(String s) { if(s == null) return null; StringBuffer sb = new StringBuffer(); int n = s.length(); for(int i = 0; i < n; i++) { char c = s.charAt(i); int pos = "\300\340\310\350\314\354\322\362\331\371\301\341\311\351\315\355\323\363\332\372\335\375\302\342\312\352\316\356\324\364\333\373\u0176\u0177\303\343\325\365\304\344\313\353\317\357\326\366\334\374\u0178\377\305\345\307\347".indexOf(c); if(pos > -1) sb.append("AaEeIiOoUuAaEeIiOoUuYyAaEeIiOoUuYyAaOoAaEeIiOoUuYyAaCc".charAt(pos)); else sb.append(c); } return sb.toString(); } public static boolean isRegex(String s) { return s.indexOf('*') != -1 || s.indexOf('\\') != -1 || s.indexOf('^') != -1 || s.indexOf('.') != -1 || s.indexOf('$') != -1 || s.indexOf('[') != -1 && s.indexOf(']') != -1 || s.indexOf('{') != -1 && s.indexOf('}') != -1; } static { String basicAddress = "^([\\w\\.-]+)@([\\w\\.-]+)$"; String specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]"; String validChars = (new StringBuilder()).append("[^ \f\n\r\t").append(specialChars).append("]").toString(); String atom = (new StringBuilder()).append(validChars).append("+").toString(); String quotedUser = "(\"[^\"]+\")"; String word = (new StringBuilder()).append("(").append(atom).append("|").append(quotedUser).append(")").toString(); String validUser = (new StringBuilder()).append("^").append(word).append("(\\.").append(word).append(")*$").toString(); String domain = (new StringBuilder()).append("^").append(atom).append("(\\.").append(atom).append(")+$").toString(); String ipDomain = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"; String knownTLDs = "^\\.(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi)$"; basicAddressPattern = Pattern.compile(basicAddress, 2); validUserPattern = Pattern.compile(validUser, 2); domainPattern = Pattern.compile(domain, 2); ipDomainPattern = Pattern.compile(ipDomain, 2); tldPattern = Pattern.compile(knownTLDs, 2); base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); indexes = new int[256]; Arrays.fill(indexes, -1); int i = 0; for(int iS = base.length; i < iS; i++) indexes[base[i]] = i; CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); IA = new int[256]; Arrays.fill(IA, -1); i = 0; for(int iS = CA.length; i < iS; i++) IA[CA[i]] = i; IA[61] = 0; allowed_query = new BitSet(256); for(i = 48; i <= 57; i++) allowed_query.set(i); for(i = 97; i <= 122; i++) allowed_query.set(i); for(i = 65; i <= 90; i++) allowed_query.set(i); allowed_query.set(45); allowed_query.set(95); allowed_query.set(46); allowed_query.set(33); allowed_query.set(126); allowed_query.set(42); allowed_query.set(39); allowed_query.set(40); allowed_query.set(41); WS_ARRAY = new char[256]; for(i = 0; i < WS_ARRAY.length; i++) WS_ARRAY[i] = ' '; HTML_ENTITY_MAP = new HashMap(); HTML_ENTITY_MAP.put(" ", "\240"); HTML_ENTITY_MAP.put(" ", "\240"); HTML_ENTITY_MAP.put("¡", "\241"); HTML_ENTITY_MAP.put("¡", "\241"); HTML_ENTITY_MAP.put("¢", "\242"); HTML_ENTITY_MAP.put("¢", "\242"); HTML_ENTITY_MAP.put("£", "\243"); HTML_ENTITY_MAP.put("£", "\243"); HTML_ENTITY_MAP.put("¤", "\244"); HTML_ENTITY_MAP.put("¤", "\244"); HTML_ENTITY_MAP.put("¥", "\245"); HTML_ENTITY_MAP.put("¥", "\245"); HTML_ENTITY_MAP.put("¦", "\246"); HTML_ENTITY_MAP.put("¦", "\246"); HTML_ENTITY_MAP.put("§", "\247"); HTML_ENTITY_MAP.put("§", "\247"); HTML_ENTITY_MAP.put("¨", "\250"); HTML_ENTITY_MAP.put("¨", "\250"); HTML_ENTITY_MAP.put("©", "\251"); HTML_ENTITY_MAP.put("©", "\251"); HTML_ENTITY_MAP.put("ª", "\252"); HTML_ENTITY_MAP.put("ª", "\252"); HTML_ENTITY_MAP.put("«", "\253"); HTML_ENTITY_MAP.put("«", "\253"); HTML_ENTITY_MAP.put("¬", "\254"); HTML_ENTITY_MAP.put("¬", "\254"); HTML_ENTITY_MAP.put("­", "\255"); HTML_ENTITY_MAP.put("­", "\255"); HTML_ENTITY_MAP.put("®", "\256"); HTML_ENTITY_MAP.put("®", "\256"); HTML_ENTITY_MAP.put("¯", "\257"); HTML_ENTITY_MAP.put("¯", "\257"); HTML_ENTITY_MAP.put("°", "\260"); HTML_ENTITY_MAP.put("°", "\260"); HTML_ENTITY_MAP.put("±", "\261"); HTML_ENTITY_MAP.put("±", "\261"); HTML_ENTITY_MAP.put("²", "\262"); HTML_ENTITY_MAP.put("²", "\262"); HTML_ENTITY_MAP.put("³", "\263"); HTML_ENTITY_MAP.put("³", "\263"); HTML_ENTITY_MAP.put("´", "\264"); HTML_ENTITY_MAP.put("´", "\264"); HTML_ENTITY_MAP.put("µ", "\265"); HTML_ENTITY_MAP.put("µ", "\265"); HTML_ENTITY_MAP.put("¶", "\266"); HTML_ENTITY_MAP.put("¶", "\266"); HTML_ENTITY_MAP.put("·", "\267"); HTML_ENTITY_MAP.put("·", "\267"); HTML_ENTITY_MAP.put("¸", "\270"); HTML_ENTITY_MAP.put("¸", "\270"); HTML_ENTITY_MAP.put("¹", "\271"); HTML_ENTITY_MAP.put("¹", "\271"); HTML_ENTITY_MAP.put("º", "\272"); HTML_ENTITY_MAP.put("º", "\272"); HTML_ENTITY_MAP.put("»", "\273"); HTML_ENTITY_MAP.put("»", "\273"); HTML_ENTITY_MAP.put("¼", "\274"); HTML_ENTITY_MAP.put("¼", "\274"); HTML_ENTITY_MAP.put("½", "\275"); HTML_ENTITY_MAP.put("½", "\275"); HTML_ENTITY_MAP.put("¾", "\276"); HTML_ENTITY_MAP.put("¾", "\276"); HTML_ENTITY_MAP.put("¿", "\277"); HTML_ENTITY_MAP.put("¿", "\277"); HTML_ENTITY_MAP.put("À", "\300"); HTML_ENTITY_MAP.put("À", "\300"); HTML_ENTITY_MAP.put("Á", "\301"); HTML_ENTITY_MAP.put("Á", "\301"); HTML_ENTITY_MAP.put("Â", "\302"); HTML_ENTITY_MAP.put("Â", "\302"); HTML_ENTITY_MAP.put("Ã", "\303"); HTML_ENTITY_MAP.put("Ã", "\303"); HTML_ENTITY_MAP.put("Ä", "\304"); HTML_ENTITY_MAP.put("Ä", "\304"); HTML_ENTITY_MAP.put("Å", "\305"); HTML_ENTITY_MAP.put("Å", "\305"); HTML_ENTITY_MAP.put("Æ", "\306"); HTML_ENTITY_MAP.put("Æ", "\306"); HTML_ENTITY_MAP.put("Ç", "\307"); HTML_ENTITY_MAP.put("Ç", "\307"); HTML_ENTITY_MAP.put("È", "\310"); HTML_ENTITY_MAP.put("È", "\310"); HTML_ENTITY_MAP.put("É", "\311"); HTML_ENTITY_MAP.put("É", "\311"); HTML_ENTITY_MAP.put("Ê", "\312"); HTML_ENTITY_MAP.put("Ê", "\312"); HTML_ENTITY_MAP.put("Ë", "\313"); HTML_ENTITY_MAP.put("Ë", "\313"); HTML_ENTITY_MAP.put("Ì", "\314"); HTML_ENTITY_MAP.put("Ì", "\314"); HTML_ENTITY_MAP.put("Í", "\315"); HTML_ENTITY_MAP.put("Í", "\315"); HTML_ENTITY_MAP.put("Î", "\316"); HTML_ENTITY_MAP.put("Î", "\316"); HTML_ENTITY_MAP.put("Ï", "\317"); HTML_ENTITY_MAP.put("Ï", "\317"); HTML_ENTITY_MAP.put("Ð", "\320"); HTML_ENTITY_MAP.put("Ð", "\320"); HTML_ENTITY_MAP.put("Ñ", "\321"); HTML_ENTITY_MAP.put("Ñ", "\321"); HTML_ENTITY_MAP.put("Ò", "\322"); HTML_ENTITY_MAP.put("Ò", "\322"); HTML_ENTITY_MAP.put("Ó", "\323"); HTML_ENTITY_MAP.put("Ó", "\323"); HTML_ENTITY_MAP.put("Ô", "\324"); HTML_ENTITY_MAP.put("Ô", "\324"); HTML_ENTITY_MAP.put("Õ", "\325"); HTML_ENTITY_MAP.put("Õ", "\325"); HTML_ENTITY_MAP.put("Ö", "\326"); HTML_ENTITY_MAP.put("Ö", "\326"); HTML_ENTITY_MAP.put("×", "\327"); HTML_ENTITY_MAP.put("×", "\327"); HTML_ENTITY_MAP.put("Ø", "\330"); HTML_ENTITY_MAP.put("Ø", "\330"); HTML_ENTITY_MAP.put("Ù", "\331"); HTML_ENTITY_MAP.put("Ù", "\331"); HTML_ENTITY_MAP.put("Ú", "\332"); HTML_ENTITY_MAP.put("Ú", "\332"); HTML_ENTITY_MAP.put("Û", "\333"); HTML_ENTITY_MAP.put("Û", "\333"); HTML_ENTITY_MAP.put("Ü", "\334"); HTML_ENTITY_MAP.put("Ü", "\334"); HTML_ENTITY_MAP.put("Ý", "\335"); HTML_ENTITY_MAP.put("Ý", "\335"); HTML_ENTITY_MAP.put("Þ", "\336"); HTML_ENTITY_MAP.put("Þ", "\336"); HTML_ENTITY_MAP.put("ß", "\337"); HTML_ENTITY_MAP.put("ß", "\337"); HTML_ENTITY_MAP.put("à", "\340"); HTML_ENTITY_MAP.put("à", "\340"); HTML_ENTITY_MAP.put("á", "\341"); HTML_ENTITY_MAP.put("á", "\341"); HTML_ENTITY_MAP.put("â", "\342"); HTML_ENTITY_MAP.put("â", "\342"); HTML_ENTITY_MAP.put("ã", "\343"); HTML_ENTITY_MAP.put("ã", "\343"); HTML_ENTITY_MAP.put("ä", "\344"); HTML_ENTITY_MAP.put("ä", "\344"); HTML_ENTITY_MAP.put("å", "\345"); HTML_ENTITY_MAP.put("å", "\345"); HTML_ENTITY_MAP.put("æ", "\346"); HTML_ENTITY_MAP.put("æ", "\346"); HTML_ENTITY_MAP.put("ç", "\347"); HTML_ENTITY_MAP.put("ç", "\347"); HTML_ENTITY_MAP.put("è", "\350"); HTML_ENTITY_MAP.put("è", "\350"); HTML_ENTITY_MAP.put("é", "\351"); HTML_ENTITY_MAP.put("é", "\351"); HTML_ENTITY_MAP.put("ê", "\352"); HTML_ENTITY_MAP.put("ê", "\352"); HTML_ENTITY_MAP.put("ë", "\353"); HTML_ENTITY_MAP.put("ë", "\353"); HTML_ENTITY_MAP.put("ì", "\354"); HTML_ENTITY_MAP.put("ì", "\354"); HTML_ENTITY_MAP.put("í", "\355"); HTML_ENTITY_MAP.put("í", "\355"); HTML_ENTITY_MAP.put("î", "\356"); HTML_ENTITY_MAP.put("î", "\356"); HTML_ENTITY_MAP.put("ï", "\357"); HTML_ENTITY_MAP.put("ï", "\357"); HTML_ENTITY_MAP.put("ð", "\360"); HTML_ENTITY_MAP.put("ð", "\360"); HTML_ENTITY_MAP.put("ñ", "\361"); HTML_ENTITY_MAP.put("ñ", "\361"); HTML_ENTITY_MAP.put("ò", "\362"); HTML_ENTITY_MAP.put("ò", "\362"); HTML_ENTITY_MAP.put("ó", "\363"); HTML_ENTITY_MAP.put("ó", "\363"); HTML_ENTITY_MAP.put("ô", "\364"); HTML_ENTITY_MAP.put("ô", "\364"); HTML_ENTITY_MAP.put("õ", "\365"); HTML_ENTITY_MAP.put("õ", "\365"); HTML_ENTITY_MAP.put("ö", "\366"); HTML_ENTITY_MAP.put("ö", "\366"); HTML_ENTITY_MAP.put("÷", "\367"); HTML_ENTITY_MAP.put("÷", "\367"); HTML_ENTITY_MAP.put("ø", "\370"); HTML_ENTITY_MAP.put("ø", "\370"); HTML_ENTITY_MAP.put("ù", "\371"); HTML_ENTITY_MAP.put("ù", "\371"); HTML_ENTITY_MAP.put("ú", "\372"); HTML_ENTITY_MAP.put("ú", "\372"); HTML_ENTITY_MAP.put("û", "\373"); HTML_ENTITY_MAP.put("û", "\373"); HTML_ENTITY_MAP.put("ü", "\374"); HTML_ENTITY_MAP.put("ü", "\374"); HTML_ENTITY_MAP.put("ý", "\375"); HTML_ENTITY_MAP.put("ý", "\375"); HTML_ENTITY_MAP.put("þ", "\376"); HTML_ENTITY_MAP.put("þ", "\376"); HTML_ENTITY_MAP.put("ÿ", "\377"); HTML_ENTITY_MAP.put("ÿ", "\377"); HTML_ENTITY_MAP.put("ƒ", "\u0192"); HTML_ENTITY_MAP.put("ƒ", "\u0192"); HTML_ENTITY_MAP.put("Α", "\u0391"); HTML_ENTITY_MAP.put("Α", "\u0391"); HTML_ENTITY_MAP.put("Β", "\u0392"); HTML_ENTITY_MAP.put("Β", "\u0392"); HTML_ENTITY_MAP.put("Γ", "\u0393"); HTML_ENTITY_MAP.put("Γ", "\u0393"); HTML_ENTITY_MAP.put("Δ", "\u0394"); HTML_ENTITY_MAP.put("Δ", "\u0394"); HTML_ENTITY_MAP.put("Ε", "\u0395"); HTML_ENTITY_MAP.put("Ε", "\u0395"); HTML_ENTITY_MAP.put("Ζ", "\u0396"); HTML_ENTITY_MAP.put("Ζ", "\u0396"); HTML_ENTITY_MAP.put("Η", "\u0397"); HTML_ENTITY_MAP.put("Η", "\u0397"); HTML_ENTITY_MAP.put("Θ", "\u0398"); HTML_ENTITY_MAP.put("Θ", "\u0398"); HTML_ENTITY_MAP.put("Ι", "\u0399"); HTML_ENTITY_MAP.put("Ι", "\u0399"); HTML_ENTITY_MAP.put("Κ", "\u039A"); HTML_ENTITY_MAP.put("Κ", "\u039A"); HTML_ENTITY_MAP.put("Λ", "\u039B"); HTML_ENTITY_MAP.put("Λ", "\u039B"); HTML_ENTITY_MAP.put("Μ", "\u039C"); HTML_ENTITY_MAP.put("Μ", "\u039C"); HTML_ENTITY_MAP.put("Ν", "\u039D"); HTML_ENTITY_MAP.put("Ν", "\u039D"); HTML_ENTITY_MAP.put("Ξ", "\u039E"); HTML_ENTITY_MAP.put("Ξ", "\u039E"); HTML_ENTITY_MAP.put("Ο", "\u039F"); HTML_ENTITY_MAP.put("Ο", "\u039F"); HTML_ENTITY_MAP.put("Π", "\u03A0"); HTML_ENTITY_MAP.put("Π", "\u03A0"); HTML_ENTITY_MAP.put("Ρ", "\u03A1"); HTML_ENTITY_MAP.put("Ρ", "\u03A1"); HTML_ENTITY_MAP.put("Σ", "\u03A3"); HTML_ENTITY_MAP.put("Σ", "\u03A3"); HTML_ENTITY_MAP.put("Τ", "\u03A4"); HTML_ENTITY_MAP.put("Τ", "\u03A4"); HTML_ENTITY_MAP.put("Υ", "\u03A5"); HTML_ENTITY_MAP.put("Υ", "\u03A5"); HTML_ENTITY_MAP.put("Φ", "\u03A6"); HTML_ENTITY_MAP.put("Φ", "\u03A6"); HTML_ENTITY_MAP.put("Χ", "\u03A7"); HTML_ENTITY_MAP.put("Χ", "\u03A7"); HTML_ENTITY_MAP.put("Ψ", "\u03A8"); HTML_ENTITY_MAP.put("Ψ", "\u03A8"); HTML_ENTITY_MAP.put("Ω", "\u03A9"); HTML_ENTITY_MAP.put("Ω", "\u03A9"); HTML_ENTITY_MAP.put("α", "\u03B1"); HTML_ENTITY_MAP.put("α", "\u03B1"); HTML_ENTITY_MAP.put("β", "\u03B2"); HTML_ENTITY_MAP.put("β", "\u03B2"); HTML_ENTITY_MAP.put("γ", "\u03B3"); HTML_ENTITY_MAP.put("γ", "\u03B3"); HTML_ENTITY_MAP.put("δ", "\u03B4"); HTML_ENTITY_MAP.put("δ", "\u03B4"); HTML_ENTITY_MAP.put("ε", "\u03B5"); HTML_ENTITY_MAP.put("ε", "\u03B5"); HTML_ENTITY_MAP.put("ζ", "\u03B6"); HTML_ENTITY_MAP.put("ζ", "\u03B6"); HTML_ENTITY_MAP.put("η", "\u03B7"); HTML_ENTITY_MAP.put("η", "\u03B7"); HTML_ENTITY_MAP.put("θ", "\u03B8"); HTML_ENTITY_MAP.put("θ", "\u03B8"); HTML_ENTITY_MAP.put("ι", "\u03B9"); HTML_ENTITY_MAP.put("ι", "\u03B9"); HTML_ENTITY_MAP.put("κ", "\u03BA"); HTML_ENTITY_MAP.put("κ", "\u03BA"); HTML_ENTITY_MAP.put("λ", "\u03BB"); HTML_ENTITY_MAP.put("λ", "\u03BB"); HTML_ENTITY_MAP.put("μ", "\u03BC"); HTML_ENTITY_MAP.put("μ", "\u03BC"); HTML_ENTITY_MAP.put("ν", "\u03BD"); HTML_ENTITY_MAP.put("ν", "\u03BD"); HTML_ENTITY_MAP.put("ξ", "\u03BE"); HTML_ENTITY_MAP.put("ξ", "\u03BE"); HTML_ENTITY_MAP.put("ο", "\u03BF"); HTML_ENTITY_MAP.put("ο", "\u03BF"); HTML_ENTITY_MAP.put("π", "\u03C0"); HTML_ENTITY_MAP.put("π", "\u03C0"); HTML_ENTITY_MAP.put("ρ", "\u03C1"); HTML_ENTITY_MAP.put("ρ", "\u03C1"); HTML_ENTITY_MAP.put("ς", "\u03C2"); HTML_ENTITY_MAP.put("ς", "\u03C2"); HTML_ENTITY_MAP.put("σ", "\u03C3"); HTML_ENTITY_MAP.put("σ", "\u03C3"); HTML_ENTITY_MAP.put("τ", "\u03C4"); HTML_ENTITY_MAP.put("τ", "\u03C4"); HTML_ENTITY_MAP.put("υ", "\u03C5"); HTML_ENTITY_MAP.put("υ", "\u03C5"); HTML_ENTITY_MAP.put("φ", "\u03C6"); HTML_ENTITY_MAP.put("φ", "\u03C6"); HTML_ENTITY_MAP.put("χ", "\u03C7"); HTML_ENTITY_MAP.put("χ", "\u03C7"); HTML_ENTITY_MAP.put("ψ", "\u03C8"); HTML_ENTITY_MAP.put("ψ", "\u03C8"); HTML_ENTITY_MAP.put("ω", "\u03C9"); HTML_ENTITY_MAP.put("ω", "\u03C9"); HTML_ENTITY_MAP.put("ϑ", "\u03D1"); HTML_ENTITY_MAP.put("ϑ", "\u03D1"); HTML_ENTITY_MAP.put("ϒ", "\u03D2"); HTML_ENTITY_MAP.put("ϒ", "\u03D2"); HTML_ENTITY_MAP.put("ϖ", "\u03D6"); HTML_ENTITY_MAP.put("ϖ", "\u03D6"); HTML_ENTITY_MAP.put("•", "\u2022"); HTML_ENTITY_MAP.put("•", "\u2022"); HTML_ENTITY_MAP.put("…", "\u2026"); HTML_ENTITY_MAP.put("…", "\u2026"); HTML_ENTITY_MAP.put("′", "\u2032"); HTML_ENTITY_MAP.put("′", "\u2032"); HTML_ENTITY_MAP.put("″", "\u2033"); HTML_ENTITY_MAP.put("″", "\u2033"); HTML_ENTITY_MAP.put("‾", "\u203E"); HTML_ENTITY_MAP.put("‾", "\u203E"); HTML_ENTITY_MAP.put("⁄", "\u2044"); HTML_ENTITY_MAP.put("⁄", "\u2044"); HTML_ENTITY_MAP.put("℘", "\u2118"); HTML_ENTITY_MAP.put("℘", "\u2118"); HTML_ENTITY_MAP.put("ℑ", "\u2111"); HTML_ENTITY_MAP.put("ℑ", "\u2111"); HTML_ENTITY_MAP.put("ℜ", "\u211C"); HTML_ENTITY_MAP.put("ℜ", "\u211C"); HTML_ENTITY_MAP.put("™", "\u2122"); HTML_ENTITY_MAP.put("™", "\u2122"); HTML_ENTITY_MAP.put("ℵ", "\u2135"); HTML_ENTITY_MAP.put("ℵ", "\u2135"); HTML_ENTITY_MAP.put("←", "\u2190"); HTML_ENTITY_MAP.put("←", "\u2190"); HTML_ENTITY_MAP.put("↑", "\u2191"); HTML_ENTITY_MAP.put("↑", "\u2191"); HTML_ENTITY_MAP.put("→", "\u2192"); HTML_ENTITY_MAP.put("→", "\u2192"); HTML_ENTITY_MAP.put("↓", "\u2193"); HTML_ENTITY_MAP.put("↓", "\u2193"); HTML_ENTITY_MAP.put("↔", "\u2194"); HTML_ENTITY_MAP.put("↔", "\u2194"); HTML_ENTITY_MAP.put("↵", "\u21B5"); HTML_ENTITY_MAP.put("↵", "\u21B5"); HTML_ENTITY_MAP.put("⇐", "\u21D0"); HTML_ENTITY_MAP.put("⇐", "\u21D0"); HTML_ENTITY_MAP.put("⇑", "\u21D1"); HTML_ENTITY_MAP.put("⇑", "\u21D1"); HTML_ENTITY_MAP.put("⇒", "\u21D2"); HTML_ENTITY_MAP.put("⇒", "\u21D2"); HTML_ENTITY_MAP.put("⇓", "\u21D3"); HTML_ENTITY_MAP.put("⇓", "\u21D3"); HTML_ENTITY_MAP.put("⇔", "\u21D4"); HTML_ENTITY_MAP.put("⇔", "\u21D4"); HTML_ENTITY_MAP.put("∀", "\u2200"); HTML_ENTITY_MAP.put("∀", "\u2200"); HTML_ENTITY_MAP.put("∂", "\u2202"); HTML_ENTITY_MAP.put("∂", "\u2202"); HTML_ENTITY_MAP.put("∃", "\u2203"); HTML_ENTITY_MAP.put("∃", "\u2203"); HTML_ENTITY_MAP.put("∅", "\u2205"); HTML_ENTITY_MAP.put("∅", "\u2205"); HTML_ENTITY_MAP.put("∇", "\u2207"); HTML_ENTITY_MAP.put("∇", "\u2207"); HTML_ENTITY_MAP.put("∈", "\u2208"); HTML_ENTITY_MAP.put("∈", "\u2208"); HTML_ENTITY_MAP.put("∉", "\u2209"); HTML_ENTITY_MAP.put("∉", "\u2209"); HTML_ENTITY_MAP.put("∋", "\u220B"); HTML_ENTITY_MAP.put("∋", "\u220B"); HTML_ENTITY_MAP.put("∏", "\u220F"); HTML_ENTITY_MAP.put("∏", "\u220F"); HTML_ENTITY_MAP.put("∑", "\u2211"); HTML_ENTITY_MAP.put("∑", "\u2211"); HTML_ENTITY_MAP.put("−", "\u2212"); HTML_ENTITY_MAP.put("−", "\u2212"); HTML_ENTITY_MAP.put("∗", "\u2217"); HTML_ENTITY_MAP.put("∗", "\u2217"); HTML_ENTITY_MAP.put("√", "\u221A"); HTML_ENTITY_MAP.put("√", "\u221A"); HTML_ENTITY_MAP.put("∝", "\u221D"); HTML_ENTITY_MAP.put("∝", "\u221D"); HTML_ENTITY_MAP.put("∞", "\u221E"); HTML_ENTITY_MAP.put("∞", "\u221E"); HTML_ENTITY_MAP.put("∠", "\u2220"); HTML_ENTITY_MAP.put("∠", "\u2220"); HTML_ENTITY_MAP.put("∧", "\u2227"); HTML_ENTITY_MAP.put("∧", "\u2227"); HTML_ENTITY_MAP.put("∨", "\u2228"); HTML_ENTITY_MAP.put("∨", "\u2228"); HTML_ENTITY_MAP.put("∩", "\u2229"); HTML_ENTITY_MAP.put("∩", "\u2229"); HTML_ENTITY_MAP.put("∪", "\u222A"); HTML_ENTITY_MAP.put("∪", "\u222A"); HTML_ENTITY_MAP.put("∫", "\u222B"); HTML_ENTITY_MAP.put("∫", "\u222B"); HTML_ENTITY_MAP.put("∴", "\u2234"); HTML_ENTITY_MAP.put("∴", "\u2234"); HTML_ENTITY_MAP.put("∼", "\u223C"); HTML_ENTITY_MAP.put("∼", "\u223C"); HTML_ENTITY_MAP.put("≅", "\u2245"); HTML_ENTITY_MAP.put("≅", "\u2245"); HTML_ENTITY_MAP.put("≈", "\u2248"); HTML_ENTITY_MAP.put("≈", "\u2248"); HTML_ENTITY_MAP.put("≠", "\u2260"); HTML_ENTITY_MAP.put("≠", "\u2260"); HTML_ENTITY_MAP.put("≡", "\u2261"); HTML_ENTITY_MAP.put("≡", "\u2261"); HTML_ENTITY_MAP.put("≤", "\u2264"); HTML_ENTITY_MAP.put("≤", "\u2264"); HTML_ENTITY_MAP.put("≥", "\u2265"); HTML_ENTITY_MAP.put("≥", "\u2265"); HTML_ENTITY_MAP.put("⊂", "\u2282"); HTML_ENTITY_MAP.put("⊂", "\u2282"); HTML_ENTITY_MAP.put("⊃", "\u2283"); HTML_ENTITY_MAP.put("⊃", "\u2283"); HTML_ENTITY_MAP.put("⊆", "\u2286"); HTML_ENTITY_MAP.put("⊆", "\u2286"); HTML_ENTITY_MAP.put("⊇", "\u2287"); HTML_ENTITY_MAP.put("⊇", "\u2287"); HTML_ENTITY_MAP.put("⊕", "\u2295"); HTML_ENTITY_MAP.put("⊕", "\u2295"); HTML_ENTITY_MAP.put("⊗", "\u2297"); HTML_ENTITY_MAP.put("⊗", "\u2297"); HTML_ENTITY_MAP.put("⊥", "\u22A5"); HTML_ENTITY_MAP.put("⊥", "\u22A5"); HTML_ENTITY_MAP.put("⋅", "\u22C5"); HTML_ENTITY_MAP.put("⋅", "\u22C5"); HTML_ENTITY_MAP.put("⌈", "\u2308"); HTML_ENTITY_MAP.put("⌈", "\u2308"); HTML_ENTITY_MAP.put("⌉", "\u2309"); HTML_ENTITY_MAP.put("⌉", "\u2309"); HTML_ENTITY_MAP.put("⌊", "\u230A"); HTML_ENTITY_MAP.put("⌊", "\u230A"); HTML_ENTITY_MAP.put("⌋", "\u230B"); HTML_ENTITY_MAP.put("⌋", "\u230B"); HTML_ENTITY_MAP.put("⟨", "\u2329"); HTML_ENTITY_MAP.put("〈", "\u2329"); HTML_ENTITY_MAP.put("⟩", "\u232A"); HTML_ENTITY_MAP.put("〉", "\u232A"); HTML_ENTITY_MAP.put("◊", "\u25CA"); HTML_ENTITY_MAP.put("◊", "\u25CA"); HTML_ENTITY_MAP.put("♠", "\u2660"); HTML_ENTITY_MAP.put("♠", "\u2660"); HTML_ENTITY_MAP.put("♣", "\u2663"); HTML_ENTITY_MAP.put("♣", "\u2663"); HTML_ENTITY_MAP.put("♥", "\u2665"); HTML_ENTITY_MAP.put("♥", "\u2665"); HTML_ENTITY_MAP.put("♦", "\u2666"); HTML_ENTITY_MAP.put("♦", "\u2666"); HTML_ENTITY_MAP.put("Œ", "\u0152"); HTML_ENTITY_MAP.put("Œ", "\u0152"); HTML_ENTITY_MAP.put("œ", "\u0153"); HTML_ENTITY_MAP.put("œ", "\u0153"); HTML_ENTITY_MAP.put("Š", "\u0160"); HTML_ENTITY_MAP.put("Š", "\u0160"); HTML_ENTITY_MAP.put("š", "\u0161"); HTML_ENTITY_MAP.put("š", "\u0161"); HTML_ENTITY_MAP.put("Ÿ", "\u0178"); HTML_ENTITY_MAP.put("Ÿ", "\u0178"); HTML_ENTITY_MAP.put("ˆ", "\u02C6"); HTML_ENTITY_MAP.put("ˆ", "\u02C6"); HTML_ENTITY_MAP.put("˜", "\u02DC"); HTML_ENTITY_MAP.put("˜", "\u02DC"); HTML_ENTITY_MAP.put(" ", "\u2002"); HTML_ENTITY_MAP.put(" ", "\u2002"); HTML_ENTITY_MAP.put(" ", "\u2003"); HTML_ENTITY_MAP.put(" ", "\u2003"); HTML_ENTITY_MAP.put(" ", "\u2009"); HTML_ENTITY_MAP.put(" ", "\u2009"); HTML_ENTITY_MAP.put("‌", "\u200C"); HTML_ENTITY_MAP.put("‌", "\u200C"); HTML_ENTITY_MAP.put("‍", "\u200D"); HTML_ENTITY_MAP.put("‍", "\u200D"); HTML_ENTITY_MAP.put("‎", "\u200E"); HTML_ENTITY_MAP.put("‎", "\u200E"); HTML_ENTITY_MAP.put("‏", "\u200F"); HTML_ENTITY_MAP.put("‏", "\u200F"); HTML_ENTITY_MAP.put("–", "\u2013"); HTML_ENTITY_MAP.put("–", "\u2013"); HTML_ENTITY_MAP.put("—", "\u2014"); HTML_ENTITY_MAP.put("—", "\u2014"); HTML_ENTITY_MAP.put("‘", "\u2018"); HTML_ENTITY_MAP.put("‘", "\u2018"); HTML_ENTITY_MAP.put("’", "\u2019"); HTML_ENTITY_MAP.put("’", "\u2019"); HTML_ENTITY_MAP.put("‚", "\u201A"); HTML_ENTITY_MAP.put("‚", "\u201A"); HTML_ENTITY_MAP.put("“", "\u201C"); HTML_ENTITY_MAP.put("“", "\u201C"); HTML_ENTITY_MAP.put("”", "\u201D"); HTML_ENTITY_MAP.put("”", "\u201D"); HTML_ENTITY_MAP.put("„", "\u201E"); HTML_ENTITY_MAP.put("„", "\u201E"); HTML_ENTITY_MAP.put("†", "\u2020"); HTML_ENTITY_MAP.put("†", "\u2020"); HTML_ENTITY_MAP.put("‡", "\u2021"); HTML_ENTITY_MAP.put("‡", "\u2021"); HTML_ENTITY_MAP.put("‰", "\u2030"); HTML_ENTITY_MAP.put("‰", "\u2030"); HTML_ENTITY_MAP.put("‹", "\u2039"); HTML_ENTITY_MAP.put("‹", "\u2039"); HTML_ENTITY_MAP.put("›", "\u203A"); HTML_ENTITY_MAP.put("›", "\u203A"); HTML_ENTITY_MAP.put("€", "\u20AC"); HTML_ENTITY_MAP.put("€", "\u20AC"); } }