001: /*
002: * Copyright 2001-2006 Stephen Colebourne
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.joda.time.field;
017:
018: import java.util.Locale;
019:
020: import org.joda.time.DateTimeField;
021: import org.joda.time.DateTimeFieldType;
022: import org.joda.time.DurationField;
023: import org.joda.time.ReadableInstant;
024: import org.joda.time.ReadablePartial;
025:
026: /**
027: * AbstractPartialFieldProperty is a base class for binding a
028: * ReadablePartial to a DateTimeField.
029: * <p>
030: * It allows the date and time manipulation code to be field based yet
031: * still easy to use.
032: *
033: * @author Stephen Colebourne
034: * @author Brian S O'Neill
035: * @since 1.0
036: */
037: public abstract class AbstractPartialFieldProperty {
038:
039: /**
040: * Constructor.
041: */
042: protected AbstractPartialFieldProperty() {
043: super ();
044: }
045:
046: //-----------------------------------------------------------------------
047: /**
048: * Gets the field being used.
049: *
050: * @return the field
051: */
052: public abstract DateTimeField getField();
053:
054: /**
055: * Gets the field type being used.
056: *
057: * @return the field type
058: */
059: public DateTimeFieldType getFieldType() {
060: return getField().getType();
061: }
062:
063: /**
064: * Gets the name of the field.
065: *
066: * @return the field name
067: */
068: public String getName() {
069: return getField().getName();
070: }
071:
072: /**
073: * Gets the partial instant being used.
074: *
075: * @return the partial instant
076: */
077: protected abstract ReadablePartial getReadablePartial();
078:
079: //-----------------------------------------------------------------------
080: /**
081: * Gets the value of this property from the instant.
082: * <p>
083: * For example, the following two lines of code are equivalent:
084: * <pre>
085: * partial.getDayOfMonth();
086: * partial.dayOfMonth().get();
087: * </pre>
088: *
089: * @return the current value
090: */
091: public abstract int get();
092:
093: /**
094: * Gets the value of this property from the instant as a string.
095: * <p>
096: * This method returns the value converted to a <code>String</code>
097: * using <code>Integer.toString</code>. This method does NOT return
098: * textual descriptions such as 'Monday' or 'January'.
099: * See {@link #getAsText()} and {@link #getAsShortText()} for those.
100: *
101: * @return the current value
102: * @see DateTimeField#get
103: * @since 1.1
104: */
105: public String getAsString() {
106: return Integer.toString(get());
107: }
108:
109: /**
110: * Gets the textual value of this property from the instant as a
111: * string in the default locale.
112: * <p>
113: * This method returns the value converted to a <code>String</code>
114: * returning the appropriate textual description wherever possible.
115: * Thus, a day of week of 1 would return 'Monday' in English.
116: *
117: * @return the current text value
118: * @see DateTimeField#getAsText
119: */
120: public String getAsText() {
121: return getAsText(null);
122: }
123:
124: /**
125: * Gets the textual value of this property from the instant as a
126: * string in the specified locale.
127: * <p>
128: * This method returns the value converted to a <code>String</code>
129: * returning the appropriate textual description wherever possible.
130: * Thus, a day of week of 1 would return 'Monday' in English.
131: *
132: * @param locale locale to use for selecting a text symbol, null means default
133: * @return the current text value
134: * @see DateTimeField#getAsText
135: */
136: public String getAsText(Locale locale) {
137: return getField()
138: .getAsText(getReadablePartial(), get(), locale);
139: }
140:
141: /**
142: * Gets the short textual value of this property from the instant as a
143: * string in the default locale.
144: * <p>
145: * This method returns the value converted to a <code>String</code>
146: * returning the appropriate textual description wherever possible.
147: * Thus, a day of week of 1 would return 'Mon' in English.
148: *
149: * @return the current text value
150: * @see DateTimeField#getAsShortText
151: */
152: public String getAsShortText() {
153: return getAsShortText(null);
154: }
155:
156: /**
157: * Gets the short textual value of this property from the instant as a
158: * string in the specified locale.
159: * <p>
160: * This method returns the value converted to a <code>String</code>
161: * returning the appropriate textual description wherever possible.
162: * Thus, a day of week of 1 would return 'Mon' in English.
163: *
164: * @param locale locale to use for selecting a text symbol, null means default
165: * @return the current text value
166: * @see DateTimeField#getAsShortText
167: */
168: public String getAsShortText(Locale locale) {
169: return getField().getAsShortText(getReadablePartial(), get(),
170: locale);
171: }
172:
173: //-----------------------------------------------------------------------
174: /**
175: * Returns the duration per unit value of this field. For example, if this
176: * field represents "hour of day", then the duration is an hour.
177: *
178: * @return the duration of this field, or UnsupportedDurationField
179: */
180: public DurationField getDurationField() {
181: return getField().getDurationField();
182: }
183:
184: /**
185: * Returns the range duration of this field. For example, if this field
186: * represents "hour of day", then the range duration is a day.
187: *
188: * @return the range duration of this field, or null if field has no range
189: */
190: public DurationField getRangeDurationField() {
191: return getField().getRangeDurationField();
192: }
193:
194: //-----------------------------------------------------------------------
195: /**
196: * Gets the minimum value for the field ignoring the current time.
197: *
198: * @return the minimum value
199: * @see DateTimeField#getMinimumValue
200: */
201: public int getMinimumValueOverall() {
202: return getField().getMinimumValue();
203: }
204:
205: /**
206: * Gets the minimum value for this field given the current field values.
207: *
208: * @return the minimum value
209: * @see DateTimeField#getMinimumValue
210: */
211: public int getMinimumValue() {
212: return getField().getMinimumValue(getReadablePartial());
213: }
214:
215: /**
216: * Gets the maximum value for the field ignoring the current time.
217: *
218: * @return the maximum value
219: * @see DateTimeField#getMaximumValue
220: */
221: public int getMaximumValueOverall() {
222: return getField().getMaximumValue();
223: }
224:
225: /**
226: * Gets the maximum value for this field given the current field values.
227: *
228: * @return the maximum value
229: * @see DateTimeField#getMaximumValue
230: */
231: public int getMaximumValue() {
232: return getField().getMaximumValue(getReadablePartial());
233: }
234:
235: //-----------------------------------------------------------------------
236: /**
237: * Gets the maximum text length for the field.
238: *
239: * @param locale optional locale to use for selecting a text symbol
240: * @return the maximum length
241: * @see DateTimeField#getMaximumTextLength
242: */
243: public int getMaximumTextLength(Locale locale) {
244: return getField().getMaximumTextLength(locale);
245: }
246:
247: /**
248: * Gets the maximum short text length for the field.
249: *
250: * @param locale optional locale to use for selecting a text symbol
251: * @return the maximum length
252: * @see DateTimeField#getMaximumShortTextLength
253: */
254: public int getMaximumShortTextLength(Locale locale) {
255: return getField().getMaximumShortTextLength(locale);
256: }
257:
258: //-----------------------------------------------------------------------
259: /**
260: * Compare this field to the same field on another instant.
261: * <p>
262: * The comparison is based on the value of the same field type, irrespective
263: * of any difference in chronology. Thus, if this property represents the
264: * hourOfDay field, then the hourOfDay field of the other instant will be queried
265: * whether in the same chronology or not.
266: *
267: * @param instant the instant to compare to
268: * @return negative value if this is less, 0 if equal, or positive value if greater
269: * @throws IllegalArgumentException if the instant is null or the instant
270: * doesn't support the field of this property
271: */
272: public int compareTo(ReadableInstant instant) {
273: if (instant == null) {
274: throw new IllegalArgumentException(
275: "The instant must not be null");
276: }
277: int this Value = get();
278: int otherValue = instant.get(getFieldType());
279: if (this Value < otherValue) {
280: return -1;
281: } else if (this Value > otherValue) {
282: return 1;
283: } else {
284: return 0;
285: }
286: }
287:
288: /**
289: * Compare this field to the same field on another partial instant.
290: * <p>
291: * The comparison is based on the value of the same field type, irrespective
292: * of any difference in chronology. Thus, if this property represents the
293: * hourOfDay field, then the hourOfDay field of the other partial will be queried
294: * whether in the same chronology or not.
295: *
296: * @param partial the partial to compare to
297: * @return negative value if this is less, 0 if equal, or positive value if greater
298: * @throws IllegalArgumentException if the instant is null
299: * @throws IllegalArgumentException if the field of this property cannot be queried
300: * on the specified instant
301: */
302: public int compareTo(ReadablePartial partial) {
303: if (partial == null) {
304: throw new IllegalArgumentException(
305: "The instant must not be null");
306: }
307: int this Value = get();
308: int otherValue = partial.get(getFieldType());
309: if (this Value < otherValue) {
310: return -1;
311: } else if (this Value > otherValue) {
312: return 1;
313: } else {
314: return 0;
315: }
316: }
317:
318: //-----------------------------------------------------------------------
319: /**
320: * Compares this property to another.
321: *
322: * @param object the object to compare to
323: * @return true if equal
324: */
325: public boolean equals(Object object) {
326: if (this == object) {
327: return true;
328: }
329: if (object instanceof AbstractPartialFieldProperty == false) {
330: return false;
331: }
332: AbstractPartialFieldProperty other = (AbstractPartialFieldProperty) object;
333: return get() == other.get()
334: && getFieldType() == other.getFieldType()
335: && FieldUtils.equals(getReadablePartial()
336: .getChronology(), other.getReadablePartial()
337: .getChronology());
338: }
339:
340: //-----------------------------------------------------------------------
341: /**
342: * Gets a suitable hashcode for the object.
343: *
344: * @return the hashcode
345: * @since 1.3
346: */
347: public int hashCode() {
348: int hash = 19;
349: hash = 13 * hash + get();
350: hash = 13 * hash + getFieldType().hashCode();
351: hash = 13 * hash
352: + getReadablePartial().getChronology().hashCode();
353: return hash;
354: }
355:
356: //-----------------------------------------------------------------------
357: /**
358: * Output a debugging string.
359: *
360: * @return debugging string
361: */
362: public String toString() {
363: return "Property[" + getName() + "]";
364: }
365:
366: }
|