1. /*
  2. * @(#)FieldPosition.java 1.20 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  9. * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  10. *
  11. * The original version of this source code and documentation is copyrighted
  12. * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  13. * materials are provided under terms of a License Agreement between Taligent
  14. * and Sun. This technology is protected by multiple US and International
  15. * patents. This notice and attribution to Taligent may not be removed.
  16. * Taligent is a registered trademark of Taligent, Inc.
  17. *
  18. */
  19. package java.text;
  20. /**
  21. * <code>FieldPosition</code> is a simple class used by <code>Format</code>
  22. * and its subclasses to identify fields in formatted output. Fields can
  23. * be identified in two ways:
  24. * <ul>
  25. * <li>By an integer constant, whose names typically end with
  26. * <code>_FIELD</code>. The constants are defined in the various
  27. * subclasses of <code>Format</code>.
  28. * <li>By a <code>Format.Field</code> constant, see <code>ERA_FIELD</code>
  29. * and its friends in <code>DateFormat</code> for an example.
  30. * </ul>
  31. * <p>
  32. * <code>FieldPosition</code> keeps track of the position of the
  33. * field within the formatted output with two indices: the index
  34. * of the first character of the field and the index of the last
  35. * character of the field.
  36. *
  37. * <p>
  38. * One version of the <code>format</code> method in the various
  39. * <code>Format</code> classes requires a <code>FieldPosition</code>
  40. * object as an argument. You use this <code>format</code> method
  41. * to perform partial formatting or to get information about the
  42. * formatted output (such as the position of a field).
  43. *
  44. * <p>
  45. * If you are interested in the positions of all attributes in the
  46. * formatted string use the <code>Format</code> method
  47. * <code>formatToCharacterIterator</code>.
  48. *
  49. * @version 1.20 01/23/03
  50. * @author Mark Davis
  51. * @see java.text.Format
  52. */
  53. public class FieldPosition {
  54. /**
  55. * Input: Desired field to determine start and end offsets for.
  56. * The meaning depends on the subclass of Format.
  57. */
  58. int field = 0;
  59. /**
  60. * Output: End offset of field in text.
  61. * If the field does not occur in the text, 0 is returned.
  62. */
  63. int endIndex = 0;
  64. /**
  65. * Output: Start offset of field in text.
  66. * If the field does not occur in the text, 0 is returned.
  67. */
  68. int beginIndex = 0;
  69. /**
  70. * Desired field this FieldPosition is for.
  71. */
  72. private Format.Field attribute;
  73. /**
  74. * Creates a FieldPosition object for the given field. Fields are
  75. * identified by constants, whose names typically end with _FIELD,
  76. * in the various subclasses of Format.
  77. *
  78. * @see java.text.NumberFormat#INTEGER_FIELD
  79. * @see java.text.NumberFormat#FRACTION_FIELD
  80. * @see java.text.DateFormat#YEAR_FIELD
  81. * @see java.text.DateFormat#MONTH_FIELD
  82. */
  83. public FieldPosition(int field) {
  84. this.field = field;
  85. }
  86. /**
  87. * Creates a FieldPosition object for the given field constant. Fields are
  88. * identified by constants defined in the various <code>Format</code>
  89. * subclasses. This is equivalent to calling
  90. * <code>new FieldPosition(attribute, -1)</code>.
  91. *
  92. * @param attribute Format.Field constant identifying a field
  93. * @since 1.4
  94. */
  95. public FieldPosition(Format.Field attribute) {
  96. this(attribute, -1);
  97. }
  98. /**
  99. * Creates a <code>FieldPosition</code> object for the given field.
  100. * The field is identified by an attribute constant from one of the
  101. * <code>Field</code> subclasses as well as an integer field ID
  102. * defined by the <code>Format</code> subclasses. <code>Format</code>
  103. * subclasses that are aware of <code>Field</code> should give precedence
  104. * to <code>attribute</code> and ignore <code>fieldID</code> if
  105. * <code>attribute</code> is not null. However, older <code>Format</code>
  106. * subclasses may not be aware of <code>Field</code> and rely on
  107. * <code>fieldID</code>. If the field has no corresponding integer
  108. * constant, <code>fieldID</code> should be -1.
  109. *
  110. * @param attribute Format.Field constant identifying a field
  111. * @param fieldID integer constantce identifying a field
  112. * @since 1.4
  113. */
  114. public FieldPosition(Format.Field attribute, int fieldID) {
  115. this.attribute = attribute;
  116. this.field = fieldID;
  117. }
  118. /**
  119. * Returns the field identifier as an attribute constant
  120. * from one of the <code>Field</code> subclasses. May return null if
  121. * the field is specified only by an integer field ID.
  122. *
  123. * @return Identifier for the field
  124. * @since 1.4
  125. */
  126. public Format.Field getFieldAttribute() {
  127. return attribute;
  128. }
  129. /**
  130. * Retrieves the field identifier.
  131. */
  132. public int getField() {
  133. return field;
  134. }
  135. /**
  136. * Retrieves the index of the first character in the requested field.
  137. */
  138. public int getBeginIndex() {
  139. return beginIndex;
  140. }
  141. /**
  142. * Retrieves the index of the character following the last character in the
  143. * requested field.
  144. */
  145. public int getEndIndex() {
  146. return endIndex;
  147. }
  148. /**
  149. * Sets the begin index. For use by subclasses of Format.
  150. * @since 1.2
  151. */
  152. public void setBeginIndex(int bi) {
  153. beginIndex = bi;
  154. }
  155. /**
  156. * Sets the end index. For use by subclasses of Format.
  157. * @since 1.2
  158. */
  159. public void setEndIndex(int ei) {
  160. endIndex = ei;
  161. }
  162. /**
  163. * Returns a <code>Format.FieldDelegate</code> instance that is associated
  164. * with the FieldPosition. When the delegate is notified of the same
  165. * field the FieldPosition is associated with, the begin/end will be
  166. * adjusted.
  167. */
  168. Format.FieldDelegate getFieldDelegate() {
  169. return new Delegate();
  170. }
  171. /**
  172. * Overrides equals
  173. */
  174. public boolean equals(Object obj)
  175. {
  176. if (obj == null) return false;
  177. if (!(obj instanceof FieldPosition))
  178. return false;
  179. FieldPosition other = (FieldPosition) obj;
  180. if (attribute == null) {
  181. if (other.attribute != null) {
  182. return false;
  183. }
  184. }
  185. else if (!attribute.equals(other.attribute)) {
  186. return false;
  187. }
  188. return (beginIndex == other.beginIndex
  189. && endIndex == other.endIndex
  190. && field == other.field);
  191. }
  192. /**
  193. * Returns a hash code for this FieldPosition.
  194. * @return a hash code value for this object
  195. */
  196. public int hashCode() {
  197. return (field << 24) | (beginIndex << 16) | endIndex;
  198. }
  199. /**
  200. * Return a string representation of this FieldPosition.
  201. * @return a string representation of this object
  202. */
  203. public String toString() {
  204. return getClass().getName() +
  205. "[field=" + field + ",attribute=" + attribute +
  206. ",beginIndex=" + beginIndex +
  207. ",endIndex=" + endIndex + ']';
  208. }
  209. /**
  210. * Return true if the receiver wants a <code>Format.Field</code> value and
  211. * <code>attribute</code> is equal to it.
  212. */
  213. private boolean matchesField(Format.Field attribute) {
  214. if (this.attribute != null) {
  215. return this.attribute.equals(attribute);
  216. }
  217. return false;
  218. }
  219. /**
  220. * Return true if the receiver wants a <code>Format.Field</code> value and
  221. * <code>attribute</code> is equal to it, or true if the receiver
  222. * represents an inteter constant and <code>field</code> equals it.
  223. */
  224. private boolean matchesField(Format.Field attribute, int field) {
  225. if (this.attribute != null) {
  226. return this.attribute.equals(attribute);
  227. }
  228. return (field == this.field);
  229. }
  230. /**
  231. * An implementation of FieldDelegate that will adjust the begin/end
  232. * of the FieldPosition if the arguments match the field of
  233. * the FieldPosition.
  234. */
  235. private class Delegate implements Format.FieldDelegate {
  236. /**
  237. * Indicates whether the field has been encountered before. If this
  238. * is true, and <code>formatted</code> is invoked, the begin/end
  239. * are not updated.
  240. */
  241. private boolean encounteredField;
  242. public void formatted(Format.Field attr, Object value, int start,
  243. int end, StringBuffer buffer) {
  244. if (!encounteredField && matchesField(attr)) {
  245. setBeginIndex(start);
  246. setEndIndex(end);
  247. encounteredField = (start != end);
  248. }
  249. }
  250. public void formatted(int fieldID, Format.Field attr, Object value,
  251. int start, int end, StringBuffer buffer) {
  252. if (!encounteredField && matchesField(attr, fieldID)) {
  253. setBeginIndex(start);
  254. setEndIndex(end);
  255. encounteredField = (start != end);
  256. }
  257. }
  258. }
  259. }