Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 /*
     27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
     28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
     29  *
     30  *   The original version of this source code and documentation is copyrighted
     31  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
     32  * materials are provided under terms of a License Agreement between Taligent
     33  * and Sun. This technology is protected by multiple US and International
     34  * patents. This notice and attribution to Taligent may not be removed.
     35  *   Taligent is a registered trademark of Taligent, Inc.
     36  *
     37  */
     38 
     39 package java.text;
     40 
     41 import java.io.Serializable;
     42 
     43 /**
     44  * <code>Format</code> is an abstract base class for formatting locale-sensitive
     45  * information such as dates, messages, and numbers.
     46  *
     47  * <p>
     48  * <code>Format</code> defines the programming interface for formatting
     49  * locale-sensitive objects into <code>String</code>s (the
     50  * <code>format</code> method) and for parsing <code>String</code>s back
     51  * into objects (the <code>parseObject</code> method).
     52  *
     53  * <p>
     54  * Generally, a format's <code>parseObject</code> method must be able to parse
     55  * any string formatted by its <code>format</code> method. However, there may
     56  * be exceptional cases where this is not possible. For example, a
     57  * <code>format</code> method might create two adjacent integer numbers with
     58  * no separator in between, and in this case the <code>parseObject</code> could
     59  * not tell which digits belong to which number.
     60  *
     61  * <h3>Subclassing</h3>
     62  *
     63  * <p>
     64  * The Java Platform provides three specialized subclasses of <code>Format</code>--
     65  * <code>DateFormat</code>, <code>MessageFormat</code>, and
     66  * <code>NumberFormat</code>--for formatting dates, messages, and numbers,
     67  * respectively.
     68  * <p>
     69  * Concrete subclasses must implement three methods:
     70  * <ol>
     71  * <li> <code>format(Object obj, StringBuffer toAppendTo, FieldPosition pos)</code>
     72  * <li> <code>formatToCharacterIterator(Object obj)</code>
     73  * <li> <code>parseObject(String source, ParsePosition pos)</code>
     74  * </ol>
     75  * These general methods allow polymorphic parsing and formatting of objects
     76  * and are used, for example, by <code>MessageFormat</code>.
     77  * Subclasses often also provide additional <code>format</code> methods for
     78  * specific input types as well as <code>parse</code> methods for specific
     79  * result types. Any <code>parse</code> method that does not take a
     80  * <code>ParsePosition</code> argument should throw <code>ParseException</code>
     81  * when no text in the required format is at the beginning of the input text.
     82  *
     83  * <p>
     84  * Most subclasses will also implement the following factory methods:
     85  * <ol>
     86  * <li>
     87  * <code>getInstance</code> for getting a useful format object appropriate
     88  * for the current locale
     89  * <li>
     90  * <code>getInstance(Locale)</code> for getting a useful format
     91  * object appropriate for the specified locale
     92  * </ol>
     93  * In addition, some subclasses may also implement other
     94  * <code>getXxxxInstance</code> methods for more specialized control. For
     95  * example, the <code>NumberFormat</code> class provides
     96  * <code>getPercentInstance</code> and <code>getCurrencyInstance</code>
     97  * methods for getting specialized number formatters.
     98  *
     99  * <p>
    100  * Subclasses of <code>Format</code> that allow programmers to create objects
    101  * for locales (with <code>getInstance(Locale)</code> for example)
    102  * must also implement the following class method:
    103  * <blockquote>
    104  * <pre>
    105  * public static Locale[] getAvailableLocales()
    106  * </pre>
    107  * </blockquote>
    108  *
    109  * <p>
    110  * And finally subclasses may define a set of constants to identify the various
    111  * fields in the formatted output. These constants are used to create a FieldPosition
    112  * object which identifies what information is contained in the field and its
    113  * position in the formatted result. These constants should be named
    114  * <code><em>item</em>_FIELD</code> where <code><em>item</em></code> identifies
    115  * the field. For examples of these constants, see <code>ERA_FIELD</code> and its
    116  * friends in {@link DateFormat}.
    117  *
    118  * <h4><a name="synchronization">Synchronization</a></h4>
    119  *
    120  * <p>
    121  * Formats are generally not synchronized.
    122  * It is recommended to create separate format instances for each thread.
    123  * If multiple threads access a format concurrently, it must be synchronized
    124  * externally.
    125  *
    126  * @see          java.text.ParsePosition
    127  * @see          java.text.FieldPosition
    128  * @see          java.text.NumberFormat
    129  * @see          java.text.DateFormat
    130  * @see          java.text.MessageFormat
    131  * @author       Mark Davis
    132  */
    133 public abstract class Format implements Serializable, Cloneable {
    134 
    135     private static final long serialVersionUID = -299282585814624189L;
    136 
    137     /**
    138      * Sole constructor.  (For invocation by subclass constructors, typically
    139      * implicit.)
    140      */
    141     protected Format() {
    142     }
    143 
    144     /**
    145      * Formats an object to produce a string. This is equivalent to
    146      * <blockquote>
    147      * {@link #format(Object, StringBuffer, FieldPosition) format}<code>(obj,
    148      *         new StringBuffer(), new FieldPosition(0)).toString();</code>
    149      * </blockquote>
    150      *
    151      * @param obj    The object to format
    152      * @return       Formatted string.
    153      * @exception IllegalArgumentException if the Format cannot format the given
    154      *            object
    155      */
    156     public final String format (Object obj) {
    157         return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
    158     }
    159 
    160     /**
    161      * Formats an object and appends the resulting text to a given string
    162      * buffer.
    163      * If the <code>pos</code> argument identifies a field used by the format,
    164      * then its indices are set to the beginning and end of the first such
    165      * field encountered.
    166      *
    167      * @param obj    The object to format
    168      * @param toAppendTo    where the text is to be appended
    169      * @param pos    A <code>FieldPosition</code> identifying a field
    170      *               in the formatted text
    171      * @return       the string buffer passed in as <code>toAppendTo</code>,
    172      *               with formatted text appended
    173      * @exception NullPointerException if <code>toAppendTo</code> or
    174      *            <code>pos</code> is null
    175      * @exception IllegalArgumentException if the Format cannot format the given
    176      *            object
    177      */
    178     public abstract StringBuffer format(Object obj,
    179                     StringBuffer toAppendTo,
    180                     FieldPosition pos);
    181 
    182     /**
    183      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
    184      * You can use the returned <code>AttributedCharacterIterator</code>
    185      * to build the resulting String, as well as to determine information
    186      * about the resulting String.
    187      * <p>
    188      * Each attribute key of the AttributedCharacterIterator will be of type
    189      * <code>Field</code>. It is up to each <code>Format</code> implementation
    190      * to define what the legal values are for each attribute in the
    191      * <code>AttributedCharacterIterator</code>, but typically the attribute
    192      * key is also used as the attribute value.
    193      * <p>The default implementation creates an
    194      * <code>AttributedCharacterIterator</code> with no attributes. Subclasses
    195      * that support fields should override this and create an
    196      * <code>AttributedCharacterIterator</code> with meaningful attributes.
    197      *
    198      * @exception NullPointerException if obj is null.
    199      * @exception IllegalArgumentException when the Format cannot format the
    200      *            given object.
    201      * @param obj The object to format
    202      * @return AttributedCharacterIterator describing the formatted value.
    203      * @since 1.4
    204      */
    205     public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
    206         return createAttributedCharacterIterator(format(obj));
    207     }
    208 
    209     /**
    210      * Parses text from a string to produce an object.
    211      * <p>
    212      * The method attempts to parse text starting at the index given by
    213      * <code>pos</code>.
    214      * If parsing succeeds, then the index of <code>pos</code> is updated
    215      * to the index after the last character used (parsing does not necessarily
    216      * use all characters up to the end of the string), and the parsed
    217      * object is returned. The updated <code>pos</code> can be used to
    218      * indicate the starting point for the next call to this method.
    219      * If an error occurs, then the index of <code>pos</code> is not
    220      * changed, the error index of <code>pos</code> is set to the index of
    221      * the character where the error occurred, and null is returned.
    222      *
    223      * @param source A <code>String</code>, part of which should be parsed.
    224      * @param pos A <code>ParsePosition</code> object with index and error
    225      *            index information as described above.
    226      * @return An <code>Object</code> parsed from the string. In case of
    227      *         error, returns null.
    228      * @exception NullPointerException if <code>pos</code> is null.
    229      */
    230     public abstract Object parseObject (String source, ParsePosition pos);
    231 
    232     /**
    233      * Parses text from the beginning of the given string to produce an object.
    234      * The method may not use the entire text of the given string.
    235      *
    236      * @param source A <code>String</code> whose beginning should be parsed.
    237      * @return An <code>Object</code> parsed from the string.
    238      * @exception ParseException if the beginning of the specified string
    239      *            cannot be parsed.
    240      */
    241     public Object parseObject(String source) throws ParseException {
    242         ParsePosition pos = new ParsePosition(0);
    243         Object result = parseObject(source, pos);
    244         if (pos.index == 0) {
    245             throw new ParseException("Format.parseObject(String) failed",
    246                 pos.errorIndex);
    247         }
    248         return result;
    249     }
    250 
    251     /**
    252      * Creates and returns a copy of this object.
    253      *
    254      * @return a clone of this instance.
    255      */
    256     public Object clone() {
    257         try {
    258             return super.clone();
    259         } catch (CloneNotSupportedException e) {
    260             // will never happen
    261             throw new InternalError(e);
    262         }
    263     }
    264 
    265     //
    266     // Convenience methods for creating AttributedCharacterIterators from
    267     // different parameters.
    268     //
    269 
    270     /**
    271      * Creates an <code>AttributedCharacterIterator</code> for the String
    272      * <code>s</code>.
    273      *
    274      * @param s String to create AttributedCharacterIterator from
    275      * @return AttributedCharacterIterator wrapping s
    276      */
    277     AttributedCharacterIterator createAttributedCharacterIterator(String s) {
    278         AttributedString as = new AttributedString(s);
    279 
    280         return as.getIterator();
    281     }
    282 
    283     /**
    284      * Creates an <code>AttributedCharacterIterator</code> containing the
    285      * concatenated contents of the passed in
    286      * <code>AttributedCharacterIterator</code>s.
    287      *
    288      * @param iterators AttributedCharacterIterators used to create resulting
    289      *                  AttributedCharacterIterators
    290      * @return AttributedCharacterIterator wrapping passed in
    291      *         AttributedCharacterIterators
    292      */
    293     AttributedCharacterIterator createAttributedCharacterIterator(
    294                        AttributedCharacterIterator[] iterators) {
    295         AttributedString as = new AttributedString(iterators);
    296 
    297         return as.getIterator();
    298     }
    299 
    300     /**
    301      * Returns an AttributedCharacterIterator with the String
    302      * <code>string</code> and additional key/value pair <code>key</code>,
    303      * <code>value</code>.
    304      *
    305      * @param string String to create AttributedCharacterIterator from
    306      * @param key Key for AttributedCharacterIterator
    307      * @param value Value associated with key in AttributedCharacterIterator
    308      * @return AttributedCharacterIterator wrapping args
    309      */
    310     AttributedCharacterIterator createAttributedCharacterIterator(
    311                       String string, AttributedCharacterIterator.Attribute key,
    312                       Object value) {
    313         AttributedString as = new AttributedString(string);
    314 
    315         as.addAttribute(key, value);
    316         return as.getIterator();
    317     }
    318 
    319     /**
    320      * Creates an AttributedCharacterIterator with the contents of
    321      * <code>iterator</code> and the additional attribute <code>key</code>
    322      * <code>value</code>.
    323      *
    324      * @param iterator Initial AttributedCharacterIterator to add arg to
    325      * @param key Key for AttributedCharacterIterator
    326      * @param value Value associated with key in AttributedCharacterIterator
    327      * @return AttributedCharacterIterator wrapping args
    328      */
    329     AttributedCharacterIterator createAttributedCharacterIterator(
    330               AttributedCharacterIterator iterator,
    331               AttributedCharacterIterator.Attribute key, Object value) {
    332         AttributedString as = new AttributedString(iterator);
    333 
    334         as.addAttribute(key, value);
    335         return as.getIterator();
    336     }
    337 
    338 
    339     /**
    340      * Defines constants that are used as attribute keys in the
    341      * <code>AttributedCharacterIterator</code> returned
    342      * from <code>Format.formatToCharacterIterator</code> and as
    343      * field identifiers in <code>FieldPosition</code>.
    344      *
    345      * @since 1.4
    346      */
    347     public static class Field extends AttributedCharacterIterator.Attribute {
    348 
    349         // Proclaim serial compatibility with 1.4 FCS
    350         private static final long serialVersionUID = 276966692217360283L;
    351 
    352         /**
    353          * Creates a Field with the specified name.
    354          *
    355          * @param name Name of the attribute
    356          */
    357         protected Field(String name) {
    358             super(name);
    359         }
    360     }
    361 
    362 
    363     /**
    364      * FieldDelegate is notified by the various <code>Format</code>
    365      * implementations as they are formatting the Objects. This allows for
    366      * storage of the individual sections of the formatted String for
    367      * later use, such as in a <code>FieldPosition</code> or for an
    368      * <code>AttributedCharacterIterator</code>.
    369      * <p>
    370      * Delegates should NOT assume that the <code>Format</code> will notify
    371      * the delegate of fields in any particular order.
    372      *
    373      * @see FieldPosition#getFieldDelegate
    374      * @see CharacterIteratorFieldDelegate
    375      */
    376     interface FieldDelegate {
    377         /**
    378          * Notified when a particular region of the String is formatted. This
    379          * method will be invoked if there is no corresponding integer field id
    380          * matching <code>attr</code>.
    381          *
    382          * @param attr Identifies the field matched
    383          * @param value Value associated with the field
    384          * @param start Beginning location of the field, will be >= 0
    385          * @param end End of the field, will be >= start and <= buffer.length()
    386          * @param buffer Contains current formatted value, receiver should
    387          *        NOT modify it.
    388          */
    389         public void formatted(Format.Field attr, Object value, int start,
    390                               int end, StringBuffer buffer);
    391 
    392         /**
    393          * Notified when a particular region of the String is formatted.
    394          *
    395          * @param fieldID Identifies the field by integer
    396          * @param attr Identifies the field matched
    397          * @param value Value associated with the field
    398          * @param start Beginning location of the field, will be >= 0
    399          * @param end End of the field, will be >= start and <= buffer.length()
    400          * @param buffer Contains current formatted value, receiver should
    401          *        NOT modify it.
    402          */
    403         public void formatted(int fieldID, Format.Field attr, Object value,
    404                               int start, int end, StringBuffer buffer);
    405     }
    406 }
    407