| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.ibm.icu4jni.text; |
| |
| import java.text.FieldPosition; |
| import java.text.Format; |
| import java.text.NumberFormat; |
| import java.text.ParsePosition; |
| import java.util.Locale; |
| |
| public class RuleBasedNumberFormat extends NumberFormat { |
| |
| /** |
| * Enum of predefined RBNF types. |
| */ |
| public enum RBNFType { |
| /** |
| * This creates a spellout instance of RBNF. |
| * It formats numbers into textual representation: |
| * 15 -> 'fifteen' or 15.15 -> 'fifteen point one five' |
| * and it can parse words into numbers: 'twenty' -> 20 |
| */ |
| SPELLOUT(0), |
| /** |
| * This creates an ordinal instance of RBNF. |
| * It formats numbers into an ordinal text representation: |
| * 15 -> '15th' and by parsing it also works in the other direction. |
| */ |
| ORDINAL(1), |
| /** |
| * This creates instance of RBNF that allows to format numbers into time |
| * values: 15 -> '15 sec.' and by parsing it also works in the other |
| * direction. |
| */ |
| DURATION(2); |
| |
| int type; |
| |
| RBNFType(int t) { |
| type = t; |
| } |
| |
| int getType() { |
| return type; |
| } |
| } |
| |
| @Override |
| protected void finalize(){ |
| close(); |
| } |
| |
| private int addr = 0; |
| |
| /** |
| * Open a new rule based number format of selected type for the |
| * default location |
| * |
| * @param type the type of rule based number format |
| */ |
| public void open(RBNFType type) { |
| this.addr = openRBNFImpl(type.getType(), |
| Locale.getDefault().toString()); |
| } |
| |
| /** |
| * Open a new rule based number format of selected type for the |
| * given location |
| * |
| * @param type the type of rule based number format |
| * @param locale the locale to use for this rule based number format |
| */ |
| public void open(RBNFType type, Locale locale) { |
| String loc = locale.toString(); |
| if (loc == null) { |
| throw new NullPointerException(); |
| } |
| this.addr = openRBNFImpl(type.getType(), loc); |
| } |
| |
| private static native int openRBNFImpl(int type, String loc); |
| |
| /** |
| * Open a new rule based number format for the |
| * default location. The rule passed to the method has to be of the form |
| * described in the ibm icu documentation for RuleBasedNumberFormat. |
| * |
| * @param rule the rule for the rule based number format |
| */ |
| public void open(String rule) { |
| if (rule == null) { |
| throw new NullPointerException(); |
| } |
| this.addr = openRBNFImpl(rule, Locale.getDefault().toString()); |
| } |
| |
| /** |
| * Open a new rule based number format for the |
| * given location. The rule passed to the method has to be of the form |
| * described in the ibm icu documentation for RuleBasedNumberFormat. |
| * |
| * @param rule the rule for the rule based number format |
| * @param locale the locale to use for this rule based number format |
| */ |
| public void open(String rule, Locale locale) { |
| String loc = locale.toString(); |
| if (loc == null || rule == null) { |
| throw new NullPointerException(); |
| } |
| this.addr = openRBNFImpl(rule, locale.toString()); |
| } |
| |
| private static native int openRBNFImpl(String rule, String loc); |
| |
| /** |
| * close a RuleBasedNumberFormat |
| */ |
| public void close() { |
| if(this.addr != 0) { |
| closeRBNFImpl(this.addr); |
| this.addr = 0; |
| } |
| } |
| |
| private static native void closeRBNFImpl(int addr); |
| |
| @Override |
| public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) { |
| |
| if(buffer == null) { |
| throw new NullPointerException(); |
| } |
| |
| String fieldType = null; |
| |
| if(field != null) { |
| fieldType = getFieldType(field.getFieldAttribute()); |
| } |
| |
| String result = formatRBNFImpl(this.addr, value, field, |
| fieldType, null); |
| |
| buffer.append(result.toCharArray(), 0, result.length()); |
| |
| return buffer; |
| } |
| |
| private static native String formatRBNFImpl(int addr, long value, |
| FieldPosition field, String fieldType, StringBuffer buffer); |
| |
| @Override |
| public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) { |
| |
| if(buffer == null) { |
| throw new NullPointerException(); |
| } |
| |
| String fieldType = null; |
| |
| if(field != null) { |
| fieldType = getFieldType(field.getFieldAttribute()); |
| } |
| |
| String result = formatRBNFImpl(this.addr, value, field, |
| fieldType, null); |
| |
| buffer.append(result.toCharArray(), 0, result.length()); |
| |
| return buffer; |
| } |
| |
| private static native String formatRBNFImpl(int addr, double value, |
| FieldPosition field, String fieldType, StringBuffer buffer); |
| |
| @Override |
| public Number parse(String string, ParsePosition position) { |
| if (string == null || position == null) { |
| throw new NullPointerException(); |
| } |
| return parseRBNFImpl(this.addr, string, position, false); |
| } |
| |
| /** |
| * This method has the same functionality |
| * as {@link #parse(String, ParsePosition)} |
| * But it uses lenient parsing. This means it also accepts strings that |
| * differ from the correct writing (e.g. case or umlaut differences). |
| * |
| * @param string the string to parse |
| * @param position the ParsePosition, updated on return with the index |
| * following the parsed text, or on error the index is unchanged and |
| * the error index is set to the index where the error occurred |
| * @return the Number resulting from the parse, or null if there is an error |
| */ |
| public Number parseLenient(String string, ParsePosition position) { |
| if (string == null || position == null) { |
| throw new NullPointerException(); |
| } |
| return parseRBNFImpl(this.addr, string, position, true); |
| } |
| |
| static native Number parseRBNFImpl(int addr, String string, ParsePosition position, boolean lenient); |
| |
| |
| static private String getFieldType(Format.Field field) { |
| if(field == null) { |
| return null; |
| } |
| if(field.equals(NumberFormat.Field.SIGN)) { |
| return "sign"; |
| } |
| if(field.equals(NumberFormat.Field.INTEGER)) { |
| return "integer"; |
| } |
| if(field.equals(NumberFormat.Field.FRACTION)) { |
| return "fraction"; |
| } |
| if(field.equals(NumberFormat.Field.EXPONENT)) { |
| return "exponent"; |
| } |
| if(field.equals(NumberFormat.Field.EXPONENT_SIGN)) { |
| return "exponent_sign"; |
| } |
| if(field.equals(NumberFormat.Field.EXPONENT_SYMBOL)) { |
| return "exponent_symbol"; |
| } |
| if(field.equals(NumberFormat.Field.CURRENCY)) { |
| return "currency"; |
| } |
| if(field.equals(NumberFormat.Field.GROUPING_SEPARATOR)) { |
| return "grouping_separator"; |
| } |
| if(field.equals(NumberFormat.Field.DECIMAL_SEPARATOR)) { |
| return "decimal_separator"; |
| } |
| if(field.equals(NumberFormat.Field.PERCENT)) { |
| return "percent"; |
| } |
| if(field.equals(NumberFormat.Field.PERMILLE)) { |
| return "permille"; |
| } |
| return null; |
| } |
| } |