/* Format.java -- Abstract superclass for formatting/parsing strings.
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.text;

import java.io.Serializable;

/**
 * This class is the abstract superclass of classes that format and parse
 * data to/from <code>Strings</code>.  It is guaranteed that any 
 * <code>String</code> produced by a concrete subclass of <code>Format</code>
 * will be parseable by that same subclass.
 * <p>
 * In addition to implementing the abstract methods in this class, subclasses
 * should provide static factory methods of the form 
 * <code>getInstance()</code> and <code>getInstance(Locale)</code> if the
 * subclass loads different formatting/parsing schemes based on locale.
 * These subclasses should also implement a static method called
 * <code>getAvailableLocales()</code> which returns an array of 
 * available locales in the current runtime environment.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner <bothner@cygnus.com>
 */
public abstract class Format implements Serializable, Cloneable
{
  /**
   * This method initializes a new instance of <code>Format</code>.
   * It performs no actions, but acts as a default constructor for
   * subclasses.
   */
  public Format ()
  {
  }

  /**
   * This method formats an <code>Object</code> into a <code>String</code>.
   * 
   * @param obj The <code>Object</code> to format.
   *
   * @return The formatted <code>String</code>.
   *
   * @exception IllegalArgumentException If the <code>Object</code>
   * cannot be formatted. 
   */
  public final String format(Object obj) throws IllegalArgumentException
  {
    StringBuffer sb = new StringBuffer ();
    format (obj, sb, new FieldPosition (0));
    return sb.toString ();
  }

  /**
   * This method formats an <code>Object</code> into a <code>String</code> and
   * appends the <code>String</code> to a <code>StringBuffer</code>.
   *
   * @param obj The <code>Object</code> to format.
   * @param sb The <code>StringBuffer</code> to append to.
   * @param pos The desired <code>FieldPosition</code>, which is also
   *            updated by this call. 
   *
   * @return The updated <code>StringBuffer</code>.
   *
   * @exception IllegalArgumentException If the <code>Object</code>
   * cannot be formatted. 
   */
  public abstract StringBuffer format (Object obj, StringBuffer sb,
				       FieldPosition pos)
    throws IllegalArgumentException;

  /**
   * This method parses a <code>String</code> and converts the parsed 
   * contents into an <code>Object</code>.
   *
   * @param str The <code>String to parse.
   *
   * @return The resulting <code>Object</code>.
   *
   * @exception ParseException If the <code>String</code> cannot be parsed.
   */
  public Object parseObject (String str) throws ParseException
  {
    ParsePosition pos = new ParsePosition(0);
    Object result = parseObject (str, pos);
    if (result == null)
      {
	int index = pos.getErrorIndex();
	if (index < 0)
	  index = pos.getIndex();
	throw new ParseException("parseObject failed", index);
      }
    return result;
  }

  /**
   * This method parses a <code>String</code> and converts the parsed
   * contents into an <code>Object</code>. 
   *
   * @param str The <code>String</code> to parse.
   * @param pos The starting parse index on input, the ending parse
   *            index on output. 
   *
   * @return The parsed <code>Object</code>, or <code>null</code> in
   *         case of error.
   */
  public abstract Object parseObject (String str, ParsePosition pos);

  /**
   * Creates a copy of this object.
   *
   * @return The copied <code>Object</code>.
   */
  public Object clone ()
  {
    try
      {
	return super.clone ();
      }
    catch (CloneNotSupportedException e)
      {
	return null;
      }
  }
}
