0001: /*
0002: *******************************************************************************
0003: * Copyright (C) 2002-2004, International Business Machines Corporation and *
0004: * others. All Rights Reserved. *
0005: *******************************************************************************
0006: */
0007: package com.ibm.icu.dev.tool.localeconverter;
0008:
0009: import java.util.*;
0010:
0011: public class PosixToNeutralConverter extends LocaleConverter {
0012: public static final byte LC_CTYPE = 0x01;
0013: public static final byte LC_TIME = 0x02;
0014: public static final byte LC_NUMERIC = 0x04;
0015: public static final byte LC_MONETARY = 0x08;
0016: public static final byte LC_MESSAGES = 0x10;
0017: public static final byte LC_MEASUREMENT = 0x11;
0018: public static final byte LC_ADDRESS = 0x12;
0019: public static final byte LC_PAPER = 0x13;
0020: public static final byte LC_NAME = 0x14;
0021: public static final byte LC_IDENTIFICATION = 0x15;
0022: public static final byte LC_TELEPHONE = 0x16;
0023:
0024: private static final byte[] masks = { LC_CTYPE, LC_TIME,
0025: LC_NUMERIC, LC_MONETARY, LC_MESSAGES, LC_MEASUREMENT,
0026: LC_ADDRESS, LC_PAPER, LC_NAME, LC_IDENTIFICATION,
0027: LC_TELEPHONE };
0028:
0029: private static final String[][] props = {
0030: //LC_CTYPE
0031: { "upper", "lower", "alpha", "digit", "space", "cntrl",
0032: "punct", "graph", "print", "xdigit", "blank",
0033: "toupper", "tolower" },
0034: //LC_TIME
0035: { "abday", "day", "abmon", "mon", "d_t_fmt", "d_ftm",
0036: "t_fmt", "am_pm", "t_fmt_ampm", "era", "era_year",
0037: "era_d_fmt", "alt_digits" },
0038: //LC_NUMERIC
0039: { "decimal_point", "thousands_sep", "grouping" },
0040: //LC_MONETARY
0041: { "int_curr_symbol", "currency_symbol",
0042: "mon_decimal_point", "mon_thousands_sep",
0043: "mon_grouping", "positive_sign", "negative_sign",
0044: "int_frac_digits", "frac_digits", "p_cs_precedes",
0045: "p_sep_by_space", "n_cs_precedes",
0046: "n_sep_by_space", "p_sign_posn", },
0047: //LC_MESSAGES
0048: { "yesexpr", "noexpr" },
0049:
0050: //LC_MEASUREMENT
0051: { "measurement" },
0052: //LC_ADDRESS
0053: { "copy", "postal_fmt", "country_name", "country_post",
0054: "country_ab2", "country_ab3", "country_num",
0055: "country_car", "country_isbn", "lang_name",
0056: "lang_ab", "lang_term", "lang_lib"
0057:
0058: },
0059: //LC_PAPER
0060: { "height", "width", "copy" },
0061: //LC_NAME
0062: { "copy", "name_fmt", "name_gen", "name_miss", "name_mr",
0063: "name_mrs", "name_ms" },
0064: //LC_IDENTIFICATION
0065: { "title", "source", "address", "contact", "email", "tel",
0066: "fax", "language", "territory", "revision ", "date" },
0067: //LC_TELEPHONE
0068: { "copy", "tel_int_fmt", "tel_dom_fmt", "int_select",
0069: "int_prefix" },
0070:
0071: };
0072: private final byte flags;
0073: private final Locale locale;
0074: private final Locale parentLocale;
0075: private final String sfileName;
0076:
0077: public PosixToNeutralConverter(byte flags, final Locale locale,
0078: final String fileName) {
0079: this .flags = flags;
0080: this .locale = locale;
0081: this .sfileName = fileName;
0082:
0083: String language = locale.getLanguage();
0084: String country = locale.getCountry();
0085: String variant = "";
0086:
0087: int ndx = language.indexOf('_');
0088: if (ndx >= 0) {
0089: country = language.substring(ndx + 1);
0090: language = language.substring(0, ndx);
0091: }
0092: ndx = country.indexOf('_');
0093: if (ndx >= 0) {
0094: variant = country.substring(ndx);
0095: country = country.substring(0, ndx);
0096: }
0097:
0098: if ("".equals(country)) {
0099: language = "";
0100: variant = "";
0101: } else if ("".equals(variant)) {
0102: country = "";
0103: }
0104:
0105: parentLocale = new Locale(language, country, variant);
0106: //{{INIT_CONTROLS
0107: //}}
0108: }
0109:
0110: protected void convert(final Hashtable result,
0111: final Hashtable source) throws ConversionError {
0112: // convertMESSAGES(result,source);
0113: writePosixCompData(result, source);
0114: convertMEASUREMENT(result, source);
0115: convertCOUNTRYNUMBER(result, source);
0116: convertCOUNTRYISBNNUMBER(result, source);
0117: convertLANGUAGELIB(result, source);
0118: convertPAPERSIZE(result, source);
0119: convertMONETARY(result, source);
0120: convertNUMERIC(result, source);
0121: convertTIME(result, source);
0122: convertCOLLATE(result, source);
0123: for (int i = 0; i < masks.length; i++) {
0124: if ((flags & masks[i]) != 0) {
0125: for (int j = 0; j < props[i].length; j++) {
0126: final String prop = props[i][j];
0127: final Object val = source.get(prop);
0128: if (val != null) {
0129: resultPut(result, prop, val);
0130: }
0131: }
0132: }
0133: }
0134: }
0135:
0136: public String[][] clone2DArr(String[][] str2Darray) {
0137: String[][] newStr2DArr = new String[str2Darray.length][str2Darray[0].length];
0138: for (int i = 0; i < str2Darray.length; i++) {
0139: for (int j = 0; j < str2Darray[i].length; j++) {
0140: newStr2DArr[i][j] = new String(str2Darray[i][j]);
0141: }
0142: }
0143: return newStr2DArr;
0144: }
0145:
0146: public Object[][] clone2DArr(Object[][] str2Darray) {
0147: Object[][] newStr2DArr = new Object[str2Darray.length][str2Darray[0].length];
0148: for (int i = 0; i < str2Darray.length; i++) {
0149: for (int j = 0; j < str2Darray[i].length; j++) {
0150: newStr2DArr[i][j] = (Object) (new String(
0151: (String) str2Darray[i][j]));
0152: }
0153: }
0154: return newStr2DArr;
0155: }
0156:
0157: public void writePosixCompData(final Hashtable result,
0158: final Hashtable source) {
0159: convertMESSAGES(result, source);
0160: convertIDENTIFICATION(result, source);
0161: convertNAMEFORMAT(result, source);
0162: convertADDRESSFORMAT(result, source);
0163: convertTELEPHONEFORMAT(result, source);
0164: }
0165:
0166: private void convertMESSAGES(final Hashtable result,
0167: final Hashtable source) {
0168: final String[][] DEFAULT_MESSAGES = (String[][]) getDefault("Messages");
0169: final String[][] myMessages = clone2DArr(DEFAULT_MESSAGES);
0170:
0171: String value = (String) source.get("yesexpr");
0172:
0173: if (value != null) {
0174: myMessages[0][1] = PosixCollationBuilder.unescape(value);
0175: }
0176: value = (String) source.get("noexpr");
0177: if (value != null) {
0178: myMessages[1][1] = PosixCollationBuilder.unescape(value);
0179: }
0180: value = (String) source.get("yesstr");
0181: if (value != null) {
0182: myMessages[2][1] = PosixCollationBuilder.unescape(value);
0183: }
0184: value = (String) source.get("nostr");
0185: if (value != null) {
0186: myMessages[3][1] = PosixCollationBuilder.unescape(value);
0187: }
0188: resultPut(result, "Messages", myMessages);
0189: }
0190:
0191: private void convertIDENTIFICATION(final Hashtable result,
0192: final Hashtable source) {
0193: final String[][] DEFAULT_MESSAGES = (String[][]) getDefault("Identification");
0194: final String[][] myIdentification = clone2DArr(DEFAULT_MESSAGES);
0195:
0196: String value = (String) source.get("title");
0197: if (value != null) {
0198: myIdentification[0][1] = PosixCollationBuilder
0199: .unescape(value);
0200: }
0201: value = (String) source.get("source");
0202: if (value != null) {
0203: myIdentification[1][1] = PosixCollationBuilder
0204: .unescape(value);
0205: }
0206: value = (String) source.get("address");
0207: if (value != null) {
0208: myIdentification[2][1] = PosixCollationBuilder
0209: .unescape(value);
0210: }
0211: value = (String) source.get("contact");
0212: if (value != null) {
0213: myIdentification[3][1] = PosixCollationBuilder
0214: .unescape(value);
0215: }
0216: value = (String) source.get("email");
0217: if (value != null) {
0218: myIdentification[4][1] = PosixCollationBuilder
0219: .unescape(value);
0220: }
0221: value = (String) source.get("tel");
0222: if (value != null) {
0223:
0224: myIdentification[5][1] = PosixCollationBuilder
0225: .unescape(value);
0226: }
0227:
0228: value = (String) source.get("fax");
0229: if (value != null) {
0230: myIdentification[6][1] = PosixCollationBuilder
0231: .unescape(value);
0232: }
0233: value = (String) source.get("language");
0234: if (value != null) {
0235: myIdentification[7][1] = PosixCollationBuilder
0236: .unescape(value);
0237: }
0238: value = (String) source.get("territory");
0239: if (value != null) {
0240: myIdentification[8][1] = PosixCollationBuilder
0241: .unescape(value);
0242: }
0243: value = (String) source.get("audience");
0244: if (value != null) {
0245: myIdentification[9][1] = PosixCollationBuilder
0246: .unescape(value);
0247: }
0248:
0249: value = (String) source.get("application");
0250: if (value != null) {
0251: myIdentification[10][1] = PosixCollationBuilder
0252: .unescape(value);
0253: } else
0254: value = (String) source.get("abbreviation");
0255: if (value != null) {
0256: myIdentification[11][1] = PosixCollationBuilder
0257: .unescape(value);
0258: }
0259: value = (String) source.get("revision");
0260: if (value != null) {
0261: myIdentification[12][1] = PosixCollationBuilder
0262: .unescape(value);
0263: }
0264: value = (String) source.get("date");
0265: if (value != null) {
0266: myIdentification[13][1] = PosixCollationBuilder
0267: .unescape(value);
0268: }
0269: resultPut(result, "Identification", myIdentification);
0270: }
0271:
0272: private void convertNAMEFORMAT(final Hashtable result,
0273: final Hashtable source) {
0274: final String[][] DEFAULT_MESSAGES = (String[][]) getDefault("NameFormat");
0275: final String[][] myNameFormat = clone2DArr(DEFAULT_MESSAGES);
0276: String value = (String) source.get("name_mr");
0277: if (value != null) {
0278: myNameFormat[2][1] = PosixCollationBuilder.unescape(value);
0279: }
0280: value = (String) source.get("name_miss");
0281: if (value != null) {
0282: myNameFormat[3][1] = PosixCollationBuilder.unescape(value);
0283: }
0284: value = (String) source.get("name_ms");
0285: if (value != null) {
0286: myNameFormat[6][1] = PosixCollationBuilder.unescape(value);
0287: }
0288: value = (String) source.get("name_mrs");
0289: if (value != null) {
0290: myNameFormat[4][1] = PosixCollationBuilder.unescape(value);
0291: }
0292: value = (String) source.get("name_gender");
0293: if (value != null) {
0294: myNameFormat[1][1] = PosixCollationBuilder.unescape(value);
0295: }
0296: value = (String) source.get("name_fmt");
0297: if (value != null) {
0298: value = PosixCollationBuilder.unescape(value);
0299: myNameFormat[0][1] = value;
0300: }
0301: resultPut(result, "NameFormat", myNameFormat);
0302: }
0303:
0304: private void convertADDRESSFORMAT(final Hashtable result,
0305: final Hashtable source) {
0306: final String[][] DEFAULT_MESSAGES = (String[][]) getDefault("AddressFormat");
0307: final String[][] myAddressFormat = (clone2DArr(DEFAULT_MESSAGES));
0308: String value = (String) source.get("postal_fmt");
0309: if (value != null) {
0310: value = PosixCollationBuilder.unescape(value);
0311: myAddressFormat[0][1] = value;
0312: }
0313: resultPut(result, "AddressFormat", myAddressFormat);
0314: }
0315:
0316: private void convertTELEPHONEFORMAT(final Hashtable result,
0317: final Hashtable source) {
0318: final String[][] DEFAULT_MESSAGES = (String[][]) getDefault("TelephoneFormat");
0319: final String[][] myTelephoneFormat = clone2DArr(DEFAULT_MESSAGES);
0320: String value = (String) source.get("tel_int_fmt");
0321: if (value != null) {
0322: value = PosixCollationBuilder.unescape(value);
0323: myTelephoneFormat[0][1] = value;
0324: }
0325: value = (String) source.get("dom_fmt");
0326: if (value != null) {
0327: value = PosixCollationBuilder.unescape(value);
0328: myTelephoneFormat[1][1] = value;
0329: }
0330: value = (String) source.get("int_select");
0331: if (value != null) {
0332: myTelephoneFormat[2][1] = PosixCollationBuilder
0333: .unescape(value);
0334: }
0335: value = (String) source.get("int_prefix");
0336: if (value != null) {
0337: myTelephoneFormat[3][1] = PosixCollationBuilder
0338: .unescape(value);
0339: }
0340: resultPut(result, "TelephoneFormat", myTelephoneFormat);
0341: }
0342:
0343: private void convertMONETARY(final Hashtable result,
0344: final Hashtable source) {
0345: final String[] DEFAULT_CURRENCY_ELEMENTS = (String[]) getDefault("CurrencyElements");
0346: final String[] elements = (String[]) DEFAULT_CURRENCY_ELEMENTS
0347: .clone();
0348: String value = (String) source.get("currency_symbol");
0349: //Replaceable temp = new Replaceable(value);
0350:
0351: if (value != null) {
0352: elements[0] = PosixCollationBuilder.unescape(value);
0353: }
0354: value = (String) source.get("int_curr_symbol");
0355: if (value != null) {
0356: elements[1] = PosixCollationBuilder.unescape(value);
0357: }
0358: value = (String) source.get("mon_decimal_point");
0359: if (value != null) {
0360: elements[2] = PosixCollationBuilder.unescape(value);
0361: }
0362: resultPut(result, "CurrencyElements", elements);
0363: }
0364:
0365: private void convertMEASUREMENT(final Hashtable result,
0366: final Hashtable source) {
0367: final String DEFAULT_MEASUREMENT = (String) getDefault("Measurement");
0368: String elements = (String) DEFAULT_MEASUREMENT;
0369: String value = (String) source.get("measurement");
0370: if (value != null) {
0371: if (value.equals("1"))
0372: elements = "Metric";
0373: else if (value.equals("2"))
0374: elements = "American";
0375: else if (value.equals("3"))
0376: elements = "Other";
0377: }
0378: resultPut(result, "Measurement", elements);
0379: }
0380:
0381: private void convertCOUNTRYNUMBER(final Hashtable result,
0382: final Hashtable source) {
0383: final String DEFAULT_COUNTRYNUMBER = (String) getDefault("CountryNumber");
0384: String elements = (String) DEFAULT_COUNTRYNUMBER;
0385: String value = (String) source.get("country_num");
0386: if (value != null) {
0387: elements = value;
0388: }
0389: resultPut(result, "CountryNumber", elements);
0390: }
0391:
0392: private void convertCOUNTRYISBNNUMBER(final Hashtable result,
0393: final Hashtable source) {
0394: final String DEFAULT_COUNTRYNUMBER = (String) getDefault("CountryISBNNumber");
0395: String elements = new String((String) DEFAULT_COUNTRYNUMBER);
0396: String value = (String) source.get("country_num");
0397: if (value != null) {
0398: elements = value;
0399: }
0400: resultPut(result, "CountryISBNNumber", elements);
0401: }
0402:
0403: private void convertLANGUAGELIB(final Hashtable result,
0404: final Hashtable source) {
0405: final String DEFAULT_LANGUAGELIB = (String) getDefault("LanguageLibraryUse");
0406: String elements = new String((String) DEFAULT_LANGUAGELIB);
0407: String value = (String) source.get("lang_lib");
0408: if (value != null) {
0409: elements = value;
0410: }
0411: resultPut(result, "LanguageLibraryUse", elements);
0412: }
0413:
0414: private void convertPAPERSIZE(final Hashtable result,
0415: final Hashtable source) {
0416: final String[][] DEFAULT_PAPERSIZE = (String[][]) getDefault("PaperSize");
0417: final String[][] elements = clone2DArr(DEFAULT_PAPERSIZE);
0418: String value = (String) source.get("height");
0419: if (value != null) {
0420: elements[0][1] = value;
0421: }
0422: value = (String) source.get("width");
0423: if (value != null) {
0424: elements[1][1] = value;
0425: }
0426: elements[2][1] = (String) "mm";
0427:
0428: resultPut(result, "PaperSize", elements);
0429: }
0430:
0431: /* private void convertIDENTIFICATION(final Hashtable result, final Hashtable source){
0432: final String[][]DEFAULT_IDENTIFICATION =(String[][]) getDefault("Identification");
0433: final String[][] elements = (String[][])DEFAULT_IDENTIFICATION.cloane();
0434:
0435: }*/
0436: private void convertNUMERIC(final Hashtable result,
0437: final Hashtable source) {
0438: //Build NumberElements data array
0439: final String[] DEFAULT_NUMBER_ELEMENTS = (String[]) getDefault("NumberElements");
0440: //Set new number elements to a copy of the default value from the parent.
0441: final String[] elements = (String[]) DEFAULT_NUMBER_ELEMENTS
0442: .clone();
0443: //put decimal seperator into the NumberElements array
0444: String decimalPoint = (String) source.get("decimal_point");
0445: if (decimalPoint != null) { //if we have a POSIX value, stomp on the default
0446: elements[0] = decimalPoint;
0447: }
0448:
0449: //put thousands seperator into the NumberElements array
0450: String thousandsSep = (String) source.get("thousands_sep");
0451: if (thousandsSep != null) { //if we have a POSIX value, stomp on the default
0452: elements[1] = thousandsSep;
0453: }
0454:
0455: //Add NumberElements to result
0456: resultPut(result, "NumberElements", elements);
0457:
0458: //use canonical decimal and thousands seperators for patterns
0459: decimalPoint = ".";
0460: thousandsSep = ",";
0461:
0462: //NumberPatterns
0463: final String[] DEFAULT_NUMBER_PATTERNS = (String[]) getDefault("NumberPatterns");
0464: final String[] patterns = (String[]) DEFAULT_NUMBER_PATTERNS
0465: .clone();
0466:
0467: final String patternDigit = elements[5];
0468: final String zeroDigit = elements[4];
0469: final String negativeSign = elements[6];
0470: final String percentSign = elements[3];
0471:
0472: String groupingString;
0473: Object groupingObj = source.get("grouping");
0474: boolean isStrArray = groupingObj instanceof String[];
0475: if (isStrArray) {
0476: groupingString = ((String[]) groupingObj)[0];
0477: } else {
0478: groupingString = (String) groupingObj;
0479: }
0480:
0481: if (groupingString == null) {
0482: patterns[0] = replace(patterns[0], elements[0], "<DECIMAL>");
0483: patterns[0] = replace(patterns[0], elements[1],
0484: "<THOUSAND>");
0485: patterns[0] = replace(patterns[0], "<DECIMAL>",
0486: decimalPoint);
0487: patterns[0] = replace(patterns[0], "<THOUSAND>",
0488: thousandsSep);
0489:
0490: patterns[2] = replace(patterns[2], elements[1],
0491: "<THOUSAND>");
0492: patterns[2] = replace(patterns[2], "<THOUSAND>",
0493: thousandsSep);
0494: } else {
0495:
0496: /* grouping:
0497: * Defines the size of each group of digits in formatted monetary
0498: * quantities. The operand for the grouping keyword consists of a
0499: * sequence of semicolon-separated integers. Each integer specifies the
0500: * number of digits in a group. The initial integer defines the size of
0501: * the group immediately to the left of the decimal delimiter.
0502: * The following integers define succeeding groups to the left of the
0503: * previous group. If the last integer is not -1, the size of the
0504: * previous group (if any) is used repeatedly for the remainder of the
0505: * digits. If the last integer is -1, no further grouping is performed.
0506: * Grouping Value Formatted Value
0507: * 3;-1 123456'789
0508: * 3 123'456'789
0509: * 3;2;-1 1234'56'789
0510: * 3;2 12'34'56'789
0511: * -1 123456789
0512: */
0513: //for a grouping of 5
0514: //#<thousandsSep>####0<decimalPoint>#####
0515: final StringBuffer pattern = new StringBuffer();
0516: int semiColonIndex = groupingString.indexOf(';');
0517: int grouping = 0;
0518: if (semiColonIndex < 0) {
0519: grouping = Integer.parseInt(groupingString);
0520: pattern.append(patternDigit);
0521: pattern.append(thousandsSep);
0522: for (int i = Math.max(1, grouping - 1); i > 0; i--) {
0523: pattern.append(patternDigit);
0524: }
0525: pattern.append(zeroDigit);
0526: pattern.append(decimalPoint);
0527: for (int i = Math.max(1, grouping - 1); i >= 0; i--) {
0528: pattern.append(patternDigit);
0529: }
0530: } else {
0531: /* int prevIndex = 0;
0532: int[] groupings = new int[4];
0533: int j =0;
0534:
0535: for(int i=0; i<groupingString.length(); i++){
0536: if(groupingString.charAt(i)==';'){
0537: groupings[j++] = Integer.parseInt(groupingString.substring(prevIndex,i));
0538: prevIndex = i;
0539: }
0540: }
0541: for(int i = j-1 ;i<-1; i--){
0542: if(groupings[i] == -1){
0543: pattern.append(p);
0544: }else{
0545:
0546: }
0547: }
0548: */
0549: System.err
0550: .println("WARNING: unimplemented pattern parser. Pattern: "
0551: + groupingString);
0552: }
0553:
0554: final String patternString = pattern.toString();
0555: patterns[0] = patternString + ";" + negativeSign
0556: + patternString;
0557:
0558: pattern.setLength(0);
0559: pattern.append(patternDigit);
0560: pattern.append(thousandsSep);
0561: for (int i = Math.max(1, grouping - 1); i > 0; i--) {
0562: pattern.append(patternDigit);
0563: }
0564: pattern.append(zeroDigit);
0565: pattern.append(percentSign);
0566: patterns[2] = pattern.toString();
0567:
0568: // final String[] currencyElements = ((String[])getDefault("CurrencyElements"));
0569: String currency_symbol = (String) source
0570: .get("currency_symbol");
0571: currency_symbol = (currency_symbol != null) ? currency_symbol
0572: : (String) source.get("int_curr_symbol");
0573: currency_symbol = (currency_symbol != null) ? currency_symbol
0574: : "";
0575:
0576: String mon_decimal_point = (String) source
0577: .get("mon_decimal_point");
0578: mon_decimal_point = (mon_decimal_point != null) ? mon_decimal_point
0579: : "";
0580:
0581: String mon_thousands_sep = (String) source
0582: .get("mon_thousands_sep");
0583: mon_thousands_sep = (mon_thousands_sep != null) ? mon_thousands_sep
0584: : "";
0585:
0586: String mon_grouping_string;
0587: /*
0588: * mon_grouping:
0589: *
0590: * Specifies a string that defines the size of each group of digits
0591: * in formatted monetary quantities. The operand for the
0592: * mon_grouping keyword consists of a sequence of
0593: * semicolon-separated integers. Each integer specifies the number
0594: * of digits in a group. The initial integer defines the size of the
0595: * group immediately to the left of the decimal delimiter.
0596: * The following integers define succeeding groups to the left of
0597: * the previous group. If the last integer is not -1, the size of
0598: * the previous group (if any) is repeatedly used for the remainder
0599: * of the digits. If the last integer is -1, no further grouping is
0600: * performed.
0601: *
0602: * Value Formatted Value
0603: * 3;-1 123456'789
0604: * 3 123'456'789
0605: * 3;2;-1 1234'56'789
0606: * 3;2 12'34'56'789
0607: * -1 123456789
0608: */
0609: final Object monGroupingObj = source.get("mon_grouping");
0610: if (monGroupingObj instanceof String[]) {
0611: mon_grouping_string = ((String[]) monGroupingObj)[0];
0612: } else {
0613: mon_grouping_string = (String) monGroupingObj;
0614: }
0615: final int mon_grouping = (mon_grouping_string == null) ? grouping
0616: : Integer.parseInt(mon_grouping_string);
0617:
0618: final String frac_digits_string = (String) source
0619: .get("frac_digits");
0620: final int frac_digits = (frac_digits_string == null) ? mon_grouping
0621: : Integer.parseInt(frac_digits_string);
0622:
0623: String positive_sign = (String) source.get("positive_sign");
0624: positive_sign = (positive_sign != null) ? positive_sign
0625: : "";
0626:
0627: String negative_sign = (String) source.get("negative_sign");
0628: negative_sign = (negative_sign != null) ? negative_sign
0629: : "";
0630:
0631: String p_sign_posn = (String) source.get("p_sign_posn");
0632: p_sign_posn = (p_sign_posn != null) ? p_sign_posn : "";
0633:
0634: String n_sign_posn = (String) source.get("n_sign_posn");
0635: n_sign_posn = (n_sign_posn != null) ? n_sign_posn : "";
0636:
0637: final boolean p_cs_precedes = !"0".equals(source
0638: .get("p_cs_precedes"));
0639: final String p_sep_by_space = (String) source
0640: .get("p_sep_by_space");
0641: final boolean n_cs_precedes = !"0".equals(source
0642: .get("n_cs_precedes"));
0643: final String n_sep_by_space = (String) source
0644: .get("n_sep_by_space");
0645:
0646: pattern.setLength(0);
0647:
0648: /*
0649: patterns[1] =
0650: createPatternString(currency_symbol, mon_decimal_point, mon_thousands_sep, mon_grouping, frac_digits,
0651: positive_sign, p_cs_precedes, p_sep_by_space, p_sign_posn, patternDigit, zeroDigit)
0652: + ";"
0653: + createPatternString(currency_symbol, mon_decimal_point, mon_thousands_sep, mon_grouping, frac_digits,
0654: negative_sign, n_cs_precedes, n_sep_by_space, n_sign_posn, patternDigit, zeroDigit);
0655: */
0656:
0657: /* patterns[1] =
0658: createPatternString(currency_symbol, ".", ",", mon_grouping, frac_digits,
0659: positive_sign, p_cs_precedes, p_sep_by_space, p_sign_posn, patternDigit, zeroDigit)
0660: + ";"
0661: + createPatternString(currency_symbol, ".", ",", mon_grouping, frac_digits,
0662: negative_sign, n_cs_precedes, n_sep_by_space, n_sign_posn, patternDigit, zeroDigit);
0663: */
0664: patterns[1] = createPatternString(".", ",", mon_grouping,
0665: frac_digits, positive_sign, p_cs_precedes,
0666: p_sep_by_space, p_sign_posn, patternDigit,
0667: zeroDigit)
0668: + ";"
0669: + createPatternString(".", ",", mon_grouping,
0670: frac_digits, negative_sign, n_cs_precedes,
0671: n_sep_by_space, n_sign_posn, patternDigit,
0672: zeroDigit);
0673:
0674: }
0675: resultPut(result, "NumberPatterns", patterns);
0676: }
0677:
0678: /**
0679: * This routine creates currency formats from all the posix stuff.
0680: */
0681: private String createPatternString(String decimal,
0682: String thousands, int grouping, int fracDigits,
0683: String sign, boolean preceeds, String sep_by_space,
0684: String sign_posn, String digit, String requiredDigit) {
0685: StringBuffer buffer = new StringBuffer();
0686: final String currency = "\u00A4";
0687: if ("2".equals(sep_by_space)
0688: && ("".equals(currency) || "".equals(sign))) {
0689: sep_by_space = "0";
0690: }
0691: if ("1".equals(sep_by_space) && "".equals(currency)) {
0692: sep_by_space = "0";
0693: }
0694:
0695: final String sign_currency_seperator = ("2"
0696: .equals(sep_by_space)) ? " " : "";
0697: final String quantity_currency_seperator = ("1"
0698: .equals(sep_by_space)) ? " " : "";
0699:
0700: if ("0".equals(sign_posn)) {
0701: buffer.append('(');
0702: }
0703: if ("1".equals(sign_posn)) {
0704: buffer.append(sign);
0705: if (preceeds) {
0706: buffer.append(sign_currency_seperator);
0707: }
0708: }
0709: if (preceeds) {
0710: if ("3".equals(sign_posn)) {
0711: buffer.append(sign);
0712: buffer.append(sign_currency_seperator);
0713: }
0714: buffer.append(currency);
0715: if ("4".equals(sign_posn)) {
0716: buffer.append(sign_currency_seperator);
0717: buffer.append(sign);
0718: }
0719: buffer.append(quantity_currency_seperator);
0720: }
0721:
0722: buffer.append(digit);
0723: if (grouping > 0) {
0724: buffer.append(thousands);
0725: for (int i = grouping - 1; i > 0; i--) {
0726: buffer.append(digit);
0727: }
0728: }
0729: buffer.append(requiredDigit);
0730: buffer.append(decimal);
0731: if (fracDigits > 0) {
0732: for (int i = fracDigits - 1; i >= 0; i--) {
0733: buffer.append(requiredDigit);
0734: }
0735: } else {
0736: buffer.append(digit);
0737: }
0738:
0739: if (!preceeds) {
0740: buffer.append(quantity_currency_seperator);
0741: if ("1".equals(sign_posn)) {
0742: buffer.append(sign_currency_seperator);
0743: }
0744: if ("3".equals(sign_posn)) {
0745: buffer.append(sign);
0746: buffer.append(sign_currency_seperator);
0747: }
0748: buffer.append(currency);
0749: if ("4".equals(sign_posn)) {
0750: buffer.append(sign_currency_seperator);
0751: buffer.append(sign);
0752: }
0753: }
0754: if ("2".equals(sign_posn)) {
0755: buffer.append(sign_currency_seperator);
0756: buffer.append(sign);
0757: }
0758: if ("0".equals(sign_posn)) {
0759: buffer.append(')');
0760: }
0761:
0762: return buffer.toString();
0763: }
0764:
0765: private void convertTIME(Hashtable result, Hashtable source) {
0766: resultPut(result, "DayNames", source.get("day"));
0767: resultPut(result, "DayAbbreviations", source.get("abday"));
0768: String[] temp = (String[]) source.get("am_pm");
0769: if (temp != null) {
0770: final String[] defaultAMPM = (String[]) getDefault("AmPmMarkers");
0771: if ("".equals(temp[0]))
0772: temp[0] = defaultAMPM[0];
0773: if ("".equals(temp[1]))
0774: temp[1] = defaultAMPM[1];
0775: resultPut(result, "AmPmMarkers", temp);
0776: }
0777:
0778: temp = (String[]) source.get("mon");
0779: if (temp != null) {
0780: //add empty 13th month
0781: String[] newTemp = new String[13];
0782: System.arraycopy(temp, 0, newTemp, 0, 12);
0783: newTemp[12] = "";
0784: resultPut(result, "MonthNames", newTemp);
0785: }
0786: temp = (String[]) source.get("abmon");
0787: if (temp != null) {
0788: //add empty 13th month
0789: String[] newTemp = new String[13];
0790: System.arraycopy(temp, 0, newTemp, 0, 12);
0791: newTemp[12] = "";
0792: resultPut(result, "MonthAbbreviations", newTemp);
0793: }
0794:
0795: final String t_fmt_ampm = (String) source.get("t_fmt_ampm");
0796: final String t_fmt = (String) source.get("t_fmt");
0797: final String d_t_fmt = (String) source.get("d_t_fmt");
0798: final String d_fmt = (String) source.get("d_fmt");
0799: final String nlldate = (String) source.get("nlldate"); //non-standard IBM thing
0800:
0801: final String DEFAULT_DATETIME_ELEMENTS[] = (String[]) getDefault("DateTimePatterns");
0802: final String[] elements = (String[]) DEFAULT_DATETIME_ELEMENTS
0803: .clone();
0804: final String X_pattern = elements[3];
0805: final String x_pattern = elements[7];
0806: final String c_pattern = elements[4] + " " + elements[0];
0807:
0808: elements[0] = (t_fmt_ampm != null && t_fmt_ampm.length() > 0) ? t_fmt_ampm
0809: : t_fmt;
0810: elements[1] = (t_fmt != null) ? t_fmt : t_fmt_ampm;
0811: elements[2] = (t_fmt != null) ? t_fmt : t_fmt_ampm;
0812: elements[3] = (t_fmt != null) ? t_fmt : t_fmt_ampm;
0813:
0814: String longishDateFormat = (nlldate != null) ? nlldate : d_fmt;
0815: if (d_t_fmt != null) {
0816: if (t_fmt != null) {
0817: //try to build a detailed data format by taking the
0818: //date-time format and removing the time portion
0819: int ndx = d_t_fmt.indexOf(t_fmt);
0820: if (ndx >= 0) {
0821: if (ndx < (d_t_fmt.length() - t_fmt.length()) / 2) {
0822: elements[8] = "{0} {1}";
0823: }
0824:
0825: longishDateFormat = replace(d_t_fmt, t_fmt, "");
0826: longishDateFormat = replace(longishDateFormat,
0827: "%Z", "");
0828: longishDateFormat = replace(longishDateFormat,
0829: " ", " ");
0830: longishDateFormat = replace(longishDateFormat,
0831: " ", " ");
0832: if (longishDateFormat.charAt(0) == ' ') {
0833: longishDateFormat = longishDateFormat
0834: .substring(1);
0835: }
0836: longishDateFormat.trim();
0837: }
0838: }
0839: }
0840: elements[4] = longishDateFormat;
0841: elements[5] = d_t_fmt;
0842: elements[6] = (nlldate != null) ? nlldate : d_fmt;
0843: elements[7] = d_fmt;
0844:
0845: for (int i = 0; i < 8; i++) {
0846: if (elements[i] != null) {
0847: elements[i] = convertFormats(elements[i], X_pattern,
0848: x_pattern, c_pattern);
0849: } else {
0850: elements[i] = DEFAULT_DATETIME_ELEMENTS[i];
0851: }
0852: }
0853: resultPut(result, "DateTimePatterns", elements);
0854: }
0855:
0856: private String convertFormats(String pattern, String X_pattern,
0857: String x_pattern, String c_pattern) {
0858:
0859: String tpattern = PosixCollationBuilder.unescape(pattern);
0860: StringBuffer result = new StringBuffer();
0861: boolean singleDigit = false;
0862: for (int i = 0; i < tpattern.length(); i++) {
0863: char c = tpattern.charAt(i);
0864: if (c != '%') {
0865: result.append(c);
0866: } else {
0867: singleDigit = false;
0868: i++;
0869: c = tpattern.charAt(i);
0870: switch (c) {
0871: case 'a':
0872: result.append("EEE");
0873: break;
0874: case 'A':
0875: result.append("EEEE");
0876: break;
0877: case 'b':
0878: result.append("MMM");
0879: break;
0880: case 'B':
0881: result.append("MMMM");
0882: break;
0883: case 'c':
0884: result.append(c_pattern);
0885: break;
0886: case 'C': //** hey {jf} - this is supposed to be the century only.
0887: result.append("YYYY");
0888: break;
0889: case 'd':
0890: if (singleDigit == true) {
0891: result.append("d");
0892: } else {
0893: result.append("dd");
0894: }
0895: break;
0896: case 'D':
0897: result.append("mm/dd/yy");
0898: break;
0899: case 'e':
0900: if (singleDigit == true) {
0901: result.append("d");
0902: } else {
0903: result.append("dd");
0904: }
0905: break;
0906: case 'h':
0907: result.append("MMM");
0908: break;
0909: case 'H':
0910: if (singleDigit == true) {
0911: result.append("H");
0912: } else {
0913: result.append("HH");
0914: }
0915: break;
0916: case 'I':
0917: if (singleDigit == true) {
0918: result.append("h");
0919: } else {
0920: result.append("hh");
0921: }
0922: break;
0923: case 'j':
0924: result.append("DDD");
0925: break;
0926: case 'm':
0927: if (singleDigit == true) {
0928: result.append("M");
0929: } else {
0930: result.append("MM");
0931: }
0932: result.append("MM");
0933: break;
0934: case 'M':
0935: if (singleDigit == true) {
0936: result.append("m");
0937: } else {
0938: result.append("mm");
0939: }
0940: ;
0941: break;
0942: case 'n':
0943: result.append('\n');
0944: break;
0945: case 'p':
0946: result.append("aa");
0947: break;
0948: case 'r':
0949: result.append(convertFormats("%I:%M:%S %p",
0950: X_pattern, x_pattern, c_pattern));
0951: break;
0952: case 'S':
0953: result.append("ss");
0954: break;
0955: case 't':
0956: result.append('\t');
0957: break;
0958: case 'T':
0959: result.append(convertFormats("%I:%M:%S", X_pattern,
0960: x_pattern, c_pattern));
0961: break;
0962: case 'U':
0963: result.append("ww");
0964: break;
0965: case 'w':
0966: result.append("E");
0967: break;
0968: case 'W':
0969: result.append("ww");
0970: break;
0971: case 'x':
0972: result.append(x_pattern);
0973: break;
0974: case 'X':
0975: result.append(X_pattern);
0976: break;
0977: case 'y':
0978: result.append("yy");
0979: break;
0980: case 'Y':
0981: result.append("yyyy");
0982: break;
0983: case 'Z':
0984: result.append("z");
0985: break;
0986: case '%':
0987: result.append("%");
0988: break;
0989: case '.':
0990: char c1 = tpattern.charAt(i + 1);
0991: if (c1 == '1') {
0992: singleDigit = true;
0993: i++;
0994: break;
0995: }
0996:
0997: default:
0998: result.append('%');
0999: result.append(c);
1000: break;
1001: }
1002: }
1003: }
1004: return result.toString();
1005: }
1006:
1007: private void convertCOLLATE(Hashtable result, Hashtable source) {
1008: String[] sortOrder = (String[]) source.get("sort_order");
1009: final Object[][] DEFAULT_COLLATION = (Object[][]) getDefault("collations");
1010: final Object[][] elements = (Object[][]) clone2DArr(DEFAULT_COLLATION);
1011: if (sortOrder != null) {
1012: if (!"forward".equals(sortOrder[0])) {
1013: System.err
1014: .println("ERROR: Unsupported primary sort order: "
1015: + sortOrder[0]);
1016: }
1017: if (sortOrder.length == 2
1018: && !"forward".equals(sortOrder[1])
1019: && !"backward".equals(sortOrder[1])) {
1020: System.err
1021: .println("ERROR: Unsupported secondary sort order: "
1022: + sortOrder[1]);
1023: }
1024: if (sortOrder.length == 3
1025: && !"forward".equals(sortOrder[2])) {
1026: System.err
1027: .println("ERROR: Unsupported tertiary sort order: "
1028: + sortOrder[2]);
1029: }
1030: if (sortOrder.length > 3) {
1031: System.err
1032: .println("WARNING: Sort levels of order greater than three ignored.");
1033: }
1034: }
1035:
1036: PosixCollationBuilder.CollationRule[] ruleSource = (PosixCollationBuilder.CollationRule[]) source
1037: .get("posix_sort_rules");
1038:
1039: if (ruleSource != null) {
1040: //allocate a list of collationItems. Add an extra entry for secondary ordering
1041: CollationItem[] rules = new CollationItem[ruleSource.length + 1];
1042: PosixCollationBuilder.CollationRule prevRule = null;
1043: //add all the rules for non-expanding characters
1044: int i = 0;
1045: for (int ndx = 0; ndx < ruleSource.length; ndx++) {
1046: PosixCollationBuilder.CollationRule rule = ruleSource[ndx];
1047: //add non-expanding characters to the sort list
1048: if (rule.getSize() <= 1) {
1049: int diff;
1050: if (prevRule == null) {
1051: //if it's the first rule, don't compare to anything,
1052: //seek back so it can be appended to the default rules
1053: rules[i] = new CollationItem(rule.getSymbol());
1054: } else {
1055: //compare to previous item
1056: diff = prevRule.compare(rule);
1057: rules[i] = new CollationItem(diff, rule
1058: .getSymbol());
1059: }
1060: rules[i++].setComment(rule.getSource());
1061: prevRule = rule;
1062: }
1063: }
1064: //add rules for expanding characters
1065: String prevSeek = null;
1066: prevRule = null;
1067: for (int ndx = 0; ndx < ruleSource.length; ndx++) {
1068: PosixCollationBuilder.CollationRule rule = ruleSource[ndx];
1069: if (rule.getSize() > 1) {
1070: //find out what this character expands to
1071: String seek = rule.getExpansion();
1072: if (!seek.equals(prevSeek)) {
1073: //if it's not the same as the previous character
1074: //then seek to the first character of the expansion
1075: //and compare to that
1076: PosixCollationBuilder.CollationRule seekRule = rule
1077: .seeksToRule();
1078: rules[i] = new CollationItem(seekRule
1079: .compare(rule), rule.getSymbol(), rule
1080: .getExpansion());
1081: prevSeek = seek;
1082: } else if (prevRule != null) {
1083: //it expands to the same characters as the previous expansion,
1084: //so compare to the previous expansion
1085: rules[i] = new CollationItem(prevRule
1086: .compare(rule), rule.getSymbol(),
1087: prevRule.getSymbol());
1088: } else {
1089: //The unlikely case that the first character will
1090: //be an expanding character...I don't think
1091: //this is even possible...
1092: rules[i] = new CollationItem(rule.getSymbol());
1093: }
1094: rules[i++].setComment(rule.getSource());
1095: }
1096: prevRule = rule;
1097: }
1098: if (sortOrder.length > 0 && "backward".equals(sortOrder[0])) {
1099: elements[1][1] = "true";
1100: } else {
1101: elements[1][1] = "false";
1102: }
1103: elements[2][1] = (Object) rules;
1104: resultPut(result, "collations", elements);
1105: }
1106: }
1107:
1108: private void resultPut(Hashtable resultTable, String tag,
1109: Object value) {
1110: if (value == null)
1111: return;
1112: resultTable.put(tag, value);
1113: }
1114:
1115: private Object getDefault(String desiredResource) {
1116: return getParentBundle().getObject(desiredResource);
1117: }
1118:
1119: private ResourceBundle getParentBundle() {
1120: return ResourceBundle
1121: .getBundle(
1122: "com.ibm.icu.dev.tool.localeconverter.myLocaleElements",
1123: parentLocale);
1124: }
1125:
1126: private String replace(String source, String target,
1127: String replacement) {
1128: if (target.equals(replacement)) {
1129: return source;
1130: } else {
1131: StringBuffer result = new StringBuffer();
1132: int lastNdx = 0;
1133: int ndx = source.indexOf(target);
1134: while (ndx >= 0) {
1135: result.append(source.substring(lastNdx, ndx));
1136: result.append(replacement);
1137: ndx += target.length();
1138: lastNdx = ndx;
1139: ndx = source.indexOf(target, ndx);
1140: }
1141: result.append(source.substring(lastNdx));
1142: return result.toString();
1143: }
1144: }
1145: //{{DECLARE_CONTROLS
1146: //}}
1147: }
|