tec.units.ri.internal.format.l10n.Format Maven / Gradle / Ivy
Show all versions of unit-ri Show documentation
/*
* Units of Measurement Reference Implementation
* Copyright (c) 2005-2015, Jean-Marie Dautelle, Werner Keil, V2COM.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package tec.units.ri.internal.format.l10n;
/*
* Portions Copyright 1999-2010 Research In Motion Limited.
* 295 Phillip Street, Waterloo, Ontario, Canada, N2L 3W8. All Rights Reserved.
*/
/*
*
* Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights
* Reserved. Use is subject to license terms.
*/
/*
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* The original version of this source code and documentation is copyrighted
* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
* materials are provided under terms of a License Agreement between Taligent
* and Sun. This technology is protected by multiple US and International
* patents. This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
*/
/**
* Format
is an abstract base class for formatting locale-sensitive
* information such as dates, messages, and numbers.
*
*
* Format
defines the programming interface for formatting
* locale-sensitive objects into String
s (the format
* method) and for parsing String
s back into objects (the
* parseObject
method).
*
*
* Generally, a format's parseObject
method must be able to parse
* any string formatted by its format
method. However, there may be
* exceptional cases where this is not possible. For example, a
* format
method might create two adjacent integer numbers with no
* separator in between, and in this case the parseObject
could not
* tell which digits belong to which number.
*
*
Subclassing
*
*
* The Java 2 platform provides three specialized subclasses of
* Format
-- DateFormat
, MessageFormat
,
* and NumberFormat
--for formatting dates, messages, and numbers,
* respectively.
*
* Concrete subclasses must implement three methods:
*
* -
*
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
* -
formatToCharacterIterator(Object obj)
* -
parseObject(String source, ParsePosition pos)
*
* These general methods allow polymorphic parsing and formatting of objects and
* are used, for example, by MessageFormat
. Subclasses often also
* provide additional format
methods for specific input types as
* well as parse
methods for specific result types. Any
* parse
method that does not take a ParsePosition
* argument should throw ParseException
when no text in the
* required format is at the beginning of the input text.
*
*
* Most subclasses will also implement the following factory methods:
*
* -
*
getInstance
for getting a useful format object appropriate for
* the current locale
* -
*
getInstance(Locale)
for getting a useful format object
* appropriate for the specified locale
*
* In addition, some subclasses may also implement other
* getXxxxInstance
methods for more specialized control. For
* example, the NumberFormat
class provides
* getPercentInstance
and getCurrencyInstance
methods
* for getting specialized number formatters.
*
*
* Subclasses of Format
that allow programmers to create objects
* for locales (with getInstance(Locale)
for example) must also
* implement the following class method:
*
*
* public static Locale[] getAvailableLocales()
*
*
*
*
*
* And finally subclasses may define a set of constants to identify the various
* fields in the formatted output. These constants are used to create a
* FieldPosition object which identifies what information is contained in the
* field and its position in the formatted result. These constants should be
* named item_FIELD
where item
* identifies the field.
*
*
Synchronization
*
*
* Formats are generally not synchronized. It is recommended to create separate
* format instances for each thread. If multiple threads access a format
* concurrently, it must be synchronized externally.
*
* @see ParsePosition
* @see FieldPosition
* @see NumberFormat
* @author Mark Davis
*/
public abstract class Format {
// private static final long serialVersionUID = -299282585814624189L;
/**
* Formats an object to produce a string. This is equivalent to
* {@link #format(Object, StringBuffer, FieldPosition) format}(obj,
* new StringBuffer(), new FieldPosition(0)).toString();
*
*
* @param obj
* The object to format
* @return Formatted string.
* @exception IllegalArgumentException
* if the Format cannot format the given object
*/
public final String format(Object obj) {
return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
}
/**
* Formats an object and appends the resulting text to a given string
* buffer. If the pos
argument identifies a field used by the
* format, then its indices are set to the beginning and end of the first
* such field encountered.
*
* @param obj
* The object to format
* @param toAppendTo
* where the text is to be appended
* @param pos
* A FieldPosition
identifying a field in the
* formatted text
* @return the string buffer passed in as toAppendTo
, with
* formatted text appended
* @exception NullPointerException
* if toAppendTo
or pos
is null
* @exception IllegalArgumentException
* if the Format cannot format the given object
*/
public abstract StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos);
/**
* Formats an Object producing an AttributedCharacterIterator
.
* You can use the returned AttributedCharacterIterator
to
* build the resulting String, as well as to determine information about the
* resulting String.
*
* Each attribute key of the AttributedCharacterIterator will be of type
* Field
. It is up to each Format
implementation
* to define what the legal values are for each attribute in the
* AttributedCharacterIterator
, but typically the attribute key
* is also used as the attribute value.
*
* The default implementation creates an
* AttributedCharacterIterator
with no attributes. Subclasses
* that support fields should override this and create an
* AttributedCharacterIterator
with meaningful attributes.
*
* @exception NullPointerException
* if obj is null.
* @exception IllegalArgumentException
* when the Format cannot format the given object.
* @param obj
* The object to format
* @return AttributedCharacterIterator describing the formatted value.
*/
AttributedCharacterIterator formatToCharacterIterator(Object obj) {
return createAttributedCharacterIterator(format(obj));
}
/**
* Parses text from a string to produce an object.
*
* The method attempts to parse text starting at the index given by
* pos
. If parsing succeeds, then the index of pos
* is updated to the index after the last character used (parsing does not
* necessarily use all characters up to the end of the string), and the
* parsed object is returned. The updated pos
can be used to
* indicate the starting point for the next call to this method. If an error
* occurs, then the index of pos
is not changed, the error
* index of pos
is set to the index of the character where the
* error occurred, and null is returned.
*
* @param source
* A String
, part of which should be parsed.
* @param pos
* A ParsePosition
object with index and error index
* information as described above.
* @return An Object
parsed from the string. In case of error,
* returns null.
* @exception NullPointerException
* if pos
is null.
*/
// public abstract Object parseObject(String source, ParsePosition pos);
/**
* Parses text from the beginning of the given string to produce an object.
* The method may not use the entire text of the given string.
*
* @param source
* A String
whose beginning should be parsed.
* @return An Object
parsed from the string.
* @exception ParseException
* if the beginning of the specified string cannot be parsed.
*/
// public Object parseObject(String source) throws ParseException {
// ParsePosition pos = new ParsePosition(0);
// Object result = parseObject(source, pos);
// if (pos.index == 0) {
// throw new ParseException(
// "Format.parseObject(String) failed", pos.errorIndex);
// }
// return result;
// }
//
// Convenience methods for creating AttributedCharacterIterators from
// different parameters.
//
/**
* Creates an AttributedCharacterIterator
for the String
* s
.
*
* @param s
* String to create AttributedCharacterIterator from
* @return AttributedCharacterIterator wrapping s
*/
AttributedCharacterIterator createAttributedCharacterIterator(String s) {
AttributedString as = new AttributedString(s);
return as.getIterator();
}
/**
* Creates an AttributedCharacterIterator
containg the
* concatenated contents of the passed in
* AttributedCharacterIterator
s.
*
* @param iterators
* AttributedCharacterIterators used to create resulting
* AttributedCharacterIterators
* @return AttributedCharacterIterator wrapping passed in
* AttributedCharacterIterators
*/
AttributedCharacterIterator createAttributedCharacterIterator(
AttributedCharacterIterator[] iterators) {
AttributedString as = new AttributedString(iterators);
return as.getIterator();
}
/**
* Returns an AttributedCharacterIterator with the String
* string
and additional key/value pair key
,
* value
.
*
* @param string
* String to create AttributedCharacterIterator from
* @param key
* Key for AttributedCharacterIterator
* @param value
* Value associated with key in AttributedCharacterIterator
* @return AttributedCharacterIterator wrapping args
*/
AttributedCharacterIterator createAttributedCharacterIterator(
String string, Attribute key, Object value) {
AttributedString as = new AttributedString(string);
as.addAttribute(key, value);
return as.getIterator();
}
/**
* Creates an AttributedCharacterIterator with the contents of
* iterator
and the additional attribute key
* value
.
*
* @param iterator
* Initial AttributedCharacterIterator to add arg to
* @param key
* Key for AttributedCharacterIterator
* @param value
* Value associated with key in AttributedCharacterIterator
* @return AttributedCharacterIterator wrapping args
*/
AttributedCharacterIterator createAttributedCharacterIterator(
AttributedCharacterIterator iterator, Attribute key, Object value) {
AttributedString as = new AttributedString(iterator);
as.addAttribute(key, value);
return as.getIterator();
}
/**
* Defines constants that are used as attribute keys in the
* AttributedCharacterIterator
returned from
* Format.formatToCharacterIterator
and as field identifiers in
* FieldPosition
.
*
* @since 1.4
*/
public static class Field extends Attribute {
/**
* Creates a Field with the specified name.
*
* @param name
* Name of the attribute
*/
protected Field(String name) {
super(name);
}
}
/**
* FieldDelegate is notified by the various Format
* implementations as they are formatting the Objects. This allows for
* storage of the individual sections of the formatted String for later use,
* such as in a FieldPosition
or for an
* AttributedCharacterIterator
.
*
* Delegates should NOT assume that the Format
will notify the
* delegate of fields in any particular order.
*
* @see FieldPosition.Delegate
* @see CharacterIteratorFieldDelegate
*/
interface FieldDelegate {
/**
* Notified when a particular region of the String is formatted. This
* method will be invoked if there is no corresponding integer field id
* matching attr
.
*
* @param attr
* Identifies the field matched
* @param value
* Value associated with the field
* @param start
* Beginning location of the field, will be >= 0
* @param end
* End of the field, will be >= start and <= buffer.length()
* @param buffer
* Contains current formatted value, receiver should NOT
* modify it.
*/
public void formatted(Format.Field attr, Object value, int start,
int end, StringBuffer buffer);
/**
* Notified when a particular region of the String is formatted.
*
* @param fieldID
* Identifies the field by integer
* @param attr
* Identifies the field matched
* @param value
* Value associated with the field
* @param start
* Beginning location of the field, will be >= 0
* @param end
* End of the field, will be >= start and <= buffer.length()
* @param buffer
* Contains current formatted value, receiver should NOT
* modify it.
*/
public void formatted(int fieldID, Format.Field attr, Object value,
int start, int end, StringBuffer buffer);
}
}