0001: /*
0002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
0003: C/Oña, 107 1º2 28050 Madrid (Spain)
0004:
0005: Redistribution and use in source and binary forms, with or without
0006: modification, are permitted provided that the following conditions
0007: are met:
0008:
0009: 1. Redistributions of source code must retain the above copyright
0010: notice, this list of conditions and the following disclaimer.
0011:
0012: 2. The end-user documentation included with the redistribution,
0013: if any, must include the following acknowledgment:
0014: "This product includes software parts from hipergate
0015: (http://www.hipergate.org/)."
0016: Alternately, this acknowledgment may appear in the software itself,
0017: if and wherever such third-party acknowledgments normally appear.
0018:
0019: 3. The name hipergate must not be used to endorse or promote products
0020: derived from this software without prior written permission.
0021: Products derived from this software may not be called hipergate,
0022: nor may hipergate appear in their name, without prior written
0023: permission.
0024:
0025: This library is distributed in the hope that it will be useful,
0026: but WITHOUT ANY WARRANTY; without even the implied warranty of
0027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0028:
0029: You should have received a copy of hipergate License with this code;
0030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
0031: */
0032:
0033: package com.knowgate.misc;
0034:
0035: import java.lang.StringBuffer;
0036: import java.lang.System;
0037:
0038: import java.util.Random;
0039: import java.util.Date;
0040: import java.util.StringTokenizer;
0041: import java.util.Collection;
0042: import java.util.LinkedList;
0043: import java.util.Iterator;
0044: import java.util.Vector;
0045: import java.util.ArrayList;
0046: import java.util.Currency;
0047: import java.util.Locale;
0048:
0049: import java.math.BigDecimal;
0050:
0051: import java.text.DecimalFormat;
0052: import java.text.FieldPosition;
0053: import java.text.NumberFormat;
0054:
0055: import java.net.InetAddress;
0056: import java.net.UnknownHostException;
0057:
0058: import org.apache.oro.text.regex.*;
0059:
0060: import com.knowgate.debug.DebugFile;
0061:
0062: /**
0063: * Miscellaneous functions and utilities.
0064: * @author Sergio Montoro Ten
0065: * @version 2.1
0066: */
0067: public final class Gadgets {
0068:
0069: private static int iSequence = 1048576;
0070:
0071: private static DecimalFormat oFmt2 = null;
0072: private static FieldPosition oFrac = null;
0073: private static Currency oCurr = null;
0074: private static String sCurr = null;
0075:
0076: private static PatternMatcher oMatcher = null;
0077: private static PatternCompiler oCompiler = null;
0078:
0079: public Gadgets() {
0080: }
0081:
0082: private static String[] byteToStr = { "00", "01", "02", "03", "04",
0083: "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e",
0084: "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18",
0085: "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22",
0086: "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c",
0087: "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36",
0088: "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40",
0089: "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a",
0090: "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54",
0091: "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e",
0092: "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68",
0093: "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72",
0094: "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c",
0095: "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86",
0096: "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90",
0097: "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a",
0098: "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4",
0099: "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae",
0100: "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8",
0101: "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2",
0102: "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc",
0103: "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6",
0104: "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0",
0105: "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea",
0106: "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4",
0107: "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe",
0108: "ff" };
0109:
0110: //-----------------------------------------------------------
0111:
0112: /**
0113: * Generate an universal unique identifier
0114: * @return An hexadecimal string of 32 characters,
0115: * created using the machine IP address, current system date, a randon number
0116: * and a sequence.
0117: */
0118: public static String generateUUID() {
0119:
0120: int iRnd;
0121: long lSeed = new Date().getTime();
0122: Random oRnd = new Random(lSeed);
0123: String sHex;
0124: StringBuffer sUUID = new StringBuffer(32);
0125: byte[] localIPAddr = new byte[4];
0126:
0127: try {
0128:
0129: // 8 characters Code IP address of this machine
0130: localIPAddr = InetAddress.getLocalHost().getAddress();
0131:
0132: sUUID.append(byteToStr[((int) localIPAddr[0]) & 255]);
0133: sUUID.append(byteToStr[((int) localIPAddr[1]) & 255]);
0134: sUUID.append(byteToStr[((int) localIPAddr[2]) & 255]);
0135: sUUID.append(byteToStr[((int) localIPAddr[3]) & 255]);
0136: } catch (UnknownHostException e) {
0137: // Use localhost by default
0138: sUUID.append("7F000000");
0139: }
0140:
0141: // Append a seed value based on current system date
0142: sUUID.append(Long.toHexString(lSeed));
0143:
0144: // 6 characters - an incremental sequence
0145: sUUID.append(Integer.toHexString(iSequence++));
0146:
0147: if (iSequence > 16777000)
0148: iSequence = 1048576;
0149:
0150: do {
0151: iRnd = oRnd.nextInt();
0152: if (iRnd > 0)
0153: iRnd = -iRnd;
0154: sHex = Integer.toHexString(iRnd);
0155: } while (0 == iRnd);
0156:
0157: // Finally append a random number
0158: sUUID.append(sHex);
0159:
0160: return sUUID.substring(0, 32);
0161: } // generateUUID()
0162:
0163: //-----------------------------------------------------------
0164:
0165: /**
0166: * <p>Return text enconded as XHTML.</p>
0167: * ASCII-7 character are returned as they are,any other character is returned as &#<i>code</i>;
0168: * @param text String
0169: * @return String
0170: */
0171: public static String XHTMLEncode(String text) {
0172: char c;
0173: int len = text.length();
0174: StringBuffer results = new StringBuffer(len * 2);
0175:
0176: for (int i = 0; i < len; ++i) {
0177: c = text.charAt(i);
0178: if (c >= 32 && c <= 127)
0179: results.append(c);
0180: else
0181: results.append("&#" + String.valueOf((int) c) + ";");
0182: }
0183: return results.toString();
0184: }
0185:
0186: //-----------------------------------------------------------
0187:
0188: /**
0189: * <p>Return text enconded as HTML.</p>
0190: * For example "Tom & Jerry" is encoded as "Tom & Jerry"
0191: * @param text Text to encode
0192: * @return HTML-encoded text
0193: */
0194: public static String HTMLEncode(String text) {
0195: if (text == null)
0196: return "";
0197:
0198: char c;
0199: int len = text.length();
0200: StringBuffer results = new StringBuffer(len);
0201:
0202: for (int i = 0; i < len; ++i) {
0203: c = text.charAt(i);
0204: switch (c) {
0205: case '&':
0206: results.append("&");
0207: break;
0208: case '<':
0209: results.append("<");
0210: break;
0211: case '>':
0212: results.append(">");
0213: break;
0214: case 39:
0215: results.append("'");
0216: break;
0217: case '"':
0218: results.append(""");
0219: break;
0220: case '¡':
0221: results.append("¡");
0222: break;
0223: case '¤':
0224: results.append("¤");
0225: break;
0226: case '¥':
0227: results.append("¥");
0228: break;
0229: case '|':
0230: results.append("¦");
0231: break;
0232: case '§':
0233: results.append("§");
0234: break;
0235: case '¨':
0236: results.append("¨");
0237: break;
0238: case '©':
0239: results.append("©");
0240: break;
0241: case 'ª':
0242: results.append("ª");
0243: break;
0244: case '«':
0245: results.append("«");
0246: break;
0247: case '»':
0248: results.append("»");
0249: break;
0250: case '€':
0251: results.append("€");
0252: break;
0253: case '£':
0254: results.append("£");
0255: break;
0256: case '':
0257: results.append("­");
0258: break;
0259: case '®':
0260: results.append("®");
0261: break;
0262: case '¯':
0263: results.append("¯");
0264: break;
0265: case '°':
0266: results.append("°");
0267: break;
0268: case '±':
0269: results.append("±");
0270: break;
0271: case '¹':
0272: results.append("¹");
0273: break;
0274: case '²':
0275: results.append("²");
0276: break;
0277: case '³':
0278: results.append("³");
0279: break;
0280: case '´':
0281: results.append("´");
0282: break;
0283: case 'µ':
0284: results.append("µ");
0285: break;
0286: case '¶':
0287: results.append("¶");
0288: break;
0289: case '·':
0290: results.append("·");
0291: break;
0292: case '¸':
0293: results.append("¸");
0294: break;
0295: case 'º':
0296: results.append("º");
0297: break;
0298: case '¿':
0299: results.append("¿");
0300: break;
0301: case 'ñ':
0302: results.append("ñ");
0303: break;
0304: case 'Ñ':
0305: results.append("Ñ");
0306: break;
0307: case 'á':
0308: results.append("á");
0309: break;
0310: case 'é':
0311: results.append("é");
0312: break;
0313: case 'í':
0314: results.append("í");
0315: break;
0316: case 'ó':
0317: results.append("ó");
0318: break;
0319: case 'ú':
0320: results.append("ú");
0321: break;
0322: case 'ü':
0323: results.append("ü");
0324: break;
0325: case 'Á':
0326: results.append("Á");
0327: break;
0328: case 'À':
0329: results.append("À");
0330: break;
0331: case 'Ä':
0332: results.append("Ä");
0333: break;
0334: case 'Â':
0335: results.append("Â");
0336: break;
0337: case 'Å':
0338: results.append("Å");
0339: break;
0340: case 'É':
0341: results.append("É");
0342: break;
0343: case 'È':
0344: results.append("È");
0345: break;
0346: case 'Ë':
0347: results.append("Ë");
0348: break;
0349: case 'Ê':
0350: results.append("Ê");
0351: break;
0352: case 'Í':
0353: results.append("Í");
0354: break;
0355: case 'Ì':
0356: results.append("Ì");
0357: break;
0358: case 'Ï':
0359: results.append("Ï");
0360: break;
0361: case 'Î':
0362: results.append("Î");
0363: break;
0364: case 'Ó':
0365: results.append("Ó");
0366: break;
0367: case 'Ò':
0368: results.append("Ò");
0369: break;
0370: case 'Ö':
0371: results.append("Ö");
0372: break;
0373: case 'Ô':
0374: results.append("Ô");
0375: break;
0376: case 'Ú':
0377: results.append("Ú");
0378: break;
0379: case 'Ù':
0380: results.append("Ù");
0381: break;
0382: case 'Ü':
0383: results.append("Ü");
0384: break;
0385: case 'Û':
0386: results.append("Û");
0387: break;
0388: case '½':
0389: results.append("½");
0390: break;
0391: case '¾':
0392: results.append("¾");
0393: break;
0394: case '¼':
0395: results.append("¼");
0396: break;
0397: case 'Ç':
0398: results.append("Ç");
0399: break;
0400: case 'ç':
0401: results.append("ç");
0402: break;
0403: case 'ð':
0404: results.append("ð");
0405: break;
0406: case '¢':
0407: results.append("¢");
0408: break;
0409: case 'Þ':
0410: results.append("Þ");
0411: break;
0412: case 'þ':
0413: results.append("þ");
0414: break;
0415: case 'Ð':
0416: results.append("Ð");
0417: break;
0418: case '×':
0419: results.append("×");
0420: break;
0421: case '÷':
0422: results.append("÷");
0423: break;
0424: case 'Æ':
0425: results.append("Æ");
0426: break;
0427:
0428: /*
0429: uml => chr 168, #umlaut (dieresis)
0430: laquo => chr 171, #angle quotation mark, left
0431: not => chr 172, #not sign
0432: shy => chr 173, #soft hyphen
0433: reg => chr 174, #registered sign
0434: macr => chr 175, #macron
0435: deg => chr 176, #degree sign
0436: sup2 => chr 178, #superscript two
0437: sup3 => chr 179, #superscript three
0438: acute => chr 180, #acute accent
0439: micro => chr 181, #micro sign
0440: para => chr 182, #pilcrow (paragraph sign)
0441: cedil => chr 184, #cedilla
0442: sup1 => chr 185, #superscript one
0443: raquo => chr 187, #angle quotation mark, right
0444: iquest => chr 191, #inverted question mark
0445: Auml => chr 196, #capital A, dieresis or umlaut mark
0446: Aring => chr 197, #capital A, ring
0447: Ccedil => chr 199, #capital C, cedilla
0448: Egrave => chr 200, #capital E, grave accent
0449: Eacute => chr 201, #capital E, acute accent
0450: Ecirc => chr 202, #capital E, circumflex accent
0451: Euml => chr 203, #capital E, dieresis or umlaut mark
0452: Igrave => chr 204, #capital I, grave accent
0453: Iacute => chr 205, #capital I, acute accent
0454: Icirc => chr 206, #capital I, circumflex accent
0455: Iuml => chr 207, #capital I, dieresis or umlaut mark
0456: Ouml => chr 214, #capital O, dieresis or umlaut mark
0457: Oslash => chr 216, #capital O, slash
0458: Ugrave => chr 217, #capital U, grave accent
0459: Uacute => chr 218, #capital U, acute accent
0460: Ucirc => chr 219, #capital U, circumflex accent
0461: Uuml => chr 220, #capital U, dieresis or umlaut mark
0462: Yacute => chr 221, #capital Y, acute accent
0463: szlig => chr 223, #small sharp s, German (sz ligature)
0464: agrave => chr 224, #small a, grave accent
0465: aacute => chr 225, #small a, acute accent
0466: acirc => chr 226, #small a, circumflex accent
0467: atilde => chr 227, #small a, tilde
0468: auml => chr 228, #small a, dieresis or umlaut mark
0469: aring => chr 229, #small a, ring
0470: aelig => chr 230, #small ae diphthong (ligature)
0471: ccedil => chr 231, #small c, cedilla
0472: egrave => chr 232, #small e, grave accent
0473: eacute => chr 233, #small e, acute accent
0474: ecirc => chr 234, #small e, circumflex accent
0475: euml => chr 235, #small e, dieresis or umlaut mark
0476: igrave => chr 236, #small i, grave accent
0477: iacute => chr 237, #small i, acute accent
0478: icirc => chr 238, #small i, circumflex accent
0479: iuml => chr 239, #small i, dieresis or umlaut mark
0480: eth => chr 240, #small eth, Icelandic
0481: ntilde => chr 241, #small n, tilde
0482: ograve => chr 242, #small o, grave accent
0483: oacute => chr 243, #small o, acute accent
0484: ocirc => chr 244, #small o, circumflex accent
0485: otilde => chr 245, #small o, tilde
0486: ouml => chr 246, #small o, dieresis or umlaut mark
0487: divide => chr 247, #divide sign
0488: oslash => chr 248, #small o, slash
0489: ugrave => chr 249, #small u, grave accent
0490: uacute => chr 250, #small u, acute accent
0491: ucirc => chr 251, #small u, circumflex accent
0492: uuml => chr 252, #small u, dieresis or umlaut mark
0493: yacute => chr 253, #small y, acute accent
0494: thorn => chr 254, #small thorn, Icelandic
0495: yuml => chr 255, #small y, dieresis or umlaut mark
0496:
0497: <!ENTITY Atilde CDATA "Ã" -- latin capital letter A with tilde,
0498: U+00C3 ISOlat1 -->
0499: <!ENTITY Aring CDATA "Å" -- latin capital letter A with ring above
0500: = latin capital letter A ring,
0501: U+00C5 ISOlat1 -->
0502: <!ENTITY AElig CDATA "Æ" -- latin capital letter AE
0503: = latin capital ligature AE,
0504: U+00C6 ISOlat1 -->
0505: <!ENTITY Egrave CDATA "È" -- latin capital letter E with grave,
0506: U+00C8 ISOlat1 -->
0507: <!ENTITY Eacute CDATA "É" -- latin capital letter E with acute,
0508: U+00C9 ISOlat1 -->
0509: <!ENTITY Ecirc CDATA "Ê" -- latin capital letter E with circumflex,
0510: U+00CA ISOlat1 -->
0511: <!ENTITY Euml CDATA "Ë" -- latin capital letter E with diaeresis,
0512: U+00CB ISOlat1 -->
0513: <!ENTITY Igrave CDATA "Ì" -- latin capital letter I with grave,
0514: U+00CC ISOlat1 -->
0515: <!ENTITY Iacute CDATA "Í" -- latin capital letter I with acute,
0516: U+00CD ISOlat1 -->
0517: <!ENTITY Icirc CDATA "Î" -- latin capital letter I with circumflex,
0518: U+00CE ISOlat1 -->
0519: <!ENTITY Iuml CDATA "Ï" -- latin capital letter I with diaeresis,
0520: U+00CF ISOlat1 -->
0521: <!ENTITY ETH CDATA "Ð" -- latin capital letter ETH, U+00D0 ISOlat1 -->
0522: <!ENTITY Ograve CDATA "Ò" -- latin capital letter O with grave,
0523: U+00D2 ISOlat1 -->
0524: <!ENTITY Oacute CDATA "Ó" -- latin capital letter O with acute,
0525: U+00D3 ISOlat1 -->
0526: <!ENTITY Ocirc CDATA "Ô" -- latin capital letter O with circumflex,
0527: U+00D4 ISOlat1 -->
0528: <!ENTITY Otilde CDATA "Õ" -- latin capital letter O with tilde,
0529: U+00D5 ISOlat1 -->
0530: <!ENTITY Ouml CDATA "Ö" -- latin capital letter O with diaeresis,
0531: U+00D6 ISOlat1 -->
0532: <!ENTITY times CDATA "×" -- multiplication sign, U+00D7 ISOnum -->
0533: <!ENTITY Oslash CDATA "Ø" -- latin capital letter O with stroke
0534: = latin capital letter O slash,
0535: U+00D8 ISOlat1 -->
0536: <!ENTITY Ugrave CDATA "Ù" -- latin capital letter U with grave,
0537: U+00D9 ISOlat1 -->
0538: <!ENTITY Uacute CDATA "Ú" -- latin capital letter U with acute,
0539: U+00DA ISOlat1 -->
0540: <!ENTITY Ucirc CDATA "Û" -- latin capital letter U with circumflex,
0541: U+00DB ISOlat1 -->
0542: <!ENTITY Uuml CDATA "Ü" -- latin capital letter U with diaeresis,
0543: U+00DC ISOlat1 -->
0544: <!ENTITY Yacute CDATA "Ý" -- latin capital letter Y with acute,
0545: U+00DD ISOlat1 -->
0546: <!ENTITY THORN CDATA "Þ" -- latin capital letter THORN,
0547: U+00DE ISOlat1 -->
0548: <!ENTITY szlig CDATA "ß" -- latin small letter sharp s = ess-zed,
0549: U+00DF ISOlat1 -->
0550: <!ENTITY agrave CDATA "à" -- latin small letter a with grave
0551: = latin small letter a grave,
0552: U+00E0 ISOlat1 -->
0553: <!ENTITY aacute CDATA "á" -- latin small letter a with acute,
0554: U+00E1 ISOlat1 -->
0555: <!ENTITY acirc CDATA "â" -- latin small letter a with circumflex,
0556: U+00E2 ISOlat1 -->
0557: <!ENTITY atilde CDATA "ã" -- latin small letter a with tilde,
0558: U+00E3 ISOlat1 -->
0559: <!ENTITY auml CDATA "ä" -- latin small letter a with diaeresis,
0560: U+00E4 ISOlat1 -->
0561: <!ENTITY aring CDATA "å" -- latin small letter a with ring above
0562: = latin small letter a ring,
0563: U+00E5 ISOlat1 -->
0564: <!ENTITY aelig CDATA "æ" -- latin small letter ae
0565: = latin small ligature ae, U+00E6 ISOlat1 -->
0566: <!ENTITY egrave CDATA "è" -- latin small letter e with grave,
0567: U+00E8 ISOlat1 -->
0568: <!ENTITY ecirc CDATA "ê" -- latin small letter e with circumflex,
0569: U+00EA ISOlat1 -->
0570: <!ENTITY euml CDATA "ë" -- latin small letter e with diaeresis,
0571: U+00EB ISOlat1 -->
0572: <!ENTITY igrave CDATA "ì" -- latin small letter i with grave,
0573: U+00EC ISOlat1 -->
0574: <!ENTITY iacute CDATA "í" -- latin small letter i with acute,
0575: U+00ED ISOlat1 -->
0576: <!ENTITY icirc CDATA "î" -- latin small letter i with circumflex,
0577: U+00EE ISOlat1 -->
0578: <!ENTITY iuml CDATA "ï" -- latin small letter i with diaeresis,
0579: U+00EF ISOlat1 -->
0580: <!ENTITY ograve CDATA "ò" -- latin small letter o with grave,
0581: U+00F2 ISOlat1 -->
0582: <!ENTITY oacute CDATA "ó" -- latin small letter o with acute,
0583: U+00F3 ISOlat1 -->
0584: <!ENTITY ocirc CDATA "ô" -- latin small letter o with circumflex,
0585: U+00F4 ISOlat1 -->
0586: <!ENTITY otilde CDATA "õ" -- latin small letter o with tilde,
0587: U+00F5 ISOlat1 -->
0588: <!ENTITY ouml CDATA "ö" -- latin small letter o with diaeresis,
0589: U+00F6 ISOlat1 -->
0590: <!ENTITY divide CDATA "÷" -- division sign, U+00F7 ISOnum -->
0591: <!ENTITY oslash CDATA "ø" -- latin small letter o with stroke,
0592: = latin small letter o slash,
0593: U+00F8 ISOlat1 -->
0594: <!ENTITY ugrave CDATA "ù" -- latin small letter u with grave,
0595: U+00F9 ISOlat1 -->
0596: <!ENTITY uacute CDATA "ú" -- latin small letter u with acute,
0597: U+00FA ISOlat1 -->
0598: <!ENTITY ucirc CDATA "û" -- latin small letter u with circumflex,
0599: U+00FB ISOlat1 -->
0600: <!ENTITY uuml CDATA "ü" -- latin small letter u with diaeresis,
0601: U+00FC ISOlat1 -->
0602: <!ENTITY yacute CDATA "ý" -- latin small letter y with acute,
0603: U+00FD ISOlat1 -->
0604: <!ENTITY thorn CDATA "þ" -- latin small letter thorn,
0605: U+00FE ISOlat1 -->
0606: <!ENTITY yuml CDATA "ÿ" -- latin small letter y with diaeresis,
0607: U+00FF ISOlat1 -->
0608:
0609: */
0610: default:
0611: if (c < 256)
0612: results.append(c);
0613: else
0614: results.append("&#" + String.valueOf(c) + ";");
0615: } // end switch (c)
0616: } // end for (i)
0617:
0618: return results.toString();
0619: } // HTMLEncode
0620:
0621: //-----------------------------------------------------------
0622:
0623: public static String HTMLDencode(String text) {
0624: if (text == null)
0625: return "";
0626:
0627: char c, d;
0628: int len = text.length();
0629: StringBuffer results = new StringBuffer(len);
0630:
0631: final String[] aEnts = { "amp;", "lt;", "gt;", "quot;",
0632: "iexcl;", "curren;", "yen;", "brvbar;", "sect;",
0633: "uml;", "copy;", "ordf;", "laquo;", "raquo;", "euro;",
0634: "pound;", "shy;", "reg;", "macr;", "deg;", "plusmn;",
0635: "sup1;", "sup2;", "sup3;", "acute;", "micro;", "para;",
0636: "middot;", "cedil;", "ordm;", "iquest;", "ntilde;",
0637: "Ntilde;", "aacute;", "eacute;", "iacute;", "oacute;",
0638: "uacute;", "uuml;", "Aacute;", "Agrave;", "Auml;",
0639: "Acirc;", "Aring;", "Eacute;", "Egrave;", "Euml;",
0640: "Ecirc;", "Iacute;", "Igrave;", "Iuml;", "Icirc;",
0641: "Oacute;", "Ograve;", "Ouml;", "Ocirc;", "Uacute;",
0642: "Ugrave;", "Uuml;", "Ucirc;", "frac12;", "frac34;",
0643: "frac14;", "Ccedil;", "ccedil;", "eth;", "cent;",
0644: "THORN;", "thorn;", "ETH;", "times;", "divide;",
0645: "AElig;" };
0646:
0647: final String[] aChars = { "&", "<", ">", "\"", "¡", "¤", "¥",
0648: "|", "§", "¨", "©", "ª", "«", "»", "€", "£", "", "®",
0649: "¯", "°", "±", "¹", "²", "³", "´", "µ", "¶", "·", "¸",
0650: "º", "¿", "ñ", "Ñ", "á", "é", "í", "ó", "ú", "ü", "Á",
0651: "À", "Ä", "Â", "Å", "É", "È", "Ë", "Ê", "Í", "Ì", "Ï",
0652: "Î", "Ó", "Ò", "Ö", "Ô", "Ú", "Ù", "Ü", "Û", "½", "¾",
0653: "¼", "Ç", "ç", "ð", "¢", "Þ", "þ", "Ð", "×", "÷", "Æ" };
0654:
0655: final int iEnts = aEnts.length;
0656:
0657: for (int i = 0; i < len; ++i) {
0658: c = text.charAt(i);
0659: if (c == '&' && i < len - 3) {
0660: try {
0661: if (text.charAt(i + 1) == '#') {
0662: int semicolon = text.indexOf(59, i + 1);
0663: if (semicolon > 0) {
0664: results.append((char) Integer.parseInt(text
0665: .substring(i + 2, semicolon)));
0666: i = semicolon + 1;
0667: } else {
0668: results.append(c);
0669: }
0670: } else {
0671: for (int e = 0; e < iEnts; e++) {
0672: if (text.substring(i + 1,
0673: i + aEnts[e].length()).equals(
0674: aEnts[e]))
0675: results.append(aChars[e]);
0676: }
0677: }
0678: } catch (StringIndexOutOfBoundsException siob) {
0679: return results.toString();
0680: }
0681: } else {
0682: results.append(c);
0683: }
0684: } // next (i)
0685:
0686: return results.toString();
0687: } // HTMLDencode
0688:
0689: // ----------------------------------------------------------
0690:
0691: /**
0692: * Return text enconded as an URL.
0693: * For example, "Tom's Bookmarks" is encodes as "Tom%27s%20Bookmarks"
0694: * @param sStr Text to encode
0695: * @return URL-encoded text
0696: */
0697: public static String URLEncode(String sStr) {
0698: if (sStr == null)
0699: return null;
0700:
0701: int iLen = sStr.length();
0702: StringBuffer sEscaped = new StringBuffer(iLen + 100);
0703: char c;
0704: for (int p = 0; p < iLen; p++) {
0705: c = sStr.charAt(p);
0706: switch (c) {
0707: case ' ':
0708: sEscaped.append("%20");
0709: break;
0710: case '"':
0711: sEscaped.append("%22");
0712: break;
0713: case '#':
0714: sEscaped.append("%23");
0715: break;
0716: case '%':
0717: sEscaped.append("%25");
0718: break;
0719: case '&':
0720: sEscaped.append("%26");
0721: break;
0722: case (char) 39:
0723: sEscaped.append("%27");
0724: break;
0725: case ',':
0726: sEscaped.append("%2C");
0727: break;
0728: case '=':
0729: sEscaped.append("%3D");
0730: break;
0731: case '?':
0732: sEscaped.append("%3F");
0733: break;
0734: case 'á':
0735: sEscaped.append("%E1");
0736: break;
0737: case 'é':
0738: sEscaped.append("%E9");
0739: break;
0740: case 'í':
0741: sEscaped.append("%ED");
0742: break;
0743: case 'ó':
0744: sEscaped.append("%F3");
0745: break;
0746: case 'ú':
0747: sEscaped.append("%FA");
0748: break;
0749: case 'Á':
0750: sEscaped.append("%C1");
0751: break;
0752: case 'É':
0753: sEscaped.append("%C9");
0754: break;
0755: case 'Í':
0756: sEscaped.append("%CD");
0757: break;
0758: case 'Ó':
0759: sEscaped.append("%D3");
0760: break;
0761: case 'Ú':
0762: sEscaped.append("%DA");
0763: break;
0764: case 'à':
0765: sEscaped.append("%E0");
0766: break;
0767: case 'è':
0768: sEscaped.append("%E8");
0769: break;
0770: case 'ì':
0771: sEscaped.append("%EC");
0772: break;
0773: case 'ò':
0774: sEscaped.append("%F2");
0775: break;
0776: case 'ù':
0777: sEscaped.append("%F9");
0778: break;
0779: case 'À':
0780: sEscaped.append("%C0");
0781: break;
0782: case 'È':
0783: sEscaped.append("%C8");
0784: break;
0785: case 'Ì':
0786: sEscaped.append("%CC");
0787: break;
0788: case 'Ò':
0789: sEscaped.append("%D2");
0790: break;
0791: case 'Ù':
0792: sEscaped.append("%D9");
0793: break;
0794: case 'ñ':
0795: sEscaped.append("%F1");
0796: break;
0797: case 'Ñ':
0798: sEscaped.append("%D1");
0799: break;
0800: case 'ç':
0801: sEscaped.append("%E7");
0802: break;
0803: case 'Ç':
0804: sEscaped.append("%C7");
0805: break;
0806: case 'ô':
0807: sEscaped.append("%F4");
0808: break;
0809: case 'Ô':
0810: sEscaped.append("%D4");
0811: break;
0812: case 'ö':
0813: sEscaped.append("%F6");
0814: break;
0815: case 'Ö':
0816: sEscaped.append("%D6");
0817: break;
0818: case '`':
0819: sEscaped.append("%60");
0820: break;
0821: case '¨':
0822: sEscaped.append("%A8");
0823: break;
0824: default:
0825: sEscaped.append(c);
0826: break;
0827: }
0828: } // next
0829:
0830: return sEscaped.toString();
0831: } // URLEncode
0832:
0833: // ----------------------------------------------------------
0834:
0835: /**
0836: * Convert an ASCII-8 String to an ASCII-7 String
0837: */
0838: public static String ASCIIEncode(String sStrIn) {
0839: if (sStrIn == null)
0840: return null;
0841:
0842: int iLen = sStrIn.length();
0843:
0844: if (iLen == 0)
0845: return sStrIn;
0846:
0847: StringBuffer sStrBuff = new StringBuffer(iLen);
0848: String sStr = sStrIn.toUpperCase();
0849:
0850: for (int c = 0; c < iLen; c++) {
0851: switch (sStr.charAt(c)) {
0852: case 'Á':
0853: case 'À':
0854: case 'Ä':
0855: case 'Â':
0856: case 'Å':
0857: sStrBuff.append('A');
0858: break;
0859: case 'É':
0860: case 'È':
0861: case 'Ë':
0862: case 'Ê':
0863: sStrBuff.append('E');
0864: break;
0865: case 'Í':
0866: case 'Ì':
0867: case 'Ï':
0868: case 'Î':
0869: sStrBuff.append('I');
0870: break;
0871: case 'Ó':
0872: case 'Ò':
0873: case 'Ö':
0874: case 'Ô':
0875: case 'Ø':
0876: sStrBuff.append('O');
0877: break;
0878: case 'Ú':
0879: case 'Ù':
0880: case 'Ü':
0881: case 'Û':
0882: sStrBuff.append('U');
0883: break;
0884: case 'Æ':
0885: sStrBuff.append('E');
0886: break;
0887: case 'Ñ':
0888: sStrBuff.append('N');
0889: break;
0890: case 'Ç':
0891: sStrBuff.append('C');
0892: break;
0893: case '°':
0894: sStrBuff.append('o');
0895: break;
0896: case '\\':
0897: case '.':
0898: case '/':
0899: sStrBuff.append('_');
0900: break;
0901: case '&':
0902: sStrBuff.append('A');
0903: break;
0904: case ':':
0905: sStrBuff.append(';');
0906: break;
0907: case '<':
0908: sStrBuff.append('L');
0909: break;
0910: case '>':
0911: sStrBuff.append('G');
0912: break;
0913: case '"':
0914: sStrBuff.append((char) 39);
0915: break;
0916: case '|':
0917: sStrBuff.append('P');
0918: break;
0919: case '¡':
0920: sStrBuff.append('E');
0921: break;
0922: case '¿':
0923: case '?':
0924: sStrBuff.append('Q');
0925: break;
0926: case '*':
0927: sStrBuff.append('W');
0928: break;
0929: case '%':
0930: sStrBuff.append('P');
0931: break;
0932: case 'ß':
0933: sStrBuff.append('B');
0934: break;
0935: case '¥':
0936: sStrBuff.append('Y');
0937: break;
0938: case (char) 255:
0939: sStrBuff.append('_');
0940: break;
0941: default:
0942: sStrBuff.append(sStr.charAt(c));
0943: } // end switch
0944: } // next ()
0945: return sStrBuff.toString();
0946: } // ASCIIEncode
0947:
0948: // ----------------------------------------------------------
0949:
0950: /**
0951: * Split a String in two parts
0952: * This method is a special case optimization of split() to be used when
0953: * the input string is to be splitted by a single character delimiter and
0954: * there at most one occurrence of that delimiter.
0955: * @param sInputStr String to split
0956: * @param cDelimiter Single character to be used as delimiter,
0957: * the String will be splited on the first occurence of character.
0958: * @return If cDelimiter is not found, or cDelimiter if found as the first
0959: * character of sInputStr or cDelimiter if found as the last character of
0960: * sInputStr then an array with a single String element is returned. If
0961: * cDelimiter is found somewhere in the middle of sInputStr then an array
0962: * with 2 elements is returned.
0963: * @throws NullPointerException If sInputStr is <b>null</b>
0964: */
0965: public static String[] split2(String sInputStr, char cDelimiter)
0966: throws NullPointerException {
0967:
0968: int iDelim = sInputStr.indexOf(cDelimiter);
0969:
0970: if (iDelim < 0)
0971: return new String[] { sInputStr };
0972: else if (iDelim == 0)
0973: return new String[] { "", sInputStr.substring(iDelim + 1) };
0974: else if (iDelim == sInputStr.length() - 1)
0975: return new String[] { sInputStr.substring(0, iDelim), "" };
0976: else
0977: return new String[] { sInputStr.substring(0, iDelim),
0978: sInputStr.substring(iDelim + 1) };
0979: } // split2
0980:
0981: // ----------------------------------------------------------
0982:
0983: /**
0984: * Split a String in two parts
0985: * This method is a special case optimization of split() to be used when
0986: * the input string is to be splitted by a variable length delimiter and
0987: * there at most one occurrence of that delimiter.
0988: * @param sInputStr String to split
0989: * @param sDelimiter String to be used as delimiter,
0990: * the String will be splited on the first occurence of sDelimiter.
0991: * @return If sDelimiter is not found, or sInputStr starts with sDelimiter or
0992: * sInputStr ends with sDelimiter then an array with a single String element
0993: * is returned. If sDelimiter is found somewhere in the middle of sInputStr
0994: * then an array with 2 elements is returned.
0995: * @throws NullPointerException If sInputStr is <b>null</b>
0996: */
0997: public static String[] split2(String sInputStr, String sDelimiter)
0998: throws NullPointerException {
0999:
1000: int iDelim = sInputStr.indexOf(sDelimiter);
1001:
1002: if (iDelim < 0)
1003: return new String[] { sInputStr };
1004: else if (iDelim == 0)
1005: return new String[] { "",
1006: sInputStr.substring(iDelim + sDelimiter.length()) };
1007: else if (iDelim == sInputStr.length() - sDelimiter.length())
1008: return new String[] { sInputStr.substring(0, iDelim), "" };
1009: else
1010: return new String[] { sInputStr.substring(0, iDelim),
1011: sInputStr.substring(iDelim + sDelimiter.length()) };
1012: } // split2
1013:
1014: // ----------------------------------------------------------
1015:
1016: /**
1017: * <p>Split a String using a character delimiter</p>
1018: * Contiguous delimiters with nothing in the middle will delimit empty substrings.<br>
1019: * This is an important behaviour difference between Gadgets.split(String,String) and Gadgets.split(String,char).<br>
1020: * Gadgets.split("1;;3;;5;6,";") will return String[4] but Gadgets.split("1;;3;;5;6,';') will return String[6]
1021: * @param sInputStr String to split
1022: * @param cDelimiter Character Delimiter
1023: * @return An array with the splitted substrings
1024: * @throws NullPointerException If sInputStr is <b>null</b>
1025: */
1026: public static String[] split(String sInputStr, char cDelimiter)
1027: throws NullPointerException {
1028: int iStrLen = sInputStr.length();
1029: int iTokCount = 0;
1030:
1031: if (DebugFile.trace) {
1032: DebugFile.writeln("Begin Gadgets.split(\"" + sInputStr
1033: + "\",'" + cDelimiter + "')");
1034: DebugFile.incIdent();
1035: }
1036:
1037: if (0 == iStrLen) {
1038: if (DebugFile.trace) {
1039: DebugFile.decIdent();
1040: DebugFile.writeln("End Gadgets.split() : 0");
1041: }
1042: return null;
1043: }
1044:
1045: for (int p = 0; p < iStrLen; p++)
1046: if (sInputStr.charAt(p) == cDelimiter)
1047: iTokCount++;
1048:
1049: if (DebugFile.trace)
1050: DebugFile.writeln(String.valueOf(iTokCount + 1)
1051: + " tokens found");
1052:
1053: String Tokens[] = new String[iTokCount + 1];
1054:
1055: int iToken = 0;
1056: int iLast = 0;
1057: for (int iNext = 0; iNext < iStrLen; iNext++) {
1058: if (sInputStr.charAt(iNext) == cDelimiter) {
1059: if (iLast == iNext)
1060: Tokens[iToken] = "";
1061: else
1062: Tokens[iToken] = sInputStr.substring(iLast, iNext);
1063: iLast = iNext + 1;
1064: iToken++;
1065: } // fi (sInputStr[iNext]==cDelimiter)
1066: } // next
1067:
1068: if (iLast >= iStrLen)
1069: Tokens[iToken] = "";
1070: else
1071: Tokens[iToken] = sInputStr.substring(iLast, iStrLen);
1072:
1073: if (DebugFile.trace) {
1074: DebugFile.decIdent();
1075: DebugFile.writeln("End Gadgets.split()");
1076: }
1077: return Tokens;
1078: } // split
1079:
1080: // ----------------------------------------------------------
1081:
1082: /**
1083: * <p>Split a String using any of the given characters as delimiter</p>
1084: * @param aDelimiter Character Delimiter Array
1085: * @return An array with the splitted substrings
1086: * @throws NullPointerException If sInputStr is <b>null</b> or aDelimiter is <b>null</b>
1087: */
1088: public static String[] split(String sInputStr, char[] aDelimiter)
1089: throws NullPointerException {
1090: int iStrLen = sInputStr.length();
1091: int iTokCount = 0;
1092: int iDelimCount = aDelimiter.length;
1093: int d;
1094: boolean b;
1095:
1096: if (DebugFile.trace) {
1097: DebugFile.writeln("Begin Gadgets.split(\"" + sInputStr
1098: + "\",char[])");
1099: DebugFile.incIdent();
1100: }
1101:
1102: if (0 == iStrLen) {
1103: if (DebugFile.trace) {
1104: DebugFile.decIdent();
1105: DebugFile.writeln("End Gadgets.split() : 0");
1106: }
1107: return null;
1108: }
1109:
1110: for (int p = 0; p < iStrLen; p++) {
1111: for (d = 0, b = false; d < iDelimCount && !b; d++)
1112: b = (sInputStr.charAt(p) == aDelimiter[d]);
1113: if (b)
1114: iTokCount++;
1115: }
1116:
1117: if (DebugFile.trace)
1118: DebugFile.writeln(String.valueOf(iTokCount + 1)
1119: + " tokens found");
1120:
1121: String Tokens[] = new String[iTokCount + 1];
1122:
1123: int iToken = 0;
1124: int iLast = 0;
1125: for (int iNext = 0; iNext < iStrLen; iNext++) {
1126: for (d = 0, b = false; d < iDelimCount && !b; d++)
1127: b = (sInputStr.charAt(iNext) == aDelimiter[d]);
1128: if (b) {
1129: if (iLast == iNext)
1130: Tokens[iToken] = "";
1131: else
1132: Tokens[iToken] = sInputStr.substring(iLast, iNext);
1133: iLast = iNext + 1;
1134: iToken++;
1135: } // fi (sInputStr[iNext]==cDelimiter)
1136: } // next
1137:
1138: if (iLast >= iStrLen)
1139: Tokens[iToken] = "";
1140: else
1141: Tokens[iToken] = sInputStr.substring(iLast, iStrLen);
1142:
1143: if (DebugFile.trace) {
1144: DebugFile.decIdent();
1145: DebugFile.writeln("End Gadgets.split()");
1146: }
1147: return Tokens;
1148: } // split
1149:
1150: // ----------------------------------------------------------
1151:
1152: /**
1153: * <p>Split a String using a substring delimiter</p>
1154: * Contiguous delimiters with nothing in the middle will be considered has a single delimiter.<br>
1155: * This is an important behaviour difference between Gadgets.split(String,String) and Gadgets.split(String,char).<br>
1156: * Gadgets.split("1;;3;;5;6,";") will return String[4] but Gadgets.split("1;;3;;5;6,';') will return String[6]
1157: * @param sInputStr String to split
1158: * @param sDelimiter Substring Delimiter (no regular expressions allowed)
1159: * @return An array with the splitted substrings
1160: * @throws NullPointerException If sInputStr is <b>null</b>
1161: */
1162: public static String[] split(String sInputStr, String sDelimiter)
1163: throws NullPointerException {
1164:
1165: if (DebugFile.trace) {
1166: DebugFile.writeln("Begin Gadgets.split(\"" + sInputStr
1167: + "\",\"" + sDelimiter + "\")");
1168: DebugFile.incIdent();
1169: }
1170:
1171: // Split an input String by a given delimiter and return an array
1172: StringTokenizer oTokenizer = new StringTokenizer(sInputStr,
1173: sDelimiter);
1174: int iTokCount = oTokenizer.countTokens();
1175: int iTok = 0;
1176: String Tokens[] = null;
1177:
1178: if (DebugFile.trace)
1179: DebugFile.writeln(String.valueOf(iTokCount)
1180: + " tokens found");
1181:
1182: if (iTokCount > 0) {
1183: Tokens = new String[iTokCount];
1184: while (oTokenizer.hasMoreTokens()) {
1185: Tokens[iTok] = oTokenizer.nextToken();
1186: if (DebugFile.trace)
1187: DebugFile.writeln("Token " + String.valueOf(iTok)
1188: + "=" + Tokens[iTok]);
1189: iTok++;
1190: } // wend
1191: }
1192:
1193: if (DebugFile.trace) {
1194: DebugFile.decIdent();
1195: DebugFile.writeln("End Gadgets.split()");
1196: }
1197:
1198: return Tokens;
1199: } // split
1200:
1201: // ----------------------------------------------------------
1202:
1203: /**
1204: * Join a Collection into a String
1205: * @param oList Collection to join
1206: * @param sDelimiter Delimiter for elements in resulting String
1207: * @return List joined as a String
1208: */
1209: public String join(Collection oList, String sDelimiter) {
1210: // Join a LinkedList into a single String
1211: StringBuffer oBuff = new StringBuffer(oList.size()
1212: * (32 + sDelimiter.length()) + 1);
1213: Iterator oIter = oList.iterator();
1214:
1215: while (oIter.hasNext()) {
1216: oBuff.append(oIter.next());
1217: oBuff.append(sDelimiter);
1218: } // wend()
1219:
1220: oIter = null;
1221:
1222: if (oBuff.length() > 0)
1223: return oBuff.substring(0, oBuff.length()
1224: - sDelimiter.length() - 1);
1225: else
1226: return "";
1227: } // join
1228:
1229: // ----------------------------------------------------------
1230:
1231: /**
1232: * Join an Array into a String
1233: * @param aList Array to join
1234: * @param sDelimiter Delimiter for elements in resulting String
1235: * @return List joined as a String
1236: * @since v3.0
1237: */
1238:
1239: public String join(String[] aList, String sDelimiter) {
1240: if (null == aList)
1241: return null;
1242: final int iCount = aList.length;
1243: if (iCount == 0)
1244: return "";
1245: if (null == sDelimiter)
1246: sDelimiter = "";
1247:
1248: // Join an array into a single String
1249: StringBuffer oBuff = new StringBuffer(iCount
1250: * (32 + sDelimiter.length()) + 1);
1251: oBuff.append(aList[0]);
1252: for (int s = 1; s < iCount; s++) {
1253: oBuff.append(sDelimiter);
1254: oBuff.append(aList[0]);
1255: }
1256: return oBuff.toString();
1257: } // join
1258:
1259: // ----------------------------------------------------------
1260:
1261: /**
1262: * <p>Split a String into a Collection using a character delimiter</p>
1263: * Contiguous delimiters with nothing in the middle will delimit empty substrings.
1264: * @param sInputStr String to split
1265: * @param cDelimiter Character Delimiter
1266: * @return A LinkedList splitted substrings
1267: * @throws NullPointerException If sInputStr is <b>null</b>
1268: */
1269:
1270: public static Collection splitAsCollection(String sInputStr,
1271: char cDelimiter) throws NullPointerException {
1272: int iStrLen = sInputStr.length();
1273: int iTokCount = 0;
1274:
1275: if (DebugFile.trace) {
1276: DebugFile.writeln("Begin Gadgets.splitAsCollection(\""
1277: + sInputStr + "\",'" + cDelimiter + "')");
1278: DebugFile.incIdent();
1279: }
1280:
1281: LinkedList oTokens = new LinkedList();
1282:
1283: int iLast = 0;
1284: for (int iNext = 0; iNext < iStrLen; iNext++) {
1285: if (sInputStr.charAt(iNext) == cDelimiter) {
1286: if (iLast == iNext)
1287: oTokens.add("");
1288: else
1289: oTokens.add(sInputStr.substring(iLast, iNext));
1290: iLast = iNext + 1;
1291: } // fi (sInputStr[iNext]==cDelimiter)
1292: } // next
1293:
1294: if (iLast >= iStrLen)
1295: oTokens.add("");
1296: else
1297: oTokens.add(sInputStr.substring(iLast, iStrLen));
1298:
1299: if (DebugFile.trace) {
1300: DebugFile.decIdent();
1301: DebugFile.writeln("End Gadgets.splitAsCollection() : "
1302: + String.valueOf(oTokens.size()));
1303: }
1304: return oTokens;
1305: } // splitAsCollection
1306:
1307: // ----------------------------------------------------------
1308:
1309: /**
1310: * Get index of a substring inside another string
1311: * @param sSource String String to be scanned
1312: * @param sSought Substring to be sought
1313: * @param iStartAt int Index to start searching from
1314: * @return int Start index of substring or -1 if not found
1315: */
1316:
1317: public static int indexOfIgnoreCase(String sSource, String sSought,
1318: int iStartAt) {
1319: if ((sSource == null) || (sSought == null))
1320: return -1;
1321:
1322: final int iSrcLen = sSource.length();
1323: final int iSghLen = sSought.length();
1324:
1325: if (iSrcLen < iSghLen)
1326: return -1;
1327:
1328: if (iSrcLen == iSghLen)
1329: return (sSource.equalsIgnoreCase(sSought) ? 0 : -1);
1330:
1331: final int iReducedLen = iSrcLen - iSghLen;
1332:
1333: if (iStartAt + iSghLen > iSrcLen)
1334: return -1;
1335:
1336: for (int p = iStartAt; p < iReducedLen; p++) {
1337: if (sSource.substring(p, p + iSghLen).equalsIgnoreCase(
1338: sSought))
1339: return p;
1340: }
1341: return -1;
1342: }
1343:
1344: // ----------------------------------------------------------
1345:
1346: /**
1347: * Get index of a substring inside another string
1348: * @param sSource String String to be scanned
1349: * @param sSought Substring to be sought
1350: * @return int Start index of substring or -1 if not found
1351: */
1352: public static int indexOfIgnoreCase(String sSource, String sSought) {
1353: if ((sSource == null) || (sSought == null))
1354: return -1;
1355:
1356: final int iSrcLen = sSource.length();
1357: final int iSghLen = sSought.length();
1358:
1359: if (iSrcLen < iSghLen)
1360: return -1;
1361:
1362: if (iSrcLen == iSghLen)
1363: return (sSource.equalsIgnoreCase(sSought) ? 0 : -1);
1364:
1365: final int iReducedLen = iSrcLen - iSghLen;
1366:
1367: for (int p = 0; p < iReducedLen; p++) {
1368: if (sSource.substring(p, p + iSghLen).equalsIgnoreCase(
1369: sSought))
1370: return p;
1371: }
1372: return -1;
1373: } // indexOfIgnoreCase
1374:
1375: // ----------------------------------------------------------
1376:
1377: /**
1378: * Fill String with a given character
1379: * @param c Character for filling
1380: * @param len Number of characters
1381: * @return A String with given numbers of characters
1382: * @throws IndexOutOfBoundsException if len<0
1383: */
1384: public static String fill(char c, int len)
1385: throws IndexOutOfBoundsException {
1386: // Return a String filled with a given character
1387: if (len < 0)
1388: throw new IndexOutOfBoundsException(
1389: "Gadgets.fill() numbers of characters must be greater than or equal to zero");
1390: else if (len == 0)
1391: return "";
1392: else {
1393: StringBuffer oStrBuff = new StringBuffer(len);
1394: for (int i = 0; i < len; i++)
1395: oStrBuff.append(c);
1396: return oStrBuff.toString();
1397: }
1398: } // fill
1399:
1400: // ----------------------------------------------------------
1401:
1402: /**
1403: * Check whether or not a String matches a regular expression
1404: * @param sSource String Source
1405: * @param sRegExp String Regular Expression
1406: * @return boolean <b>false</b> if either sSource or sRegExp are <b>null</b>
1407: * @throws MalformedPatternException
1408: * @since v3.0
1409: * @see http://www.savarese.org/oro/docs/OROMatcher/Syntax.html
1410: */
1411: public static boolean matches(String sSource, String sRegExp)
1412: throws MalformedPatternException {
1413: if (null == oMatcher)
1414: oMatcher = new Perl5Matcher();
1415: if (null == oCompiler)
1416: oCompiler = new Perl5Compiler();
1417:
1418: if (sSource == null || sRegExp == null)
1419: return false;
1420: else
1421: return oMatcher
1422: .matches(sSource, oCompiler.compile(sRegExp));
1423: } // matches
1424:
1425: // ----------------------------------------------------------
1426:
1427: /**
1428: * Check whether or not a String contains a regular expression
1429: * @param sSource String Source
1430: * @param sRegExp String Regular Expression
1431: * @return boolean <b>false</b> if either sSource or sRegExp are <b>null</b>
1432: * @throws MalformedPatternException
1433: * @since v3.0
1434: * @see http://www.savarese.org/oro/docs/OROMatcher/Syntax.html
1435: */
1436: public static boolean contains(String sSource, String sRegExp)
1437: throws MalformedPatternException {
1438: if (null == oMatcher)
1439: oMatcher = new Perl5Matcher();
1440: if (null == oCompiler)
1441: oCompiler = new Perl5Compiler();
1442:
1443: if (sSource == null || sRegExp == null)
1444: return false;
1445: else
1446: return oMatcher.contains(sSource, oCompiler
1447: .compile(sRegExp));
1448: } // contains
1449:
1450: // ----------------------------------------------------------
1451:
1452: /**
1453: * Get the first substring that matches the given regular expression
1454: * @param sSource String Source
1455: * @param sRegExp String Regular Expression
1456: * @return String if no substring matches the regular expression then <b>null</b> is returned
1457: * @throws MalformedPatternException
1458: * @since v3.0
1459: * @see http://jakarta.apache.org/oro/api/org/apache/oro/text/regex/Perl5Matcher.html
1460: */
1461: public static String getFirstMatchSubStr(String sSource,
1462: String sRegExp) throws MalformedPatternException {
1463: String sRetStr;
1464: if (sSource == null || sRegExp == null)
1465: sRetStr = null;
1466: else {
1467: if (null == oMatcher)
1468: oMatcher = new Perl5Matcher();
1469: if (null == oCompiler)
1470: oCompiler = new Perl5Compiler();
1471: if (oMatcher.contains(sSource, oCompiler.compile(sRegExp))) {
1472: sRetStr = oMatcher.getMatch().group(0);
1473: } else {
1474: sRetStr = null;
1475: }
1476: }
1477: return sRetStr;
1478: } // getFirstMatchSubStr
1479:
1480: // ----------------------------------------------------------
1481:
1482: /**
1483: * Replace a given pattern on a string with a fixed value
1484: * @param sSource Source String
1485: * @param sRegExp Regular Expression to be matched
1486: * @param sNewVal New value for replacement
1487: * @throws MalformedPatternException
1488: * @see http://www.savarese.org/oro/docs/OROMatcher/Syntax.html
1489: */
1490: public static String replace(String sSource, String sRegExp,
1491: String sNewVal) throws MalformedPatternException {
1492: Pattern oPattern;
1493: if (null == oMatcher)
1494: oMatcher = new Perl5Matcher();
1495: if (null == oCompiler)
1496: oCompiler = new Perl5Compiler();
1497:
1498: oPattern = oCompiler.compile(sRegExp);
1499:
1500: return Util.substitute(oMatcher, oPattern,
1501: new Perl5Substitution(sNewVal,
1502: Perl5Substitution.INTERPOLATE_ALL), sSource,
1503: Util.SUBSTITUTE_ALL);
1504: } // replace
1505:
1506: /**
1507: * Replace a given pattern on a string with a fixed value
1508: * @param sSource Source String
1509: * @param sRegExp Regular Expression to be matched
1510: * @param sNewVal New value for replacement
1511: * @param iOptions A set of flags giving the compiler instructions on how to
1512: * treat the regular expression. The flags are a logical OR of any number of
1513: * the five <a href="http://jakarta.apache.org/oro/api/org/apache/oro/text/regex/Perl5Compiler.html">
1514: * org.apache.oro.text.regex.Perl5Compiler</A> MASK constants.<br>
1515: * <table>
1516: * <tr><td>CASE_INSENSITIVE_MASK</td><td>Compiled regular expression should be case insensitive</td></tr>
1517: * <tr><td>DEFAULT_MASK</td><td>Use default mask for compile method</td></tr>
1518: * <tr><td>EXTENDED_MASK</td><td>compiled regular expression should be treated as a Perl5 extended pattern (i.e., a pattern using the /x modifier)</td></tr>
1519: * <tr><td>MULTILINE_MASK</td><td>Compiled regular expression should treat input as having multiple lines</td></tr>
1520: * <tr><td>READ_ONLY_MASK</td><td>Resulting Perl5Pattern should be treated as a read only data structure by Perl5Matcher, making it safe to share a single Perl5Pattern instance among multiple threads without needing synchronization</td></tr>
1521: * <tr><td>SINGLELINE_MASK</td><td>Compiled regular expression should treat input as being a single line</td></tr>
1522: * @throws MalformedPatternException
1523: * @see http://www.savarese.org/oro/docs/OROMatcher/Syntax.html
1524: */
1525: public static String replace(String sSource, String sRegExp,
1526: String sNewVal, int iOptions)
1527: throws MalformedPatternException {
1528: Pattern oPattern;
1529: if (null == oMatcher)
1530: oMatcher = new Perl5Matcher();
1531: if (null == oCompiler)
1532: oCompiler = new Perl5Compiler();
1533:
1534: oPattern = oCompiler.compile(sRegExp, iOptions);
1535:
1536: return Util.substitute(oMatcher, oPattern,
1537: new Perl5Substitution(sNewVal,
1538: Perl5Substitution.INTERPOLATE_ALL), sSource,
1539: Util.SUBSTITUTE_ALL);
1540: } // replace
1541:
1542: // ----------------------------------------------------------
1543:
1544: /**
1545: * Count occurrences of a given substring
1546: * @param sSource String Source
1547: * @param sSubStr Substring to be searched (no wildcards)
1548: * @param iOptions int org.apache.oro.text.regex.Perl5Compiler.CASE_INSENSITIVE_MASK for case insensitive search
1549: * @return int Number of occurrences of sSubStr at sSource.
1550: * If sSource is null or sSubStr is null then the number of occurrences is zero.
1551: * If sSource is empty or sSubStr is empty then the number of occurrences is zero.
1552: */
1553: public static int countOccurrences(String sSource, String sSubStr,
1554: int iOptions) throws MalformedPatternException {
1555: if (null == sSource || null == sSubStr)
1556: return 0;
1557: if (sSource.length() == 0 || sSubStr.length() == 0)
1558: return 0;
1559:
1560: int lSource = sSource.length();
1561: int lSubStr = sSubStr.length();
1562: int iOccurrences = 0;
1563: int iCurPos;
1564: if ((org.apache.oro.text.regex.Perl5Compiler.CASE_INSENSITIVE_MASK & iOptions) == 0) {
1565: iCurPos = sSource.indexOf(sSubStr);
1566: while (iCurPos != -1 && iCurPos + lSubStr <= lSource) {
1567: iOccurrences++;
1568: iCurPos = sSource.indexOf(sSubStr, iCurPos + 1);
1569: }
1570: } else {
1571: iCurPos = Gadgets.indexOfIgnoreCase(sSource, sSubStr);
1572: while (iCurPos != -1 && iCurPos + lSubStr <= lSource) {
1573: iOccurrences++;
1574: iCurPos = Gadgets.indexOfIgnoreCase(sSource, sSubStr,
1575: iCurPos + 1);
1576: }
1577: }
1578: return iOccurrences;
1579: } // countOccurrences
1580:
1581: // ----------------------------------------------------------
1582:
1583: /**
1584: * Return left portion of a string.
1585: * This function is similar to substring(sSource, nChars) but it does not raise
1586: * any exception if sSource.length()>nChars but just return the full sSource
1587: * input String.
1588: * @param sSource Source String
1589: * @param nChars Number of characters to the left of String to get.
1590: * @return Left characters of sSource String or <b>null</b> if sSource is <b>null</b>.
1591: */
1592: public static String left(String sSource, int nChars) {
1593: int iLen;
1594:
1595: if (null == sSource)
1596: return null;
1597:
1598: iLen = sSource.length();
1599:
1600: if (iLen > nChars)
1601: return sSource.substring(0, nChars);
1602: else
1603: return sSource;
1604: } // left
1605:
1606: // ----------------------------------------------------------
1607:
1608: /**
1609: * Add padding characters to the left.
1610: * @param sSource Input String
1611: * @param cPad Padding character
1612: * @param nChars Final length of the padded string
1613: * @return Padded String
1614: */
1615: public static String leftPad(String sSource, char cPad, int nChars) {
1616: if (null == sSource)
1617: return null;
1618:
1619: int iPadLen = nChars - sSource.length();
1620:
1621: if (iPadLen <= 0)
1622: return sSource;
1623:
1624: char aPad[] = new char[iPadLen];
1625:
1626: for (int c = 0; c < iPadLen; c++)
1627: aPad[c] = cPad;
1628:
1629: return new String(aPad) + sSource;
1630: } // leftPad
1631:
1632: // ----------------------------------------------------------
1633:
1634: /**
1635: * Ensure that a String ends with a given character
1636: * @param sSource Input String
1637: * @param cEndsWith Character that the String must end with.
1638: * @return If sSource ends with cEndsWith then sSource is returned,
1639: * else sSource+cEndsWith is returned.
1640: */
1641: public static String chomp(String sSource, char cEndsWith) {
1642:
1643: if (null == sSource)
1644: return null;
1645: else if (sSource.length() == 0)
1646: return "";
1647: else if (sSource.charAt(sSource.length() - 1) == cEndsWith)
1648: return sSource;
1649: else
1650: return sSource + String.valueOf(cEndsWith);
1651: } // chomp
1652:
1653: // ----------------------------------------------------------
1654:
1655: /**
1656: * Ensure that a String ends with a given substring
1657: * @param sSource Input String
1658: * @param sEndsWith Substring that the String must end with.
1659: * @return If sSource ends with sEndsWith then sSource is returned,
1660: * else sSource+sEndsWith is returned.
1661: */
1662: public static String chomp(String sSource, String sEndsWith) {
1663:
1664: if (null == sSource)
1665: return null;
1666: else if (sSource.length() == 0)
1667: return "";
1668: else if (sSource.endsWith(sEndsWith))
1669: return sSource;
1670: else
1671: return sSource + sEndsWith;
1672: } // chomp
1673:
1674: // ----------------------------------------------------------
1675:
1676: /**
1677: * Ensure that a String does not end with a given substring
1678: * @param sSource Input String
1679: * @param sEndsWith Substring that the String must not end with.
1680: * @return If sSource does not end with sEndsWith then sSource is returned,
1681: * else sSource-sEndsWith is returned.
1682: */
1683: public static String dechomp(String sSource, String sEndsWith) {
1684:
1685: if (null == sSource)
1686: return null;
1687: else if (sEndsWith == null)
1688: return sSource;
1689: else if (sSource.length() < sEndsWith.length())
1690: return sSource;
1691: else if (sSource.endsWith(sEndsWith))
1692: return sSource.substring(0, sSource.length()
1693: - sEndsWith.length());
1694: else
1695: return sSource;
1696: } // dechomp
1697:
1698: // ----------------------------------------------------------
1699:
1700: /**
1701: * Ensure that a String does not end with a given character
1702: * @param sSource Input String
1703: * @param cEndsWith Character that the String must not end with.
1704: * @return If sSource does not end with sEndsWith then sSource is returned,
1705: * else sSource-cEndsWith is returned.
1706: */
1707: public static String dechomp(String sSource, char cEndsWith) {
1708:
1709: if (null == sSource)
1710: return null;
1711: else if (sSource.length() < 1)
1712: return sSource;
1713: else if (sSource.charAt(sSource.length() - 1) == cEndsWith)
1714: return sSource.substring(0, sSource.length() - 1);
1715: else
1716: return sSource;
1717: } // dechomp
1718:
1719: // ----------------------------------------------------------
1720:
1721: /**
1722: * <p>Take an input string and tokenize each command on it<p>
1723: * @param sSource String to be parsed.<br>
1724: * Tokens are separated by spaces. Single or double quotes are allowed for qualifying string literals.
1725: * @return String[] Array of tokens. If sSource is <b>null</b> then the return value is <b>null</b>,
1726: * if sSource is empty then the return value is an array with a single element being it <b>null</b>.
1727: * @throws StringIndexOutOfBoundsException
1728: */
1729: public static String[] tokenizeCmdLine(String sSource)
1730: throws StringIndexOutOfBoundsException {
1731: String[] aTokens;
1732:
1733: if (DebugFile.trace) {
1734: DebugFile.writeln("Begin Gadgets.tokenizeCmdLine("
1735: + sSource + ")");
1736: DebugFile.incIdent();
1737: }
1738:
1739: if (null == sSource) {
1740: aTokens = null;
1741: } else if (sSource.length() == 0) {
1742: aTokens = new String[] { null };
1743: } else {
1744: final int iLen = sSource.length();
1745: ArrayList oTokens = new ArrayList();
1746: char cTextQualifier = (char) 0;
1747: char cCurrentChar;
1748: StringBuffer oCurrentToken = new StringBuffer(256);
1749: for (int p = 0; p < iLen; p++) {
1750: cCurrentChar = sSource.charAt(p);
1751: switch (cCurrentChar) {
1752: case ' ':
1753: if (0 != cTextQualifier) {
1754: oCurrentToken.append(cCurrentChar);
1755: } else if (oCurrentToken.length() > 0) {
1756: oTokens.add(oCurrentToken.toString());
1757: oCurrentToken.setLength(0);
1758: }
1759: break;
1760: case '\\':
1761: if (p == iLen - 1)
1762: throw new StringIndexOutOfBoundsException(
1763: "Input string terminated with a single backslash character");
1764: switch (sSource.charAt(++p)) {
1765: case 'n':
1766: oCurrentToken.append('\n');
1767: break;
1768: case 't':
1769: oCurrentToken.append('\t');
1770: break;
1771: case '\\':
1772: oCurrentToken.append('\\');
1773: break;
1774: case '"':
1775: oCurrentToken.append('"');
1776: break;
1777: default:
1778: throw new StringIndexOutOfBoundsException(
1779: "Unrecognized escape sequence \\"
1780: + sSource.charAt(p));
1781: } // end switch (charAt(++p))
1782: break;
1783: case '"':
1784: if (0 == cTextQualifier) {
1785: cTextQualifier = '"';
1786: } else if ('"' == cTextQualifier) {
1787: cTextQualifier = (char) 0;
1788: }
1789: break;
1790: case '\'':
1791: if (0 == cTextQualifier) {
1792: cTextQualifier = '\'';
1793: } else if ('\'' == cTextQualifier) {
1794: cTextQualifier = (char) 0;
1795: }
1796: break;
1797: case ',':
1798: case ';':
1799: case '(':
1800: case ')':
1801: case '[':
1802: case ']':
1803: case '{':
1804: case '}':
1805: case '-':
1806: case '+':
1807: case '/':
1808: case '*':
1809: case '=':
1810: case '&':
1811: case '!':
1812: case '?':
1813: if (0 != cTextQualifier) {
1814: oCurrentToken.append(cCurrentChar);
1815: } else {
1816: if (oCurrentToken.length() > 0) {
1817: oTokens.add(oCurrentToken.toString());
1818: oCurrentToken.setLength(0);
1819: }
1820: oTokens.add(new String(
1821: new char[] { cCurrentChar }));
1822: }
1823: break;
1824: default:
1825: oCurrentToken.append(cCurrentChar);
1826: }
1827: } // next
1828: if (oCurrentToken.length() > 0) {
1829: oTokens.add(oCurrentToken.toString());
1830: }
1831: aTokens = new String[oTokens.size()];
1832: System.arraycopy(oTokens.toArray(), 0, aTokens, 0,
1833: aTokens.length);
1834: }
1835:
1836: if (DebugFile.trace) {
1837: StringBuffer oOutput = new StringBuffer();
1838: if (aTokens != null)
1839: for (int t = 0; t < aTokens.length; t++)
1840: oOutput.append(aTokens[t]
1841: + (t < aTokens.length - 1 ? "¶" : ""));
1842: DebugFile.decIdent();
1843: DebugFile.writeln("End Gadgets.tokenizeCmdLine() : "
1844: + oOutput.toString());
1845: }
1846:
1847: return aTokens;
1848: } // tokenizeCmdLine
1849:
1850: // ----------------------------------------------------------
1851:
1852: /**
1853: * Check that an e-mail address is syntactically valid.
1854: * @param sEMailAddr e-mail address to check
1855: * @return <b>true</b> if e-mail address is syntactically valid.
1856: */
1857: public static boolean checkEMail(String sEMailAddr) {
1858: final String nu = "1234567890";
1859: final String ok = "1234567890qwertyuiop[]asdfghjklzxcvbnm.@-_QWERTYUIOPASDFGHJKLZXCVBNM";
1860: int iAt, iDot;
1861:
1862: if (sEMailAddr == null)
1863: return false;
1864:
1865: if (sEMailAddr.trim().length() == 0)
1866: return false;
1867:
1868: iAt = sEMailAddr.indexOf("@");
1869: iDot = sEMailAddr.lastIndexOf(".");
1870:
1871: // Domain extension must exist
1872: if (iDot <= 0)
1873: return false;
1874:
1875: if (iAt <= 0 || iAt == sEMailAddr.length() - 1)
1876: return false;
1877:
1878: // Domain name must exist
1879: if (ok.indexOf(sEMailAddr.substring(iAt - 1, iAt)) < 0
1880: || ok.indexOf(sEMailAddr.substring(iAt + 1, iAt + 2)) < 0)
1881: return false;
1882:
1883: // Domain name cannot start with a number
1884: if (nu.indexOf(sEMailAddr.substring(iAt + 1, iAt + 2)) >= 0)
1885: return false;
1886:
1887: // Domain extension is at most 4 characters
1888: if (iDot < sEMailAddr.length() - 5)
1889: return false;
1890:
1891: // Domain extension is at least 2 characters
1892: if (iDot > sEMailAddr.length() - 3)
1893: return false;
1894:
1895: return true;
1896: } // checkEMail
1897:
1898: // ----------------------------------------------------------
1899:
1900: public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4',
1901: '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1902:
1903: public static void toHexChars(int val, char dst[], int dstIndex,
1904: int size) {
1905: while (size > 0) {
1906: dst[dstIndex + size - 1] = HEX_DIGITS[val & 0x000F];
1907: if (val != 0) {
1908: val >>>= 4;
1909: }
1910: size--;
1911: }
1912: }
1913:
1914: // ----------------------------------------------------------
1915:
1916: public static String toHexString(int val, int size) {
1917: char[] c = new char[size];
1918: toHexChars(val, c, 0, size);
1919: return new String(c);
1920: }
1921:
1922: // ----------------------------------------------------------
1923:
1924: /**
1925: * Convert a byte array into its corresponding Hexadecimal String representation
1926: * @param src Input array
1927: * @param srcIndex Begin Index
1928: * @param size Number of bytes to be readed
1929: * @return A String with two hexadecimal upper case digits per byte on the input array
1930: */
1931: public static String toHexString(byte[] src, int srcIndex, int size) {
1932: if (null == src)
1933: return null;
1934:
1935: char[] c = new char[size];
1936: size = (size % 2 == 0) ? size / 2 : size / 2 + 1;
1937: for (int i = 0, j = 0; i < size; i++) {
1938: c[j++] = HEX_DIGITS[(src[i] >> 4) & 0x0F];
1939: if (j == c.length) {
1940: break;
1941: }
1942: c[j++] = HEX_DIGITS[src[i] & 0x0F];
1943: }
1944: return new String(c);
1945: }
1946:
1947: // ----------------------------------------------------------
1948:
1949: /**
1950: * Convert a byte array into its corresponding Hexadecimal String representation
1951: * @param src Input array
1952: * @return A String with two hexadecimal upper case digits per byte on the input array
1953: */
1954: public static String toHexString(byte[] src) {
1955: if (null == src)
1956: return null;
1957:
1958: return toHexString(src, 0, src.length);
1959: }
1960:
1961: // ----------------------------------------------------------
1962:
1963: /**
1964: * Remove a character from a String
1965: * @param sInput Input String
1966: * @param cRemove Character to be removed
1967: * @return The input String without all the occurences of the given character
1968: */
1969: public static String removeChar(String sInput, char cRemove) {
1970: if (null == sInput)
1971: return null;
1972: if (sInput.length() == 0)
1973: return sInput;
1974:
1975: final int iLen = sInput.length();
1976: StringBuffer oOutput = new StringBuffer(iLen);
1977:
1978: for (int i = 0; i < iLen; i++) {
1979: char c = sInput.charAt(i);
1980: if (cRemove != c)
1981: oOutput.append(c);
1982: } // next
1983:
1984: return oOutput.toString();
1985: } // removeChar
1986:
1987: // ----------------------------------------------------------
1988:
1989: /**
1990: * Remove a character set from a String
1991: * @param sInput Input String
1992: * @param sRemove A String containing all the characters to be removed from input String
1993: * @return The input String without all the characters of sRemove
1994: */
1995: public static String removeChars(String sInput, String sRemove) {
1996: if (null == sInput)
1997: return null;
1998: if (null == sRemove)
1999: return sInput;
2000: if (sInput.length() == 0)
2001: return sInput;
2002: if (sRemove.length() == 0)
2003: return sInput;
2004:
2005: final int iLen = sInput.length();
2006: StringBuffer oOutput = new StringBuffer(iLen);
2007:
2008: for (int i = 0; i < iLen; i++) {
2009: char c = sInput.charAt(i);
2010: if (sRemove.indexOf(c) < 0)
2011: oOutput.append(c);
2012: } // next
2013:
2014: return oOutput.toString();
2015: } // removeChars
2016:
2017: // ----------------------------------------------------------
2018:
2019: /**
2020: * Rounds a BigDecimal value to two decimals
2021: * @param oDec BigDecimal to be rounded
2022: * @return BigDecimal If oDec is <b>null</b> then round2 returns <b>null</b>
2023: */
2024: public static BigDecimal round2(BigDecimal oDec) {
2025: if (null == oDec)
2026: return null;
2027: StringBuffer oBuffer = new StringBuffer();
2028: if (null == oFmt2) {
2029: oFmt2 = new DecimalFormat("#0.00");
2030: oFrac = new FieldPosition(
2031: java.text.NumberFormat.FRACTION_FIELD);
2032: }
2033: oFmt2.format(oDec.doubleValue(), oBuffer, oFrac);
2034: return new BigDecimal(oBuffer.toString());
2035: }
2036:
2037: // ----------------------------------------------------------
2038:
2039: /**
2040: * Format a BigDecimal as a String following the rules for an specific locale
2041: * @param oDec BigDecimal to be formatted
2042: * @param sCurrency String ISO 4217 currency code (EUR, USD, GBP, BRL, CNY, etc.)
2043: * @param sLanguage String lowercase two-letter ISO-639 code
2044: * @param sLocale2 String uppercase two-letter ISO-3166 code
2045: * @return String
2046: * @see <a href="http://www.bsi-global.com/British_Standards/currency/index.xalter">BSI Currency Code Service (ISO 4217 Maintenance Agency)</a>
2047: * @see <a href="http://www.xe.com/iso4217.htm">ISO 4217 currency code list</a>
2048: * @see <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">ISO 639 language codes</a>
2049: * @see <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166 country codes</a>
2050: */
2051: public static String formatCurrency(BigDecimal oDec,
2052: String sCurrency, String sLanguage, String sCountry) {
2053: if (null == oDec)
2054: return null;
2055:
2056: Locale oLoc;
2057: if (null != sLanguage && null != sCountry)
2058: oLoc = new Locale(sLanguage, sCountry);
2059: else if (null != sLanguage)
2060: oLoc = new Locale(sLanguage);
2061: else
2062: oLoc = Locale.getDefault();
2063: if (null == sCurrency) {
2064: oCurr = Currency.getInstance(oLoc);
2065: } else if (!sCurrency.equals(sCurr)) {
2066: oCurr = Currency.getInstance(sCurrency);
2067: }
2068: NumberFormat oFmtC = NumberFormat.getCurrencyInstance(oLoc);
2069: oFmtC.setCurrency(oCurr);
2070: return oFmtC.format(oDec.doubleValue());
2071: }
2072:
2073: // ----------------------------------------------------------
2074:
2075: /**
2076: * Format a BigDecimal as a String following the rules for an specific locale
2077: * @param oDec BigDecimal to be formatted
2078: * @param sCurrency String ISO 4217 currency code (EUR, USD, GBP, BRL, CNY, etc.)
2079: * @param sLanguage String lowercase two-letter ISO-639 code
2080: * @return String
2081: * @see <a href="http://www.xe.com/iso4217.htm">ISO 4217 currency code list</a>
2082: * @see <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">ISO 639 language codes</a>
2083: */
2084: public static String formatCurrency(BigDecimal oDec,
2085: String sCurrency, String sLanguage) {
2086: if (null == oDec)
2087: return null;
2088:
2089: Locale oLoc = (sLanguage == null ? Locale.getDefault()
2090: : new Locale(sLanguage));
2091: if (null == sCurrency) {
2092: oCurr = Currency.getInstance(oLoc);
2093: } else if (!sCurrency.equals(sCurr)) {
2094: oCurr = Currency.getInstance(sCurrency);
2095: }
2096: NumberFormat oFmtC = NumberFormat.getCurrencyInstance(oLoc);
2097: oFmtC.setCurrency(oCurr);
2098: return oFmtC.format(oDec.doubleValue());
2099: }
2100:
2101: // ----------------------------------------------------------
2102: /**
2103: * Format a BigDecimal as a String following the rules for an specific locale
2104: * @param oDec BigDecimal to be formatted
2105: * @param sCurrency String ISO 4217 currency code (EUR, USD, GBP, BRL, CNY, etc.)
2106: * @param oLocale Locale used for formatting
2107: * @return String
2108: * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Locale.html">java.util.Locale</a>
2109: */
2110: public static String formatCurrency(BigDecimal oDec,
2111: String sCurrency, Locale oLocale) {
2112: NumberFormat oFmtC;
2113: if (null == oDec)
2114: return null;
2115:
2116: if (null == sCurrency) {
2117: oCurr = Currency.getInstance(oLocale == null ? Locale
2118: .getDefault() : oLocale);
2119: } else if (!sCurrency.equals(sCurr)) {
2120: oCurr = Currency.getInstance(sCurrency);
2121: }
2122: if (null == oLocale)
2123: oFmtC = NumberFormat.getCurrencyInstance(Locale
2124: .getDefault());
2125: else
2126: oFmtC = NumberFormat.getCurrencyInstance(oLocale);
2127: oFmtC.setCurrency(oCurr);
2128: return oFmtC.format(oDec.doubleValue());
2129: }
2130:
2131: // ----------------------------------------------------------
2132:
2133: public static void main(String[] argv) {
2134: if (argv.length > 0) {
2135: if (argv[0].equalsIgnoreCase("uuidgen")) {
2136: System.out.println(Gadgets.generateUUID());
2137: } // fi (argv[0]=="uuidgen")
2138: }
2139: }
2140:
2141: } // Gadgets
|