View Javadoc

1   /*
2    *  Copyright 2001-2006 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time.field;
17  
18  import java.util.Locale;
19  
20  import org.joda.time.DateTimeField;
21  import org.joda.time.DateTimeFieldType;
22  import org.joda.time.DurationField;
23  import org.joda.time.ReadableInstant;
24  import org.joda.time.ReadablePartial;
25  
26  /**
27   * AbstractPartialFieldProperty is a base class for binding a
28   * ReadablePartial to a DateTimeField.
29   * <p>
30   * It allows the date and time manipulation code to be field based yet
31   * still easy to use.
32   *
33   * @author Stephen Colebourne
34   * @author Brian S O'Neill
35   * @since 1.0
36   */
37  public abstract class AbstractPartialFieldProperty {
38  
39      /**
40       * Constructor.
41       */
42      protected AbstractPartialFieldProperty() {
43          super();
44      }
45  
46      //-----------------------------------------------------------------------
47      /**
48       * Gets the field being used.
49       * 
50       * @return the field
51       */
52      public abstract DateTimeField getField();
53  
54      /**
55       * Gets the field type being used.
56       * 
57       * @return the field type
58       */
59      public DateTimeFieldType getFieldType() {
60          return getField().getType();
61      }
62  
63      /**
64       * Gets the name of the field.
65       * 
66       * @return the field name
67       */
68      public String getName() {
69          return getField().getName();
70      }
71  
72      /**
73       * Gets the partial instant being used.
74       * 
75       * @return the partial instant
76       */
77      protected abstract ReadablePartial getReadablePartial();
78  
79      //-----------------------------------------------------------------------
80      /**
81       * Gets the value of this property from the instant.
82       * <p>
83       * For example, the following two lines of code are equivalent:
84       * <pre>
85       * partial.getDayOfMonth();
86       * partial.dayOfMonth().get();
87       * </pre>
88       * 
89       * @return the current value
90       */
91      public abstract int get();
92  
93      /**
94       * Gets the value of this property from the instant as a string.
95       * <p>
96       * This method returns the value converted to a <code>String</code>
97       * using <code>Integer.toString</code>. This method does NOT return
98       * textual descriptions such as 'Monday' or 'January'.
99       * 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().getAsText(getReadablePartial(), get(), locale);
138     }
139 
140     /**
141      * Gets the short textual value of this property from the instant as a
142      * string in the default locale.
143      * <p>
144      * This method returns the value converted to a <code>String</code>
145      * returning the appropriate textual description wherever possible.
146      * Thus, a day of week of 1 would return 'Mon' in English.
147      * 
148      * @return the current text value
149      * @see DateTimeField#getAsShortText
150      */
151     public String getAsShortText() {
152         return getAsShortText(null);
153     }
154 
155     /**
156      * Gets the short textual value of this property from the instant as a
157      * string in the specified locale.
158      * <p>
159      * This method returns the value converted to a <code>String</code>
160      * returning the appropriate textual description wherever possible.
161      * Thus, a day of week of 1 would return 'Mon' in English.
162      * 
163      * @param locale  locale to use for selecting a text symbol, null means default
164      * @return the current text value
165      * @see DateTimeField#getAsShortText
166      */
167     public String getAsShortText(Locale locale) {
168         return getField().getAsShortText(getReadablePartial(), get(), locale);
169     }
170 
171     //-----------------------------------------------------------------------
172     /**
173      * Returns the duration per unit value of this field. For example, if this
174      * field represents "hour of day", then the duration is an hour.
175      *
176      * @return the duration of this field, or UnsupportedDurationField
177      */
178     public DurationField getDurationField() {
179         return getField().getDurationField();
180     }
181 
182     /**
183      * Returns the range duration of this field. For example, if this field
184      * represents "hour of day", then the range duration is a day.
185      *
186      * @return the range duration of this field, or null if field has no range
187      */
188     public DurationField getRangeDurationField() {
189         return getField().getRangeDurationField();
190     }
191 
192     //-----------------------------------------------------------------------
193     /**
194      * Gets the minimum value for the field ignoring the current time.
195      * 
196      * @return the minimum value
197      * @see DateTimeField#getMinimumValue
198      */
199     public int getMinimumValueOverall() {
200         return getField().getMinimumValue();
201     }
202 
203     /**
204      * Gets the minimum value for this field given the current field values.
205      * 
206      * @return the minimum value
207      * @see DateTimeField#getMinimumValue
208      */
209     public int getMinimumValue() {
210         return getField().getMinimumValue(getReadablePartial());
211     }
212 
213     /**
214      * Gets the maximum value for the field ignoring the current time.
215      * 
216      * @return the maximum value
217      * @see DateTimeField#getMaximumValue
218      */
219     public int getMaximumValueOverall() {
220         return getField().getMaximumValue();
221     }
222 
223     /**
224      * Gets the maximum value for this field given the current field values.
225      * 
226      * @return the maximum value
227      * @see DateTimeField#getMaximumValue
228      */
229     public int getMaximumValue() {
230         return getField().getMaximumValue(getReadablePartial());
231     }
232 
233     //-----------------------------------------------------------------------
234     /**
235      * Gets the maximum text length for the field.
236      * 
237      * @param locale  optional locale to use for selecting a text symbol
238      * @return the maximum length
239      * @see DateTimeField#getMaximumTextLength
240      */
241     public int getMaximumTextLength(Locale locale) {
242         return getField().getMaximumTextLength(locale);
243     }
244 
245     /**
246      * Gets the maximum short text length for the field.
247      * 
248      * @param locale  optional locale to use for selecting a text symbol
249      * @return the maximum length
250      * @see DateTimeField#getMaximumShortTextLength
251      */
252     public int getMaximumShortTextLength(Locale locale) {
253         return getField().getMaximumShortTextLength(locale);
254     }
255 
256     //-----------------------------------------------------------------------
257     /**
258      * Compare this field to the same field on another instant.
259      * <p>
260      * The comparison is based on the value of the same field type, irrespective
261      * of any difference in chronology. Thus, if this property represents the
262      * hourOfDay field, then the hourOfDay field of the other instant will be queried
263      * whether in the same chronology or not.
264      * 
265      * @param instant  the instant to compare to
266      * @return negative value if this is less, 0 if equal, or positive value if greater
267      * @throws IllegalArgumentException if the instant is null or the instant
268      *  doesn't support the field of this property
269      */
270     public int compareTo(ReadableInstant instant) {
271         if (instant == null) {
272             throw new IllegalArgumentException("The instant must not be null");
273         }
274         int thisValue = get();
275         int otherValue = instant.get(getFieldType());
276         if (thisValue < otherValue) {
277             return -1;
278         } else if (thisValue > otherValue) {
279             return 1;
280         } else {
281             return 0;
282         }
283     }
284 
285     /**
286      * Compare this field to the same field on another partial instant.
287      * <p>
288      * The comparison is based on the value of the same field type, irrespective
289      * of any difference in chronology. Thus, if this property represents the
290      * hourOfDay field, then the hourOfDay field of the other partial will be queried
291      * whether in the same chronology or not.
292      * 
293      * @param partial  the partial to compare to
294      * @return negative value if this is less, 0 if equal, or positive value if greater
295      * @throws IllegalArgumentException if the instant is null
296      * @throws IllegalArgumentException if the field of this property cannot be queried
297      *  on the specified instant
298      */
299     public int compareTo(ReadablePartial partial) {
300         if (partial == null) {
301             throw new IllegalArgumentException("The instant must not be null");
302         }
303         int thisValue = get();
304         int otherValue = partial.get(getFieldType());
305         if (thisValue < otherValue) {
306             return -1;
307         } else if (thisValue > otherValue) {
308             return 1;
309         } else {
310             return 0;
311         }
312     }
313 
314     //-----------------------------------------------------------------------
315     /**
316      * Compares this property to another.
317      * 
318      * @param object  the object to compare to
319      * @return true if equal
320      */
321     public boolean equals(Object object) {
322         if (this == object) {
323             return true;
324         }
325         if (object instanceof AbstractPartialFieldProperty == false) {
326             return false;
327         }
328         AbstractPartialFieldProperty other = (AbstractPartialFieldProperty) object;
329         return
330             get() == other.get() &&
331             getFieldType() == other.getFieldType() &&
332             FieldUtils.equals(getReadablePartial().getChronology(), other.getReadablePartial().getChronology());
333     }
334 
335     //-----------------------------------------------------------------------
336     /**
337      * Gets a suitable hashcode for the object.
338      * 
339      * @return the hashcode
340      * @since 1.3
341      */
342     public int hashCode() {
343         int hash = 19;
344         hash = 13 * hash + get();
345         hash = 13 * hash + getFieldType().hashCode();
346         hash = 13 * hash + getReadablePartial().getChronology().hashCode();
347         return hash;
348     }
349 
350     //-----------------------------------------------------------------------
351     /**
352      * Output a debugging string.
353      * 
354      * @return debugging string
355      */
356     public String toString() {
357         return "Property[" + getName() + "]";
358     }
359 
360 }