/* GENERATED SOURCE. DO NOT MODIFY. */ // © 2018 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html package android.icu.text; import java.text.Format.Field; import java.util.Objects; /** * Represents a span of a string containing a given field. * * This class differs from FieldPosition in the following ways: * * 1. It has information on the field category. * 2. It allows you to set constraints to use when iterating over field positions. * 3. It is used for the newer FormattedValue APIs. * * @author sffc */ public class ConstrainedFieldPosition { /** * Represents the type of constraint for ConstrainedFieldPosition. * * Constraints are used to control the behavior of iteration in FormattedValue. */ private enum ConstraintType { /** * Represents the lack of a constraint. * * This is the value of fConstraint * if no "constrain" methods were called. */ NONE, /** * Represents that the field class is constrained. * * This is the value of fConstraint * after {@link #constrainClass} is called. * * FormattedValue implementations should not change the field class when this constraint is active. */ CLASS, /** * Represents that the field is constrained. * * This is the value of fConstraint * after {@link #constrainField} is called. * * FormattedValue implementations should not change the field when this constraint is active. */ FIELD, /** * Represents that the field value is constrained. * * This is the value of fConstraint * after {@link #constrainField} is called. * * FormattedValue implementations should not change the field or value with this constraint. */ VALUE }; private ConstraintType fConstraint; private Class fClassConstraint; private Field fField; private Object fValue; private int fStart; private int fLimit; private long fContext; /** * Initializes a CategoryFieldPosition. * * By default, the CategoryFieldPosition has no iteration constraints. */ public ConstrainedFieldPosition() { reset(); } /** * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created: * * - Removes any constraints that may have been set on the instance. * - Resets the iteration position. */ public void reset() { fConstraint = ConstraintType.NONE; fClassConstraint = Object.class; fField = null; fValue = null; fStart = 0; fLimit = 0; fContext = 0; } /** * Sets a constraint on the field. * * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are * skipped unless they have the given field. * * Any previously set constraints are cleared. * * For example, to loop over all grouping separators: * *
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainField(NumberFormat.Field.GROUPING_SEPARATOR);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the grouping separator position
     * }
     * 
* * Changing the constraint while in the middle of iterating over a FormattedValue * does not generally have well-defined behavior. * * @param field * The field to fix when iterating. */ public void constrainField(Field field) { if (field == null) { throw new IllegalArgumentException("Cannot constrain on null field"); } fConstraint = ConstraintType.FIELD; fClassConstraint = Object.class; fField = field; fValue = null; } /** * Sets a constraint on the field class. * * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are * skipped unless the field is an instance of the class constraint, including subclasses. * * Any previously set constraints are cleared. * * For example, to loop over only the number-related fields: * *
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainClass(NumberFormat.Field.class);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the number-related field position
     * }
     * 
* * @param classConstraint * The field class to fix when iterating. */ public void constrainClass(Class classConstraint) { if (classConstraint == null) { throw new IllegalArgumentException("Cannot constrain on null field class"); } fConstraint = ConstraintType.CLASS; fClassConstraint = classConstraint; fField = null; fValue = null; } /** * Sets a constraint on field and field value. * * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are * skipped unless both the field and the field value are equal. * * Any previously set constraints are cleared. * * For example, to find the span a date interval corresponding to the first date: * *
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainFieldAndValue(DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 0);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the span of the first date in the date interval
     * }
     * 
* * @param field The field to fix when iterating. * @param fieldValue The field value to fix when iterating. * @deprecated This API is for technology preview and might be changed or removed in a future release. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public void constrainFieldAndValue(Field field, Object fieldValue) { fConstraint = ConstraintType.VALUE; fClassConstraint = Object.class; fField = field; fValue = fieldValue; } /** * Gets the field for the current position. * * The return value is well-defined and non-null only after * FormattedValue#nextPosition returns true. * * @return The field saved in the instance. See above for null conditions. */ public Field getField() { return fField; } /** * Gets the INCLUSIVE start index for the current position. * * The return value is well-defined only after FormattedValue#nextPosition returns true. * * @return The start index saved in the instance. */ public int getStart() { return fStart; } /** * Gets the EXCLUSIVE end index stored for the current position. * * The return value is well-defined only after FormattedValue#nextPosition returns true. * * @return The end index saved in the instance. */ public int getLimit() { return fLimit; } /** * Gets the value associated with the current field position. The field value is often not set. * * The return value is well-defined only after FormattedValue#nextPosition returns true. * * @return The value for the current position. Might be null. */ public Object getFieldValue() { return fValue; } /** * Gets an int64 that FormattedValue implementations may use for storage. * * The initial value is zero. * * Users of FormattedValue should not need to call this method. * * @return The current iteration context from {@link #setInt64IterationContext}. */ public long getInt64IterationContext() { return fContext; } /** * Sets an int64 that FormattedValue implementations may use for storage. * * Intended to be used by FormattedValue implementations. * * @param context * The new iteration context. */ public void setInt64IterationContext(long context) { fContext = context; } /** * Sets new values for the primary public getters. * * Intended to be used by FormattedValue implementations. * * It is up to the implementation to ensure that the user-requested * constraints are satisfied. This method does not check! * * @param field * The new field. * @param value * The new field value. Should be null if there is no value. * @param start * The new inclusive start index. * @param limit * The new exclusive end index. */ public void setState(Field field, Object value, int start, int limit) { // Check matchesField only as an assertion (debug build) if (field != null) { assert matchesField(field, value); } fField = field; fValue = value; fStart = start; fLimit = limit; } /** * Determines whether a given field and value should be included given the * constraints. * * Intended to be used by FormattedValue implementations. * * @param field The field to test. * @param fieldValue The field value to test. Should be null if there is no value. * @return Whether the field should be included given the constraints. */ public boolean matchesField(Field field, Object fieldValue) { if (field == null) { throw new IllegalArgumentException("field must not be null"); } switch (fConstraint) { case NONE: return true; case CLASS: return fClassConstraint.isAssignableFrom(field.getClass()); case FIELD: return fField == field; case VALUE: // Note: Objects.equals is Android API level 19 and Java 1.7 return fField == field && Objects.equals(fValue, fieldValue); default: throw new AssertionError(); } } /** * {@inheritDoc} */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("CFPos["); sb.append(fStart); sb.append('-'); sb.append(fLimit); sb.append(' '); sb.append(fField); sb.append(']'); return sb.toString(); } }