messageformat.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 850 行 · 第 1/3 页

JAVA
850
字号
                other.formats[i] = (Format)formats[i].clone();
        }
        // for primitives or immutables, shallow clone is enough
        other.offsets = (int[]) offsets.clone();
        other.argumentNumbers = (int[]) argumentNumbers.clone();

        return other;
    }

    /**
     * Equality comparision between two message format objects
     */
    public boolean equals(Object obj) {
        if (this == obj)                      // quick check
            return true;
        if (getClass() != obj.getClass())
            return false;
        MessageFormat other = (MessageFormat) obj;
        return (maxOffset == other.maxOffset
                && pattern.equals(other.pattern)
            && Utility.objectEquals(locale, other.locale)   // does null check
                && Utility.arrayEquals(offsets,other.offsets)
            && Utility.arrayEquals(argumentNumbers,other.argumentNumbers)
            && Utility.arrayEquals(formats,other.formats));
    }

    /**
     * Generates a hash code for the message format object.
     */
    public int hashCode() {
        return pattern.hashCode(); // enough for reasonable distribution
    }


    // ===========================privates============================

    // Mark : Is this the right fix?  (HS)
    private Locale locale = Locale.getDefault();
    private String pattern = "";
    // later, allow more than ten items
    private Format[] formats = new Format[10];
    private int[] offsets = new int[10];
    private int[] argumentNumbers = new int[10];
    private int maxOffset = -1;

    /**
     * Constructs with the specified pattern.
     * @see MessageFormat#applyPattern
     */
    private MessageFormat(String pattern, Locale loc) {
        locale = (Locale)loc.clone();
        applyPattern(pattern);
    }

    /**
     * Internal routine used by format.
     * @param recursionProtection Initially zero. Bits 0..9 are used to indicate
     * that a parameter has already been seen, to avoid recursion.  Currently
     * unused.
     */

    private StringBuffer format(Object[] arguments, StringBuffer result,
                                FieldPosition status, int recursionProtection) {
        // note: this implementation assumes a fast substring & index.
        // if this is not true, would be better to append chars one by one.
        int lastOffset = 0;
        for (int i = 0; i <= maxOffset; ++i) {
            result.append(pattern.substring(lastOffset, offsets[i]));
            lastOffset = offsets[i];
            int argumentNumber = argumentNumbers[i];
            if (argumentNumber >= arguments.length)
                throw new IllegalArgumentException("Argument # > Arg length");
            // int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);
            if (false) { // if (argRecursion == 3){
                // prevent loop!!!
                result.append('\uFFFD');
            } else {
                Object obj = arguments[argumentNumber];
                String arg;
                boolean tryRecursion = false;
                if (formats[i] != null) {
                    arg = formats[i].format(obj);
                    tryRecursion = formats[i] instanceof ChoiceFormat;
                } else if (obj instanceof Number) {
                    // format number if can
                    arg = NumberFormat.getInstance(locale).format(obj); // fix
                } else if (obj instanceof Date) {
                    // format a Date if can
                    arg = DateFormat.getDateTimeInstance(DateFormat.SHORT,
                                                       DateFormat.SHORT,
                                                       locale).format(obj);//fix
                } else if (obj instanceof String) {
                    arg = (String) obj;

                } else {
                    arg = obj.toString();
                    if (arg == null) arg = "null";
                }

                // recurse if necessary
                if (tryRecursion && arg.indexOf('{') >= 0) {
                    MessageFormat temp = new MessageFormat(arg, locale);
                    temp.format(arguments,result,status,recursionProtection);
                } else {
                    result.append(arg);
                }
            }
        }
        result.append(pattern.substring(lastOffset, pattern.length()));
        return result;
    }
    private static final String[] typeList =
    {"", "", "number", "", "date", "", "time", "", "choice"};
    private static final String[] modifierList =
    {"", "", "currency", "", "percent", "", "integer"};
    private static final String[] dateModifierList =
    {"", "", "short", "", "medium", "", "long", "", "full"};

    private void makeFormat(int position, int offsetNumber,
                            StringBuffer[] segments)
    {

        // get the number
        int argumentNumber;
        try {
            argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized!
            if (argumentNumber < 0 || argumentNumber > 9) {
                throw new NumberFormatException();
            }
            maxOffset = offsetNumber;
            offsets[offsetNumber] = segments[0].length();
            argumentNumbers[offsetNumber] = argumentNumber;
        } catch (Exception e) {
            throw new IllegalArgumentException("argument number too large at ");
        }

        // now get the format
        Format newFormat = null;
        switch (findKeyword(segments[2].toString(), typeList)) {
        case 0:
            // string format
            /*if (!segments[3].equals(""))
              throw new IllegalArgumentException("can't modify string format, at ");
              //*/
        break;
        case 1: case 2:// number
            switch (findKeyword(segments[3].toString(), modifierList)) {
            case 0: // default;
                newFormat = NumberFormat.getInstance(locale);
                break;
            case 1: case 2:// currency
                newFormat = NumberFormat.getCurrencyInstance(locale);
                break;
            case 3: case 4:// percent
                newFormat = NumberFormat.getPercentInstance(locale);
                break;
            case 5: case 6:// integer
                newFormat = getIntegerFormat(locale);
                break;
            default: // pattern
                newFormat = NumberFormat.getInstance(locale);
                try {
                    ((DecimalFormat)newFormat).applyPattern(segments[3].toString());
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                                             "Pattern incorrect or locale does not support formats, error at ");
                }
                break;
            }
            break;
        case 3: case 4: // date
            switch (findKeyword(segments[3].toString(), dateModifierList)) {
            case 0: // default
                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
                break;
            case 1: case 2: // short
                newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
                break;
            case 3: case 4: // medium
                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
                break;
            case 5: case 6: // long
                newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale);
                break;
            case 7: case 8: // full
                newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
                break;
            default:
                newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
                try {
                    ((SimpleDateFormat)newFormat).applyPattern(segments[3].toString());
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                                             "Pattern incorrect or locale does not support formats, error at ");
                }
                break;
            }
            break;
        case 5: case 6:// time
            switch (findKeyword(segments[3].toString(), dateModifierList)) {
            case 0: // default
                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
                break;
            case 1: case 2: // short
                newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
                break;
            case 3: case 4: // medium
                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
                break;
            case 5: case 6: // long
                newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale);
                break;
            case 7: case 8: // full
                newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale);
                break;
            default:
                newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
                try {
                    ((SimpleDateFormat)newFormat).applyPattern(segments[3].toString());
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                                             "Pattern incorrect or locale does not support formats, error at ");
                }
                break;
            }
            break;
        case 7: case 8:// choice
            try {
                newFormat = new ChoiceFormat(segments[3].toString());
            } catch (Exception e) {
                throw new IllegalArgumentException(
                                         "Choice Pattern incorrect, error at ");
            }
            break;
        default:
            throw new IllegalArgumentException("unknown format type at ");
        }
        formats[offsetNumber] = newFormat;
        segments[1].setLength(0);   // throw away other segments
        segments[2].setLength(0);
        segments[3].setLength(0);
    }

    private static final int findKeyword(String s, String[] list) {
        s = s.trim().toLowerCase();
        for (int i = 0; i < list.length; ++i) {
            if (s.equals(list[i]))
                return i;
        }
        return -1;
    }

    /**
     * Convenience method that ought to be in NumberFormat
     */
    NumberFormat getIntegerFormat(Locale locale) {
        NumberFormat temp = NumberFormat.getInstance(locale);
        if (temp instanceof DecimalFormat) {
            DecimalFormat temp2 = (DecimalFormat) temp;
            temp2.setMaximumFractionDigits(0);
            temp2.setDecimalSeparatorAlwaysShown(false);
            temp2.setParseIntegerOnly(true);
        }
        return temp;
    }

    private static final void copyAndFixQuotes(
                                               String source, int start, int end, StringBuffer target) {
        for (int i = start; i < end; ++i) {
            char ch = source.charAt(i);
            if (ch == '{') {
                target.append("'{'");
            } else if (ch == '\'') {
                target.append("''");
            } else {
                target.append(ch);
            }
        }
    }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?