tec.units.ri.internal.format.l10n.FieldPosition 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.
*/
/*
* (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 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.
*
*/
package tec.units.ri.internal.format.l10n;
/**
* FieldPosition
is a simple class used by Format
and
* its subclasses to identify fields in formatted output. Fields can be
* identified in two ways:
*
* - By an integer constant, whose names typically end with
*
_FIELD
. The constants are defined in the various subclasses of
* Format
.
* - By a
Format.Field
constant, see ERA_FIELD
and
* its friends in DateFormat
for an example.
*
*
* FieldPosition
keeps track of the position of the field within
* the formatted output with two indices: the index of the first character of
* the field and the index of the last character of the field.
*
*
* One version of the format
method in the various
* Format
classes requires a FieldPosition
object as
* an argument. You use this format
method to perform partial
* formatting or to get information about the formatted output (such as the
* position of a field).
*
*
* If you are interested in the positions of all attributes in the formatted
* string use the Format
method
* formatToCharacterIterator
.
*
* @author Mark Davis
* @see Format
*/
public class FieldPosition {
/**
* Input: Desired field to determine start and end offsets for. The meaning
* depends on the subclass of Format.
*/
int field = 0;
/**
* Output: End offset of field in text. If the field does not occur in the
* text, 0 is returned.
*/
int endIndex = 0;
/**
* Output: Start offset of field in text. If the field does not occur in the
* text, 0 is returned.
*/
int beginIndex = 0;
/**
* Desired field this FieldPosition is for.
*/
private Format.Field attribute;
/**
* Creates a FieldPosition object for the given field. Fields are identified
* by constants, whose names typically end with _FIELD, in the various
* subclasses of Format.
*
* @see NumberFormat#INTEGER_FIELD
* @see NumberFormat#FRACTION_FIELD
*/
public FieldPosition(int field) {
this.field = field;
}
/**
* Creates a FieldPosition object for the given field constant. Fields are
* identified by constants defined in the various Format
* subclasses. This is equivalent to calling
* new FieldPosition(attribute, -1)
.
*
* @param attribute
* Format.Field constant identifying a field
* @since 1.4
*/
public FieldPosition(Format.Field attribute) {
this(attribute, -1);
}
/**
* Creates a FieldPosition
object for the given field. The
* field is identified by an attribute constant from one of the
* Field
subclasses as well as an integer field ID defined by
* the Format
subclasses. Format
subclasses that
* are aware of Field
should give precedence to
* attribute
and ignore fieldID
if
* attribute
is not null. However, older Format
* subclasses may not be aware of Field
and rely on
* fieldID
. If the field has no corresponding integer constant,
* fieldID
should be -1.
*
* @param attribute
* Format.Field constant identifying a field
* @param fieldID
* integer constantce identifying a field
* @since 1.4
*/
public FieldPosition(Format.Field attribute, int fieldID) {
this.attribute = attribute;
this.field = fieldID;
}
/**
* Returns the field identifier as an attribute constant from one of the
* Field
subclasses. May return null if the field is specified
* only by an integer field ID.
*
* @return Identifier for the field
* @since 1.4
*/
public Format.Field getFieldAttribute() {
return attribute;
}
/**
* Retrieves the field identifier.
*/
public int getField() {
return field;
}
/**
* Retrieves the index of the first character in the requested field.
*/
public int getBeginIndex() {
return beginIndex;
}
/**
* Retrieves the index of the character following the last character in the
* requested field.
*/
public int getEndIndex() {
return endIndex;
}
/**
* Sets the begin index. For use by subclasses of Format.
*
* @since 1.2
*/
public void setBeginIndex(int bi) {
beginIndex = bi;
}
/**
* Sets the end index. For use by subclasses of Format.
*
* @since 1.2
*/
public void setEndIndex(int ei) {
endIndex = ei;
}
/**
* Returns a Format.FieldDelegate
instance that is associated
* with the FieldPosition. When the delegate is notified of the same field
* the FieldPosition is associated with, the begin/end will be adjusted.
*/
Format.FieldDelegate getFieldDelegate() {
return new Delegate();
}
/**
* Overrides equals
*/
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof FieldPosition))
return false;
FieldPosition other = (FieldPosition) obj;
if (attribute == null) {
if (other.attribute != null) {
return false;
}
} else if (!attribute.equals(other.attribute)) {
return false;
}
return (beginIndex == other.beginIndex && endIndex == other.endIndex && field == other.field);
}
/**
* Returns a hash code for this FieldPosition.
*
* @return a hash code value for this object
*/
public int hashCode() {
return (field << 24) | (beginIndex << 16) | endIndex;
}
/**
* Return a string representation of this FieldPosition.
*
* @return a string representation of this object
*/
public String toString() {
return getClass().getName() + "[field=" + field + ",attribute="
+ attribute + ",beginIndex=" + beginIndex + ",endIndex="
+ endIndex + ']';
}
/**
* Return true if the receiver wants a Format.Field
value and
* attribute
is equal to it.
*/
private boolean matchesField(Format.Field attribute) {
if (this.attribute != null) {
return this.attribute.equals(attribute);
}
return false;
}
/**
* Return true if the receiver wants a Format.Field
value and
* attribute
is equal to it, or true if the receiver represents
* an inteter constant and field
equals it.
*/
private boolean matchesField(Format.Field attribute, int field) {
if (this.attribute != null) {
return this.attribute.equals(attribute);
}
return (field == this.field);
}
/**
* An implementation of FieldDelegate that will adjust the begin/end of the
* FieldPosition if the arguments match the field of the FieldPosition.
*/
private class Delegate implements Format.FieldDelegate {
/**
* Indicates whether the field has been encountered before. If this is
* true, and formatted
is invoked, the begin/end are not
* updated.
*/
private boolean encounteredField;
public void formatted(Format.Field attr, Object value, int start,
int end, StringBuffer buffer) {
if (!encounteredField && matchesField(attr)) {
setBeginIndex(start);
setEndIndex(end);
encounteredField = (start != end);
}
}
public void formatted(int fieldID, Format.Field attr, Object value,
int start, int end, StringBuffer buffer) {
if (!encounteredField && matchesField(attr, fieldID)) {
setBeginIndex(start);
setEndIndex(end);
encounteredField = (start != end);
}
}
}
}