Initial revision
From-SVN: r102074
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/* Annotation.java -- Wrapper for a text attribute object
|
||||
Copyright (C) 1998, 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This class is used as a wrapper for a text attribute object. Annotation
|
||||
* objects are associated with a specific range of text. Changing either
|
||||
* the text range or the underlying text invalidates the object.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class Annotation
|
||||
{
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the attribute object being wrappered
|
||||
*/
|
||||
private Object attrib;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>Annotation</code> to
|
||||
* wrapper the specified text attribute object.
|
||||
*
|
||||
* @param attrib The text attribute <code>Object</code> to wrapper.
|
||||
*/
|
||||
public
|
||||
Annotation(Object attrib)
|
||||
{
|
||||
this.attrib = attrib;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method returns the text attribute object this <code>Annotation</code>
|
||||
* instance is wrappering.
|
||||
*
|
||||
* @return The text attribute object for this <code>Annotation</code>.
|
||||
*/
|
||||
public Object
|
||||
getValue()
|
||||
{
|
||||
return(attrib);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this
|
||||
* object.
|
||||
*
|
||||
* @return This object as a <code>String</code>.
|
||||
*/
|
||||
public String
|
||||
toString()
|
||||
{
|
||||
return(getClass().getName() + "[value=" + attrib.toString() + "]");
|
||||
}
|
||||
|
||||
} // class Annotation
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/* AttributedCharacterIterator.java -- Iterate over attributes
|
||||
Copyright (C) 1998, 1999, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.InvalidObjectException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This interface extends the <code>CharacterIterator</code> interface
|
||||
* in order to support iteration over character attributes as well as
|
||||
* over the characters themselves.
|
||||
* <p>
|
||||
* In addition to attributes of specific characters, this interface
|
||||
* supports the concept of the "attribute run", which is an attribute
|
||||
* that is defined for a particular value across an entire range of
|
||||
* characters or which is undefined over a range of characters.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public interface AttributedCharacterIterator extends CharacterIterator
|
||||
{
|
||||
/**
|
||||
* This class defines attribute keys that are used as text attributes.
|
||||
*/
|
||||
public static class Attribute implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -9142742483513960612L;
|
||||
|
||||
/**
|
||||
* This is the attribute for the language of the text. The value of
|
||||
* attributes of this key type are instances of <code>Locale</code>.
|
||||
*/
|
||||
public static final Attribute LANGUAGE = new Attribute ("LANGUAGE");
|
||||
|
||||
/**
|
||||
* This is the attribute for the reading form of text. This is used
|
||||
* for storing pronunciation along with the written text for languages
|
||||
* which need it. The value of attributes of this key type are
|
||||
* instances of <code>Annotation</code> which wrappers a <code>String</code>.
|
||||
*/
|
||||
public static final Attribute READING = new Attribute ("READING");
|
||||
|
||||
/**
|
||||
* This is the attribute for input method segments. The value of attributes
|
||||
* of this key type are instances of <code>Annotation</code> which wrapper
|
||||
* a <code>String</code>.
|
||||
*/
|
||||
public static final Attribute INPUT_METHOD_SEGMENT =
|
||||
new Attribute ("INPUT_METHOD_SEGMENT");
|
||||
|
||||
/**
|
||||
* This is the name of the attribute key
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of this class with the specified
|
||||
* name.
|
||||
*
|
||||
* @param name The name of this attribute key.
|
||||
*/
|
||||
protected Attribute (String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the name of this attribute.
|
||||
*
|
||||
* @return The attribute name
|
||||
*/
|
||||
protected String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method resolves an instance of <code>AttributedCharacterIterator.Attribute</code>
|
||||
* that is being deserialized to one of the three pre-defined attribute
|
||||
* constants. It does this by comparing the names of the attributes. The
|
||||
* constant that the deserialized object resolves to is returned.
|
||||
*
|
||||
* @return The resolved contant value
|
||||
*
|
||||
* @exception InvalidObjectException If the object being deserialized cannot be resolved.
|
||||
*/
|
||||
protected Object readResolve() throws InvalidObjectException
|
||||
{
|
||||
if (this.equals (READING))
|
||||
return READING;
|
||||
|
||||
if (this.equals (LANGUAGE))
|
||||
return LANGUAGE;
|
||||
|
||||
if (this.equals (INPUT_METHOD_SEGMENT))
|
||||
return INPUT_METHOD_SEGMENT;
|
||||
|
||||
throw new InvalidObjectException ("Can't resolve Attribute: " + getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests this object for equality against the specified object.
|
||||
* The two objects will be considered equal if and only if:
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.
|
||||
* <li>The specified object is an instance of <code>AttributedCharacterIterator.Attribute</code>.
|
||||
* <li>The specified object has the same attribute name as this object.
|
||||
* </ul>
|
||||
*
|
||||
* @param The <code>Object</code> to test for equality against this object.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this one, <code>false</code> otherwise.
|
||||
*/
|
||||
public final boolean equals (Object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public final int hashCode()
|
||||
{
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this object.
|
||||
*
|
||||
* @return A <code>String</code> representation of this object.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "(" + getName() + ")";
|
||||
}
|
||||
|
||||
} // Inner class Attribute
|
||||
|
||||
/**
|
||||
* This method returns a list of all keys that are defined for the
|
||||
* text range. This can be an empty list if no attributes are defined.
|
||||
*
|
||||
* @return A list of keys
|
||||
*/
|
||||
Set getAllAttributeKeys();
|
||||
|
||||
/**
|
||||
* This method returns a <code>Map</code> of the attributed defined for
|
||||
* the current character.
|
||||
*
|
||||
* @return A <code>Map</code> of the attributes for the current character.
|
||||
*/
|
||||
Map getAttributes();
|
||||
|
||||
/**
|
||||
* This method returns the value of the specified attribute for the
|
||||
* current character. If the attribute is not defined for the current
|
||||
* character, <code>null</code> is returned.
|
||||
*
|
||||
* @param attrib The attribute to retrieve the value of.
|
||||
*
|
||||
* @return The value of the specified attribute
|
||||
*/
|
||||
Object getAttribute (AttributedCharacterIterator.Attribute attrib);
|
||||
|
||||
/**
|
||||
* This method returns the index of the first character in the run that
|
||||
* contains all attributes defined for the current character.
|
||||
*
|
||||
* @return The start index of the run
|
||||
*/
|
||||
int getRunStart();
|
||||
|
||||
/**
|
||||
* This method returns the index of the first character in the run that
|
||||
* contains all attributes in the specified <code>Set</code> defined for
|
||||
* the current character.
|
||||
*
|
||||
* @param attribs The <code>Set</code> of attributes.
|
||||
*
|
||||
* @return The start index of the run.
|
||||
*/
|
||||
int getRunStart (Set attribs);
|
||||
|
||||
/**
|
||||
* This method returns the index of the first character in the run that
|
||||
* contains the specified attribute defined for the current character.
|
||||
*
|
||||
* @param attrib The attribute.
|
||||
*
|
||||
* @return The start index of the run.
|
||||
*/
|
||||
int getRunStart (AttributedCharacterIterator.Attribute attrib);
|
||||
|
||||
/**
|
||||
* This method returns the index of the character after the end of the run
|
||||
* that contains all attributed defined for the current character.
|
||||
*
|
||||
* @return The end index of the run.
|
||||
*/
|
||||
int getRunLimit();
|
||||
|
||||
/**
|
||||
* This method returns the index of the character after the end of the run
|
||||
* that contains all attributes in the specified <code>Set</code> defined
|
||||
* for the current character.
|
||||
*
|
||||
* @param attribs The <code>Set</code> of attributes.
|
||||
*
|
||||
* @return The end index of the run.
|
||||
*/
|
||||
int getRunLimit (Set attribs);
|
||||
|
||||
/**
|
||||
* This methods returns the index of the character after the end of the run
|
||||
* that contains the specified attribute defined for the current character.
|
||||
*
|
||||
* @param attrib The attribute.
|
||||
*
|
||||
* @return The end index of the run.
|
||||
*/
|
||||
int getRunLimit (AttributedCharacterIterator.Attribute attrib);
|
||||
|
||||
} // interface AttributedCharacterIterator
|
||||
@@ -0,0 +1,425 @@
|
||||
/* AttributedString.java -- Models text with attributes
|
||||
Copyright (C) 1998, 1999, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class models a <code>String</code> with attributes over various
|
||||
* subranges of the string. It allows applications to access this
|
||||
* information via the <code>AttributedCharcterIterator</code> interface.
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class AttributedString
|
||||
{
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Inner Classes
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class contains the attributes and ranges of text over which
|
||||
* that attributes apply.
|
||||
*/
|
||||
final class AttributeRange
|
||||
{
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Map of the attributes
|
||||
*/
|
||||
Map attribs;
|
||||
|
||||
/**
|
||||
* The beginning index of the attributes
|
||||
*/
|
||||
int begin_index;
|
||||
|
||||
/**
|
||||
* The ending index of the attributes
|
||||
*/
|
||||
int end_index;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
AttributeRange(Map attribs, int begin_index, int end_index)
|
||||
{
|
||||
this.attribs = attribs;
|
||||
this.begin_index = begin_index;
|
||||
this.end_index = end_index;
|
||||
}
|
||||
|
||||
} // Inner class AttributeRange
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* This object holds the string we are representing.
|
||||
*/
|
||||
private StringCharacterIterator sci;
|
||||
|
||||
/**
|
||||
* This is the attribute information
|
||||
*/
|
||||
private AttributeRange[] attribs;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>AttributedString</code>
|
||||
* that represents the specified <code>String</code> with no attributes.
|
||||
*
|
||||
* @param str The <code>String</code> to be attributed.
|
||||
*/
|
||||
public
|
||||
AttributedString(String str)
|
||||
{
|
||||
sci = new StringCharacterIterator(str);
|
||||
attribs = new AttributeRange[0];
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>AttributedString</code>
|
||||
* that represents that specified <code>String</code> with the specified
|
||||
* attributes over the entire length of the <code>String</code>.
|
||||
*
|
||||
* @param str The <code>String</code> to be attributed.
|
||||
* @param attributes The attribute list.
|
||||
*/
|
||||
public
|
||||
AttributedString(String str, Map attributes)
|
||||
{
|
||||
this(str);
|
||||
|
||||
attribs = new AttributeRange[1];
|
||||
attribs[0] = new AttributeRange(attributes, 0, str.length());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>AttributedString</code>
|
||||
* that will use the text and attribute information from the specified
|
||||
* <code>AttributedCharacterIterator</code>.
|
||||
*
|
||||
* @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
|
||||
*/
|
||||
public
|
||||
AttributedString(AttributedCharacterIterator aci)
|
||||
{
|
||||
this(aci, aci.getBeginIndex(), aci.getEndIndex(), null);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>AttributedString</code>
|
||||
* that will use the text and attribute information from the specified
|
||||
* subrange of the specified <code>AttributedCharacterIterator</code>.
|
||||
*
|
||||
* @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
|
||||
* @param begin_index The beginning index of the text subrange.
|
||||
* @param end_index The ending index of the text subrange.
|
||||
*/
|
||||
public
|
||||
AttributedString(AttributedCharacterIterator aci, int begin_index,
|
||||
int end_index)
|
||||
{
|
||||
this(aci, begin_index, end_index, null);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>AttributedString</code>
|
||||
* that will use the text and attribute information from the specified
|
||||
* subrange of the specified <code>AttributedCharacterIterator</code>.
|
||||
* Only attributes from the source iterator that are present in the
|
||||
* specified array of attributes will be included in the attribute list
|
||||
* for this object.
|
||||
*
|
||||
* @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
|
||||
* @param begin_index The beginning index of the text subrange.
|
||||
* @param end_index The ending index of the text subrange.
|
||||
* @param attributes A list of attributes to include from the iterator, or <code>null</code> to include all attributes.
|
||||
*/
|
||||
public
|
||||
AttributedString(AttributedCharacterIterator aci, int begin_index,
|
||||
int end_index, AttributedCharacterIterator.Attribute[] attributes)
|
||||
{
|
||||
// Validate some arguments
|
||||
if ((begin_index < 0) || (end_index < begin_index))
|
||||
throw new IllegalArgumentException("Bad index values");
|
||||
|
||||
StringBuffer sb = new StringBuffer("");
|
||||
|
||||
// Get the valid attribute list
|
||||
Set all_attribs = aci.getAllAttributeKeys();
|
||||
if (attributes != null)
|
||||
all_attribs.retainAll(Arrays.asList(attributes));
|
||||
|
||||
// Loop through and extract the attributes
|
||||
char c = aci.setIndex(begin_index);
|
||||
|
||||
ArrayList accum = new ArrayList();
|
||||
do
|
||||
{
|
||||
sb.append(c);
|
||||
|
||||
Iterator iter = all_attribs.iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
Object obj = iter.next();
|
||||
|
||||
// What should we do if this is not true?
|
||||
if (!(obj instanceof AttributedCharacterIterator.Attribute))
|
||||
continue;
|
||||
|
||||
AttributedCharacterIterator.Attribute attrib =
|
||||
(AttributedCharacterIterator.Attribute)obj;
|
||||
|
||||
// Make sure the attribute is defined.
|
||||
int rl = aci.getRunLimit(attrib);
|
||||
if (rl == -1)
|
||||
continue;
|
||||
if (rl > end_index)
|
||||
rl = end_index;
|
||||
rl -= begin_index;
|
||||
|
||||
// Check to see if we already processed this one
|
||||
int rs = aci.getRunStart(attrib);
|
||||
if ((rs < aci.getIndex()) && (aci.getIndex() != begin_index))
|
||||
continue;
|
||||
|
||||
// If the attribute run starts before the beginning index, we
|
||||
// need to junk it if it is an Annotation.
|
||||
Object attrib_obj = aci.getAttribute(attrib);
|
||||
if (rs < begin_index)
|
||||
{
|
||||
if (attrib_obj instanceof Annotation)
|
||||
continue;
|
||||
|
||||
rs = begin_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs -= begin_index;
|
||||
}
|
||||
|
||||
// Create a map object. Yes this will only contain one attribute
|
||||
Map new_map = new Hashtable();
|
||||
new_map.put(attrib, attrib_obj);
|
||||
|
||||
// Add it to the attribute list.
|
||||
accum.add(new AttributeRange(new_map, rs, rl));
|
||||
}
|
||||
|
||||
c = aci.next();
|
||||
}
|
||||
while(c != CharacterIterator.DONE);
|
||||
|
||||
attribs = new AttributeRange[accum.size()];
|
||||
attribs = (AttributeRange[]) accum.toArray(attribs);
|
||||
|
||||
sci = new StringCharacterIterator(sb.toString());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method adds a new attribute that will cover the entire string.
|
||||
*
|
||||
* @param attrib The attribute to add.
|
||||
* @param value The value of the attribute.
|
||||
*/
|
||||
public void
|
||||
addAttribute(AttributedCharacterIterator.Attribute attrib, Object value)
|
||||
{
|
||||
addAttribute(attrib, value, 0, sci.getEndIndex());
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method adds a new attribute that will cover the specified subrange
|
||||
* of the string.
|
||||
*
|
||||
* @param attrib The attribute to add.
|
||||
* @param value The value of the attribute, which may be null.
|
||||
* @param begin_index The beginning index of the subrange.
|
||||
* @param end_index The ending index of the subrange.
|
||||
*
|
||||
* @exception IllegalArgumentException If attribute is <code>null</code> or the subrange is not valid.
|
||||
*/
|
||||
public void
|
||||
addAttribute(AttributedCharacterIterator.Attribute attrib, Object value,
|
||||
int begin_index, int end_index)
|
||||
{
|
||||
if (attrib == null)
|
||||
throw new IllegalArgumentException("null attribute");
|
||||
|
||||
HashMap hm = new HashMap();
|
||||
hm.put(attrib, value);
|
||||
|
||||
addAttributes(hm, begin_index, end_index);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method adds all of the attributes in the specified list to the
|
||||
* specified subrange of the string.
|
||||
*
|
||||
* @param attributes The list of attributes.
|
||||
* @param begin_index The beginning index.
|
||||
* @param end_index The ending index
|
||||
*
|
||||
* @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid.
|
||||
*/
|
||||
public void
|
||||
addAttributes(Map attributes, int begin_index, int end_index)
|
||||
{
|
||||
if (attributes == null)
|
||||
throw new IllegalArgumentException("null attribute");
|
||||
|
||||
if ((begin_index < 0) || (end_index > sci.getEndIndex()) ||
|
||||
(end_index < begin_index))
|
||||
throw new IllegalArgumentException("bad range");
|
||||
|
||||
AttributeRange[] new_list = new AttributeRange[attribs.length + 1];
|
||||
System.arraycopy(attribs, 0, new_list, 0, attribs.length);
|
||||
attribs = new_list;
|
||||
attribs[attribs.length - 1] = new AttributeRange(attributes, begin_index,
|
||||
end_index);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an <code>AttributedCharacterIterator</code> that
|
||||
* will iterate over the entire string.
|
||||
*
|
||||
* @return An <code>AttributedCharacterIterator</code> for the entire string.
|
||||
*/
|
||||
public AttributedCharacterIterator
|
||||
getIterator()
|
||||
{
|
||||
return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex(), null));
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an <code>AttributedCharacterIterator</code> that
|
||||
* will iterate over the entire string. This iterator will return information
|
||||
* about the list of attributes in the specified array. Attributes not in
|
||||
* the array may or may not be returned by the iterator. If the specified
|
||||
* array is <code>null</code>, all attributes will be returned.
|
||||
*
|
||||
* @param attributes A list of attributes to include in the returned iterator.
|
||||
*
|
||||
* @return An <code>AttributedCharacterIterator</code> for this string.
|
||||
*/
|
||||
public AttributedCharacterIterator
|
||||
getIterator(AttributedCharacterIterator.Attribute[] attributes)
|
||||
{
|
||||
return(getIterator(attributes, 0, sci.getEndIndex()));
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns an <code>AttributedCharacterIterator</code> that
|
||||
* will iterate over the specified subrange. This iterator will return information
|
||||
* about the list of attributes in the specified array. Attributes not in
|
||||
* the array may or may not be returned by the iterator. If the specified
|
||||
* array is <code>null</code>, all attributes will be returned.
|
||||
*
|
||||
* @param attributes A list of attributes to include in the returned iterator.
|
||||
* @param begin_index The beginning index of the subrange.
|
||||
* @param end_index The ending index of the subrange.
|
||||
*
|
||||
* @return An <code>AttributedCharacterIterator</code> for this string.
|
||||
*/
|
||||
public AttributedCharacterIterator
|
||||
getIterator(AttributedCharacterIterator.Attribute[] attributes,
|
||||
int begin_index, int end_index)
|
||||
{
|
||||
if ((begin_index < 0) || (end_index > sci.getEndIndex()) ||
|
||||
(end_index < begin_index))
|
||||
throw new IllegalArgumentException("bad range");
|
||||
|
||||
return(new AttributedStringIterator(sci, attribs, begin_index, end_index,
|
||||
attributes));
|
||||
}
|
||||
|
||||
} // class AttributedString
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
/* AttributedStringIterator.java -- Class to iterate over AttributedString
|
||||
Copyright (C) 1998, 1999, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class implements the AttributedCharacterIterator interface. It
|
||||
* is used by AttributedString.getIterator().
|
||||
*
|
||||
* @version 0.0
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
class AttributedStringIterator implements AttributedCharacterIterator
|
||||
{
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Instance Variables
|
||||
*/
|
||||
|
||||
/**
|
||||
* The character iterator containing the text
|
||||
*/
|
||||
private CharacterIterator ci;
|
||||
|
||||
/**
|
||||
* The list of attributes and ranges
|
||||
*/
|
||||
private AttributedString.AttributeRange[] attribs;
|
||||
|
||||
/**
|
||||
* The list of attributes that the user is interested in. We may,
|
||||
* at our option, not return any other attributes.
|
||||
*/
|
||||
private AttributedCharacterIterator.Attribute[] restricts;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Constructors
|
||||
*/
|
||||
|
||||
AttributedStringIterator(StringCharacterIterator sci,
|
||||
AttributedString.AttributeRange[] attribs,
|
||||
int begin_index, int end_index,
|
||||
AttributedCharacterIterator.Attribute[] restricts)
|
||||
{
|
||||
this.ci = new StringCharacterIterator(sci, begin_index, end_index);
|
||||
this.attribs = attribs;
|
||||
this.restricts = restricts;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Instance Methods
|
||||
*/
|
||||
|
||||
// First we have a bunch of stupid redirects. If StringCharacterIterator
|
||||
// weren't final, I just would have extended that for this class. Alas, no.
|
||||
|
||||
public Object
|
||||
clone()
|
||||
{
|
||||
return(ci.clone());
|
||||
}
|
||||
|
||||
public char
|
||||
current()
|
||||
{
|
||||
return(ci.current());
|
||||
}
|
||||
|
||||
public char
|
||||
next()
|
||||
{
|
||||
return(ci.next());
|
||||
}
|
||||
|
||||
public char
|
||||
previous()
|
||||
{
|
||||
return(ci.previous());
|
||||
}
|
||||
|
||||
public char
|
||||
first()
|
||||
{
|
||||
return(ci.first());
|
||||
}
|
||||
|
||||
public char
|
||||
last()
|
||||
{
|
||||
return(ci.last());
|
||||
}
|
||||
|
||||
public int
|
||||
getIndex()
|
||||
{
|
||||
return(ci.getIndex());
|
||||
}
|
||||
|
||||
public char
|
||||
setIndex(int index)
|
||||
{
|
||||
return(ci.setIndex(index));
|
||||
}
|
||||
|
||||
public int
|
||||
getBeginIndex()
|
||||
{
|
||||
return(ci.getBeginIndex());
|
||||
}
|
||||
|
||||
public int
|
||||
getEndIndex()
|
||||
{
|
||||
return(ci.getEndIndex());
|
||||
}
|
||||
|
||||
/*
|
||||
* Here is where the AttributedCharacterIterator methods start.
|
||||
*/
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns a list of all the attribute keys that are defined anywhere
|
||||
* on this string.
|
||||
*/
|
||||
public Set
|
||||
getAllAttributeKeys()
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
if (attribs == null)
|
||||
return(s);
|
||||
|
||||
for (int i = 0; i < attribs.length; i++)
|
||||
{
|
||||
if (attribs[i].begin_index > getEndIndex()
|
||||
|| attribs[i].end_index <= getBeginIndex())
|
||||
continue;
|
||||
|
||||
Set key_set = attribs[i].attribs.keySet();
|
||||
Iterator iter = key_set.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
s.add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Various methods that determine how far the run extends for various
|
||||
* attribute combinations.
|
||||
*/
|
||||
|
||||
public int
|
||||
getRunLimit()
|
||||
{
|
||||
return(getRunLimit(getAttributes().keySet()));
|
||||
}
|
||||
|
||||
public int
|
||||
getRunLimit(AttributedCharacterIterator.Attribute attrib)
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
s.add(attrib);
|
||||
|
||||
return(getRunLimit(s));
|
||||
}
|
||||
|
||||
public synchronized int
|
||||
getRunLimit(Set attribute_set)
|
||||
{
|
||||
boolean hit = false;
|
||||
int runLimit = ci.getEndIndex ();
|
||||
int pos = ci.getIndex ();
|
||||
|
||||
for (int i = 0; i < attribs.length; ++i)
|
||||
{
|
||||
if (pos >= attribs[i].begin_index &&
|
||||
pos < attribs[i].end_index)
|
||||
{
|
||||
Iterator iter = attribute_set.iterator();
|
||||
while(iter.hasNext())
|
||||
if (attribs[i].attribs.containsKey(iter.next()))
|
||||
{
|
||||
hit = true;
|
||||
runLimit = Math.min(runLimit, attribs[i].end_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hit)
|
||||
return runLimit;
|
||||
else
|
||||
return ci.getEndIndex();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Various methods that determine where the run begins for various
|
||||
* attribute combinations.
|
||||
*/
|
||||
|
||||
public int
|
||||
getRunStart()
|
||||
{
|
||||
return(getRunStart(getAttributes().keySet()));
|
||||
}
|
||||
|
||||
public int
|
||||
getRunStart(AttributedCharacterIterator.Attribute attrib)
|
||||
{
|
||||
HashSet s = new HashSet();
|
||||
s.add(attrib);
|
||||
|
||||
return(getRunStart(s));
|
||||
}
|
||||
|
||||
public int
|
||||
getRunStart(Set attribute_set)
|
||||
{
|
||||
boolean hit = false;
|
||||
int runBegin = 0;
|
||||
int pos = ci.getIndex ();
|
||||
|
||||
for (int i = 0; i < attribs.length; ++i)
|
||||
{
|
||||
if (pos >= attribs[i].begin_index &&
|
||||
pos <= attribs[i].end_index)
|
||||
{
|
||||
Iterator iter = attribute_set.iterator();
|
||||
while(iter.hasNext())
|
||||
if (attribs[i].attribs.containsKey(iter.next()))
|
||||
{
|
||||
hit = true;
|
||||
runBegin = Math.max(runBegin, attribs[i].begin_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hit)
|
||||
return runBegin;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
public Object
|
||||
getAttribute(AttributedCharacterIterator.Attribute attrib)
|
||||
{
|
||||
if (attribs == null)
|
||||
return(null);
|
||||
|
||||
for (int i = 0; i < attribs.length; i++)
|
||||
{
|
||||
Set key_set = attribs[i].attribs.keySet();
|
||||
Iterator iter = key_set.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
Object obj = iter.next();
|
||||
|
||||
// Check for attribute match and range match
|
||||
if (obj.equals(attrib))
|
||||
if ((ci.getIndex() >= attribs[i].begin_index) &&
|
||||
(ci.getIndex() < attribs[i].end_index))
|
||||
return(attribs[i].attribs.get(obj));
|
||||
}
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Return a list of all the attributes and values defined for this
|
||||
* character
|
||||
*/
|
||||
public Map
|
||||
getAttributes()
|
||||
{
|
||||
HashMap m = new HashMap();
|
||||
if (attribs == null)
|
||||
return(m);
|
||||
|
||||
for (int i = 0; i < attribs.length; i++)
|
||||
{
|
||||
if ((ci.getIndex() >= attribs[i].begin_index) &&
|
||||
(ci.getIndex() < attribs[i].end_index))
|
||||
m.putAll(attribs[i].attribs);
|
||||
}
|
||||
|
||||
return(m);
|
||||
}
|
||||
|
||||
} // class AttributedStringIterator
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
/* BreakIterator.java -- Breaks text into elements
|
||||
Copyright (C) 1998, 1999, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* This class iterates over text elements such as words, lines, sentences,
|
||||
* and characters. It can only iterate over one of these text elements at
|
||||
* a time. An instance of this class configured for the desired iteration
|
||||
* type is created by calling one of the static factory methods, not
|
||||
* by directly calling a constructor.
|
||||
*
|
||||
* The standard iterators created by the factory methods in this
|
||||
* class will be valid upon creation. That is, their methods will
|
||||
* not cause exceptions if called before you call setText().
|
||||
*
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @date March 19, 1999
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 beta from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to 1.1.
|
||||
*/
|
||||
public abstract class BreakIterator implements Cloneable
|
||||
{
|
||||
/**
|
||||
* This value is returned by the <code>next()</code> and
|
||||
* <code>previous</code> in order to indicate that the end of the
|
||||
* text has been reached.
|
||||
*/
|
||||
// The value was discovered by writing a test program.
|
||||
public static final int DONE = -1;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>BreakIterator</code>.
|
||||
* This protected constructor is available to subclasses as a default
|
||||
* no-arg superclass constructor.
|
||||
*/
|
||||
protected BreakIterator ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this object.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the index of the current text element boundary.
|
||||
*
|
||||
* @return The current text boundary.
|
||||
*/
|
||||
public abstract int current ();
|
||||
|
||||
/**
|
||||
* This method returns the first text element boundary in the text being
|
||||
* iterated over.
|
||||
*
|
||||
* @return The first text boundary.
|
||||
*/
|
||||
public abstract int first ();
|
||||
|
||||
/**
|
||||
* This methdod returns the offset of the text element boundary following
|
||||
* the specified offset.
|
||||
*
|
||||
* @param offset The text index from which to find the next text boundary.
|
||||
*
|
||||
* @param The next text boundary following the specified index.
|
||||
*/
|
||||
public abstract int following (int pos);
|
||||
|
||||
/**
|
||||
* This method returns a list of locales for which instances of
|
||||
* <code>BreakIterator</code> are available.
|
||||
*
|
||||
* @return A list of available locales
|
||||
*/
|
||||
public static synchronized Locale[] getAvailableLocales ()
|
||||
{
|
||||
Locale[] l = new Locale[1];
|
||||
l[0] = Locale.US;
|
||||
return l;
|
||||
}
|
||||
|
||||
private static BreakIterator getInstance (String type, Locale loc)
|
||||
{
|
||||
String className;
|
||||
try
|
||||
{
|
||||
ResourceBundle res
|
||||
= ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
|
||||
loc, ClassLoader.getSystemClassLoader());
|
||||
className = res.getString(type);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
Class k = Class.forName(className);
|
||||
return (BreakIterator) k.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException x1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (InstantiationException x2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (IllegalAccessException x3)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over characters as defined in the default locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getCharacterInstance ()
|
||||
{
|
||||
return getCharacterInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over characters as defined in the specified locale. If the
|
||||
* desired locale is not available, the default locale is used.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getCharacterInstance (Locale loc)
|
||||
{
|
||||
BreakIterator r = getInstance ("CharacterIterator", loc);
|
||||
if (r == null)
|
||||
r = new gnu.java.text.CharacterBreakIterator ();
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over line breaks as defined in the default locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getLineInstance ()
|
||||
{
|
||||
return getLineInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over line breaks as defined in the specified locale. If the
|
||||
* desired locale is not available, the default locale is used.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getLineInstance (Locale loc)
|
||||
{
|
||||
BreakIterator r = getInstance ("LineIterator", loc);
|
||||
if (r == null)
|
||||
r = new gnu.java.text.LineBreakIterator ();
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over sentences as defined in the default locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getSentenceInstance ()
|
||||
{
|
||||
return getSentenceInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over sentences as defined in the specified locale. If the
|
||||
* desired locale is not available, the default locale is used.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getSentenceInstance (Locale loc)
|
||||
{
|
||||
BreakIterator r = getInstance ("SentenceIterator", loc);
|
||||
if (r == null)
|
||||
r = new gnu.java.text.SentenceBreakIterator ();
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the text this object is iterating over as a
|
||||
* <code>CharacterIterator</code>.
|
||||
*
|
||||
* @param The text being iterated over.
|
||||
*/
|
||||
public abstract CharacterIterator getText ();
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over words as defined in the default locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getWordInstance ()
|
||||
{
|
||||
return getWordInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>BreakIterator</code> that will
|
||||
* iterate over words as defined in the specified locale. If the
|
||||
* desired locale is not available, the default locale is used.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return A <code>BreakIterator</code> instance for the default locale.
|
||||
*/
|
||||
public static BreakIterator getWordInstance (Locale loc)
|
||||
{
|
||||
BreakIterator r = getInstance ("WordIterator", loc);
|
||||
if (r == null)
|
||||
r = new gnu.java.text.WordBreakIterator ();
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests whether or not the specified position is a text
|
||||
* element boundary.
|
||||
*
|
||||
* @param offset The text position to test.
|
||||
*
|
||||
* @return <code>true</code> if the position is a boundary,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isBoundary (int pos)
|
||||
{
|
||||
if (pos == 0)
|
||||
return true;
|
||||
return following (pos - 1) == pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the last text element boundary in the text being
|
||||
* iterated over.
|
||||
*
|
||||
* @return The last text boundary.
|
||||
*/
|
||||
public abstract int last ();
|
||||
|
||||
/**
|
||||
* This method returns the text element boundary following the current
|
||||
* text position.
|
||||
*
|
||||
* @return The next text boundary.
|
||||
*/
|
||||
public abstract int next ();
|
||||
|
||||
/**
|
||||
* This method returns the n'th text element boundary following the current
|
||||
* text position.
|
||||
*
|
||||
* @param n The number of text element boundaries to skip.
|
||||
*
|
||||
* @return The next text boundary.
|
||||
*/
|
||||
public abstract int next (int n);
|
||||
|
||||
/**
|
||||
* This methdod returns the offset of the text element boundary preceding
|
||||
* the specified offset.
|
||||
*
|
||||
* @param offset The text index from which to find the preceding
|
||||
* text boundary.
|
||||
*
|
||||
* @returns The next text boundary preceding the specified index.
|
||||
*/
|
||||
public int preceding (int pos)
|
||||
{
|
||||
if (following (pos) == DONE)
|
||||
last ();
|
||||
while (previous () >= pos)
|
||||
;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the text element boundary preceding the current
|
||||
* text position.
|
||||
*
|
||||
* @return The previous text boundary.
|
||||
*/
|
||||
public abstract int previous ();
|
||||
|
||||
/**
|
||||
* This method sets the text string to iterate over.
|
||||
*
|
||||
* @param str The <code>String</code> to iterate over.
|
||||
*/
|
||||
public void setText (String newText)
|
||||
{
|
||||
setText (new StringCharacterIterator (newText));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the text to iterate over from the specified
|
||||
* <code>CharacterIterator</code>.
|
||||
*
|
||||
* @param ci The desired <code>CharacterIterator</code>.
|
||||
*/
|
||||
public abstract void setText (CharacterIterator newText);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/* CharacterIterator.java -- Iterate over a character range
|
||||
Copyright (C) 1998, 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This interface defines a mechanism for iterating over a range of
|
||||
* characters. For a given range of text, a beginning and ending index,
|
||||
* as well as a current index are defined. These values can be queried
|
||||
* by the methods in this interface. Additionally, various methods allow
|
||||
* the index to be set.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public interface CharacterIterator extends Cloneable
|
||||
{
|
||||
/**
|
||||
* This is a special constant value that is returned when the beginning or
|
||||
* end of the character range has been reached.
|
||||
*/
|
||||
char DONE = '\uFFFF';
|
||||
|
||||
/**
|
||||
* This method returns the character at the current index position
|
||||
*
|
||||
* @return The character at the current index position.
|
||||
*/
|
||||
char current();
|
||||
|
||||
/**
|
||||
* This method increments the current index and then returns the character
|
||||
* at the new index value. If the index is already at <code>getEndIndex() - 1</code>,
|
||||
* it will not be incremented.
|
||||
*
|
||||
* @return The character at the position of the incremented index value,
|
||||
* or <code>DONE</code> if the index has reached getEndIndex() - 1
|
||||
*/
|
||||
char next();
|
||||
|
||||
/**
|
||||
* This method decrements the current index and then returns the character
|
||||
* at the new index value. If the index value is already at the beginning
|
||||
* index, it will not be decremented.
|
||||
*
|
||||
* @return The character at the position of the decremented index value,
|
||||
* or <code>DONE</code> if index was already equal to the beginning index value.
|
||||
*/
|
||||
char previous();
|
||||
|
||||
/**
|
||||
* This method sets the index value to the beginning of the range and returns
|
||||
* the character there.
|
||||
*
|
||||
* @return The character at the beginning of the range, or <code>DONE</code> if the range is empty.
|
||||
*/
|
||||
char first();
|
||||
|
||||
/**
|
||||
* This method sets the index value to <code>getEndIndex() - 1</code> and
|
||||
* returns the character there. If the range is empty, then the index value
|
||||
* will be set equal to the beginning index.
|
||||
*
|
||||
* @return The character at the end of the range, or <code>DONE</code> if the range is empty.
|
||||
*/
|
||||
char last();
|
||||
|
||||
/**
|
||||
* This method returns the current value of the index.
|
||||
*
|
||||
* @return The current index value
|
||||
*/
|
||||
int getIndex();
|
||||
|
||||
/**
|
||||
* This method sets the value of the index to the specified value, then
|
||||
* returns the character at that position.
|
||||
*
|
||||
* @param index The new index value.
|
||||
*
|
||||
* @return The character at the new index value or <code>DONE</code> if the index value is equal to <code>getEndIndex</code>.
|
||||
*/
|
||||
char setIndex (int index) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* This method returns the character position of the first character in the
|
||||
* range.
|
||||
*
|
||||
* @return The index of the first character in the range.
|
||||
*/
|
||||
int getBeginIndex();
|
||||
|
||||
/**
|
||||
* This method returns the character position of the end of the text range.
|
||||
* This will actually be the index of the first character following the
|
||||
* end of the range. In the event the text range is empty, this will be
|
||||
* equal to the first character in the range.
|
||||
*
|
||||
* @return The index of the end of the range.
|
||||
*/
|
||||
int getEndIndex();
|
||||
|
||||
/**
|
||||
* This method creates a copy of this <code>CharacterIterator</code>.
|
||||
*
|
||||
* @return A copy of this <code>CharacterIterator</code>.
|
||||
*/
|
||||
Object clone();
|
||||
|
||||
} // interface CharacterIterator
|
||||
@@ -0,0 +1,503 @@
|
||||
/* ChoiceFormat.java -- Format over a range of numbers
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.Vector;
|
||||
|
||||
/**
|
||||
* This class allows a format to be specified based on a range of numbers.
|
||||
* To use this class, first specify two lists of formats and range terminators.
|
||||
* These lists must be arrays of equal length. The format of index
|
||||
* <code>i</code> will be selected for value <code>X</code> if
|
||||
* <code>terminator[i] <= X < limit[i + 1]</code>. If the value X is not
|
||||
* included in any range, then either the first or last format will be
|
||||
* used depending on whether the value X falls outside the range.
|
||||
* <p>
|
||||
* This sounds complicated, but that is because I did a poor job of
|
||||
* explaining it. Consider the following example:
|
||||
* <p>
|
||||
*
|
||||
<pre>terminators = { 1, ChoiceFormat.nextDouble(1) }
|
||||
formats = { "file", "files" }</pre>
|
||||
*
|
||||
* <p>
|
||||
* In this case if the actual number tested is one or less, then the word
|
||||
* "file" is used as the format value. If the number tested is greater than
|
||||
* one, then "files" is used. This allows plurals to be handled
|
||||
* gracefully. Note the use of the method <code>nextDouble</code>. This
|
||||
* method selects the next highest double number than its argument. This
|
||||
* effectively makes any double greater than 1.0 cause the "files" string
|
||||
* to be selected. (Note that all terminator values are specified as
|
||||
* doubles.
|
||||
* <p>
|
||||
* Note that in order for this class to work properly, the range terminator
|
||||
* array must be sorted in ascending order and the format string array
|
||||
* must be the same length as the terminator array.
|
||||
*
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @date March 9, 1999
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to 1.1.
|
||||
*/
|
||||
public class ChoiceFormat extends NumberFormat
|
||||
{
|
||||
/**
|
||||
* This method sets new range terminators and format strings for this
|
||||
* object based on the specified pattern. This pattern is of the form
|
||||
* "term#string|term#string...". For example "1#Sunday|2#Monday|#Tuesday".
|
||||
*
|
||||
* @param pattern The pattern of terminators and format strings.
|
||||
*
|
||||
* @exception IllegalArgumentException If the pattern is not valid
|
||||
*/
|
||||
public void applyPattern (String newPattern)
|
||||
{
|
||||
// Note: we assume the same kind of quoting rules apply here.
|
||||
// This isn't explicitly documented. But for instance we accept
|
||||
// '#' as a literal hash in a format string.
|
||||
int index = 0, max = newPattern.length();
|
||||
Vector stringVec = new Vector ();
|
||||
Vector limitVec = new Vector ();
|
||||
StringBuffer buf = new StringBuffer ();
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Find end of double.
|
||||
int dstart = index;
|
||||
while (index < max)
|
||||
{
|
||||
char c = newPattern.charAt(index);
|
||||
if (c == '#' || c == '\u2064' || c == '<')
|
||||
break;
|
||||
++index;
|
||||
}
|
||||
|
||||
if (index == max)
|
||||
throw new IllegalArgumentException ("unexpected end of text");
|
||||
Double d = new Double (newPattern.substring(dstart, index));
|
||||
|
||||
if (newPattern.charAt(index) == '<')
|
||||
d = new Double (nextDouble (d.doubleValue()));
|
||||
|
||||
limitVec.addElement(d);
|
||||
|
||||
// Scan text.
|
||||
++index;
|
||||
buf.setLength(0);
|
||||
while (index < max)
|
||||
{
|
||||
char c = newPattern.charAt(index);
|
||||
if (c == '\'' && index < max + 1
|
||||
&& newPattern.charAt(index + 1) == '\'')
|
||||
{
|
||||
buf.append(c);
|
||||
++index;
|
||||
}
|
||||
else if (c == '\'' && index < max + 2)
|
||||
{
|
||||
buf.append(newPattern.charAt(index + 1));
|
||||
index += 2;
|
||||
}
|
||||
else if (c == '|')
|
||||
break;
|
||||
else
|
||||
buf.append(c);
|
||||
++index;
|
||||
}
|
||||
|
||||
stringVec.addElement(buf.toString());
|
||||
if (index == max)
|
||||
break;
|
||||
++index;
|
||||
}
|
||||
|
||||
choiceFormats = new String[stringVec.size()];
|
||||
stringVec.copyInto(choiceFormats);
|
||||
|
||||
choiceLimits = new double[limitVec.size()];
|
||||
for (int i = 0; i < choiceLimits.length; ++i)
|
||||
{
|
||||
Double d = (Double) limitVec.elementAt(i);
|
||||
choiceLimits[i] = d.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>ChoiceFormat</code> that
|
||||
* generates its range terminator and format string arrays from the
|
||||
* specified pattern. This pattern is of the form
|
||||
* "term#string|term#string...". For example "1#Sunday|2#Monday|#Tuesday".
|
||||
* This is the same pattern type used by the <code>applyPattern</code>
|
||||
* method.
|
||||
*
|
||||
* @param pattern The pattern of terminators and format strings.
|
||||
*
|
||||
* @exception IllegalArgumentException If the pattern is not valid
|
||||
*/
|
||||
public ChoiceFormat (String newPattern)
|
||||
{
|
||||
super ();
|
||||
applyPattern (newPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>ChoiceFormat</code> that
|
||||
* will use the specified range terminators and format strings.
|
||||
*
|
||||
* @param choiceLimits The array of range terminators
|
||||
* @param choiceFormats The array of format strings
|
||||
*/
|
||||
public ChoiceFormat (double[] choiceLimits, String[] choiceFormats)
|
||||
{
|
||||
super ();
|
||||
setChoices (choiceLimits, choiceFormats);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests this object for equality with the specified
|
||||
* object. This will be true if and only if:
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.</li>
|
||||
* <li>The specified object is an instance of <code>ChoiceFormat</code>.</li>
|
||||
* <li>The termination ranges and format strings are identical to
|
||||
* this object's. </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The object to test for equality against.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to
|
||||
* this one, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof ChoiceFormat))
|
||||
return false;
|
||||
ChoiceFormat cf = (ChoiceFormat) obj;
|
||||
if (choiceLimits.length != cf.choiceLimits.length)
|
||||
return false;
|
||||
for (int i = choiceLimits.length - 1; i >= 0; --i)
|
||||
{
|
||||
if (choiceLimits[i] != cf.choiceLimits[i]
|
||||
|| !choiceFormats[i].equals(cf.choiceFormats[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends the appropriate format string to the specified
|
||||
* <code>StringBuffer</code> based on the supplied <code>long</code>
|
||||
* argument.
|
||||
*
|
||||
* @param number The number used for determine (based on the range
|
||||
* terminators) which format string to append.
|
||||
* @param sb The <code>StringBuffer</code> to append the format string to.
|
||||
* @param status Unused.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> with the format string appended.
|
||||
*/
|
||||
public StringBuffer format (long num, StringBuffer appendBuf,
|
||||
FieldPosition pos)
|
||||
{
|
||||
return format ((double) num, appendBuf, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends the appropriate format string to the specified
|
||||
* <code>StringBuffer</code> based on the supplied <code>double</code>
|
||||
* argument.
|
||||
*
|
||||
* @param number The number used for determine (based on the range
|
||||
* terminators) which format string to append.
|
||||
* @param sb The <code>StringBuffer</code> to append the format string to.
|
||||
* @param status Unused.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> with the format string appended.
|
||||
*/
|
||||
public StringBuffer format (double num, StringBuffer appendBuf,
|
||||
FieldPosition pos)
|
||||
{
|
||||
if (choiceLimits.length == 0)
|
||||
return appendBuf;
|
||||
|
||||
int index = 0;
|
||||
if (! Double.isNaN(num) && num >= choiceLimits[0])
|
||||
{
|
||||
for (; index < choiceLimits.length - 1; ++index)
|
||||
{
|
||||
if (choiceLimits[index] <= num && num < choiceLimits[index + 1])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return appendBuf.append(choiceFormats[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of format strings in use.
|
||||
*
|
||||
* @return The list of format objects.
|
||||
*/
|
||||
public Object[] getFormats ()
|
||||
{
|
||||
return (Object[]) choiceFormats.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of range terminators in use.
|
||||
*
|
||||
* @return The list of range terminators.
|
||||
*/
|
||||
public double[] getLimits ()
|
||||
{
|
||||
return (double[]) choiceLimits.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
int hash = 0;
|
||||
for (int i = 0; i < choiceLimits.length; ++i)
|
||||
{
|
||||
long v = Double.doubleToLongBits(choiceLimits[i]);
|
||||
hash ^= (v ^ (v >>> 32));
|
||||
hash ^= choiceFormats[i].hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the lowest possible double greater than the
|
||||
* specified double. If the specified double value is equal to
|
||||
* <code>Double.NaN</code> then that is the value returned.
|
||||
*
|
||||
* @param d The specified double
|
||||
*
|
||||
* @return The lowest double value greater than the specified double.
|
||||
*/
|
||||
public static final double nextDouble (double d)
|
||||
{
|
||||
return nextDouble (d, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a double that is either the next highest double
|
||||
* or next lowest double compared to the specified double depending on the
|
||||
* value of the passed boolean parameter. If the boolean parameter is
|
||||
* <code>true</code>, then the lowest possible double greater than the
|
||||
* specified double will be returned. Otherwise the highest possible
|
||||
* double less than the specified double will be returned.
|
||||
*
|
||||
* @param d The specified double
|
||||
* @param positive <code>true</code> to return the next highest
|
||||
* double, <code>false</code> otherwise.
|
||||
*
|
||||
* @return The next highest or lowest double value.
|
||||
*/
|
||||
public static double nextDouble (double d, boolean next)
|
||||
{
|
||||
if (Double.isInfinite(d) || Double.isNaN(d))
|
||||
return d;
|
||||
|
||||
long bits = Double.doubleToLongBits(d);
|
||||
|
||||
long mantMask = (1L << mantissaBits) - 1;
|
||||
long mantissa = bits & mantMask;
|
||||
|
||||
long expMask = (1L << exponentBits) - 1;
|
||||
long exponent = (bits >>> mantissaBits) & expMask;
|
||||
|
||||
if (next ^ (bits < 0)) // Increment magnitude
|
||||
{
|
||||
if (mantissa == (1L << mantissaBits) - 1)
|
||||
{
|
||||
mantissa = 0L;
|
||||
exponent++;
|
||||
|
||||
// Check for absolute overflow.
|
||||
if (exponent >= (1L << mantissaBits))
|
||||
return (bits > 0) ? Double.POSITIVE_INFINITY
|
||||
: Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
else
|
||||
mantissa++;
|
||||
}
|
||||
else // Decrement magnitude
|
||||
{
|
||||
if (exponent == 0L && mantissa == 0L)
|
||||
{
|
||||
// The only case where there is a change of sign
|
||||
return next ? Double.MIN_VALUE : -Double.MIN_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mantissa == 0L)
|
||||
{
|
||||
mantissa = (1L << mantissaBits) - 1;
|
||||
exponent--;
|
||||
}
|
||||
else
|
||||
mantissa--;
|
||||
}
|
||||
}
|
||||
|
||||
long result = bits < 0 ? 1 : 0;
|
||||
result = (result << exponentBits) | exponent;
|
||||
result = (result << mantissaBits) | mantissa;
|
||||
return Double.longBitsToDouble(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* I'm not sure what this method is really supposed to do, as it is
|
||||
* not documented.
|
||||
*/
|
||||
public Number parse (String sourceStr, ParsePosition pos)
|
||||
{
|
||||
int index = pos.getIndex();
|
||||
for (int i = 0; i < choiceLimits.length; ++i)
|
||||
{
|
||||
if (sourceStr.startsWith(choiceFormats[i], index))
|
||||
{
|
||||
pos.setIndex(index + choiceFormats[i].length());
|
||||
return new Double (choiceLimits[i]);
|
||||
}
|
||||
}
|
||||
pos.setErrorIndex(index);
|
||||
return new Double (Double.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the highest possible double less than the
|
||||
* specified double. If the specified double value is equal to
|
||||
* <code>Double.NaN</code> then that is the value returned.
|
||||
*
|
||||
* @param d The specified double
|
||||
*
|
||||
* @return The highest double value less than the specified double.
|
||||
*/
|
||||
public static final double previousDouble (double d)
|
||||
{
|
||||
return nextDouble (d, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets new range terminators and format strings for this
|
||||
* object.
|
||||
*
|
||||
* @param choiceLimits The new range terminators
|
||||
* @param choiceFormats The new choice formats
|
||||
*/
|
||||
public void setChoices (double[] choiceLimits, String[] choiceFormats)
|
||||
{
|
||||
if (choiceLimits == null || choiceFormats == null)
|
||||
throw new NullPointerException ();
|
||||
if (choiceLimits.length != choiceFormats.length)
|
||||
throw new IllegalArgumentException ();
|
||||
this.choiceFormats = (String[]) choiceFormats.clone();
|
||||
this.choiceLimits = (double[]) choiceLimits.clone();
|
||||
}
|
||||
|
||||
private void quoteString (StringBuffer dest, String text)
|
||||
{
|
||||
int max = text.length();
|
||||
for (int i = 0; i < max; ++i)
|
||||
{
|
||||
char c = text.charAt(i);
|
||||
if (c == '\'')
|
||||
{
|
||||
dest.append(c);
|
||||
dest.append(c);
|
||||
}
|
||||
else if (c == '#' || c == '|' || c == '\u2064' || c == '<')
|
||||
{
|
||||
dest.append('\'');
|
||||
dest.append(c);
|
||||
dest.append('\'');
|
||||
}
|
||||
else
|
||||
dest.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the range terminator list and format string list
|
||||
* as a <code>String</code> suitable for using with the
|
||||
* <code>applyPattern</code> method.
|
||||
*
|
||||
* @return A pattern string for this object
|
||||
*/
|
||||
public String toPattern ()
|
||||
{
|
||||
StringBuffer result = new StringBuffer ();
|
||||
for (int i = 0; i < choiceLimits.length; ++i)
|
||||
{
|
||||
result.append(choiceLimits[i]);
|
||||
result.append('#');
|
||||
quoteString (result, choiceFormats[i]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the list of format strings. Note that this variable is
|
||||
* specified by the serialization spec of this class.
|
||||
*/
|
||||
private String[] choiceFormats;
|
||||
|
||||
/**
|
||||
* This is the list of range terminator values. Note that this variable is
|
||||
* specified by the serialization spec of this class.
|
||||
*/
|
||||
private double[] choiceLimits;
|
||||
|
||||
// Number of mantissa bits in double.
|
||||
private static final int mantissaBits = 52;
|
||||
// Number of exponent bits in a double.
|
||||
private static final int exponentBits = 11;
|
||||
|
||||
private static final long serialVersionUID = 1795184449645032964L;
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
/* CollationElementIterator.java -- Walks through collation elements
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.ArrayList;
|
||||
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to JDK 1.1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class walks through the character collation elements of a
|
||||
* <code>String</code> as defined by the collation rules in an instance of
|
||||
* <code>RuleBasedCollator</code>. There is no public constructor for
|
||||
* this class. An instance is created by calling the
|
||||
* <code>getCollationElementIterator</code> method on
|
||||
* <code>RuleBasedCollator</code>.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Guilhem Lavaux (guilhem.lavaux@free.fr)
|
||||
*/
|
||||
public final class CollationElementIterator
|
||||
{
|
||||
/**
|
||||
* This is a constant value that is returned to indicate that the end of
|
||||
* the string was encountered.
|
||||
*/
|
||||
public static final int NULLORDER = -1;
|
||||
|
||||
/**
|
||||
* This is the RuleBasedCollator this object was created from.
|
||||
*/
|
||||
RuleBasedCollator collator;
|
||||
|
||||
/**
|
||||
* This is the String that is being iterated over.
|
||||
*/
|
||||
String text;
|
||||
|
||||
/**
|
||||
* This is the index into the collation decomposition where we are currently scanning.
|
||||
*/
|
||||
int index;
|
||||
|
||||
/**
|
||||
* This is the index into the String where we are currently scanning.
|
||||
*/
|
||||
int textIndex;
|
||||
|
||||
/**
|
||||
* Array containing the collation decomposition of the
|
||||
* text given to the constructor.
|
||||
*/
|
||||
private RuleBasedCollator.CollationElement[] text_decomposition;
|
||||
|
||||
/**
|
||||
* Array containing the index of the specified block.
|
||||
*/
|
||||
private int[] text_indexes;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>CollationElementIterator</code>
|
||||
* to iterate over the specified <code>String</code> using the rules in the
|
||||
* specified <code>RuleBasedCollator</code>.
|
||||
*
|
||||
* @param collator The <code>RuleBasedCollation</code> used for calculating collation values
|
||||
* @param text The <code>String</code> to iterate over.
|
||||
*/
|
||||
CollationElementIterator(RuleBasedCollator collator, String text)
|
||||
{
|
||||
this.collator = collator;
|
||||
|
||||
setText (text);
|
||||
}
|
||||
|
||||
RuleBasedCollator.CollationElement nextBlock()
|
||||
{
|
||||
if (index >= text_decomposition.length)
|
||||
return null;
|
||||
|
||||
RuleBasedCollator.CollationElement e = text_decomposition[index];
|
||||
|
||||
textIndex = text_indexes[index+1];
|
||||
|
||||
index++;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
RuleBasedCollator.CollationElement previousBlock()
|
||||
{
|
||||
if (index == 0)
|
||||
return null;
|
||||
|
||||
index--;
|
||||
RuleBasedCollator.CollationElement e = text_decomposition[index];
|
||||
|
||||
textIndex = text_indexes[index+1];
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the collation ordering value of the next character sequence
|
||||
* in the string (it may be an extended character following collation rules).
|
||||
* This method will return <code>NULLORDER</code> if the
|
||||
* end of the string was reached.
|
||||
*
|
||||
* @return The collation ordering value.
|
||||
*/
|
||||
public int next()
|
||||
{
|
||||
RuleBasedCollator.CollationElement e = nextBlock();
|
||||
|
||||
if (e == null)
|
||||
return NULLORDER;
|
||||
|
||||
return e.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the collation ordering value of the previous character
|
||||
* in the string. This method will return <code>NULLORDER</code> if the
|
||||
* beginning of the string was reached.
|
||||
*
|
||||
* @return The collation ordering value.
|
||||
*/
|
||||
public int previous()
|
||||
{
|
||||
RuleBasedCollator.CollationElement e = previousBlock();
|
||||
|
||||
if (e == null)
|
||||
return NULLORDER;
|
||||
|
||||
return e.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the primary order value for the given collation
|
||||
* value.
|
||||
*
|
||||
* @param value The collation value returned from <code>next()</code> or <code>previous()</code>.
|
||||
*
|
||||
* @return The primary order value of the specified collation value. This is the high 16 bits.
|
||||
*/
|
||||
public static int primaryOrder(int order)
|
||||
{
|
||||
// From the JDK 1.2 spec.
|
||||
return order >>> 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method resets the internal position pointer to read from the
|
||||
* beginning of the <code>String</code> again.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
index = 0;
|
||||
textIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the secondary order value for the given collation
|
||||
* value.
|
||||
*
|
||||
* @param value The collation value returned from <code>next()</code> or <code>previous()</code>.
|
||||
*
|
||||
* @return The secondary order value of the specified collation value. This is the bits 8-15.
|
||||
*/
|
||||
public static short secondaryOrder(int order)
|
||||
{
|
||||
// From the JDK 1.2 spec.
|
||||
return (short) ((order >>> 8) & 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the tertiary order value for the given collation
|
||||
* value.
|
||||
*
|
||||
* @param value The collation value returned from <code>next()</code> or <code>previous()</code>.
|
||||
*
|
||||
* @return The tertiary order value of the specified collation value. This is the low eight bits.
|
||||
*/
|
||||
public static short tertiaryOrder(int order)
|
||||
{
|
||||
// From the JDK 1.2 spec.
|
||||
return (short) (order & 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the <code>String</code> that it is iterating over
|
||||
* to the specified <code>String</code>.
|
||||
*
|
||||
* @param text The new <code>String</code> to iterate over.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public void setText(String text)
|
||||
{
|
||||
int idx = 0;
|
||||
int idx_idx = 0;
|
||||
int alreadyExpanded = 0;
|
||||
int idxToMove = 0;
|
||||
|
||||
this.text = text;
|
||||
this.index = 0;
|
||||
|
||||
String work_text = text.intern();
|
||||
|
||||
ArrayList a_element = new ArrayList();
|
||||
ArrayList a_idx = new ArrayList();
|
||||
|
||||
// Build element collection ordered as they come in "text".
|
||||
while (idx < work_text.length())
|
||||
{
|
||||
String key, key_old;
|
||||
|
||||
Object object = null;
|
||||
int p = 1;
|
||||
|
||||
// IMPROVE: use a TreeMap with a prefix-ordering rule.
|
||||
key_old = key = null;
|
||||
do
|
||||
{
|
||||
if (object != null)
|
||||
key_old = key;
|
||||
key = work_text.substring (idx, idx+p);
|
||||
object = collator.prefix_tree.get (key);
|
||||
if (object != null && idx < alreadyExpanded)
|
||||
{
|
||||
RuleBasedCollator.CollationElement prefix = (RuleBasedCollator.CollationElement)object;
|
||||
if (prefix.expansion != null &&
|
||||
prefix.expansion.startsWith(work_text.substring(0, idx)))
|
||||
{
|
||||
object = null;
|
||||
key = key_old;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
while (idx+p <= work_text.length());
|
||||
|
||||
if (object == null)
|
||||
key = key_old;
|
||||
|
||||
RuleBasedCollator.CollationElement prefix =
|
||||
(RuleBasedCollator.CollationElement) collator.prefix_tree.get (key);
|
||||
|
||||
/*
|
||||
* First case: There is no such sequence in the database.
|
||||
* We will have to build one from the context.
|
||||
*/
|
||||
if (prefix == null)
|
||||
{
|
||||
/*
|
||||
* We are dealing with sequences in an expansion. They
|
||||
* are treated as accented characters (tertiary order).
|
||||
*/
|
||||
if (alreadyExpanded > 0)
|
||||
{
|
||||
RuleBasedCollator.CollationElement e =
|
||||
collator.getDefaultAccentedElement (work_text.charAt (idx));
|
||||
|
||||
a_element.add (e);
|
||||
a_idx.add (new Integer(idx_idx));
|
||||
idx++;
|
||||
alreadyExpanded--;
|
||||
if (alreadyExpanded == 0)
|
||||
{
|
||||
/* There is not any characters left in the expansion set.
|
||||
* We can increase the pointer in the source string.
|
||||
*/
|
||||
idx_idx += idxToMove;
|
||||
idxToMove = 0;
|
||||
}
|
||||
else
|
||||
idx_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a normal character. */
|
||||
RuleBasedCollator.CollationElement e =
|
||||
collator.getDefaultElement (work_text.charAt (idx));
|
||||
Integer i_ref = new Integer(idx_idx);
|
||||
|
||||
/* Don't forget to mark it as a special sequence so the
|
||||
* string can be ordered.
|
||||
*/
|
||||
a_element.add (RuleBasedCollator.SPECIAL_UNKNOWN_SEQ);
|
||||
a_idx.add (i_ref);
|
||||
a_element.add (e);
|
||||
a_idx.add (i_ref);
|
||||
idx_idx++;
|
||||
idx++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Second case: Here we have found a matching sequence.
|
||||
* Here we have an expansion string prepend it to the "work text" and
|
||||
* add the corresponding sorting element. We must also mark
|
||||
*/
|
||||
if (prefix.expansion != null)
|
||||
{
|
||||
work_text = prefix.expansion
|
||||
+ work_text.substring (idx+prefix.key.length());
|
||||
idx = 0;
|
||||
a_element.add (prefix);
|
||||
a_idx.add (new Integer(idx_idx));
|
||||
if (alreadyExpanded == 0)
|
||||
idxToMove = prefix.key.length();
|
||||
alreadyExpanded += prefix.expansion.length()-prefix.key.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Third case: the simplest. We have got the prefix and it
|
||||
* has not to be expanded.
|
||||
*/
|
||||
a_element.add (prefix);
|
||||
a_idx.add (new Integer(idx_idx));
|
||||
idx += prefix.key.length();
|
||||
/* If the sequence is in an expansion, we must decrease the
|
||||
* counter.
|
||||
*/
|
||||
if (alreadyExpanded > 0)
|
||||
{
|
||||
alreadyExpanded -= prefix.key.length();
|
||||
if (alreadyExpanded == 0)
|
||||
{
|
||||
idx_idx += idxToMove;
|
||||
idxToMove = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
idx_idx += prefix.key.length();
|
||||
}
|
||||
}
|
||||
|
||||
text_decomposition = (RuleBasedCollator.CollationElement[])
|
||||
a_element.toArray(new RuleBasedCollator.CollationElement[a_element.size()]);
|
||||
text_indexes = new int[a_idx.size()+1];
|
||||
for (int i = 0; i < a_idx.size(); i++)
|
||||
{
|
||||
text_indexes[i] = ((Integer)a_idx.get(i)).intValue();
|
||||
}
|
||||
text_indexes[a_idx.size()] = text.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the <code>String</code> that it is iterating over
|
||||
* to the <code>String</code> represented by the specified
|
||||
* <code>CharacterIterator</code>.
|
||||
*
|
||||
* @param source The <code>CharacterIterator</code> containing the new
|
||||
* <code>String</code> to iterate over.
|
||||
*/
|
||||
public void setText(CharacterIterator source)
|
||||
{
|
||||
StringBuffer expand = new StringBuffer();
|
||||
|
||||
// For now assume we read from the beginning of the string.
|
||||
for (char c = source.first();
|
||||
c != CharacterIterator.DONE;
|
||||
c = source.next())
|
||||
expand.append(c);
|
||||
|
||||
setText(expand.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current offset into the <code>String</code>
|
||||
* that is being iterated over.
|
||||
*
|
||||
* @return The iteration index position.
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public int getOffset()
|
||||
{
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the iteration index position into the current
|
||||
* <code>String</code> to the specified value. This value must not
|
||||
* be negative and must not be greater than the last index position
|
||||
* in the <code>String</code>.
|
||||
*
|
||||
* @param offset The new iteration index position.
|
||||
*
|
||||
* @exception IllegalArgumentException If the new offset is not valid.
|
||||
*/
|
||||
public void setOffset(int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
throw new IllegalArgumentException("Negative offset: " + offset);
|
||||
|
||||
if (offset > (text.length() - 1))
|
||||
throw new IllegalArgumentException("Offset too large: " + offset);
|
||||
|
||||
for (index = 0; index < text_decomposition.length; index++)
|
||||
{
|
||||
if (offset <= text_indexes[index])
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* As text_indexes[0] == 0, we should not have to take care whether index is
|
||||
* greater than 0. It is always.
|
||||
*/
|
||||
if (text_indexes[index] == offset)
|
||||
textIndex = offset;
|
||||
else
|
||||
textIndex = text_indexes[index-1];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the maximum length of any expansion sequence that
|
||||
* ends with the specified collation order value. (Whatever that means).
|
||||
*
|
||||
* @param value The collation order value
|
||||
*
|
||||
* @param The maximum length of an expansion sequence.
|
||||
*/
|
||||
public int getMaxExpansion(int value)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/* CollationKey.java -- Precomputed collation value
|
||||
Copyright (C) 1998, 1999, 2000, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents a pre-computed series of bits representing a
|
||||
* <code>String</code> for under a particular <code>Collator</code>. This
|
||||
* value may be compared bitwise against another <code>CollationKey</code>
|
||||
* representing a different <code>String</code> under the same
|
||||
* <code>Collator</code> in a manner than is usually more efficient than
|
||||
* using the raw <code>Collator</code> compare methods. There is overhead
|
||||
* associated with calculating this value, so it is generally not
|
||||
* advisable to compute <code>CollationKey</code>'s unless multiple
|
||||
* comparisons against a <code>String</code> will be done. (For example,
|
||||
* in a sort routine).
|
||||
* <p>
|
||||
* This class cannot be instantiated directly. Instead, a
|
||||
* <code>CollationKey</code> is created by calling the
|
||||
* <code>getCollationKey</code> method on an instance of <code>Collator</code>.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @date March 25, 1999
|
||||
*/
|
||||
public final class CollationKey implements Comparable
|
||||
{
|
||||
/**
|
||||
* This is the <code>Collator</code> this object was created from.
|
||||
*/
|
||||
private Collator collator;
|
||||
|
||||
/**
|
||||
* This is the <code>String</code> this object represents.
|
||||
*/
|
||||
private String originalText;
|
||||
|
||||
/**
|
||||
* This is the bit value for this key.
|
||||
*/
|
||||
private byte[] key;
|
||||
|
||||
CollationKey (Collator collator, String originalText, byte[] key)
|
||||
{
|
||||
this.collator = collator;
|
||||
this.originalText = originalText;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the specified object to this one. An integer is
|
||||
* returned which indicates whether the specified object is less than,
|
||||
* greater than, or equal to this object.
|
||||
*
|
||||
* @param ck The <code>CollationKey</code> to compare against this one.
|
||||
*
|
||||
* @return A negative integer if this object is less than the specified object, 0 if it is equal or a positive integer if it is greater than the specified object.
|
||||
*/
|
||||
public int compareTo (CollationKey ck)
|
||||
{
|
||||
int max = Math.min (key.length, ck.key.length);
|
||||
|
||||
for (int i = 0; i < max; ++i)
|
||||
{
|
||||
if (key[i] != ck.key[i])
|
||||
return key[i] - ck.key[i];
|
||||
}
|
||||
|
||||
return key.length - ck.key.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the specified object to this one. The specified
|
||||
* object must be an instance of <code>CollationKey</code> or an exception
|
||||
* will be thrown. An integer is returned which indicates whether the
|
||||
* specified object is less than, greater than, or equal to this object.
|
||||
*
|
||||
* @param obj The <code>Object</code> to compare against this one.
|
||||
*
|
||||
* @return A negative integer if this object is less than the specified object, 0 if it is equal or a positive integer if it is greater than the specified object.
|
||||
*/
|
||||
public int compareTo (Object obj)
|
||||
{
|
||||
return compareTo ((CollationKey) obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests the specified <code>Object</code> for equality with
|
||||
* this object. This will be true if and only if:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The specified object must not be <code>null</code></li>
|
||||
* <li>The specified object is an instance of <code>CollationKey</code>.</li>
|
||||
* <li>The specified object was created from the same <code>Collator</code>
|
||||
* as this object.</li>
|
||||
* <li>The specified object has the same source string and bit key as
|
||||
* this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The <code>Object</code> to test for equality.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this one, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof CollationKey))
|
||||
return false;
|
||||
|
||||
CollationKey ck = (CollationKey) obj;
|
||||
|
||||
if (ck.collator != collator)
|
||||
return false;
|
||||
|
||||
if (!ck.getSourceString ().equals (getSourceString ()))
|
||||
return false;
|
||||
|
||||
if (!ck.toByteArray ().equals (toByteArray ()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the <code>String</code> that this object was created
|
||||
* from.
|
||||
*
|
||||
* @return The source <code>String</code> for this object.
|
||||
*/
|
||||
public String getSourceString()
|
||||
{
|
||||
return originalText;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object. The hash value
|
||||
* returned will be the hash code of the bit key so that identical bit
|
||||
* keys will return the same value.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
// We just follow BitSet instead of thinking up something new.
|
||||
long h = originalText.hashCode();
|
||||
for (int i = key.length - 1; i >= 0; --i)
|
||||
h ^= key[i] * (i + 1);
|
||||
return (int) ((h >> 32) ^ h);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the collation bit sequence as a byte array.
|
||||
*
|
||||
* @param A byte array containing the collation bit sequence.
|
||||
*/
|
||||
public byte[] toByteArray()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
/* Collator.java -- Perform locale dependent String comparisons.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.Comparator;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* This class is the abstract superclass of classes which perform
|
||||
* locale dependent <code>String</code> comparisons. A caller requests
|
||||
* an instance of <code>Collator</code> for a particular locale using
|
||||
* the <code>getInstance()</code> static method in this class. That method
|
||||
* will return a locale specific subclass of <code>Collator</code> which
|
||||
* can be used to perform <code>String</code> comparisons for that locale.
|
||||
* If a subclass of <code>Collator</code> cannot be located for a particular
|
||||
* locale, a default instance for the current locale will be returned.
|
||||
*
|
||||
* In addition to setting the correct locale, there are two additional
|
||||
* settings that can be adjusted to affect <code>String</code> comparisons:
|
||||
* strength and decomposition. The strength value determines the level
|
||||
* of signficance of character differences required for them to sort
|
||||
* differently. (For example, whether or not capital letters are considered
|
||||
* different from lower case letters). The decomposition value affects how
|
||||
* variants of the same character are treated for sorting purposes. (For
|
||||
* example, whether or not an accent is signficant or not). These settings
|
||||
* are described in detail in the documentation for the methods and values
|
||||
* that are related to them.
|
||||
*
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @date March 18, 1999
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Mostly complete, but parts stubbed out. Look for FIXME.
|
||||
*/
|
||||
public abstract class Collator implements Comparator, Cloneable
|
||||
{
|
||||
/**
|
||||
* This constant is a strength value which indicates that only primary
|
||||
* differences between characters will be considered signficant. As an
|
||||
* example, two completely different English letters such as 'a' and 'b'
|
||||
* are considered to have a primary difference.
|
||||
*/
|
||||
public static final int PRIMARY = 0;
|
||||
|
||||
/**
|
||||
* This constant is a strength value which indicates that only secondary
|
||||
* or primary differences between characters will be considered
|
||||
* significant. An example of a secondary difference between characters
|
||||
* are instances of the same letter with different accented forms.
|
||||
*/
|
||||
public static final int SECONDARY = 1;
|
||||
|
||||
/**
|
||||
* This constant is a strength value which indicates that tertiary,
|
||||
* secondary, and primary differences will be considered during sorting.
|
||||
* An example of a tertiary difference is capitalization of a given letter.
|
||||
* This is the default value for the strength setting.
|
||||
*/
|
||||
public static final int TERTIARY = 2;
|
||||
|
||||
/**
|
||||
* This constant is a strength value which indicates that any difference
|
||||
* at all between character values are considered significant.
|
||||
*/
|
||||
public static final int IDENTICAL = 3;
|
||||
|
||||
/**
|
||||
* This constant indicates that accented characters won't be decomposed
|
||||
* when performing comparisons. This will yield the fastest results, but
|
||||
* will only work correctly in call cases for languages which do not
|
||||
* use accents such as English.
|
||||
*/
|
||||
public static final int NO_DECOMPOSITION = 0;
|
||||
|
||||
/**
|
||||
* This constant indicates that only characters which are canonical variants
|
||||
* in Unicode 2.0 will be decomposed prior to performing comparisons. This
|
||||
* will cause accented languages to be sorted correctly. This is the
|
||||
* default decomposition value.
|
||||
*/
|
||||
public static final int CANONICAL_DECOMPOSITION = 1;
|
||||
|
||||
/**
|
||||
* This constant indicates that both canonical variants and compatibility
|
||||
* variants in Unicode 2.0 will be decomposed prior to performing
|
||||
* comparisons. This is the slowest mode, but is required to get the
|
||||
* correct sorting for certain languages with certain special formats.
|
||||
*/
|
||||
public static final int FULL_DECOMPOSITION = 2;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>Collator</code> to have
|
||||
* the default strength (TERTIARY) and decomposition
|
||||
* (CANONICAL_DECOMPOSITION) settings. This constructor is protected and
|
||||
* is for use by subclasses only. Non-subclass callers should use the
|
||||
* static <code>getInstance()</code> methods of this class to instantiate
|
||||
* <code>Collation</code> objects for the desired locale.
|
||||
*/
|
||||
protected Collator ()
|
||||
{
|
||||
strength = TERTIARY;
|
||||
decmp = CANONICAL_DECOMPOSITION;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the two <code>String</code>'s and returns an
|
||||
* integer indicating whether or not the first argument is less than,
|
||||
* equal to, or greater than the second argument. The comparison is
|
||||
* performed according to the rules of the locale for this
|
||||
* <code>Collator</code> and the strength and decomposition rules in
|
||||
* effect.
|
||||
*
|
||||
* @param str1 The first object to compare
|
||||
* @param str2 The second object to compare
|
||||
*
|
||||
* @return A negative integer if str1 < str2, 0 if str1 == str2, or
|
||||
* a positive integer if str1 > str2.
|
||||
*/
|
||||
public abstract int compare (String source, String target);
|
||||
|
||||
/**
|
||||
* This method compares the two <code>Object</code>'s and returns an
|
||||
* integer indicating whether or not the first argument is less than,
|
||||
* equal to, or greater than the second argument. These two objects
|
||||
* must be <code>String</code>'s or an exception will be thrown.
|
||||
*
|
||||
* @param obj1 The first object to compare
|
||||
* @param obj2 The second object to compare
|
||||
*
|
||||
* @return A negative integer if obj1 < obj2, 0 if obj1 == obj2, or
|
||||
* a positive integer if obj1 > obj2.
|
||||
*
|
||||
* @exception ClassCastException If the arguments are not instances
|
||||
* of <code>String</code>.
|
||||
*/
|
||||
public int compare (Object o1, Object o2)
|
||||
{
|
||||
return compare ((String) o1, (String) o2);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests the specified object for equality against this
|
||||
* object. This will be true if and only if the following conditions are
|
||||
* met:
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.</li>
|
||||
* <li>The specified object is an instance of <code>Collator</code>.</li>
|
||||
* <li>The specified object has the same strength and decomposition
|
||||
* settings as this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The <code>Object</code> to test for equality against
|
||||
* this object.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to
|
||||
* this one, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof Collator))
|
||||
return false;
|
||||
Collator c = (Collator) obj;
|
||||
return decmp == c.decmp && strength == c.strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests whether the specified <code>String</code>'s are equal
|
||||
* according to the collation rules for the locale of this object and
|
||||
* the current strength and decomposition settings.
|
||||
*
|
||||
* @param str1 The first <code>String</code> to compare
|
||||
* @param str2 The second <code>String</code> to compare
|
||||
*
|
||||
* @return <code>true</code> if the two strings are equal,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (String source, String target)
|
||||
{
|
||||
return compare (source, target) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a copy of this <code>Collator</code> object.
|
||||
*
|
||||
* @return A duplicate of this object.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone ();
|
||||
}
|
||||
catch (CloneNotSupportedException _)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an array of <code>Locale</code> objects which is
|
||||
* the list of locales for which <code>Collator</code> objects exist.
|
||||
*
|
||||
* @return The list of locales for which <code>Collator</code>'s exist.
|
||||
*/
|
||||
public static synchronized Locale[] getAvailableLocales ()
|
||||
{
|
||||
// FIXME
|
||||
Locale[] l = new Locale[1];
|
||||
l[0] = Locale.US;
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method transforms the specified <code>String</code> into a
|
||||
* <code>CollationKey</code> for faster comparisons. This is useful when
|
||||
* comparisons against a string might be performed multiple times, such
|
||||
* as during a sort operation.
|
||||
*
|
||||
* @param str The <code>String</code> to convert.
|
||||
*
|
||||
* @return A <code>CollationKey</code> for the specified <code>String</code>.
|
||||
*/
|
||||
public abstract CollationKey getCollationKey (String source);
|
||||
|
||||
/**
|
||||
* This method returns the current decomposition setting for this
|
||||
* object. This * will be one of NO_DECOMPOSITION,
|
||||
* CANONICAL_DECOMPOSITION, or * FULL_DECOMPOSITION. See the
|
||||
* documentation for those constants for an * explanation of this
|
||||
* setting.
|
||||
*
|
||||
* @return The current decomposition setting.
|
||||
*/
|
||||
public synchronized int getDecomposition ()
|
||||
{
|
||||
return decmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>Collator</code> for the
|
||||
* default locale.
|
||||
*
|
||||
* @return A <code>Collator</code> for the default locale.
|
||||
*/
|
||||
public static Collator getInstance ()
|
||||
{
|
||||
return getInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>Collator</code> for the
|
||||
* specified locale. If no <code>Collator</code> exists for the desired
|
||||
* locale, a <code>Collator</code> for the default locale will be returned.
|
||||
*
|
||||
* @param locale The desired localed to load a <code>Collator</code> for.
|
||||
*
|
||||
* @return A <code>Collator</code> for the requested locale
|
||||
*/
|
||||
public static Collator getInstance (Locale loc)
|
||||
{
|
||||
ResourceBundle res;
|
||||
String pattern;
|
||||
try
|
||||
{
|
||||
res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
|
||||
loc, ClassLoader.getSystemClassLoader());
|
||||
pattern = res.getString("collation_rules");
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
pattern = "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" +
|
||||
"<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y<z,Z";
|
||||
}
|
||||
try
|
||||
{
|
||||
return new RuleBasedCollator (pattern);
|
||||
}
|
||||
catch (ParseException x)
|
||||
{
|
||||
throw (InternalError)new InternalError().initCause(x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current strength setting for this object. This
|
||||
* will be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL. See the
|
||||
* documentation for those constants for an explanation of this setting.
|
||||
*
|
||||
* @return The current strength setting.
|
||||
*/
|
||||
public synchronized int getStrength ()
|
||||
{
|
||||
return strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash code value for this object.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public abstract int hashCode ();
|
||||
|
||||
/**
|
||||
* This method sets the decomposition setting for this object to the
|
||||
* specified value. This must be one of NO_DECOMPOSITION,
|
||||
* CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION. Otherwise an
|
||||
* exception will be thrown. See the documentation for those
|
||||
* contants for an explanation of this setting.
|
||||
*
|
||||
* @param decmp The new decomposition setting.
|
||||
*
|
||||
* @exception IllegalArgumentException If the requested
|
||||
* decomposition setting is not valid.
|
||||
*/
|
||||
public synchronized void setDecomposition (int mode)
|
||||
{
|
||||
if (mode != NO_DECOMPOSITION
|
||||
&& mode != CANONICAL_DECOMPOSITION
|
||||
&& mode != FULL_DECOMPOSITION)
|
||||
throw new IllegalArgumentException ();
|
||||
decmp = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the strength setting for this object to the specified
|
||||
* value. This must be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.
|
||||
* Otherwise an exception is thrown. See the documentation for these
|
||||
* constants for an explanation of this setting.
|
||||
*
|
||||
* @param strength The new strength setting.
|
||||
*
|
||||
* @exception IllegalArgumentException If the requested strength
|
||||
* setting value is not valid.
|
||||
*/
|
||||
public synchronized void setStrength (int strength)
|
||||
{
|
||||
if (strength != PRIMARY && strength != SECONDARY
|
||||
&& strength != TERTIARY && strength != IDENTICAL)
|
||||
throw new IllegalArgumentException ();
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
// Decompose a single character and append results to the buffer.
|
||||
// FIXME: for libgcj this is a native method which handles
|
||||
// decomposition. For Classpath, for now, it does nothing.
|
||||
final void decomposeCharacter (char c, StringBuffer buf)
|
||||
{
|
||||
buf.append (c);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the current collation decomposition setting.
|
||||
*/
|
||||
int decmp;
|
||||
|
||||
/**
|
||||
* This is the current collation strength setting.
|
||||
*/
|
||||
int strength;
|
||||
}
|
||||
@@ -0,0 +1,892 @@
|
||||
/* DateFormat.java -- Class for formatting/parsing date/times
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.InvalidObjectException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
* @date October 25, 1998.
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 beta from http://www.javasoft.com.
|
||||
* Status: Mostly complete; search for FIXME to see omissions.
|
||||
*/
|
||||
|
||||
public abstract class DateFormat extends Format implements Cloneable
|
||||
{
|
||||
protected Calendar calendar;
|
||||
protected NumberFormat numberFormat;
|
||||
|
||||
// (Values determined using a test program.)
|
||||
public static final int FULL = 0;
|
||||
public static final int LONG = 1;
|
||||
public static final int MEDIUM = 2;
|
||||
public static final int SHORT = 3;
|
||||
public static final int DEFAULT = MEDIUM;
|
||||
|
||||
/* These constants need to have these exact values. They
|
||||
* correspond to index positions within the localPatternChars
|
||||
* string for a given locale. Each locale may specify its
|
||||
* own character for a particular field, but the position
|
||||
* of these characters must correspond to an appropriate field
|
||||
* number (as listed below), in order for their meaning to
|
||||
* be determined. For example, the US locale uses
|
||||
* the string "GyMdkHmsSEDFwWahKzYeugAZ", where 'G' is the character
|
||||
* for era, 'y' for year, and so on down to 'Z' for time zone.
|
||||
*/
|
||||
/**
|
||||
* Represents the position of the era
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* For example, 'AD' is an era used
|
||||
* in the Gregorian calendar system.
|
||||
* In the U.S. locale, this is 'G'.
|
||||
*/
|
||||
public static final int ERA_FIELD = 0;
|
||||
/**
|
||||
* Represents the position of the year
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'y'.
|
||||
*/
|
||||
public static final int YEAR_FIELD = 1;
|
||||
/**
|
||||
* Represents the position of the month
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'M'.
|
||||
*/
|
||||
public static final int MONTH_FIELD = 2;
|
||||
/**
|
||||
* Represents the position of the date
|
||||
* or day of the month pattern character
|
||||
* in the array of localized pattern
|
||||
* characters. In the U.S. locale,
|
||||
* this is 'd'.
|
||||
*/
|
||||
public static final int DATE_FIELD = 3;
|
||||
/**
|
||||
* Represents the position of the 24
|
||||
* hour pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'k'.
|
||||
* This field numbers hours from 1 to 24.
|
||||
*/
|
||||
public static final int HOUR_OF_DAY1_FIELD = 4;
|
||||
/**
|
||||
* Represents the position of the 24
|
||||
* hour pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'H'.
|
||||
* This field numbers hours from 0 to 23.
|
||||
*/
|
||||
public static final int HOUR_OF_DAY0_FIELD = 5;
|
||||
/**
|
||||
* Represents the position of the minute
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'm'.
|
||||
*/
|
||||
public static final int MINUTE_FIELD = 6;
|
||||
/**
|
||||
* Represents the position of the second
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 's'.
|
||||
*/
|
||||
public static final int SECOND_FIELD = 7;
|
||||
/**
|
||||
* Represents the position of the millisecond
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'S'.
|
||||
*/
|
||||
public static final int MILLISECOND_FIELD = 8;
|
||||
/**
|
||||
* Represents the position of the day of the
|
||||
* week pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'E'.
|
||||
*/
|
||||
public static final int DAY_OF_WEEK_FIELD = 9;
|
||||
/**
|
||||
* Represents the position of the day of the
|
||||
* year pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'D'.
|
||||
*/
|
||||
public static final int DAY_OF_YEAR_FIELD = 10;
|
||||
/**
|
||||
* Represents the position of the day of the
|
||||
* week in the month pattern character in the
|
||||
* array of localized pattern characters.
|
||||
* In the U.S. locale, this is 'F'.
|
||||
*/
|
||||
public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
|
||||
/**
|
||||
* Represents the position of the week of the
|
||||
* year pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'w'.
|
||||
*/
|
||||
public static final int WEEK_OF_YEAR_FIELD = 12;
|
||||
/**
|
||||
* Represents the position of the week of the
|
||||
* month pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'W'.
|
||||
*/
|
||||
public static final int WEEK_OF_MONTH_FIELD = 13;
|
||||
/**
|
||||
* Represents the position of the am/pm
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'a'.
|
||||
*/
|
||||
public static final int AM_PM_FIELD = 14;
|
||||
/**
|
||||
* Represents the position of the 12
|
||||
* hour pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'h'.
|
||||
* This field numbers hours from 1 to 12.
|
||||
*/
|
||||
public static final int HOUR1_FIELD = 15;
|
||||
/**
|
||||
* Represents the position of the 12
|
||||
* hour pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'K'.
|
||||
* This field numbers hours from 0 to 11.
|
||||
*/
|
||||
public static final int HOUR0_FIELD = 16;
|
||||
/**
|
||||
* Represents the position of the generic
|
||||
* timezone pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'z'.
|
||||
*/
|
||||
public static final int TIMEZONE_FIELD = 17;
|
||||
/**
|
||||
* Represents the position of the ISO year
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'Y'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. This value may
|
||||
* differ from the normal year value.
|
||||
*/
|
||||
public static final int ISO_YEAR_FIELD = 18;
|
||||
/**
|
||||
* Represents the position of the localized
|
||||
* day of the week pattern character in the
|
||||
* array of localized pattern characters.
|
||||
* In the U.S. locale, this is 'e'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. This value only
|
||||
* differs from the day of the week with
|
||||
* numeric formatting, in which case the
|
||||
* locale's first day of the week is used.
|
||||
*/
|
||||
public static final int LOCALIZED_DAY_OF_WEEK_FIELD = 19;
|
||||
/**
|
||||
* Represents the position of the extended year
|
||||
* pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'u'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. This value modifies
|
||||
* the year value, so as to incorporate the era.
|
||||
* For example, in the Gregorian calendar system,
|
||||
* the extended year is negative instead of being
|
||||
* marked as BC.
|
||||
*/
|
||||
public static final int EXTENDED_YEAR_FIELD = 20;
|
||||
/**
|
||||
* Represents the position of the modified Julian
|
||||
* day pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'g'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. This value differs
|
||||
* from the standard Julian day in that days
|
||||
* are marked from midnight onwards rather than
|
||||
* noon, and the local time zone affects the value.
|
||||
* In simple terms, it can be thought of as all
|
||||
* the date fields represented as a single number.
|
||||
*/
|
||||
public static final int MODIFIED_JULIAN_DAY_FIELD = 21;
|
||||
/**
|
||||
* Represents the position of the millisecond
|
||||
* in the day pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'A'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. This value represents
|
||||
* all the time fields (excluding the time zone)
|
||||
* numerically, giving the number of milliseconds
|
||||
* into the day (e.g. 10 in the morning would
|
||||
* be 10 * 60 * 60 * 1000). Any daylight savings
|
||||
* offset also affects this value.
|
||||
*/
|
||||
public static final int MILLISECOND_IN_DAY_FIELD = 22;
|
||||
/**
|
||||
* Represents the position of the RFC822
|
||||
* timezone pattern character in the array of
|
||||
* localized pattern characters.
|
||||
* In the U.S. locale, this is 'Z'.
|
||||
* This is a GNU extension in accordance with
|
||||
* the CLDR data used. The value is the offset
|
||||
* of the current time from GMT e.g. -0500 would
|
||||
* be five hours prior to GMT.
|
||||
*/
|
||||
public static final int RFC822_TIMEZONE_FIELD = 23;
|
||||
|
||||
public static class Field extends Format.Field
|
||||
{
|
||||
static final long serialVersionUID = 7441350119349544720L;
|
||||
|
||||
private int calendarField;
|
||||
|
||||
public static final DateFormat.Field ERA
|
||||
= new Field("era", Calendar.ERA);
|
||||
public static final DateFormat.Field YEAR
|
||||
= new Field("year", Calendar.YEAR);
|
||||
public static final DateFormat.Field MONTH
|
||||
= new Field("month", Calendar.MONTH);
|
||||
public static final DateFormat.Field DAY_OF_MONTH
|
||||
= new Field("day of month", Calendar.DAY_OF_MONTH);
|
||||
public static final DateFormat.Field HOUR_OF_DAY1
|
||||
= new Field("hour of day 1", Calendar.HOUR_OF_DAY);
|
||||
public static final DateFormat.Field HOUR_OF_DAY0
|
||||
= new Field("hour of day 0", Calendar.HOUR_OF_DAY);
|
||||
public static final DateFormat.Field MINUTE
|
||||
= new Field("minute", Calendar.MINUTE);
|
||||
public static final DateFormat.Field SECOND
|
||||
= new Field("second", Calendar.SECOND);
|
||||
public static final DateFormat.Field MILLISECOND
|
||||
= new Field("millisecond", Calendar.MILLISECOND);
|
||||
public static final DateFormat.Field DAY_OF_WEEK
|
||||
= new Field("day of week", Calendar.DAY_OF_WEEK);
|
||||
public static final DateFormat.Field DAY_OF_YEAR
|
||||
= new Field("day of year", Calendar.DAY_OF_YEAR);
|
||||
public static final DateFormat.Field DAY_OF_WEEK_IN_MONTH
|
||||
= new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
|
||||
public static final DateFormat.Field WEEK_OF_YEAR
|
||||
= new Field("week of year", Calendar.WEEK_OF_YEAR);
|
||||
public static final DateFormat.Field WEEK_OF_MONTH
|
||||
= new Field("week of month", Calendar.WEEK_OF_MONTH);
|
||||
public static final DateFormat.Field AM_PM
|
||||
= new Field("am/pm", Calendar.AM_PM);
|
||||
public static final DateFormat.Field HOUR1
|
||||
= new Field("hour1", Calendar.HOUR);
|
||||
public static final DateFormat.Field HOUR0
|
||||
= new Field("hour0", Calendar.HOUR);
|
||||
public static final DateFormat.Field TIME_ZONE
|
||||
= new Field("timezone", Calendar.ZONE_OFFSET);
|
||||
public static final DateFormat.Field ISO_YEAR
|
||||
= new Field("iso year", Calendar.YEAR);
|
||||
public static final DateFormat.Field LOCALIZED_DAY_OF_WEEK
|
||||
= new Field("localized day of week", Calendar.DAY_OF_WEEK);
|
||||
public static final DateFormat.Field EXTENDED_YEAR
|
||||
= new Field("extended year", Calendar.YEAR);
|
||||
public static final DateFormat.Field MODIFIED_JULIAN_DAY
|
||||
= new Field("julian day", -1);
|
||||
public static final DateFormat.Field MILLISECOND_IN_DAY
|
||||
= new Field("millisecond in day", -1);
|
||||
public static final DateFormat.Field RFC822_TIME_ZONE
|
||||
= new Field("rfc822 timezone", Calendar.ZONE_OFFSET);
|
||||
|
||||
static final DateFormat.Field[] allFields =
|
||||
{
|
||||
ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY1,
|
||||
HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
|
||||
DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
|
||||
WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
|
||||
TIME_ZONE, ISO_YEAR, LOCALIZED_DAY_OF_WEEK,
|
||||
EXTENDED_YEAR, MODIFIED_JULIAN_DAY, MILLISECOND_IN_DAY,
|
||||
RFC822_TIME_ZONE
|
||||
};
|
||||
|
||||
// For deserialization
|
||||
private Field()
|
||||
{
|
||||
super("");
|
||||
}
|
||||
|
||||
protected Field(String name, int calendarField)
|
||||
{
|
||||
super(name);
|
||||
this.calendarField = calendarField;
|
||||
}
|
||||
|
||||
public int getCalendarField()
|
||||
{
|
||||
return calendarField;
|
||||
}
|
||||
|
||||
public static Field ofCalendarField(int calendarField)
|
||||
{
|
||||
if (calendarField >= allFields.length || calendarField < 0)
|
||||
throw new IllegalArgumentException("no such calendar field ("
|
||||
+ calendarField + ")");
|
||||
|
||||
return allFields[calendarField];
|
||||
}
|
||||
|
||||
protected Object readResolve() throws InvalidObjectException
|
||||
{
|
||||
String s = getName();
|
||||
|
||||
for (int i=0;i<allFields.length;i++)
|
||||
if (s.equals(allFields[i].getName()))
|
||||
return allFields[i];
|
||||
|
||||
throw new InvalidObjectException("no such DateFormat field called " + s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>DateFormat</code>.
|
||||
*/
|
||||
protected DateFormat ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests this object for equality against the specified object.
|
||||
* The two objects will be considered equal if an only if the specified
|
||||
* object:
|
||||
* <P>
|
||||
* <ul>
|
||||
* <li>Is not <code>null</code>.</li>
|
||||
* <li>Is an instance of <code>DateFormat</code>.</li>
|
||||
* <li>Has the same numberFormat field value as this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The object to test for equality against.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this object,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (!(obj instanceof DateFormat))
|
||||
return false;
|
||||
|
||||
DateFormat d = (DateFormat) obj;
|
||||
|
||||
return numberFormat.equals(d.numberFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a copy of this object.
|
||||
*
|
||||
* @return A copy of this object.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
// We know the superclass just call's Object's generic cloner.
|
||||
return super.clone ();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats the specified <code>Object</code> into a date string
|
||||
* and appends it to the specified <code>StringBuffer</code>.
|
||||
* The specified object must be an instance of <code>Number</code> or
|
||||
* <code>Date</code> or an <code>IllegalArgumentException</code> will be
|
||||
* thrown.
|
||||
*
|
||||
* @param obj The <code>Object</code> to format.
|
||||
* @param toAppendTo The <code>StringBuffer</code> to append the resultant
|
||||
* <code>String</code> to.
|
||||
* @param fieldPosition Is updated to the start and end index of the
|
||||
* specified field.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> supplied on input, with the
|
||||
* formatted date/time appended.
|
||||
*/
|
||||
public final StringBuffer format (Object obj,
|
||||
StringBuffer buf, FieldPosition pos)
|
||||
{
|
||||
if (obj instanceof Number)
|
||||
obj = new Date(((Number) obj).longValue());
|
||||
else if (! (obj instanceof Date))
|
||||
throw new IllegalArgumentException
|
||||
("Cannot format given Object as a Date");
|
||||
|
||||
return format ((Date) obj, buf, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the date argument according to the pattern specified.
|
||||
*
|
||||
* @param date The formatted date.
|
||||
*/
|
||||
public final String format (Date date)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer ();
|
||||
format (date, sb, new FieldPosition (MONTH_FIELD));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats a <code>Date</code> into a string and appends it
|
||||
* to the specified <code>StringBuffer</code>.
|
||||
*
|
||||
* @param date The <code>Date</code> value to format.
|
||||
* @param toAppendTo The <code>StringBuffer</code> to append the resultant
|
||||
* <code>String</code> to.
|
||||
* @param fieldPosition Is updated to the start and end index of the
|
||||
* specified field.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> supplied on input, with the
|
||||
* formatted date/time appended.
|
||||
*/
|
||||
public abstract StringBuffer format (Date date,
|
||||
StringBuffer buf, FieldPosition pos);
|
||||
|
||||
/**
|
||||
* This method returns a list of available locales supported by this
|
||||
* class.
|
||||
*/
|
||||
public static Locale[] getAvailableLocales()
|
||||
{
|
||||
return Locale.getAvailableLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the <code>Calendar</code> object being used by
|
||||
* this object to parse/format datetimes.
|
||||
*
|
||||
* @return The <code>Calendar</code> being used by this object.
|
||||
*
|
||||
* @see java.util.Calendar
|
||||
*/
|
||||
public Calendar getCalendar ()
|
||||
{
|
||||
return calendar;
|
||||
}
|
||||
|
||||
private static DateFormat computeInstance (int style, Locale loc,
|
||||
boolean use_date, boolean use_time)
|
||||
{
|
||||
return computeInstance (style, style, loc, use_date, use_time);
|
||||
}
|
||||
|
||||
private static DateFormat computeInstance (int dateStyle, int timeStyle,
|
||||
Locale loc, boolean use_date,
|
||||
boolean use_time)
|
||||
{
|
||||
ResourceBundle res;
|
||||
try
|
||||
{
|
||||
res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
|
||||
loc, ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
res = null;
|
||||
}
|
||||
|
||||
String pattern = null;
|
||||
if (use_date)
|
||||
{
|
||||
String name, def;
|
||||
switch (dateStyle)
|
||||
{
|
||||
case FULL:
|
||||
name = "fullDateFormat";
|
||||
def = "EEEE MMMM d, yyyy G";
|
||||
break;
|
||||
case LONG:
|
||||
name = "longDateFormat";
|
||||
def = "MMMM d, yyyy";
|
||||
break;
|
||||
case MEDIUM:
|
||||
name = "mediumDateFormat";
|
||||
def = "d-MMM-yy";
|
||||
break;
|
||||
case SHORT:
|
||||
name = "shortDateFormat";
|
||||
def = "M/d/yy";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException ();
|
||||
}
|
||||
try
|
||||
{
|
||||
pattern = res == null ? def : res.getString(name);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
pattern = def;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_time)
|
||||
{
|
||||
if (pattern == null)
|
||||
pattern = "";
|
||||
else
|
||||
pattern += " ";
|
||||
|
||||
String name, def;
|
||||
switch (timeStyle)
|
||||
{
|
||||
case FULL:
|
||||
name = "fullTimeFormat";
|
||||
def = "h:mm:ss;S 'o''clock' a z";
|
||||
break;
|
||||
case LONG:
|
||||
name = "longTimeFormat";
|
||||
def = "h:mm:ss a z";
|
||||
break;
|
||||
case MEDIUM:
|
||||
name = "mediumTimeFormat";
|
||||
def = "h:mm:ss a";
|
||||
break;
|
||||
case SHORT:
|
||||
name = "shortTimeFormat";
|
||||
def = "h:mm a";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException ();
|
||||
}
|
||||
|
||||
String s;
|
||||
try
|
||||
{
|
||||
s = res == null ? def : res.getString(name);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
s = def;
|
||||
}
|
||||
pattern += s;
|
||||
}
|
||||
|
||||
return new SimpleDateFormat (pattern, loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the default formatting style for dates.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getDateInstance ()
|
||||
{
|
||||
return getDateInstance (DEFAULT, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the specified formatting style for dates.
|
||||
*
|
||||
* @param style The type of formatting to perform.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getDateInstance (int style)
|
||||
{
|
||||
return getDateInstance (style, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the specified formatting style for dates. The specified
|
||||
* localed will be used in place of the default.
|
||||
*
|
||||
* @param style The type of formatting to perform.
|
||||
* @param aLocale The desired locale.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getDateInstance (int style, Locale loc)
|
||||
{
|
||||
return computeInstance (style, loc, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a new instance of <code>DateFormat</code> that
|
||||
* formats both dates and times using the <code>SHORT</code> style.
|
||||
*
|
||||
* @return A new <code>DateFormat</code>instance.
|
||||
*/
|
||||
public static final DateFormat getDateTimeInstance ()
|
||||
{
|
||||
return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a new instance of <code>DateFormat</code> that
|
||||
* formats both dates and times using the <code>DEFAULT</code> style.
|
||||
*
|
||||
* @return A new <code>DateFormat</code>instance.
|
||||
*/
|
||||
public static final DateFormat getDateTimeInstance (int dateStyle,
|
||||
int timeStyle)
|
||||
{
|
||||
return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a new instance of <code>DateFormat</code> that
|
||||
* formats both dates and times using the specified styles.
|
||||
*
|
||||
* @param dateStyle The desired style for date formatting.
|
||||
* @param timeStyle The desired style for time formatting
|
||||
*
|
||||
* @return A new <code>DateFormat</code>instance.
|
||||
*/
|
||||
public static final DateFormat getDateTimeInstance (int dateStyle,
|
||||
int timeStyle,
|
||||
Locale loc)
|
||||
{
|
||||
return computeInstance (dateStyle, timeStyle, loc, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a new instance of <code>DateFormat</code> that
|
||||
* formats both dates and times using the <code>SHORT</code> style.
|
||||
*
|
||||
* @return A new <code>DateFormat</code>instance.
|
||||
*/
|
||||
public static final DateFormat getInstance ()
|
||||
{
|
||||
// JCL book says SHORT.
|
||||
return getDateTimeInstance (SHORT, SHORT, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the <code>NumberFormat</code> object being used
|
||||
* by this object to parse/format time values.
|
||||
*
|
||||
* @return The <code>NumberFormat</code> in use by this object.
|
||||
*/
|
||||
public NumberFormat getNumberFormat ()
|
||||
{
|
||||
return numberFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the default formatting style for times.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getTimeInstance ()
|
||||
{
|
||||
return getTimeInstance (DEFAULT, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the specified formatting style for times.
|
||||
*
|
||||
* @param style The type of formatting to perform.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getTimeInstance (int style)
|
||||
{
|
||||
return getTimeInstance (style, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>DateFormat</code> that will
|
||||
* format using the specified formatting style for times. The specified
|
||||
* localed will be used in place of the default.
|
||||
*
|
||||
* @param style The type of formatting to perform.
|
||||
* @param aLocale The desired locale.
|
||||
*
|
||||
* @return A new <code>DateFormat</code> instance.
|
||||
*/
|
||||
public static final DateFormat getTimeInstance (int style, Locale loc)
|
||||
{
|
||||
return computeInstance (style, loc, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the <code>TimeZone</code> object being used by
|
||||
* this instance.
|
||||
*
|
||||
* @return The time zone in use.
|
||||
*/
|
||||
public TimeZone getTimeZone ()
|
||||
{
|
||||
return calendar.getTimeZone();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
if (numberFormat != null)
|
||||
return numberFormat.hashCode();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the parsing of date and time
|
||||
* values should be done in a lenient value.
|
||||
*
|
||||
* @return <code>true</code> if date/time parsing is lenient,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isLenient ()
|
||||
{
|
||||
return calendar.isLenient();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the specified date/time string.
|
||||
*
|
||||
* @param source The string to parse.
|
||||
* @return The resultant date.
|
||||
*
|
||||
* @exception ParseException If the specified string cannot be parsed.
|
||||
*/
|
||||
public Date parse (String source) throws ParseException
|
||||
{
|
||||
ParsePosition pos = new ParsePosition(0);
|
||||
Date result = parse (source, pos);
|
||||
if (result == null)
|
||||
{
|
||||
int index = pos.getErrorIndex();
|
||||
if (index < 0)
|
||||
index = pos.getIndex();
|
||||
throw new ParseException("invalid Date syntax in \""
|
||||
+ source + '\"', index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the specified <code>String</code> into a
|
||||
* <code>Date</code>. The <code>pos</code> argument contains the
|
||||
* starting parse position on method entry and the ending parse
|
||||
* position on method exit.
|
||||
*
|
||||
* @param text The string to parse.
|
||||
* @param pos The starting parse position in entry, the ending parse
|
||||
* position on exit.
|
||||
*
|
||||
* @return The parsed date, or <code>null</code> if the string cannot
|
||||
* be parsed.
|
||||
*/
|
||||
public abstract Date parse (String source, ParsePosition pos);
|
||||
|
||||
/**
|
||||
* This method is identical to <code>parse(String, ParsePosition)</code>,
|
||||
* but returns its result as an <code>Object</code> instead of a
|
||||
* <code>Date</code>.
|
||||
*
|
||||
* @param source The string to parse.
|
||||
* @param pos The starting parse position in entry, the ending parse
|
||||
* position on exit.
|
||||
*
|
||||
* @return The parsed date, or <code>null</code> if the string cannot
|
||||
* be parsed.
|
||||
*/
|
||||
public Object parseObject (String source, ParsePosition pos)
|
||||
{
|
||||
return parse(source, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method specified the <code>Calendar</code> that should be used
|
||||
* by this object to parse/format datetimes.
|
||||
*
|
||||
* @param The new <code>Calendar</code> for this object.
|
||||
*
|
||||
* @see java.util.Calendar
|
||||
*/
|
||||
public void setCalendar (Calendar calendar)
|
||||
{
|
||||
this.calendar = calendar;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method specifies whether or not this object should be lenient in
|
||||
* the syntax it accepts while parsing date/time values.
|
||||
*
|
||||
* @param lenient <code>true</code> if parsing should be lenient,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public void setLenient (boolean lenient)
|
||||
{
|
||||
calendar.setLenient(lenient);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method specifies the <code>NumberFormat</code> object that should
|
||||
* be used by this object to parse/format times.
|
||||
*
|
||||
* @param The <code>NumberFormat</code> in use by this object.
|
||||
*/
|
||||
public void setNumberFormat (NumberFormat numberFormat)
|
||||
{
|
||||
this.numberFormat = numberFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the time zone that should be used by this object.
|
||||
*
|
||||
* @param The new time zone.
|
||||
*/
|
||||
public void setTimeZone (TimeZone timeZone)
|
||||
{
|
||||
calendar.setTimeZone(timeZone);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
/* DateFormatSymbols.java -- Format over a range of numbers
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* This class acts as container for locale specific date/time formatting
|
||||
* information such as the days of the week and the months of the year.
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
* @date October 24, 1998.
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
|
||||
* Status: Believed complete and correct.
|
||||
*/
|
||||
public class DateFormatSymbols implements java.io.Serializable, Cloneable
|
||||
{
|
||||
String[] ampms;
|
||||
String[] eras;
|
||||
private String localPatternChars;
|
||||
String[] months;
|
||||
String[] shortMonths;
|
||||
String[] shortWeekdays;
|
||||
String[] weekdays;
|
||||
private String[][] zoneStrings;
|
||||
|
||||
private static final long serialVersionUID = -5987973545549424702L;
|
||||
|
||||
// The order of these prefixes must be the same as in DateFormat
|
||||
private static final String[] formatPrefixes =
|
||||
{
|
||||
"full", "long", "medium", "short"
|
||||
};
|
||||
|
||||
// These are each arrays with a value for SHORT, MEDIUM, LONG, FULL,
|
||||
// and DEFAULT (constants defined in java.text.DateFormat). While
|
||||
// not part of the official spec, we need a way to get at locale-specific
|
||||
// default formatting patterns. They are declared package scope so
|
||||
// as to be easily accessible where needed (DateFormat, SimpleDateFormat).
|
||||
transient String[] dateFormats;
|
||||
transient String[] timeFormats;
|
||||
|
||||
private static String[] getStringArray(ResourceBundle res, String name)
|
||||
{
|
||||
return res.getString(name).split("\u00ae");
|
||||
}
|
||||
|
||||
private String[][] getZoneStrings(ResourceBundle res)
|
||||
{
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
String data = res.getString("zoneStrings");
|
||||
String[] zones = data.split("\u00a9");
|
||||
String[][] array = new String[zones.length][];
|
||||
for (int a = 0; a < zones.length; ++a)
|
||||
array[a] = zones[a].split("\u00ae");
|
||||
return array;
|
||||
}
|
||||
catch (MissingResourceException e)
|
||||
{
|
||||
return new String[0][];
|
||||
}
|
||||
}
|
||||
|
||||
private String[] formatsForKey(ResourceBundle res, String key)
|
||||
{
|
||||
String[] values = new String[formatPrefixes.length];
|
||||
|
||||
for (int i = 0; i < formatPrefixes.length; i++)
|
||||
values[i] = res.getString(formatPrefixes[i] + key);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>DateFormatSymbols</code>
|
||||
* by loading the date format information for the specified locale.
|
||||
*
|
||||
* @param locale The locale for which date formatting symbols should
|
||||
* be loaded.
|
||||
*/
|
||||
public DateFormatSymbols (Locale locale) throws MissingResourceException
|
||||
{
|
||||
ResourceBundle res
|
||||
= ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
|
||||
ampms = getStringArray(res, "ampms");
|
||||
eras = getStringArray(res, "eras");
|
||||
localPatternChars = res.getString("localPatternChars");
|
||||
months = getStringArray(res, "months");
|
||||
shortMonths = getStringArray(res, "shortMonths");
|
||||
shortWeekdays = getStringArray(res, "shortWeekdays");
|
||||
weekdays = getStringArray(res, "weekdays");
|
||||
zoneStrings = getZoneStrings(res);
|
||||
dateFormats = formatsForKey(res, "DateFormat");
|
||||
timeFormats = formatsForKey(res, "TimeFormat");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads the format symbol information for the default
|
||||
* locale.
|
||||
*/
|
||||
public DateFormatSymbols () throws MissingResourceException
|
||||
{
|
||||
this (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying AM or PM.
|
||||
* This is a two element <code>String</code> array indexed by
|
||||
* <code>Calendar.AM</code> and <code>Calendar.PM</code>
|
||||
*
|
||||
* @return The list of AM/PM display strings.
|
||||
*/
|
||||
public String[] getAmPmStrings()
|
||||
{
|
||||
return ampms;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying eras
|
||||
* (e.g., "BC" and "AD"). This is a two element <code>String</code>
|
||||
* array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
|
||||
*
|
||||
* @return The list of era disply strings.
|
||||
*/
|
||||
public String[] getEras()
|
||||
{
|
||||
return eras;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the pattern character information for this
|
||||
* object. This is an 18 character string that contains the characters
|
||||
* that are used in creating the date formatting strings in
|
||||
* <code>SimpleDateFormat</code>. The following are the character
|
||||
* positions in the string and which format character they correspond
|
||||
* to (the character in parentheses is the default value in the US English
|
||||
* locale):
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>0 - era (G)</li>
|
||||
* <li>1 - year (y)</li>
|
||||
* <li>2 - month (M)</li>
|
||||
* <li>3 - day of month (d)</li>
|
||||
* <li>4 - hour out of 12, from 1-12 (h)</li>
|
||||
* <li>5 - hour out of 24, from 0-23 (H)</li>
|
||||
* <li>6 - minute (m)</li>
|
||||
* <li>7 - second (s)</li>
|
||||
* <li>8 - millisecond (S)</li>
|
||||
* <li>9 - date of week (E)</li>
|
||||
* <li>10 - date of year (D)</li>
|
||||
* <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
|
||||
* <li>12 - week in year (w)</li>
|
||||
* <li>13 - week in month (W)</li>
|
||||
* <li>14 - am/pm (a)</li>
|
||||
* <li>15 - hour out of 24, from 1-24 (k)</li>
|
||||
* <li>16 - hour out of 12, from 0-11 (K)</li>
|
||||
* <li>17 - time zone (z)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return The format patter characters
|
||||
*/
|
||||
public String getLocalPatternChars()
|
||||
{
|
||||
return localPatternChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying month
|
||||
* names (e.g., "January" and "February"). This is a thirteen element
|
||||
* string array indexed by <code>Calendar.JANUARY</code> through
|
||||
* <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
|
||||
* elements because some calendars have thriteen months.
|
||||
*
|
||||
* @return The list of month display strings.
|
||||
*/
|
||||
public String[] getMonths ()
|
||||
{
|
||||
return months;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying abbreviated
|
||||
* month names (e.g., "Jan" and "Feb"). This is a thirteen element
|
||||
* <code>String</code> array indexed by <code>Calendar.JANUARY</code>
|
||||
* through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
|
||||
* elements because some calendars have thirteen months.
|
||||
*
|
||||
* @return The list of abbreviated month display strings.
|
||||
*/
|
||||
public String[] getShortMonths ()
|
||||
{
|
||||
return shortMonths;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying abbreviated
|
||||
* weekday names (e.g., "Sun" and "Mon"). This is an eight element
|
||||
* <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
|
||||
* through <code>Calendar.SATURDAY</code>. Note that the first element
|
||||
* of this array is ignored.
|
||||
*
|
||||
* @return This list of abbreviated weekday display strings.
|
||||
*/
|
||||
public String[] getShortWeekdays ()
|
||||
{
|
||||
return shortWeekdays;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the list of strings used for displaying weekday
|
||||
* names (e.g., "Sunday" and "Monday"). This is an eight element
|
||||
* <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
|
||||
* through <code>Calendar.SATURDAY</code>. Note that the first element
|
||||
* of this array is ignored.
|
||||
*
|
||||
* @return This list of weekday display strings.
|
||||
*/
|
||||
public String[] getWeekdays ()
|
||||
{
|
||||
return weekdays;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns this list of localized timezone display strings.
|
||||
* This is a two dimensional <code>String</code> array where each row in
|
||||
* the array contains five values:
|
||||
* <P>
|
||||
* <ul>
|
||||
* <li>0 - The non-localized time zone id string.</li>
|
||||
* <li>1 - The long name of the time zone (standard time).</li>
|
||||
* <li>2 - The short name of the time zone (standard time).</li>
|
||||
* <li>3 - The long name of the time zone (daylight savings time).</li>
|
||||
* <li>4 - the short name of the time zone (daylight savings time).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return The list of time zone display strings.
|
||||
*/
|
||||
public String[] [] getZoneStrings ()
|
||||
{
|
||||
return zoneStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display AM/PM values to
|
||||
* the specified list.
|
||||
* This is a two element <code>String</code> array indexed by
|
||||
* <code>Calendar.AM</code> and <code>Calendar.PM</code>
|
||||
*
|
||||
* @param ampms The new list of AM/PM display strings.
|
||||
*/
|
||||
public void setAmPmStrings (String[] value)
|
||||
{
|
||||
ampms = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display time eras to
|
||||
* to the specified list.
|
||||
* This is a two element <code>String</code>
|
||||
* array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
|
||||
*
|
||||
* @param eras The new list of era disply strings.
|
||||
*/
|
||||
public void setEras (String[] value)
|
||||
{
|
||||
eras = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of characters used to specific date/time
|
||||
* formatting strings.
|
||||
* This is an 18 character string that contains the characters
|
||||
* that are used in creating the date formatting strings in
|
||||
* <code>SimpleDateFormat</code>. The following are the character
|
||||
* positions in the string and which format character they correspond
|
||||
* to (the character in parentheses is the default value in the US English
|
||||
* locale):
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>0 - era (G)</li>
|
||||
* <li>1 - year (y)</li>
|
||||
* <li>2 - month (M)</li>
|
||||
* <li>3 - day of month (d)</li>
|
||||
* <li>4 - hour out of 12, from 1-12 (h)</li>
|
||||
* <li>5 - hour out of 24, from 0-23 (H)</li>
|
||||
* <li>6 - minute (m)</li>
|
||||
* <li>7 - second (s)</li>
|
||||
* <li>8 - millisecond (S)</li>
|
||||
* <li>9 - date of week (E)</li>
|
||||
* <li>10 - date of year (D)</li>
|
||||
* <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
|
||||
* <li>12 - week in year (w)</li>
|
||||
* <li>13 - week in month (W)</li>
|
||||
* <li>14 - am/pm (a)</li>
|
||||
* <li>15 - hour out of 24, from 1-24 (k)</li>
|
||||
* <li>16 - hour out of 12, from 0-11 (K)</li>
|
||||
* <li>17 - time zone (z)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param localPatternChars The new format patter characters
|
||||
*/
|
||||
public void setLocalPatternChars (String value)
|
||||
{
|
||||
localPatternChars = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display month names.
|
||||
* This is a thirteen element
|
||||
* string array indexed by <code>Calendar.JANUARY</code> through
|
||||
* <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
|
||||
* elements because some calendars have thriteen months.
|
||||
*
|
||||
* @param months The list of month display strings.
|
||||
*/
|
||||
public void setMonths (String[] value)
|
||||
{
|
||||
months = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display abbreviated month
|
||||
* names.
|
||||
* This is a thirteen element
|
||||
* <code>String</code> array indexed by <code>Calendar.JANUARY</code>
|
||||
* through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
|
||||
* elements because some calendars have thirteen months.
|
||||
*
|
||||
* @param shortMonths The new list of abbreviated month display strings.
|
||||
*/
|
||||
public void setShortMonths (String[] value)
|
||||
{
|
||||
shortMonths = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display abbreviated
|
||||
* weekday names.
|
||||
* This is an eight element
|
||||
* <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
|
||||
* through <code>Calendar.SATURDAY</code>. Note that the first element
|
||||
* of this array is ignored.
|
||||
*
|
||||
* @param shortWeekdays This list of abbreviated weekday display strings.
|
||||
*/
|
||||
public void setShortWeekdays (String[] value)
|
||||
{
|
||||
shortWeekdays = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of strings used to display weekday names.
|
||||
* This is an eight element
|
||||
* <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
|
||||
* through <code>Calendar.SATURDAY</code>. Note that the first element
|
||||
* of this array is ignored.
|
||||
*
|
||||
* @param weekdays This list of weekday display strings.
|
||||
*/
|
||||
public void setWeekdays (String[] value)
|
||||
{
|
||||
weekdays = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the list of display strings for time zones.
|
||||
* This is a two dimensional <code>String</code> array where each row in
|
||||
* the array contains five values:
|
||||
* <P>
|
||||
* <ul>
|
||||
* <li>0 - The non-localized time zone id string.</li>
|
||||
* <li>1 - The long name of the time zone (standard time).</li>
|
||||
* <li>2 - The short name of the time zone (standard time).</li>
|
||||
* <li>3 - The long name of the time zone (daylight savings time).</li>
|
||||
* <li>4 - the short name of the time zone (daylight savings time).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return The list of time zone display strings.
|
||||
*/
|
||||
public void setZoneStrings (String[][] value)
|
||||
{
|
||||
zoneStrings = value;
|
||||
}
|
||||
|
||||
/* Does a "deep" equality test - recurses into arrays. */
|
||||
private static boolean equals (Object x, Object y)
|
||||
{
|
||||
if (x == y)
|
||||
return true;
|
||||
if (x == null || y == null)
|
||||
return false;
|
||||
if (! (x instanceof Object[]) || ! (y instanceof Object[]))
|
||||
return x.equals(y);
|
||||
Object[] xa = (Object[]) x;
|
||||
Object[] ya = (Object[]) y;
|
||||
if (xa.length != ya.length)
|
||||
return false;
|
||||
for (int i = xa.length; --i >= 0; )
|
||||
{
|
||||
if (! equals(xa[i], ya[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int hashCode (Object x)
|
||||
{
|
||||
if (x == null)
|
||||
return 0;
|
||||
if (! (x instanceof Object[]))
|
||||
return x.hashCode();
|
||||
Object[] xa = (Object[]) x;
|
||||
int hash = 0;
|
||||
for (int i = 0; i < xa.length; i++)
|
||||
hash = 37 * hashCode(xa[i]);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests a specified object for equality against this object.
|
||||
* This will be true if and only if the specified object:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> Is not <code>null</code>.</li>
|
||||
* <li> Is an instance of <code>DateFormatSymbols</code>.</li>
|
||||
* <li> Contains identical formatting symbols to this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The <code>Object</code> to test for equality against.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this one,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof DateFormatSymbols))
|
||||
return false;
|
||||
DateFormatSymbols other = (DateFormatSymbols) obj;
|
||||
return (equals(ampms, other.ampms)
|
||||
&& equals(eras, other.eras)
|
||||
&& equals(localPatternChars, other.localPatternChars)
|
||||
&& equals(months, other.months)
|
||||
&& equals(shortMonths, other.shortMonths)
|
||||
&& equals(shortWeekdays, other.shortWeekdays)
|
||||
&& equals(weekdays, other.weekdays)
|
||||
&& equals(zoneStrings, other.zoneStrings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new copy of this object.
|
||||
*
|
||||
* @param A copy of this object
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone ();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
return (hashCode(ampms)
|
||||
^ hashCode(eras)
|
||||
^ hashCode(localPatternChars)
|
||||
^ hashCode(months)
|
||||
^ hashCode(shortMonths)
|
||||
^ hashCode(shortWeekdays)
|
||||
^ hashCode(weekdays)
|
||||
^ hashCode(zoneStrings));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,688 @@
|
||||
/* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat
|
||||
Copyright (C) 1999, 2000, 2001, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* This class is a container for the symbols used by
|
||||
* <code>DecimalFormat</code> to format numbers and currency
|
||||
* for a particular locale. These are
|
||||
* normally handled automatically, but an application can override
|
||||
* values as desired using this class.
|
||||
*
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @date February 24, 1999
|
||||
* @see java.text.DecimalFormat
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to 1.2.
|
||||
*/
|
||||
public final class DecimalFormatSymbols implements Cloneable, Serializable
|
||||
{
|
||||
public Object clone ()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone ();
|
||||
}
|
||||
catch(CloneNotSupportedException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of
|
||||
* <code>DecimalFormatSymbols</code> for the default locale.
|
||||
*/
|
||||
public DecimalFormatSymbols ()
|
||||
{
|
||||
this (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a valid string, either using the supplied resource
|
||||
* bundle or the default value.
|
||||
*
|
||||
* @param bundle the resource bundle to use to find the string.
|
||||
* @param name key for the string in the resource bundle.
|
||||
* @param def default value for the string.
|
||||
*/
|
||||
private String safeGetString(ResourceBundle bundle,
|
||||
String name, String def)
|
||||
{
|
||||
if (bundle != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return bundle.getString(name);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
private char safeGetChar(ResourceBundle bundle,
|
||||
String name, char def)
|
||||
{
|
||||
String r = null;
|
||||
if (bundle != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
r = bundle.getString(name);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
}
|
||||
}
|
||||
if (r == null || r.length() < 1)
|
||||
return def;
|
||||
return r.charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of
|
||||
* <code>DecimalFormatSymbols</code> for the specified locale.
|
||||
* <strong>Note</strong>: if the locale does not have an associated
|
||||
* <code>Currency</code> instance, the currency symbol and
|
||||
* international currency symbol will be set to the strings "?"
|
||||
* and "XXX" respectively. This generally happens with language
|
||||
* locales (those with no specified country), such as
|
||||
* <code>Locale.ENGLISH</code>.
|
||||
*
|
||||
* @param locale The local to load symbols for.
|
||||
* @throws NullPointerException if the locale is null.
|
||||
*/
|
||||
public DecimalFormatSymbols (Locale loc)
|
||||
{
|
||||
ResourceBundle res;
|
||||
|
||||
currency = Currency.getInstance("XXX");
|
||||
currencySymbol = "?";
|
||||
intlCurrencySymbol = "XXX";
|
||||
try
|
||||
{
|
||||
res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
|
||||
loc, ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
res = null;
|
||||
}
|
||||
try
|
||||
{
|
||||
Currency localeCurrency = Currency.getInstance(loc);
|
||||
if (localeCurrency != null)
|
||||
{
|
||||
setCurrency(localeCurrency);
|
||||
}
|
||||
}
|
||||
catch(IllegalArgumentException exception)
|
||||
{
|
||||
/* Locale has an invalid currency */
|
||||
}
|
||||
decimalSeparator = safeGetChar (res, "decimalSeparator", '.');
|
||||
digit = safeGetChar (res, "digit", '#');
|
||||
exponential = safeGetChar (res, "exponential", 'E');
|
||||
groupingSeparator = safeGetChar (res, "groupingSeparator", ',');
|
||||
infinity = safeGetString (res, "infinity", "\u221e");
|
||||
try
|
||||
{
|
||||
monetarySeparator = safeGetChar (res, "monetarySeparator", '.');
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
monetarySeparator = decimalSeparator;
|
||||
}
|
||||
minusSign = safeGetChar (res, "minusSign", '-');
|
||||
NaN = safeGetString (res, "NaN", "\ufffd");
|
||||
patternSeparator = safeGetChar (res, "patternSeparator", ';');
|
||||
percent = safeGetChar (res, "percent", '%');
|
||||
perMill = safeGetChar (res, "perMill", '\u2030');
|
||||
zeroDigit = safeGetChar (res, "zeroDigit", '0');
|
||||
locale = loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method this this object for equality against the specified object.
|
||||
* This will be true if and only if the following criteria are met with
|
||||
* regard to the specified object:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>It is not <code>null</code>.</li>
|
||||
* <li>It is an instance of <code>DecimalFormatSymbols</code>.</li>
|
||||
* <li>All of its symbols are identical to the symbols in this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this
|
||||
* object, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof DecimalFormatSymbols))
|
||||
return false;
|
||||
DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj;
|
||||
return (currencySymbol.equals(dfs.currencySymbol)
|
||||
&& decimalSeparator == dfs.decimalSeparator
|
||||
&& digit == dfs.digit
|
||||
&& exponential == dfs.exponential
|
||||
&& groupingSeparator == dfs.groupingSeparator
|
||||
&& infinity.equals(dfs.infinity)
|
||||
&& intlCurrencySymbol.equals(dfs.intlCurrencySymbol)
|
||||
&& minusSign == dfs.minusSign
|
||||
&& monetarySeparator == dfs.monetarySeparator
|
||||
&& NaN.equals(dfs.NaN)
|
||||
&& patternSeparator == dfs.patternSeparator
|
||||
&& percent == dfs.percent
|
||||
&& perMill == dfs.perMill
|
||||
&& zeroDigit == dfs.zeroDigit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currency corresponding to the currency symbol stored
|
||||
* in this instance of <code>DecimalFormatSymbols</code>.
|
||||
*
|
||||
* @return An instance of <code>Currency</code> which matches
|
||||
* the currency used, or null if there is no corresponding
|
||||
* instance.
|
||||
*/
|
||||
public Currency getCurrency ()
|
||||
{
|
||||
return currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the currency symbol in local format. For example,
|
||||
* "$" for Canadian dollars.
|
||||
*
|
||||
* @return The currency symbol in local format.
|
||||
*/
|
||||
public String getCurrencySymbol ()
|
||||
{
|
||||
return currencySymbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used as the decimal point.
|
||||
*
|
||||
* @return The character used as the decimal point.
|
||||
*/
|
||||
public char getDecimalSeparator ()
|
||||
{
|
||||
return decimalSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent a digit in a
|
||||
* format pattern string.
|
||||
*
|
||||
* @return The character used to represent a digit in a format
|
||||
* pattern string.
|
||||
*/
|
||||
public char getDigit ()
|
||||
{
|
||||
return digit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent the exponential
|
||||
* format. This is a GNU Classpath extension.
|
||||
*
|
||||
* @return the character used to represent an exponential in a format
|
||||
* pattern string.
|
||||
*/
|
||||
char getExponential ()
|
||||
{
|
||||
return exponential;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to separate groups of digits. For
|
||||
* example, the United States uses a comma (,) to separate thousands in
|
||||
* a number.
|
||||
*
|
||||
* @return The character used to separate groups of digits.
|
||||
*/
|
||||
public char getGroupingSeparator ()
|
||||
{
|
||||
return groupingSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent infinity.
|
||||
*
|
||||
* @return The character used to represent infinity.
|
||||
*/
|
||||
public String getInfinity ()
|
||||
{
|
||||
return infinity;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ISO 4217 currency code for
|
||||
* the currency used.
|
||||
*
|
||||
* @return the ISO 4217 currency code.
|
||||
*/
|
||||
public String getInternationalCurrencySymbol ()
|
||||
{
|
||||
return intlCurrencySymbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent the minus sign.
|
||||
*
|
||||
* @return The character used to represent the minus sign.
|
||||
*/
|
||||
public char getMinusSign ()
|
||||
{
|
||||
return minusSign;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent the decimal
|
||||
* point for currency values.
|
||||
*
|
||||
* @return The decimal point character used in currency values.
|
||||
*/
|
||||
public char getMonetaryDecimalSeparator ()
|
||||
{
|
||||
return monetarySeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the string used to represent the NaN (not a number)
|
||||
* value.
|
||||
*
|
||||
* @return The string used to represent NaN
|
||||
*/
|
||||
public String getNaN ()
|
||||
{
|
||||
return NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to separate positive and negative
|
||||
* subpatterns in a format pattern.
|
||||
*
|
||||
* @return The character used to separate positive and negative subpatterns
|
||||
* in a format pattern.
|
||||
*/
|
||||
public char getPatternSeparator ()
|
||||
{
|
||||
return patternSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used as the percent sign.
|
||||
*
|
||||
* @return The character used as the percent sign.
|
||||
*/
|
||||
public char getPercent ()
|
||||
{
|
||||
return percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used as the per mille character.
|
||||
*
|
||||
* @return The per mille character.
|
||||
*/
|
||||
public char getPerMill ()
|
||||
{
|
||||
return perMill;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character used to represent the digit zero.
|
||||
*
|
||||
* @return The character used to represent the digit zero.
|
||||
*/
|
||||
public char getZeroDigit ()
|
||||
{
|
||||
return zeroDigit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object.
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
// Compute based on zero digit, grouping separator, and decimal
|
||||
// separator -- JCL book. This probably isn't a very good hash
|
||||
// code.
|
||||
return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the currency symbol and ISO 4217 currency
|
||||
* code to the values obtained from the supplied currency.
|
||||
*
|
||||
* @param currency the currency from which to obtain the values.
|
||||
* @throws NullPointerException if the currency is null.
|
||||
*/
|
||||
public void setCurrency (Currency currency)
|
||||
{
|
||||
intlCurrencySymbol = currency.getCurrencyCode();
|
||||
currencySymbol = currency.getSymbol();
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the currency symbol to the specified value.
|
||||
*
|
||||
* @param currencySymbol The new currency symbol
|
||||
*/
|
||||
public void setCurrencySymbol (String currency)
|
||||
{
|
||||
currencySymbol = currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the decimal point character to the specified value.
|
||||
*
|
||||
* @param decimalSeparator The new decimal point character
|
||||
*/
|
||||
public void setDecimalSeparator (char decimalSep)
|
||||
{
|
||||
decimalSeparator = decimalSep;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to represents a digit in a format
|
||||
* string to the specified value.
|
||||
*
|
||||
* @param digit The character used to represent a digit in a format pattern.
|
||||
*/
|
||||
public void setDigit (char digit)
|
||||
{
|
||||
this.digit = digit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the exponential character used in the format string to
|
||||
* the specified value. This is a GNU Classpath extension.
|
||||
*
|
||||
* @param exp the character used for the exponential in a format pattern.
|
||||
*/
|
||||
void setExponential (char exp)
|
||||
{
|
||||
exponential = exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to separate groups of digits.
|
||||
*
|
||||
* @param groupingSeparator The character used to separate groups of digits.
|
||||
*/
|
||||
public void setGroupingSeparator (char groupSep)
|
||||
{
|
||||
groupingSeparator = groupSep;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the string used to represents infinity.
|
||||
*
|
||||
* @param infinity The string used to represent infinity.
|
||||
*/
|
||||
public void setInfinity (String infinity)
|
||||
{
|
||||
this.infinity = infinity;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the international currency symbol to the
|
||||
* specified value. If a valid <code>Currency</code> instance
|
||||
* exists for the international currency code, then this is
|
||||
* used for the currency attribute, and the currency symbol
|
||||
* is set to the corresponding value from this instance.
|
||||
* Otherwise, the currency attribute is set to null and the
|
||||
* symbol is left unmodified.
|
||||
*
|
||||
* @param currencyCode The new international currency symbol.
|
||||
*/
|
||||
public void setInternationalCurrencySymbol (String currencyCode)
|
||||
{
|
||||
intlCurrencySymbol = currencyCode;
|
||||
try
|
||||
{
|
||||
currency = Currency.getInstance(currencyCode);
|
||||
}
|
||||
catch (IllegalArgumentException exception)
|
||||
{
|
||||
currency = null;
|
||||
}
|
||||
if (currency != null)
|
||||
{
|
||||
setCurrencySymbol(currency.getSymbol(locale));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to represent the minus sign.
|
||||
*
|
||||
* @param minusSign The character used to represent the minus sign.
|
||||
*/
|
||||
public void setMinusSign (char minusSign)
|
||||
{
|
||||
this.minusSign = minusSign;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used for the decimal point in currency
|
||||
* values.
|
||||
*
|
||||
* @param monetarySeparator The decimal point character used in
|
||||
* currency values.
|
||||
*/
|
||||
public void setMonetaryDecimalSeparator (char decimalSep)
|
||||
{
|
||||
monetarySeparator = decimalSep;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the string used to represent the NaN (not a
|
||||
* number) value.
|
||||
*
|
||||
* @param NaN The string used to represent NaN
|
||||
*/
|
||||
public void setNaN (String nan)
|
||||
{
|
||||
NaN = nan;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to separate positive and negative
|
||||
* subpatterns in a format pattern.
|
||||
*
|
||||
* @param patternSeparator The character used to separate positive and
|
||||
* negative subpatterns in a format pattern.
|
||||
*/
|
||||
public void setPatternSeparator (char patternSep)
|
||||
{
|
||||
patternSeparator = patternSep;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used as the percent sign.
|
||||
*
|
||||
* @param percent The character used as the percent sign.
|
||||
*/
|
||||
public void setPercent (char percent)
|
||||
{
|
||||
this.percent = percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used as the per mille character.
|
||||
*
|
||||
* @param perMill The per mille character.
|
||||
*/
|
||||
public void setPerMill (char perMill)
|
||||
{
|
||||
this.perMill = perMill;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the character used to represent the digit zero.
|
||||
*
|
||||
* @param zeroDigit The character used to represent the digit zero.
|
||||
*/
|
||||
public void setZeroDigit (char zeroDigit)
|
||||
{
|
||||
this.zeroDigit = zeroDigit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial A string used for the local currency
|
||||
*/
|
||||
private String currencySymbol;
|
||||
/**
|
||||
* @serial The <code>char</code> used to separate decimals in a number.
|
||||
*/
|
||||
private char decimalSeparator;
|
||||
/**
|
||||
* @serial This is the <code>char</code> used to represent a digit in
|
||||
* a format specification.
|
||||
*/
|
||||
private char digit;
|
||||
/**
|
||||
* @serial This is the <code>char</code> used to represent the exponent
|
||||
* separator in exponential notation.
|
||||
*/
|
||||
private char exponential;
|
||||
/**
|
||||
* @serial This separates groups of thousands in numbers.
|
||||
*/
|
||||
private char groupingSeparator;
|
||||
/**
|
||||
* @serial This string represents infinity.
|
||||
*/
|
||||
private String infinity;
|
||||
/**
|
||||
* @serial This string represents the local currency in an international
|
||||
* context, eg, "C$" for Canadian dollars.
|
||||
*/
|
||||
private String intlCurrencySymbol;
|
||||
/**
|
||||
* @serial This is the character used to represent the minus sign.
|
||||
*/
|
||||
private char minusSign;
|
||||
/**
|
||||
* @serial This character is used to separate decimals when formatting
|
||||
* currency values.
|
||||
*/
|
||||
private char monetarySeparator;
|
||||
/**
|
||||
* @serial This string is used the represent the Java NaN value for
|
||||
* "not a number".
|
||||
*/
|
||||
private String NaN;
|
||||
/**
|
||||
* @serial This is the character used to separate positive and negative
|
||||
* subpatterns in a format pattern.
|
||||
*/
|
||||
private char patternSeparator;
|
||||
/**
|
||||
* @serial This is the percent symbols
|
||||
*/
|
||||
private char percent;
|
||||
/**
|
||||
* @serial This character is used for the mille percent sign.
|
||||
*/
|
||||
private char perMill;
|
||||
/**
|
||||
* @serial This value represents the type of object being de-serialized.
|
||||
* 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later.
|
||||
* 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later,
|
||||
* 2 indicates 1.4 or later
|
||||
*/
|
||||
private int serialVersionOnStream = 2;
|
||||
/**
|
||||
* @serial This is the character used to represent 0.
|
||||
*/
|
||||
private char zeroDigit;
|
||||
|
||||
/**
|
||||
* @serial The locale of these currency symbols.
|
||||
*/
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* The currency used for the symbols in this instance.
|
||||
* This is stored temporarily for efficiency reasons,
|
||||
* as well as to ensure that the correct instance
|
||||
* is restored from the currency code.
|
||||
*
|
||||
* @serial Ignored.
|
||||
*/
|
||||
private transient Currency currency;
|
||||
|
||||
private static final long serialVersionUID = 5772796243397350300L;
|
||||
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
stream.defaultReadObject();
|
||||
if (serialVersionOnStream < 1)
|
||||
{
|
||||
monetarySeparator = decimalSeparator;
|
||||
exponential = 'E';
|
||||
}
|
||||
if (serialVersionOnStream < 2)
|
||||
locale = Locale.getDefault();
|
||||
|
||||
serialVersionOnStream = 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/* FieldPosition.java -- Keeps track of field positions while formatting
|
||||
Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This class is used by the java.text formatting classes to track
|
||||
* field positions. A field position is defined by an identifier value
|
||||
* and begin and end index positions. The formatting classes in java.text
|
||||
* typically define constant values for the field identifiers.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
*/
|
||||
public class FieldPosition
|
||||
{
|
||||
/**
|
||||
* This is the field identifier value.
|
||||
*/
|
||||
private int field_id;
|
||||
|
||||
/**
|
||||
* This is the beginning index of the field.
|
||||
*/
|
||||
private int begin;
|
||||
|
||||
/**
|
||||
* This is the ending index of the field.
|
||||
*/
|
||||
private int end;
|
||||
|
||||
/**
|
||||
* This is the field attribute value.
|
||||
*/
|
||||
private Format.Field field_attribute;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>FieldPosition</code>
|
||||
* to have the specified field attribute. The attribute will be used as
|
||||
* an id. It is formally equivalent to calling FieldPosition(field, -1).
|
||||
*
|
||||
* @param field The field format attribute.
|
||||
*/
|
||||
public FieldPosition (Format.Field field)
|
||||
{
|
||||
this(field, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>FieldPosition</code>
|
||||
* to have the specified field attribute. The attribute will be used as
|
||||
* an id is non null. The integer field id is only used if the Format.Field
|
||||
* attribute is not used by the formatter.
|
||||
*
|
||||
* @param field The field format attribute.
|
||||
* @param field_id The field identifier value.
|
||||
*/
|
||||
public FieldPosition (Format.Field field, int field_id)
|
||||
{
|
||||
this.field_attribute = field;
|
||||
this.field_id = field_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>FieldPosition</code> to
|
||||
* have the specified field id.
|
||||
*
|
||||
* @param field_id The field identifier value.
|
||||
*/
|
||||
public FieldPosition (int field_id)
|
||||
{
|
||||
this.field_id = field_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the field identifier value for this object.
|
||||
*
|
||||
* @return The field identifier.
|
||||
*/
|
||||
public int getField ()
|
||||
{
|
||||
return field_id;
|
||||
}
|
||||
|
||||
public Format.Field getFieldAttribute ()
|
||||
{
|
||||
return field_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the beginning index for this field.
|
||||
*
|
||||
* @return The beginning index.
|
||||
*/
|
||||
public int getBeginIndex ()
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the beginning index of this field to the specified value.
|
||||
*
|
||||
* @param begin The new beginning index.
|
||||
*/
|
||||
public void setBeginIndex (int begin)
|
||||
{
|
||||
this.begin = begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ending index for the field.
|
||||
*
|
||||
* @return The ending index.
|
||||
*/
|
||||
public int getEndIndex ()
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the ending index of this field to the specified value.
|
||||
*
|
||||
* @param end The new ending index.
|
||||
*/
|
||||
public void setEndIndex (int end)
|
||||
{
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests this object for equality against the specified object.
|
||||
* The objects will be considered equal if and only if:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.
|
||||
* <li>The specified object has the same class as this object.
|
||||
* <li>The specified object has the same field identifier, field attribute
|
||||
* and beginning and ending index as this object.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The object to test for equality to this object.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to
|
||||
* this object, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (obj == null || obj.getClass() != this.getClass())
|
||||
return false;
|
||||
|
||||
FieldPosition fp = (FieldPosition) obj;
|
||||
return (field_id == fp.field_id
|
||||
&& (field_attribute == fp.field_attribute
|
||||
|| (field_attribute != null
|
||||
&& field_attribute.equals(fp.field_attribute)))
|
||||
&& begin == fp.begin
|
||||
&& end == fp.end);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object
|
||||
*
|
||||
* @return A hash value for this object.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
int hash = 5;
|
||||
|
||||
hash = 31 * hash + field_id;
|
||||
hash = 31 * hash + begin;
|
||||
hash = 31 * hash + end;
|
||||
hash = 31 * hash +
|
||||
(null == field_attribute ? 0 : field_attribute.hashCode());
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this
|
||||
* object.
|
||||
*
|
||||
* @return A <code>String</code> representation of this object.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return (getClass ().getName ()
|
||||
+ "[field=" + getField ()
|
||||
+ ",attribute=" + getFieldAttribute ()
|
||||
+ ",beginIndex=" + getBeginIndex ()
|
||||
+ ",endIndex=" + getEndIndex ()
|
||||
+ "]");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/* Format.java -- Abstract superclass for formatting/parsing strings.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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 gnu.java.text.FormatCharacterIterator;
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* For compatability with Sun's JDK 1.4.2 rev. 5
|
||||
*/
|
||||
static final long serialVersionUID = -299282585814624189L;
|
||||
|
||||
public static class Field extends AttributedCharacterIterator.Attribute
|
||||
{
|
||||
static final long serialVersionUID = 276966692217360283L;
|
||||
|
||||
protected Field(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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</code> 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);
|
||||
|
||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj)
|
||||
{
|
||||
return new FormatCharacterIterator(format(obj), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*
|
||||
* @return The copied <code>Object</code>.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone ();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,832 @@
|
||||
/* MessageFormat.java - Localized message formatting.
|
||||
Copyright (C) 1999, 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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 gnu.java.text.FormatCharacterIterator;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
|
||||
public class MessageFormat extends Format
|
||||
{
|
||||
/**
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Jorge Aliss (jaliss@hotmail.com)
|
||||
* @date March 3, 1999
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to 1.2, except serialization.
|
||||
* and parsing.
|
||||
*/
|
||||
private static final class MessageFormatElement
|
||||
{
|
||||
// Argument number.
|
||||
int argNumber;
|
||||
// Formatter to be used. This is the format set by setFormat.
|
||||
Format setFormat;
|
||||
// Formatter to be used based on the type.
|
||||
Format format;
|
||||
|
||||
// Argument will be checked to make sure it is an instance of this
|
||||
// class.
|
||||
Class formatClass;
|
||||
|
||||
// Formatter type.
|
||||
String type;
|
||||
// Formatter style.
|
||||
String style;
|
||||
|
||||
// Text to follow this element.
|
||||
String trailer;
|
||||
|
||||
// Recompute the locale-based formatter.
|
||||
void setLocale (Locale loc)
|
||||
{
|
||||
if (type == null)
|
||||
;
|
||||
else if (type.equals("number"))
|
||||
{
|
||||
formatClass = java.lang.Number.class;
|
||||
|
||||
if (style == null)
|
||||
format = NumberFormat.getInstance(loc);
|
||||
else if (style.equals("currency"))
|
||||
format = NumberFormat.getCurrencyInstance(loc);
|
||||
else if (style.equals("percent"))
|
||||
format = NumberFormat.getPercentInstance(loc);
|
||||
else if (style.equals("integer"))
|
||||
{
|
||||
NumberFormat nf = NumberFormat.getNumberInstance(loc);
|
||||
nf.setMaximumFractionDigits(0);
|
||||
nf.setGroupingUsed(false);
|
||||
format = nf;
|
||||
}
|
||||
else
|
||||
{
|
||||
format = NumberFormat.getNumberInstance(loc);
|
||||
DecimalFormat df = (DecimalFormat) format;
|
||||
df.applyPattern(style);
|
||||
}
|
||||
}
|
||||
else if (type.equals("time") || type.equals("date"))
|
||||
{
|
||||
formatClass = java.util.Date.class;
|
||||
|
||||
int val = DateFormat.DEFAULT;
|
||||
boolean styleIsPattern = false;
|
||||
if (style == null)
|
||||
;
|
||||
else if (style.equals("short"))
|
||||
val = DateFormat.SHORT;
|
||||
else if (style.equals("medium"))
|
||||
val = DateFormat.MEDIUM;
|
||||
else if (style.equals("long"))
|
||||
val = DateFormat.LONG;
|
||||
else if (style.equals("full"))
|
||||
val = DateFormat.FULL;
|
||||
else
|
||||
styleIsPattern = true;
|
||||
|
||||
if (type.equals("time"))
|
||||
format = DateFormat.getTimeInstance(val, loc);
|
||||
else
|
||||
format = DateFormat.getDateInstance(val, loc);
|
||||
|
||||
if (styleIsPattern)
|
||||
{
|
||||
SimpleDateFormat sdf = (SimpleDateFormat) format;
|
||||
sdf.applyPattern(style);
|
||||
}
|
||||
}
|
||||
else if (type.equals("choice"))
|
||||
{
|
||||
formatClass = java.lang.Number.class;
|
||||
|
||||
if (style == null)
|
||||
throw new
|
||||
IllegalArgumentException ("style required for choice format");
|
||||
format = new ChoiceFormat (style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 6479157306784022952L;
|
||||
|
||||
public static class Field extends Format.Field
|
||||
{
|
||||
static final long serialVersionUID = 7899943957617360810L;
|
||||
|
||||
/**
|
||||
* This is the attribute set for all characters produced
|
||||
* by MessageFormat during a formatting.
|
||||
*/
|
||||
public static final MessageFormat.Field ARGUMENT = new MessageFormat.Field("argument");
|
||||
|
||||
// For deserialization
|
||||
private Field()
|
||||
{
|
||||
super("");
|
||||
}
|
||||
|
||||
protected Field(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* invoked to resolve the true static constant by
|
||||
* comparing the deserialized object to know name.
|
||||
*
|
||||
* @return object constant
|
||||
*/
|
||||
protected Object readResolve() throws InvalidObjectException
|
||||
{
|
||||
if (getName().equals(ARGUMENT.getName()))
|
||||
return ARGUMENT;
|
||||
|
||||
throw new InvalidObjectException("no such MessageFormat field called " + getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Helper that returns the text up to the next format opener. The
|
||||
// text is put into BUFFER. Returns index of character after end of
|
||||
// string. Throws IllegalArgumentException on error.
|
||||
private static int scanString(String pat, int index, StringBuffer buffer)
|
||||
{
|
||||
int max = pat.length();
|
||||
buffer.setLength(0);
|
||||
boolean quoted = false;
|
||||
for (; index < max; ++index)
|
||||
{
|
||||
char c = pat.charAt(index);
|
||||
if (quoted)
|
||||
{
|
||||
// In a quoted context, a single quote ends the quoting.
|
||||
if (c == '\'')
|
||||
quoted = false;
|
||||
else
|
||||
buffer.append(c);
|
||||
}
|
||||
// Check for '', which is a single quote.
|
||||
else if (c == '\'' && index + 1 < max && pat.charAt(index + 1) == '\'')
|
||||
{
|
||||
buffer.append(c);
|
||||
++index;
|
||||
}
|
||||
else if (c == '\'')
|
||||
{
|
||||
// Start quoting.
|
||||
quoted = true;
|
||||
}
|
||||
else if (c == '{')
|
||||
break;
|
||||
else
|
||||
buffer.append(c);
|
||||
}
|
||||
// Note that we explicitly allow an unterminated quote. This is
|
||||
// done for compatibility.
|
||||
return index;
|
||||
}
|
||||
|
||||
// This helper retrieves a single part of a format element. Returns
|
||||
// the index of the terminating character.
|
||||
private static int scanFormatElement(String pat, int index,
|
||||
StringBuffer buffer, char term)
|
||||
{
|
||||
int max = pat.length();
|
||||
buffer.setLength(0);
|
||||
int brace_depth = 1;
|
||||
boolean quoted = false;
|
||||
|
||||
for (; index < max; ++index)
|
||||
{
|
||||
char c = pat.charAt(index);
|
||||
// First see if we should turn off quoting.
|
||||
if (quoted)
|
||||
{
|
||||
if (c == '\'')
|
||||
quoted = false;
|
||||
// In both cases we fall through to inserting the
|
||||
// character here.
|
||||
}
|
||||
// See if we have just a plain quote to insert.
|
||||
else if (c == '\'' && index + 1 < max
|
||||
&& pat.charAt(index + 1) == '\'')
|
||||
{
|
||||
buffer.append(c);
|
||||
++index;
|
||||
}
|
||||
// See if quoting should turn on.
|
||||
else if (c == '\'')
|
||||
quoted = true;
|
||||
else if (c == '{')
|
||||
++brace_depth;
|
||||
else if (c == '}')
|
||||
{
|
||||
if (--brace_depth == 0)
|
||||
break;
|
||||
}
|
||||
// Check for TERM after braces, because TERM might be `}'.
|
||||
else if (c == term)
|
||||
break;
|
||||
// All characters, including opening and closing quotes, are
|
||||
// inserted here.
|
||||
buffer.append(c);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// This is used to parse a format element and whatever non-format
|
||||
// text might trail it.
|
||||
private static int scanFormat(String pat, int index, StringBuffer buffer,
|
||||
Vector elts, Locale locale)
|
||||
{
|
||||
MessageFormatElement mfe = new MessageFormatElement ();
|
||||
elts.addElement(mfe);
|
||||
|
||||
int max = pat.length();
|
||||
|
||||
// Skip the opening `{'.
|
||||
++index;
|
||||
|
||||
// Fetch the argument number.
|
||||
index = scanFormatElement (pat, index, buffer, ',');
|
||||
try
|
||||
{
|
||||
mfe.argNumber = Integer.parseInt(buffer.toString());
|
||||
}
|
||||
catch (NumberFormatException nfx)
|
||||
{
|
||||
IllegalArgumentException iae = new IllegalArgumentException(pat);
|
||||
iae.initCause(nfx);
|
||||
throw iae;
|
||||
}
|
||||
|
||||
// Extract the element format.
|
||||
if (index < max && pat.charAt(index) == ',')
|
||||
{
|
||||
index = scanFormatElement (pat, index + 1, buffer, ',');
|
||||
mfe.type = buffer.toString();
|
||||
|
||||
// Extract the style.
|
||||
if (index < max && pat.charAt(index) == ',')
|
||||
{
|
||||
index = scanFormatElement (pat, index + 1, buffer, '}');
|
||||
mfe.style = buffer.toString ();
|
||||
}
|
||||
}
|
||||
|
||||
// Advance past the last terminator.
|
||||
if (index >= max || pat.charAt(index) != '}')
|
||||
throw new IllegalArgumentException("Missing '}' at end of message format");
|
||||
++index;
|
||||
|
||||
// Now fetch trailing string.
|
||||
index = scanString (pat, index, buffer);
|
||||
mfe.trailer = buffer.toString ();
|
||||
|
||||
mfe.setLocale(locale);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified pattern to this MessageFormat.
|
||||
*
|
||||
* @param aPattern The Pattern
|
||||
*/
|
||||
public void applyPattern (String newPattern)
|
||||
{
|
||||
pattern = newPattern;
|
||||
|
||||
StringBuffer tempBuffer = new StringBuffer ();
|
||||
|
||||
int index = scanString (newPattern, 0, tempBuffer);
|
||||
leader = tempBuffer.toString();
|
||||
|
||||
Vector elts = new Vector ();
|
||||
while (index < newPattern.length())
|
||||
index = scanFormat (newPattern, index, tempBuffer, elts, locale);
|
||||
|
||||
elements = new MessageFormatElement[elts.size()];
|
||||
elts.copyInto(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Format.clone()
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
MessageFormat c = (MessageFormat) super.clone ();
|
||||
c.elements = (MessageFormatElement[]) elements.clone ();
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Format.equals(Object obj)
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof MessageFormat))
|
||||
return false;
|
||||
MessageFormat mf = (MessageFormat) obj;
|
||||
return (pattern.equals(mf.pattern)
|
||||
&& locale.equals(mf.locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* A convinience method to format patterns.
|
||||
*
|
||||
* @param aPattern The pattern used when formatting.
|
||||
* @param arguments The array containing the objects to be formatted.
|
||||
*/
|
||||
public AttributedCharacterIterator formatToCharacterIterator (Object arguments)
|
||||
{
|
||||
Object[] arguments_array = (Object[])arguments;
|
||||
FormatCharacterIterator iterator = new FormatCharacterIterator();
|
||||
|
||||
formatInternal(arguments_array, new StringBuffer(), null, iterator);
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convinience method to format patterns.
|
||||
*
|
||||
* @param aPattern The pattern used when formatting.
|
||||
* @param arguments The array containing the objects to be formatted.
|
||||
*/
|
||||
public static String format (String pattern, Object arguments[])
|
||||
{
|
||||
MessageFormat mf = new MessageFormat (pattern);
|
||||
StringBuffer sb = new StringBuffer ();
|
||||
FieldPosition fp = new FieldPosition (NumberFormat.INTEGER_FIELD);
|
||||
return mf.formatInternal(arguments, sb, fp, null).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern with the formatted objects.
|
||||
*
|
||||
* @param source The array containing the objects to be formatted.
|
||||
* @param result The StringBuffer where the text is appened.
|
||||
* @param fp A FieldPosition object (it is ignored).
|
||||
*/
|
||||
public final StringBuffer format (Object arguments[], StringBuffer appendBuf,
|
||||
FieldPosition fp)
|
||||
{
|
||||
return formatInternal(arguments, appendBuf, fp, null);
|
||||
}
|
||||
|
||||
private StringBuffer formatInternal (Object arguments[],
|
||||
StringBuffer appendBuf,
|
||||
FieldPosition fp,
|
||||
FormatCharacterIterator output_iterator)
|
||||
{
|
||||
appendBuf.append(leader);
|
||||
if (output_iterator != null)
|
||||
output_iterator.append(leader);
|
||||
|
||||
for (int i = 0; i < elements.length; ++i)
|
||||
{
|
||||
Object thisArg = null;
|
||||
boolean unavailable = false;
|
||||
if (arguments == null || elements[i].argNumber >= arguments.length)
|
||||
unavailable = true;
|
||||
else
|
||||
thisArg = arguments[elements[i].argNumber];
|
||||
|
||||
AttributedCharacterIterator iterator = null;
|
||||
|
||||
Format formatter = null;
|
||||
|
||||
if (fp != null && i == fp.getField() && fp.getFieldAttribute() == Field.ARGUMENT)
|
||||
fp.setBeginIndex(appendBuf.length());
|
||||
|
||||
if (unavailable)
|
||||
appendBuf.append("{" + elements[i].argNumber + "}");
|
||||
else
|
||||
{
|
||||
if (elements[i].setFormat != null)
|
||||
formatter = elements[i].setFormat;
|
||||
else if (elements[i].format != null)
|
||||
{
|
||||
if (elements[i].formatClass != null
|
||||
&& ! elements[i].formatClass.isInstance(thisArg))
|
||||
throw new IllegalArgumentException("Wrong format class");
|
||||
|
||||
formatter = elements[i].format;
|
||||
}
|
||||
else if (thisArg instanceof Number)
|
||||
formatter = NumberFormat.getInstance(locale);
|
||||
else if (thisArg instanceof Date)
|
||||
formatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
|
||||
else
|
||||
appendBuf.append(thisArg);
|
||||
}
|
||||
|
||||
if (fp != null && fp.getField() == i && fp.getFieldAttribute() == Field.ARGUMENT)
|
||||
fp.setEndIndex(appendBuf.length());
|
||||
|
||||
if (formatter != null)
|
||||
{
|
||||
// Special-case ChoiceFormat.
|
||||
if (formatter instanceof ChoiceFormat)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer ();
|
||||
formatter.format(thisArg, buf, fp);
|
||||
MessageFormat mf = new MessageFormat ();
|
||||
mf.setLocale(locale);
|
||||
mf.applyPattern(buf.toString());
|
||||
mf.format(arguments, appendBuf, fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output_iterator != null)
|
||||
iterator = formatter.formatToCharacterIterator(thisArg);
|
||||
else
|
||||
formatter.format(thisArg, appendBuf, fp);
|
||||
}
|
||||
|
||||
elements[i].format = formatter;
|
||||
}
|
||||
|
||||
if (output_iterator != null)
|
||||
{
|
||||
HashMap hash_argument = new HashMap();
|
||||
int position = output_iterator.getEndIndex();
|
||||
|
||||
hash_argument.put (MessageFormat.Field.ARGUMENT,
|
||||
new Integer(elements[i].argNumber));
|
||||
|
||||
|
||||
if (iterator != null)
|
||||
{
|
||||
output_iterator.append(iterator);
|
||||
output_iterator.addAttributes(hash_argument, position,
|
||||
output_iterator.getEndIndex());
|
||||
}
|
||||
else
|
||||
output_iterator.append(thisArg.toString(), hash_argument);
|
||||
|
||||
output_iterator.append(elements[i].trailer);
|
||||
}
|
||||
|
||||
appendBuf.append(elements[i].trailer);
|
||||
}
|
||||
|
||||
return appendBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern with the formatted objects. The first argument
|
||||
* must be a array of Objects.
|
||||
* This is equivalent to format((Object[]) objectArray, appendBuf, fpos)
|
||||
*
|
||||
* @param objectArray The object array to be formatted.
|
||||
* @param appendBuf The StringBuffer where the text is appened.
|
||||
* @param fpos A FieldPosition object (it is ignored).
|
||||
*/
|
||||
public final StringBuffer format (Object objectArray, StringBuffer appendBuf,
|
||||
FieldPosition fpos)
|
||||
{
|
||||
return format ((Object[])objectArray, appendBuf, fpos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with the Formats for
|
||||
* the arguments.
|
||||
*/
|
||||
public Format[] getFormats ()
|
||||
{
|
||||
Format[] f = new Format[elements.length];
|
||||
for (int i = elements.length - 1; i >= 0; --i)
|
||||
f[i] = elements[i].setFormat;
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale.
|
||||
*/
|
||||
public Locale getLocale ()
|
||||
{
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Format.hashCode()
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
// FIXME: not a very good hash.
|
||||
return pattern.hashCode() + locale.hashCode();
|
||||
}
|
||||
|
||||
private MessageFormat ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new MessageFormat object with
|
||||
* the specified pattern
|
||||
*
|
||||
* @param pattern The Pattern
|
||||
*/
|
||||
public MessageFormat(String pattern)
|
||||
{
|
||||
this(pattern, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new MessageFormat object with
|
||||
* the specified pattern
|
||||
*
|
||||
* @param pattern The Pattern
|
||||
* @param locale The Locale to use
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public MessageFormat(String pattern, Locale locale)
|
||||
{
|
||||
this.locale = locale;
|
||||
applyPattern (pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string <code>sourceStr</code> against the pattern specified
|
||||
* to the MessageFormat constructor.
|
||||
*
|
||||
* @param sourceStr the string to be parsed.
|
||||
* @param pos the current parse position (and eventually the error position).
|
||||
* @return the array of parsed objects sorted according to their argument number
|
||||
* in the pattern.
|
||||
*/
|
||||
public Object[] parse (String sourceStr, ParsePosition pos)
|
||||
{
|
||||
// Check initial text.
|
||||
int index = pos.getIndex();
|
||||
if (! sourceStr.startsWith(leader, index))
|
||||
{
|
||||
pos.setErrorIndex(index);
|
||||
return null;
|
||||
}
|
||||
index += leader.length();
|
||||
|
||||
Vector results = new Vector (elements.length, 1);
|
||||
// Now check each format.
|
||||
for (int i = 0; i < elements.length; ++i)
|
||||
{
|
||||
Format formatter = null;
|
||||
if (elements[i].setFormat != null)
|
||||
formatter = elements[i].setFormat;
|
||||
else if (elements[i].format != null)
|
||||
formatter = elements[i].format;
|
||||
|
||||
Object value = null;
|
||||
if (formatter instanceof ChoiceFormat)
|
||||
{
|
||||
// We must special-case a ChoiceFormat because it might
|
||||
// have recursive formatting.
|
||||
ChoiceFormat cf = (ChoiceFormat) formatter;
|
||||
String[] formats = (String[]) cf.getFormats();
|
||||
double[] limits = (double[]) cf.getLimits();
|
||||
MessageFormat subfmt = new MessageFormat ();
|
||||
subfmt.setLocale(locale);
|
||||
ParsePosition subpos = new ParsePosition (index);
|
||||
|
||||
int j;
|
||||
for (j = 0; value == null && j < limits.length; ++j)
|
||||
{
|
||||
subfmt.applyPattern(formats[j]);
|
||||
subpos.setIndex(index);
|
||||
value = subfmt.parse(sourceStr, subpos);
|
||||
}
|
||||
if (value != null)
|
||||
{
|
||||
index = subpos.getIndex();
|
||||
value = new Double (limits[j]);
|
||||
}
|
||||
}
|
||||
else if (formatter != null)
|
||||
{
|
||||
pos.setIndex(index);
|
||||
value = formatter.parseObject(sourceStr, pos);
|
||||
if (value != null)
|
||||
index = pos.getIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have a String format. This can lose in a number
|
||||
// of ways, but we give it a shot.
|
||||
int next_index;
|
||||
if (elements[i].trailer.length() > 0)
|
||||
next_index = sourceStr.indexOf(elements[i].trailer, index);
|
||||
else
|
||||
next_index = sourceStr.length();
|
||||
if (next_index == -1)
|
||||
{
|
||||
pos.setErrorIndex(index);
|
||||
return null;
|
||||
}
|
||||
value = sourceStr.substring(index, next_index);
|
||||
index = next_index;
|
||||
}
|
||||
|
||||
if (value == null
|
||||
|| ! sourceStr.startsWith(elements[i].trailer, index))
|
||||
{
|
||||
pos.setErrorIndex(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (elements[i].argNumber >= results.size())
|
||||
results.setSize(elements[i].argNumber + 1);
|
||||
results.setElementAt(value, elements[i].argNumber);
|
||||
|
||||
index += elements[i].trailer.length();
|
||||
}
|
||||
|
||||
Object[] r = new Object[results.size()];
|
||||
results.copyInto(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public Object[] parse (String sourceStr) throws ParseException
|
||||
{
|
||||
ParsePosition pp = new ParsePosition (0);
|
||||
Object[] r = parse (sourceStr, pp);
|
||||
if (r == null)
|
||||
throw new ParseException ("couldn't parse string", pp.getErrorIndex());
|
||||
return r;
|
||||
}
|
||||
|
||||
public Object parseObject (String sourceStr, ParsePosition pos)
|
||||
{
|
||||
return parse (sourceStr, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the format for the argument at an specified
|
||||
* index.
|
||||
*
|
||||
* @param index The index.
|
||||
* @format The Format object.
|
||||
*/
|
||||
public void setFormat (int variableNum, Format newFormat)
|
||||
{
|
||||
elements[variableNum].setFormat = newFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the formats for the arguments.
|
||||
*
|
||||
* @param formats An array of Format objects.
|
||||
*/
|
||||
public void setFormats (Format[] newFormats)
|
||||
{
|
||||
if (newFormats.length < elements.length)
|
||||
throw new IllegalArgumentException("Not enough format objects");
|
||||
|
||||
int len = Math.min(newFormats.length, elements.length);
|
||||
for (int i = 0; i < len; ++i)
|
||||
elements[i].setFormat = newFormats[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale.
|
||||
*
|
||||
* @param locale A Locale
|
||||
*/
|
||||
public void setLocale (Locale loc)
|
||||
{
|
||||
locale = loc;
|
||||
if (elements != null)
|
||||
{
|
||||
for (int i = 0; i < elements.length; ++i)
|
||||
elements[i].setLocale(loc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern.
|
||||
*/
|
||||
public String toPattern ()
|
||||
{
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the formatters used sorted by argument index. It uses the
|
||||
* internal table to fill in this array: if a format has been
|
||||
* set using <code>setFormat</code> or <code>setFormatByArgumentIndex</code>
|
||||
* then it returns it at the right index. If not it uses the detected
|
||||
* formatters during a <code>format</code> call. If nothing is known
|
||||
* about that argument index it just puts null at that position.
|
||||
* To get useful informations you may have to call <code>format</code>
|
||||
* at least once.
|
||||
*
|
||||
* @return an array of formatters sorted by argument index.
|
||||
*/
|
||||
public Format[] getFormatsByArgumentIndex()
|
||||
{
|
||||
int argNumMax = 0;
|
||||
// First, find the greatest argument number.
|
||||
for (int i=0;i<elements.length;i++)
|
||||
if (elements[i].argNumber > argNumMax)
|
||||
argNumMax = elements[i].argNumber;
|
||||
|
||||
Format[] formats = new Format[argNumMax];
|
||||
for (int i=0;i<elements.length;i++)
|
||||
{
|
||||
if (elements[i].setFormat != null)
|
||||
formats[elements[i].argNumber] = elements[i].setFormat;
|
||||
else if (elements[i].format != null)
|
||||
formats[elements[i].argNumber] = elements[i].format;
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the format to used using the argument index number.
|
||||
*
|
||||
* @param argumentIndex the argument index.
|
||||
* @param newFormat the format to use for this argument.
|
||||
*/
|
||||
public void setFormatByArgumentIndex(int argumentIndex,
|
||||
Format newFormat)
|
||||
{
|
||||
for (int i=0;i<elements.length;i++)
|
||||
{
|
||||
if (elements[i].argNumber == argumentIndex)
|
||||
elements[i].setFormat = newFormat;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the format for argument using a specified array of formatters
|
||||
* which is sorted according to the argument index. If the number of
|
||||
* elements in the array is fewer than the number of arguments only
|
||||
* the arguments specified by the array are touched.
|
||||
*
|
||||
* @param newFormats array containing the new formats to set.
|
||||
*
|
||||
* @throws NullPointerException if newFormats is null
|
||||
*/
|
||||
public void setFormatsByArgumentIndex(Format[] newFormats)
|
||||
{
|
||||
for (int i=0;i<newFormats.length;i++)
|
||||
{
|
||||
// Nothing better than that can exist here.
|
||||
setFormatByArgumentIndex(i, newFormats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// The pattern string.
|
||||
private String pattern;
|
||||
// The locale.
|
||||
private Locale locale;
|
||||
// Variables.
|
||||
private MessageFormatElement[] elements;
|
||||
// Leader text.
|
||||
private String leader;
|
||||
}
|
||||
@@ -0,0 +1,808 @@
|
||||
/* NumberFormat.java -- Formats and parses numbers
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* This is the abstract superclass of all classes which format and
|
||||
* parse numeric values such as decimal numbers, integers, currency values,
|
||||
* and percentages. These classes perform their parsing and formatting
|
||||
* in a locale specific manner, accounting for such items as differing
|
||||
* currency symbols and thousands separators.
|
||||
* <p>
|
||||
* To create an instance of a concrete subclass of <code>NumberFormat</code>,
|
||||
* do not call a class constructor directly. Instead, use one of the
|
||||
* static factory methods in this class such as
|
||||
* <code>getCurrencyInstance</code>.
|
||||
*
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @date March 4, 1999
|
||||
*/
|
||||
/* Written using "Java Class Libraries", 2nd edition, plus online
|
||||
* API docs for JDK 1.2 from http://www.javasoft.com.
|
||||
* Status: Believed complete and correct to 1.2, except getAvailableLocales.
|
||||
*/
|
||||
public abstract class NumberFormat extends Format implements Cloneable
|
||||
{
|
||||
/**
|
||||
* This is a constant used to create a <code>FieldPosition</code> object
|
||||
* that will return the integer portion of a formatted number.
|
||||
*/
|
||||
public static final int INTEGER_FIELD = 0;
|
||||
|
||||
/**
|
||||
* This is a constant used to create a <code>FieldPosition</code> object
|
||||
* that will return the fractional portion of a formatted number.
|
||||
*/
|
||||
public static final int FRACTION_FIELD = 1;
|
||||
|
||||
public static class Field extends Format.Field
|
||||
{
|
||||
static final long serialVersionUID = 7494728892700160890L;
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing digits of the integer
|
||||
* part.
|
||||
*/
|
||||
public static final NumberFormat.Field INTEGER
|
||||
= new Field("integer");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing digits of the fractional
|
||||
* part.
|
||||
*/
|
||||
public static final NumberFormat.Field FRACTION
|
||||
= new Field("fraction");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing digits of the exponential
|
||||
* part.
|
||||
*/
|
||||
public static final NumberFormat.Field EXPONENT
|
||||
= new Field("exponent");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing a decimal separator.
|
||||
*/
|
||||
public static final NumberFormat.Field DECIMAL_SEPARATOR
|
||||
= new Field("decimal separator");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing a sign (plus or minus).
|
||||
*/
|
||||
public static final NumberFormat.Field SIGN
|
||||
= new Field("sign");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing a grouping separator (e.g.
|
||||
* a comma, a white space,...).
|
||||
*/
|
||||
public static final NumberFormat.Field GROUPING_SEPARATOR
|
||||
= new Field("grouping separator");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing an exponential symbol (e.g.
|
||||
* 'E')
|
||||
*/
|
||||
public static final NumberFormat.Field EXPONENT_SYMBOL
|
||||
= new Field("exponent symbol");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing a percent symbol (e.g. '%')
|
||||
*/
|
||||
public static final NumberFormat.Field PERCENT
|
||||
= new Field("percent");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing a permille symbol.
|
||||
*/
|
||||
public static final NumberFormat.Field PERMILLE
|
||||
= new Field("permille");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing the currency unit.
|
||||
*/
|
||||
public static final NumberFormat.Field CURRENCY
|
||||
= new Field("currency");
|
||||
|
||||
/**
|
||||
* Attribute set to all characters containing the exponent sign.
|
||||
*/
|
||||
public static final NumberFormat.Field EXPONENT_SIGN
|
||||
= new Field("exponent sign");
|
||||
|
||||
/**
|
||||
* Private fields to register all fields contained in this descriptor.
|
||||
*/
|
||||
private static final NumberFormat.Field[] allFields =
|
||||
{
|
||||
INTEGER, FRACTION, EXPONENT, DECIMAL_SEPARATOR, SIGN,
|
||||
GROUPING_SEPARATOR, EXPONENT_SYMBOL, PERCENT,
|
||||
PERMILLE, CURRENCY, EXPONENT_SIGN
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor is only used by the deserializer. Without it,
|
||||
* it would fail to construct a valid object.
|
||||
*/
|
||||
private Field()
|
||||
{
|
||||
super("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Field instance with the specified field name.
|
||||
*
|
||||
* @param field_name Field name for the new Field instance.
|
||||
*/
|
||||
protected Field(String field_name)
|
||||
{
|
||||
super (field_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used by the deserializer to know which object
|
||||
* to use when it encounters an encoded NumberFormat.Field in a
|
||||
* serialization stream. If the stream is valid it should return
|
||||
* one of the above field. In the other case we throw an exception.
|
||||
*
|
||||
* @return a valid official NumberFormat.Field instance.
|
||||
*
|
||||
* @throws InvalidObjectException if the field name is invalid.
|
||||
*/
|
||||
protected Object readResolve() throws InvalidObjectException
|
||||
{
|
||||
String s = getName();
|
||||
for (int i = 0; i < allFields.length; i++)
|
||||
if (s.equals(allFields[i].getName()))
|
||||
return allFields[i];
|
||||
|
||||
throw new InvalidObjectException("no such NumberFormat field called "
|
||||
+ s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a specialization of the format method that performs
|
||||
* a simple formatting of the specified <code>long</code> number.
|
||||
*
|
||||
* @param number The <code>long</code> to format.
|
||||
*
|
||||
* @return The formatted number
|
||||
*/
|
||||
public final String format (long number)
|
||||
{
|
||||
StringBuffer sbuf = new StringBuffer(50);
|
||||
format (number, sbuf, null);
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
public final StringBuffer format (Object obj, StringBuffer sbuf,
|
||||
FieldPosition pos)
|
||||
{
|
||||
if (obj instanceof Number)
|
||||
return format(((Number) obj).doubleValue(), sbuf, pos);
|
||||
else
|
||||
throw new IllegalArgumentException
|
||||
("Cannot format given Object as a Number");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats the specified <code>double</code> and appends it to
|
||||
* a <code>StringBuffer</code>.
|
||||
*
|
||||
* @param number The <code>double</code> to format.
|
||||
* @param sb The <code>StringBuffer</code> to append the formatted number to.
|
||||
* @param pos The desired <code>FieldPosition</code>.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> with the appended number.
|
||||
*/
|
||||
public abstract StringBuffer format (double number,
|
||||
StringBuffer sbuf, FieldPosition pos);
|
||||
|
||||
/**
|
||||
* This method formats the specified <code>long</code> and appends it to
|
||||
* a <code>StringBuffer</code>.
|
||||
*
|
||||
* @param number The <code>long</code> to format.
|
||||
* @param sb The <code>StringBuffer</code> to append the formatted number to.
|
||||
* @param pos The desired <code>FieldPosition</code>.
|
||||
*
|
||||
* @return The <code>StringBuffer</code> with the appended number.
|
||||
*/
|
||||
public abstract StringBuffer format (long number,
|
||||
StringBuffer sbuf, FieldPosition pos);
|
||||
|
||||
/**
|
||||
* This method tests the specified object for equality against this object.
|
||||
* This will be <code>true</code> if the following conditions are met:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.
|
||||
* <li>The specified object is an instance of <code>NumberFormat</code>.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Since this method does not test much, it is highly advised that
|
||||
* concrete subclasses override this method.
|
||||
*
|
||||
* @param obj The <code>Object</code> to test against equality with
|
||||
* this object.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to
|
||||
* this object, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof NumberFormat))
|
||||
return false;
|
||||
NumberFormat nf = (NumberFormat) obj;
|
||||
return (groupingUsed == nf.groupingUsed
|
||||
&& maximumFractionDigits == nf.maximumFractionDigits
|
||||
&& maximumIntegerDigits == nf.maximumIntegerDigits
|
||||
&& minimumFractionDigits == nf.minimumFractionDigits
|
||||
&& minimumIntegerDigits == nf.minimumIntegerDigits
|
||||
&& parseIntegerOnly == nf.parseIntegerOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a list of locales for which concrete instances
|
||||
* of <code>NumberFormat</code> subclasses may be created.
|
||||
*
|
||||
* @return The list of available locales.
|
||||
*/
|
||||
public static Locale[] getAvailableLocales ()
|
||||
{
|
||||
Locale[] list = new Locale[1];
|
||||
list[0] = Locale.US;
|
||||
return list;
|
||||
}
|
||||
|
||||
private static NumberFormat computeInstance(Locale loc, String resource,
|
||||
String def)
|
||||
{
|
||||
ResourceBundle res;
|
||||
try
|
||||
{
|
||||
res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
|
||||
loc, ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
res = null;
|
||||
}
|
||||
String fmt;
|
||||
try
|
||||
{
|
||||
fmt = res == null ? def : res.getString(resource);
|
||||
}
|
||||
catch (MissingResourceException x)
|
||||
{
|
||||
fmt = def;
|
||||
}
|
||||
DecimalFormatSymbols dfs = new DecimalFormatSymbols (loc);
|
||||
return new DecimalFormat (fmt, dfs);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>NumberFormat</code> suitable
|
||||
* for formatting and parsing currency values in the default locale.
|
||||
*
|
||||
* @return An instance of <code>NumberFormat</code> for handling currencies.
|
||||
*/
|
||||
public static final NumberFormat getCurrencyInstance ()
|
||||
{
|
||||
return getCurrencyInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>NumberFormat</code> suitable
|
||||
* for formatting and parsing currency values in the specified locale.
|
||||
*
|
||||
* @return An instance of <code>NumberFormat</code> for handling currencies.
|
||||
*/
|
||||
public static NumberFormat getCurrencyInstance (Locale loc)
|
||||
{
|
||||
NumberFormat format;
|
||||
|
||||
format = computeInstance (loc, "currencyFormat", "$#,##0.00;($#,##0.00)");
|
||||
format.setMaximumFractionDigits(format.getCurrency().getDefaultFractionDigits());
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a default instance for the default locale. This
|
||||
* will be a concrete subclass of <code>NumberFormat</code>, but the
|
||||
* actual class returned is dependent on the locale.
|
||||
*
|
||||
* @return An instance of the default <code>NumberFormat</code> class.
|
||||
*/
|
||||
public static final NumberFormat getInstance ()
|
||||
{
|
||||
return getInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a default instance for the specified locale. This
|
||||
* will be a concrete subclass of <code>NumberFormat</code>, but the
|
||||
* actual class returned is dependent on the locale.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return An instance of the default <code>NumberFormat</code> class.
|
||||
*/
|
||||
public static NumberFormat getInstance (Locale loc)
|
||||
{
|
||||
// For now always return a number instance.
|
||||
return getNumberInstance (loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the maximum number of digits allowed in the fraction
|
||||
* portion of a number.
|
||||
*
|
||||
* @return The maximum number of digits allowed in the fraction
|
||||
* portion of a number.
|
||||
*/
|
||||
public int getMaximumFractionDigits ()
|
||||
{
|
||||
return maximumFractionDigits;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the maximum number of digits allowed in the integer
|
||||
* portion of a number.
|
||||
*
|
||||
* @return The maximum number of digits allowed in the integer
|
||||
* portion of a number.
|
||||
*/
|
||||
public int getMaximumIntegerDigits ()
|
||||
{
|
||||
return maximumIntegerDigits;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the minimum number of digits allowed in the fraction
|
||||
* portion of a number.
|
||||
*
|
||||
* @return The minimum number of digits allowed in the fraction
|
||||
* portion of a number.
|
||||
*/
|
||||
public int getMinimumFractionDigits ()
|
||||
{
|
||||
return minimumFractionDigits;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the minimum number of digits allowed in the integer
|
||||
* portion of a number.
|
||||
*
|
||||
* @return The minimum number of digits allowed in the integer
|
||||
* portion of a number.
|
||||
*/
|
||||
public int getMinimumIntegerDigits ()
|
||||
{
|
||||
return minimumIntegerDigits;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a default instance for the specified locale. This
|
||||
* will be a concrete subclass of <code>NumberFormat</code>, but the
|
||||
* actual class returned is dependent on the locale.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return An instance of the default <code>NumberFormat</code> class.
|
||||
*/
|
||||
public static final NumberFormat getNumberInstance ()
|
||||
{
|
||||
return getNumberInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a general purpose number formatting and parsing
|
||||
* class for the default locale. This will be a concrete subclass of
|
||||
* <code>NumberFormat</code>, but the actual class returned is dependent
|
||||
* on the locale.
|
||||
*
|
||||
* @return An instance of a generic number formatter for the default locale.
|
||||
*/
|
||||
public static NumberFormat getNumberInstance (Locale loc)
|
||||
{
|
||||
return computeInstance (loc, "numberFormat", "#,##0.###");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an integer formatting and parsing class for the
|
||||
* default locale. This will be a concrete subclass of <code>NumberFormat</code>,
|
||||
* but the actual class returned is dependent on the locale.
|
||||
*
|
||||
* @return An instance of an integer number formatter for the default locale.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final NumberFormat getIntegerInstance()
|
||||
{
|
||||
return getIntegerInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an integer formatting and parsing class for the
|
||||
* default locale. This will be a concrete subclass of <code>NumberFormat</code>,
|
||||
* but the actual class returned is dependent on the locale.
|
||||
*
|
||||
* @param locale the desired locale.
|
||||
*
|
||||
* @return An instance of an integer number formatter for the desired locale.
|
||||
* @since 1.4
|
||||
*/
|
||||
public static NumberFormat getIntegerInstance(Locale locale)
|
||||
{
|
||||
NumberFormat format = computeInstance (locale, "numberFormat", "#,##0");
|
||||
format.setMaximumFractionDigits(0);
|
||||
format.setParseIntegerOnly (true);
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>NumberFormat</code> suitable
|
||||
* for formatting and parsing percentage values in the default locale.
|
||||
*
|
||||
* @return An instance of <code>NumberFormat</code> for handling percentages.
|
||||
*/
|
||||
public static final NumberFormat getPercentInstance ()
|
||||
{
|
||||
return getPercentInstance (Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an instance of <code>NumberFormat</code> suitable
|
||||
* for formatting and parsing percentage values in the specified locale.
|
||||
*
|
||||
* @param locale The desired locale.
|
||||
*
|
||||
* @return An instance of <code>NumberFormat</code> for handling percentages.
|
||||
*/
|
||||
public static NumberFormat getPercentInstance (Locale loc)
|
||||
{
|
||||
return computeInstance (loc, "percentFormat", "#,##0%");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a hash value for this object.
|
||||
*
|
||||
* @return The hash code.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
int hash = super.hashCode();
|
||||
hash ^= (maximumFractionDigits + maximumIntegerDigits
|
||||
+ minimumFractionDigits + minimumIntegerDigits);
|
||||
if (groupingUsed)
|
||||
hash ^= 0xf0f0;
|
||||
if (parseIntegerOnly)
|
||||
hash ^= 0x0f0f;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests whether or not grouping is in use. Grouping is
|
||||
* a method of marking separations in numbers, such as thousand separators
|
||||
* in the US English locale. The grouping positions and symbols are all
|
||||
* locale specific. As an example, with grouping disabled, the number one
|
||||
* million would appear as "1000000". With grouping enabled, this number
|
||||
* might appear as "1,000,000". (Both of these assume the US English
|
||||
* locale).
|
||||
*
|
||||
* @return <code>true</code> if grouping is enabled,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isGroupingUsed ()
|
||||
{
|
||||
return groupingUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests whether or not only integer values should be parsed.
|
||||
* If this class is parsing only integers, parsing stops at the decimal
|
||||
* point.
|
||||
*
|
||||
* @return <code>true</code> if only integers are parsed,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isParseIntegerOnly ()
|
||||
{
|
||||
return parseIntegerOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a default constructor for use by subclasses.
|
||||
*/
|
||||
public NumberFormat ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the specified string into a <code>Number</code>. This
|
||||
* will be a <code>Long</code> if possible, otherwise it will be a
|
||||
* <code>Double</code>. If no number can be parsed, no exception is
|
||||
* thrown. Instead, the parse position remains at its initial index.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param pp The desired <code>ParsePosition</code>.
|
||||
*
|
||||
* @return The parsed <code>Number</code>
|
||||
*/
|
||||
public abstract Number parse (String sourceStr, ParsePosition pos);
|
||||
|
||||
/**
|
||||
* This method parses the specified string into a <code>Number</code>. This
|
||||
* will be a <code>Long</code> if possible, otherwise it will be a
|
||||
* <code>Double</code>. If no number can be parsed, an exception will be
|
||||
* thrown.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
*
|
||||
* @return The parsed <code>Number</code>
|
||||
*
|
||||
* @exception ParseException If no number can be parsed.
|
||||
*/
|
||||
public Number parse (String sourceStr) throws ParseException
|
||||
{
|
||||
ParsePosition pp = new ParsePosition (0);
|
||||
Number r = parse (sourceStr, pp);
|
||||
if (r == null)
|
||||
{
|
||||
int index = pp.getErrorIndex();
|
||||
if (index < 0)
|
||||
index = pp.getIndex();
|
||||
throw new ParseException ("couldn't parse number", index);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method parses the specified string into an <code>Object</code>. This
|
||||
* will be a <code>Long</code> if possible, otherwise it will be a
|
||||
* <code>Double</code>. If no number can be parsed, no exception is
|
||||
* thrown. Instead, the parse position remains at its initial index.
|
||||
*
|
||||
* @param str The string to parse.
|
||||
* @param pp The desired <code>ParsePosition</code>.
|
||||
*
|
||||
* @return The parsed <code>Object</code>
|
||||
*/
|
||||
public final Object parseObject (String sourceStr, ParsePosition pos)
|
||||
{
|
||||
return parse (sourceStr, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the grouping behavior of this formatter. Grouping is
|
||||
* a method of marking separations in numbers, such as thousand separators
|
||||
* in the US English locale. The grouping positions and symbols are all
|
||||
* locale specific. As an example, with grouping disabled, the number one
|
||||
* million would appear as "1000000". With grouping enabled, this number
|
||||
* might appear as "1,000,000". (Both of these assume the US English
|
||||
* locale).
|
||||
*
|
||||
* @param groupingUsed <code>true</code> to enable grouping,
|
||||
* <code>false</code> to disable it.
|
||||
*/
|
||||
public void setGroupingUsed (boolean newValue)
|
||||
{
|
||||
groupingUsed = newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the maximum number of digits allowed in the fraction
|
||||
* portion of a number to the specified value. If this is less than the
|
||||
* current minimum allowed digits, the minimum allowed digits value will
|
||||
* be lowered to be equal to the new maximum allowed digits value.
|
||||
*
|
||||
* @param maximumFractionDigits The new maximum fraction digits value.
|
||||
*/
|
||||
public void setMaximumFractionDigits (int newValue)
|
||||
{
|
||||
maximumFractionDigits = newValue;
|
||||
if (getMinimumFractionDigits () > maximumFractionDigits)
|
||||
setMinimumFractionDigits (maximumFractionDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the maximum number of digits allowed in the integer
|
||||
* portion of a number to the specified value. If this is less than the
|
||||
* current minimum allowed digits, the minimum allowed digits value will
|
||||
* be lowered to be equal to the new maximum allowed digits value.
|
||||
*
|
||||
* @param maximumIntegerDigits The new maximum integer digits value.
|
||||
*/
|
||||
public void setMaximumIntegerDigits (int newValue)
|
||||
{
|
||||
maximumIntegerDigits = newValue;
|
||||
if (getMinimumIntegerDigits () > maximumIntegerDigits)
|
||||
setMinimumIntegerDigits (maximumIntegerDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the minimum number of digits allowed in the fraction
|
||||
* portion of a number to the specified value. If this is greater than the
|
||||
* current maximum allowed digits, the maximum allowed digits value will
|
||||
* be raised to be equal to the new minimum allowed digits value.
|
||||
*
|
||||
* @param minimumFractionDigits The new minimum fraction digits value.
|
||||
*/
|
||||
public void setMinimumFractionDigits (int newValue)
|
||||
{
|
||||
minimumFractionDigits = newValue;
|
||||
if (getMaximumFractionDigits () < minimumFractionDigits)
|
||||
setMaximumFractionDigits (minimumFractionDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the minimum number of digits allowed in the integer
|
||||
* portion of a number to the specified value. If this is greater than the
|
||||
* current maximum allowed digits, the maximum allowed digits value will
|
||||
* be raised to be equal to the new minimum allowed digits value.
|
||||
*
|
||||
* @param minimumIntegerDigits The new minimum integer digits value.
|
||||
*/
|
||||
public void setMinimumIntegerDigits (int newValue)
|
||||
{
|
||||
minimumIntegerDigits = newValue;
|
||||
if (getMaximumIntegerDigits () < minimumIntegerDigits)
|
||||
setMaximumIntegerDigits (minimumIntegerDigits);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the parsing behavior of this object to parse only
|
||||
* integers or not.
|
||||
*
|
||||
* @param parseIntegerOnly <code>true</code> to parse only integers,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public void setParseIntegerOnly (boolean value)
|
||||
{
|
||||
parseIntegerOnly = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a specialization of the format method that performs
|
||||
* a simple formatting of the specified <code>double</code> number.
|
||||
*
|
||||
* @param number The <code>double</code> to format.
|
||||
*
|
||||
* @return The formatted number
|
||||
*/
|
||||
public final String format (double number)
|
||||
{
|
||||
StringBuffer sbuf = new StringBuffer(50);
|
||||
format (number, sbuf, null);
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
// These field names are fixed by the serialization spec.
|
||||
boolean groupingUsed;
|
||||
int maximumFractionDigits;
|
||||
private byte maxFractionDigits;
|
||||
int maximumIntegerDigits;
|
||||
private byte maxIntegerDigits;
|
||||
int minimumFractionDigits;
|
||||
private byte minFractionDigits;
|
||||
int minimumIntegerDigits;
|
||||
private byte minIntegerDigits;
|
||||
boolean parseIntegerOnly;
|
||||
private int serialVersionOnStream;
|
||||
private static final long serialVersionUID = -2308460125733713944L;
|
||||
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
stream.defaultReadObject();
|
||||
if (serialVersionOnStream < 1)
|
||||
{
|
||||
maximumFractionDigits = maxFractionDigits;
|
||||
maximumIntegerDigits = maxIntegerDigits;
|
||||
minimumFractionDigits = minFractionDigits;
|
||||
minimumIntegerDigits = minIntegerDigits;
|
||||
serialVersionOnStream = 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException
|
||||
{
|
||||
maxFractionDigits = maximumFractionDigits < Byte.MAX_VALUE ?
|
||||
(byte) maximumFractionDigits : Byte.MAX_VALUE;
|
||||
maxIntegerDigits = maximumIntegerDigits < Byte.MAX_VALUE ?
|
||||
(byte) maximumIntegerDigits : Byte.MAX_VALUE;
|
||||
minFractionDigits = minimumFractionDigits < Byte.MAX_VALUE ?
|
||||
(byte) minimumFractionDigits : Byte.MAX_VALUE;
|
||||
minIntegerDigits = minimumIntegerDigits < Byte.MAX_VALUE ?
|
||||
(byte) minimumIntegerDigits : Byte.MAX_VALUE;
|
||||
serialVersionOnStream = 1;
|
||||
stream.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currency used by this number format when formatting currency
|
||||
* values.
|
||||
*
|
||||
* The default implementation throws UnsupportedOperationException.
|
||||
*
|
||||
* @return The used currency object, or null.
|
||||
*
|
||||
* @throws UnsupportedOperationException If the number format class doesn't
|
||||
* implement currency formatting.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public Currency getCurrency()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currency used by this number format when formatting currency
|
||||
* values.
|
||||
*
|
||||
* The default implementation throws UnsupportedOperationException.
|
||||
*
|
||||
* @param currency The new currency to be used by this number format.
|
||||
*
|
||||
* @throws NullPointerException If currenc is null.
|
||||
* @throws UnsupportedOperationException If the number format class doesn't
|
||||
* implement currency formatting.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public void setCurrency(Currency currency)
|
||||
{
|
||||
if (currency == null)
|
||||
throw new NullPointerException("currency may not be null");
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* ParseException.java -- an error occurred while parsing
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an unexpected error occurs during parsing.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
* @see Format
|
||||
* @see FieldPosition
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class ParseException extends Exception
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.1+.
|
||||
*/
|
||||
private static final long serialVersionUID = 2703218443322787634L;
|
||||
|
||||
/**
|
||||
* This is the position where the error was encountered.
|
||||
*
|
||||
* @serial the zero-based offset in the string where the error occurred
|
||||
*/
|
||||
private final int errorOffset;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>ParseException</code>
|
||||
* with a detailed error message and a error position.
|
||||
*
|
||||
* @param msg the descriptive message describing the error
|
||||
* @param offset the position where the error was encountered
|
||||
*/
|
||||
public ParseException(String s, int offset)
|
||||
{
|
||||
super(s);
|
||||
errorOffset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the position where the error occurred.
|
||||
*
|
||||
* @return the position where the error occurred
|
||||
*/
|
||||
public int getErrorOffset()
|
||||
{
|
||||
return errorOffset;
|
||||
}
|
||||
} // class ParseException
|
||||
@@ -0,0 +1,151 @@
|
||||
/* ParsePosition.java -- Keep track of position while parsing.
|
||||
Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This class is used to keep track of the current position during parsing
|
||||
* operations.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
*/
|
||||
public class ParsePosition
|
||||
{
|
||||
/**
|
||||
* This is the index of the current parse position.
|
||||
*/
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* This is the index of the position where an error occurred during parsing.
|
||||
*/
|
||||
private int error_index;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of <code>ParsePosition</code> to
|
||||
* have the specified initial index value.
|
||||
*
|
||||
* @param index The initial parsing index.
|
||||
*/
|
||||
public ParsePosition (int index)
|
||||
{
|
||||
this.index = index;
|
||||
error_index = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current parsing index.
|
||||
*
|
||||
* @return The current parsing index
|
||||
*/
|
||||
public int getIndex ()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the current parsing index to the specified value.
|
||||
*
|
||||
* @param index The new parsing index.
|
||||
*/
|
||||
public void setIndex (int index)
|
||||
{
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the error index value. This value defaults to -1
|
||||
* unless explicitly set to another value.
|
||||
*
|
||||
* @return The error index.
|
||||
*/
|
||||
public int getErrorIndex ()
|
||||
{
|
||||
return error_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the error index to the specified value.
|
||||
*
|
||||
* @param error_index The new error index
|
||||
*/
|
||||
public void setErrorIndex (int error_index)
|
||||
{
|
||||
this.error_index = error_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tests the specified object for equality with this
|
||||
* object. The two objects will be considered equal if and only if
|
||||
* all of the following conditions are met.
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The specified object is not <code>null</code>.</li>
|
||||
* <li>The specified object is an instance of <code>ParsePosition</code>.</li>
|
||||
* <li>The specified object has the same index and error index as
|
||||
* this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The <code>Object</code> to test for equality against
|
||||
* this object.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to
|
||||
* this object, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof ParsePosition))
|
||||
return false;
|
||||
|
||||
ParsePosition other = (ParsePosition) obj;
|
||||
return index == other.index && error_index == other.error_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a <code>String</code> representation of this
|
||||
* object.
|
||||
*
|
||||
* @return A <code>String</code> that represents this object.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return (getClass ().getName () + "[index=" + getIndex ()
|
||||
+ ",errorIndex=" + getErrorIndex () + "]");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,356 @@
|
||||
/* StringCharacterIterator.java -- Iterate over a character range in a string
|
||||
Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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;
|
||||
|
||||
/**
|
||||
* This class iterates over a range of characters in a <code>String</code>.
|
||||
* For a given range of text, a beginning and ending index,
|
||||
* as well as a current index are defined. These values can be queried
|
||||
* by the methods in this interface. Additionally, various methods allow
|
||||
* the index to be set.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Tom Tromey (tromey@cygnus.com)
|
||||
*/
|
||||
public final class StringCharacterIterator implements CharacterIterator
|
||||
{
|
||||
/**
|
||||
* This is the string to iterate over
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* This is the value of the start position of the text range.
|
||||
*/
|
||||
private int begin;
|
||||
|
||||
/**
|
||||
* This is the value of the ending position of the text range.
|
||||
*/
|
||||
private int end;
|
||||
|
||||
/**
|
||||
* This is the current value of the scan index.
|
||||
*/
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of
|
||||
* <code>StringCharacterIterator</code> to iterate over the entire
|
||||
* text of the specified <code>String</code>. The initial index
|
||||
* value will be set to the first character in the string.
|
||||
*
|
||||
* @param text The <code>String</code> to iterate through.
|
||||
*/
|
||||
public StringCharacterIterator (String text)
|
||||
{
|
||||
this (text, 0, text.length (), 0);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of
|
||||
* <code>StringCharacterIterator</code> to iterate over the entire
|
||||
* text of the specified <code>String</code>. The initial index
|
||||
* value will be set to the specified value.
|
||||
*
|
||||
* @param text The <code>String</code> to iterate through.
|
||||
* @param index The initial index position.
|
||||
*/
|
||||
public StringCharacterIterator (String text, int index)
|
||||
{
|
||||
this (text, 0, text.length (), index);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method initializes a new instance of
|
||||
* <code>StringCharacterIterator</code> that iterates over the text
|
||||
* in a subrange of the specified <code>String</code>. The
|
||||
* beginning and end of the range are specified by the caller, as is
|
||||
* the initial index position.
|
||||
*
|
||||
* @param text The <code>String</code> to iterate through.
|
||||
* @param begin The beginning position in the character range.
|
||||
* @param end The ending position in the character range.
|
||||
* @param index The initial index position.
|
||||
*
|
||||
* @param IllegalArgumentException If any of the range values are
|
||||
* invalid.
|
||||
*/
|
||||
public StringCharacterIterator (String text, int begin, int end, int index)
|
||||
{
|
||||
int len = text.length ();
|
||||
|
||||
if ((begin < 0) || (begin > len))
|
||||
throw new IllegalArgumentException ("Bad begin position");
|
||||
|
||||
if ((end < begin) || (end > len))
|
||||
throw new IllegalArgumentException ("Bad end position");
|
||||
|
||||
if ((index < begin) || (index > end))
|
||||
throw new IllegalArgumentException ("Bad initial index position");
|
||||
|
||||
this.text = text;
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a package level constructor that copies the text out of
|
||||
* an existing StringCharacterIterator and resets the beginning and
|
||||
* ending index.
|
||||
*
|
||||
* @param scci The StringCharacterIterator to copy the info from
|
||||
* @param begin The beginning index of the range we are interested in.
|
||||
* @param end The ending index of the range we are interested in.
|
||||
*/
|
||||
StringCharacterIterator (StringCharacterIterator sci, int begin, int end)
|
||||
{
|
||||
this (sci.text, begin, end, begin);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the character at the current index position
|
||||
*
|
||||
* @return The character at the current index position.
|
||||
*/
|
||||
public char current ()
|
||||
{
|
||||
return (index < end) ? text.charAt (index) : DONE;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method increments the current index and then returns the
|
||||
* character at the new index value. If the index is already at
|
||||
* <code>getEndIndex () - 1</code>, it will not be incremented.
|
||||
*
|
||||
* @return The character at the position of the incremented index
|
||||
* value, or <code>DONE</code> if the index has reached
|
||||
* getEndIndex () - 1.
|
||||
*/
|
||||
public char next ()
|
||||
{
|
||||
if (index == end)
|
||||
return DONE;
|
||||
|
||||
++index;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method decrements the current index and then returns the
|
||||
* character at the new index value. If the index value is already
|
||||
* at the beginning index, it will not be decremented.
|
||||
*
|
||||
* @return The character at the position of the decremented index
|
||||
* value, or <code>DONE</code> if index was already equal to the
|
||||
* beginning index value.
|
||||
*/
|
||||
public char previous ()
|
||||
{
|
||||
if (index == begin)
|
||||
return DONE;
|
||||
|
||||
--index;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method sets the index value to the beginning of the range and returns
|
||||
* the character there.
|
||||
*
|
||||
* @return The character at the beginning of the range, or
|
||||
* <code>DONE</code> if the range is empty.
|
||||
*/
|
||||
public char first ()
|
||||
{
|
||||
index = begin;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method sets the index value to <code>getEndIndex () - 1</code> and
|
||||
* returns the character there. If the range is empty, then the index value
|
||||
* will be set equal to the beginning index.
|
||||
*
|
||||
* @return The character at the end of the range, or
|
||||
* <code>DONE</code> if the range is empty.
|
||||
*/
|
||||
public char last ()
|
||||
{
|
||||
if (end == begin)
|
||||
return DONE;
|
||||
|
||||
index = end - 1;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns the current value of the index.
|
||||
*
|
||||
* @return The current index value
|
||||
*/
|
||||
public int getIndex ()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method sets the value of the index to the specified value, then
|
||||
* returns the character at that position.
|
||||
*
|
||||
* @param index The new index value.
|
||||
*
|
||||
* @return The character at the new index value or <code>DONE</code>
|
||||
* if the index value is equal to <code>getEndIndex</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException If the specified index is not valid
|
||||
*/
|
||||
public char setIndex (int index)
|
||||
{
|
||||
if ((index < begin) || (index > end))
|
||||
throw new IllegalArgumentException ("Bad index specified");
|
||||
|
||||
this.index = index;
|
||||
return current ();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns the character position of the first character in the
|
||||
* range.
|
||||
*
|
||||
* @return The index of the first character in the range.
|
||||
*/
|
||||
public int getBeginIndex ()
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method returns the character position of the end of the text range.
|
||||
* This will actually be the index of the first character following the
|
||||
* end of the range. In the event the text range is empty, this will be
|
||||
* equal to the first character in the range.
|
||||
*
|
||||
* @return The index of the end of the range.
|
||||
*/
|
||||
public int getEndIndex ()
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method creates a copy of this <code>CharacterIterator</code>.
|
||||
*
|
||||
* @return A copy of this <code>CharacterIterator</code>.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
return new StringCharacterIterator (text, begin, end, index);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method tests this object for equality againt the specified
|
||||
* object. This will be true if and only if the specified object:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>is not <code>null</code>.</li>
|
||||
* <li>is an instance of <code>StringCharacterIterator</code></li>
|
||||
* <li>has the same text as this object</li>
|
||||
* <li>has the same beginning, ending, and current index as this object.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj The object to test for equality against.
|
||||
*
|
||||
* @return <code>true</code> if the specified object is equal to this
|
||||
* object, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
if (! (obj instanceof StringCharacterIterator))
|
||||
return false;
|
||||
|
||||
StringCharacterIterator sci = (StringCharacterIterator) obj;
|
||||
|
||||
return (begin == sci.begin
|
||||
&& end == sci.end
|
||||
&& index == sci.index
|
||||
&& text.equals (sci.text));
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* This method allows other classes in java.text to change the value
|
||||
* of the underlying text being iterated through.
|
||||
*
|
||||
* @param text The new <code>String</code> to iterate through.
|
||||
*/
|
||||
public void setText (String text)
|
||||
{
|
||||
this.text = text;
|
||||
this.begin = 0;
|
||||
this.end = text.length ();
|
||||
this.index = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
# This property file contains dependencies of classes, methods, and
|
||||
# field on other methods or classes.
|
||||
#
|
||||
# Syntax:
|
||||
#
|
||||
# <used>: <needed 1> [... <needed N>]
|
||||
#
|
||||
# means that when <used> is included, <needed 1> (... <needed N>) must
|
||||
# be included as well.
|
||||
#
|
||||
# <needed X> and <used> are of the form
|
||||
#
|
||||
# <class.methodOrField(signature)>
|
||||
#
|
||||
# or just
|
||||
#
|
||||
# <class>
|
||||
#
|
||||
# Within dependencies, variables can be used. A variable is defined as
|
||||
# follows:
|
||||
#
|
||||
# {variable}: value1 value2 ... value<n>
|
||||
#
|
||||
# variables can be used on the right side of dependencies as follows:
|
||||
#
|
||||
# <used>: com.bla.blu.{variable}.Class.m()V
|
||||
#
|
||||
# The use of the variable will expand to <n> dependencies of the form
|
||||
#
|
||||
# <used>: com.bla.blu.value1.Class.m()V
|
||||
# <used>: com.bla.blu.value2.Class.m()V
|
||||
# ...
|
||||
# <used>: com.bla.blu.value<n>.Class.m()V
|
||||
#
|
||||
# Variables can be redefined when building a system to select the
|
||||
# required support for features like encodings, protocols, etc.
|
||||
#
|
||||
# Hints:
|
||||
#
|
||||
# - For methods and fields, the signature is mandatory. For
|
||||
# specification, please see the Java Virtual Machine Specification by
|
||||
# SUN. Unlike in the spec, field signatures (types) are in brackets.
|
||||
#
|
||||
# - Package names must be separated by '/' (and not '.'). E.g.,
|
||||
# java/lang/Class (this is necessary, because the '.' is used to
|
||||
# separate method or field names from classes)
|
||||
#
|
||||
# - In case <needed> refers to a class, only the class itself will be
|
||||
# included in the resulting binary, NOT necessarily all its methods
|
||||
# and fields. If you want to refer to all methods and fields, you can
|
||||
# write class.* as an abbreviation.
|
||||
#
|
||||
# - Abbreviations for packages are also possible: my/package/* means all
|
||||
# methods and fields of all classes in my/package.
|
||||
#
|
||||
# - A line with a trailing '\' continues in the next line.
|
||||
|
||||
# end of file
|
||||
|
||||
# All locales supported are loaded via classes from java.text (see below)
|
||||
# from class gnu/java/locale/LocaleInformation_<locale_id>
|
||||
#
|
||||
# This introduces a dependency for all locales. To allow an easy selection
|
||||
# and addition of locales, the library variable {text_locales} can be set to
|
||||
# the set of supported locales.
|
||||
#
|
||||
|
||||
{text_locales}: \
|
||||
af_ZA \
|
||||
ar_AE \
|
||||
ar_BH \
|
||||
ar_DZ \
|
||||
ar_EG \
|
||||
ar_IN \
|
||||
ar_IQ \
|
||||
ar_JO \
|
||||
ar_KW \
|
||||
ar_LB \
|
||||
ar_LY \
|
||||
ar_MA \
|
||||
ar_OM \
|
||||
ar_QA \
|
||||
ar_SD \
|
||||
ar_SY \
|
||||
ar_TN \
|
||||
ar_YE \
|
||||
be_BY \
|
||||
bn_IN \
|
||||
br_FR \
|
||||
bs_BA \
|
||||
ca_ES \
|
||||
cs_CZ \
|
||||
cy_GB \
|
||||
da_DK \
|
||||
de \
|
||||
de_AT \
|
||||
de_BE \
|
||||
de_CH \
|
||||
de_DE \
|
||||
de_LU \
|
||||
el_GR \
|
||||
en \
|
||||
en_AU \
|
||||
en_BW \
|
||||
en_CA \
|
||||
en_DK \
|
||||
en_GB \
|
||||
en_HK \
|
||||
en_IE \
|
||||
en_IN \
|
||||
en_NZ \
|
||||
en_PH \
|
||||
en_SG \
|
||||
en_US \
|
||||
en_ZA \
|
||||
en_ZW \
|
||||
es_AR \
|
||||
es_BO \
|
||||
es_CL \
|
||||
es_CO \
|
||||
es_CR \
|
||||
es_DO \
|
||||
es_EC \
|
||||
es_ES \
|
||||
es_GT \
|
||||
es_HN \
|
||||
es_MX \
|
||||
es_NI \
|
||||
es_PA \
|
||||
es_PE \
|
||||
es_PR \
|
||||
es_PY \
|
||||
es_SV \
|
||||
es_US \
|
||||
es_UY \
|
||||
es_VE \
|
||||
et_EE \
|
||||
eu_ES \
|
||||
fa_IR \
|
||||
fi_FI \
|
||||
fo_FO \
|
||||
fr_BE \
|
||||
fr_CA \
|
||||
fr_CH \
|
||||
fr_FR \
|
||||
fr_LU \
|
||||
ga_IE \
|
||||
gd_GB \
|
||||
gl_ES \
|
||||
gv_GB \
|
||||
he_IL \
|
||||
hi_IN \
|
||||
hr_HR \
|
||||
hu_HU \
|
||||
id_ID \
|
||||
it_CH \
|
||||
it_IT \
|
||||
iw_IL \
|
||||
ja_JP \
|
||||
ka_GE \
|
||||
kl_GL \
|
||||
ko_KR \
|
||||
kw_GB \
|
||||
lt_LT \
|
||||
lv_LV \
|
||||
mi_NZ \
|
||||
mk_MK \
|
||||
mr_IN \
|
||||
mt_MT \
|
||||
nl \
|
||||
nl_BE \
|
||||
nl_NL \
|
||||
nn_NO \
|
||||
no_NO \
|
||||
oc_FR \
|
||||
pl_PL \
|
||||
pt_BR \
|
||||
pt_PT \
|
||||
ro_RO \
|
||||
ru_RU \
|
||||
ru_UA \
|
||||
se_NO \
|
||||
sk_SK \
|
||||
sl_SI \
|
||||
sq_AL \
|
||||
sr_YU \
|
||||
sv_FI \
|
||||
sv_SE \
|
||||
ta_IN \
|
||||
te_IN \
|
||||
tg_TJ \
|
||||
tl_PH \
|
||||
tr_TR \
|
||||
uk_UA \
|
||||
ur_PK \
|
||||
uz_UZ \
|
||||
vi_VN \
|
||||
yi_US \
|
||||
zh_CN \
|
||||
zh_HK \
|
||||
zh_SG \
|
||||
zh_TW
|
||||
|
||||
java/text/Collator.getInstance(Ljava/util/Locale;)Ljava/text/Collator;: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
|
||||
java/text/DateFormatSymbols.<init>(Ljava/util/Locale;)V: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
|
||||
java/text/DecimalFormatSymbols.<init>(Ljava/util/Locale;)V: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
|
||||
java/text/BreakIterator.getInstance(Ljava/lang/String;Ljava/util/Locale;)Ljava/text/BreakIterator;: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
|
||||
java/text/NumberFormat.computeInstance(Ljava/util/Locale;Ljava/lang/String;Ljava/lang/String;)Ljava/text/NumberFormat;: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
|
||||
java/text/DateFormat.computeInstance(IILjava/util/Locale;ZZ)Ljava/text/DateFormat;: \
|
||||
gnu/java/locale/LocaleInformation_{text_locales}.*
|
||||
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in java.text package.
|
||||
Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - java.text</title></head>
|
||||
|
||||
<body>
|
||||
<p>Classes to iterate over strings and to format texts according to a
|
||||
specific locale.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user