EMMA Coverage Report (generated Tue Oct 28 00:01:11 GMT 2008)
[all classes][org.joda.time.base]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractPartial.java]

nameclass, %method, %block, %line, %
AbstractPartial.java100% (1/1)100% (20/20)100% (406/406)100% (81/81)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractPartial100% (1/1)100% (20/20)100% (406/406)100% (81/81)
AbstractPartial (): void 100% (1/1)100% (3/3)100% (2/2)
compareTo (Object): int 100% (1/1)100% (70/70)100% (14/14)
equals (Object): boolean 100% (1/1)100% (52/52)100% (11/11)
get (DateTimeFieldType): int 100% (1/1)100% (6/6)100% (1/1)
getField (int): DateTimeField 100% (1/1)100% (6/6)100% (1/1)
getFieldType (int): DateTimeFieldType 100% (1/1)100% (7/7)100% (1/1)
getFieldTypes (): DateTimeFieldType [] 100% (1/1)100% (20/20)100% (4/4)
getFields (): DateTimeField [] 100% (1/1)100% (20/20)100% (4/4)
getValues (): int [] 100% (1/1)100% (20/20)100% (4/4)
hashCode (): int 100% (1/1)100% (37/37)100% (6/6)
indexOf (DateTimeFieldType): int 100% (1/1)100% (19/19)100% (4/4)
indexOf (DurationFieldType): int 100% (1/1)100% (20/20)100% (4/4)
indexOfSupported (DateTimeFieldType): int 100% (1/1)100% (23/23)100% (4/4)
indexOfSupported (DurationFieldType): int 100% (1/1)100% (23/23)100% (4/4)
isAfter (ReadablePartial): boolean 100% (1/1)100% (15/15)100% (3/3)
isBefore (ReadablePartial): boolean 100% (1/1)100% (15/15)100% (3/3)
isEqual (ReadablePartial): boolean 100% (1/1)100% (15/15)100% (3/3)
isSupported (DateTimeFieldType): boolean 100% (1/1)100% (9/9)100% (1/1)
toDateTime (ReadableInstant): DateTime 100% (1/1)100% (17/17)100% (4/4)
toString (DateTimeFormatter): String 100% (1/1)100% (9/9)100% (3/3)

1/*
2 *  Copyright 2001-2005 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 */
16package org.joda.time.base;
17 
18import org.joda.time.Chronology;
19import org.joda.time.DateTime;
20import org.joda.time.DateTimeField;
21import org.joda.time.DateTimeFieldType;
22import org.joda.time.DateTimeUtils;
23import org.joda.time.DurationFieldType;
24import org.joda.time.ReadableInstant;
25import org.joda.time.ReadablePartial;
26import org.joda.time.field.FieldUtils;
27import org.joda.time.format.DateTimeFormatter;
28 
29/**
30 * AbstractPartial provides a standard base implementation of most methods
31 * in the ReadablePartial interface.
32 * <p>
33 * Calculations on are performed using a {@link Chronology}.
34 * This chronology is set to be in the UTC time zone for all calculations.
35 * <p>
36 * The methods on this class use {@link ReadablePartial#size()},
37 * {@link AbstractPartial#getField(int, Chronology)} and
38 * {@link ReadablePartial#getValue(int)} to calculate their results.
39 * Subclasses may have a better implementation.
40 * <p>
41 * AbstractPartial allows subclasses may be mutable and not thread-safe.
42 *
43 * @author Stephen Colebourne
44 * @since 1.0
45 */
46public abstract class AbstractPartial
47        implements ReadablePartial, Comparable {
48 
49    //-----------------------------------------------------------------------
50    /**
51     * Constructor.
52     */
53    protected AbstractPartial() {
54        super();
55    }
56 
57    //-----------------------------------------------------------------------
58    /**
59     * Gets the field for a specific index in the chronology specified.
60     * <p>
61     * This method must not use any instance variables.
62     * 
63     * @param index  the index to retrieve
64     * @param chrono  the chronology to use
65     * @return the field
66     * @throws IndexOutOfBoundsException if the index is invalid
67     */
68    protected abstract DateTimeField getField(int index, Chronology chrono);
69 
70    //-----------------------------------------------------------------------
71    /**
72     * Gets the field type at the specifed index.
73     * 
74     * @param index  the index
75     * @return the field type
76     * @throws IndexOutOfBoundsException if the index is invalid
77     */
78    public DateTimeFieldType getFieldType(int index) {
79        return getField(index, getChronology()).getType();
80    }
81 
82    /**
83     * Gets an array of the field types that this partial supports.
84     * <p>
85     * The fields are returned largest to smallest, for example Hour, Minute, Second.
86     *
87     * @return the fields supported in an array that may be altered, largest to smallest
88     */
89    public DateTimeFieldType[] getFieldTypes() {
90        DateTimeFieldType[] result = new DateTimeFieldType[size()];
91        for (int i = 0; i < result.length; i++) {
92            result[i] = getFieldType(i);
93        }
94        return result;
95    }
96 
97    /**
98     * Gets the field at the specifed index.
99     * 
100     * @param index  the index
101     * @return the field
102     * @throws IndexOutOfBoundsException if the index is invalid
103     */
104    public DateTimeField getField(int index) {
105        return getField(index, getChronology());
106    }
107 
108    /**
109     * Gets an array of the fields that this partial supports.
110     * <p>
111     * The fields are returned largest to smallest, for example Hour, Minute, Second.
112     *
113     * @return the fields supported in an array that may be altered, largest to smallest
114     */
115    public DateTimeField[] getFields() {
116        DateTimeField[] result = new DateTimeField[size()];
117        for (int i = 0; i < result.length; i++) {
118            result[i] = getField(i);
119        }
120        return result;
121    }
122 
123    /**
124     * Gets an array of the value of each of the fields that this partial supports.
125     * <p>
126     * The fields are returned largest to smallest, for example Hour, Minute, Second.
127     * Each value corresponds to the same array index as <code>getFields()</code>
128     *
129     * @return the current values of each field in an array that may be altered, largest to smallest
130     */
131    public int[] getValues() {
132        int[] result = new int[size()];
133        for (int i = 0; i < result.length; i++) {
134            result[i] = getValue(i);
135        }
136        return result;
137    }
138 
139    //-----------------------------------------------------------------------
140    /**
141     * Get the value of one of the fields of a datetime.
142     * <p>
143     * The field specified must be one of those that is supported by the partial.
144     *
145     * @param type  a DateTimeFieldType instance that is supported by this partial
146     * @return the value of that field
147     * @throws IllegalArgumentException if the field is null or not supported
148     */
149    public int get(DateTimeFieldType type) {
150        return getValue(indexOfSupported(type));
151    }
152 
153    /**
154     * Checks whether the field specified is supported by this partial.
155     *
156     * @param type  the type to check, may be null which returns false
157     * @return true if the field is supported
158     */
159    public boolean isSupported(DateTimeFieldType type) {
160        return (indexOf(type) != -1);
161    }
162 
163    /**
164     * Gets the index of the specified field, or -1 if the field is unsupported.
165     *
166     * @param type  the type to check, may be null which returns -1
167     * @return the index of the field, -1 if unsupported
168     */
169    public int indexOf(DateTimeFieldType type) {
170        for (int i = 0, isize = size(); i < isize; i++) {
171            if (getFieldType(i) == type) {
172                return i;
173            }
174        }
175        return -1;
176    }
177 
178    /**
179     * Gets the index of the specified field, throwing an exception if the
180     * field is unsupported.
181     *
182     * @param type  the type to check, not null
183     * @return the index of the field
184     * @throws IllegalArgumentException if the field is null or not supported
185     */
186    protected int indexOfSupported(DateTimeFieldType type) {
187        int index = indexOf(type);
188        if (index == -1) {
189            throw new IllegalArgumentException("Field '" + type + "' is not supported");
190        }
191        return index;
192    }
193 
194    /**
195     * Gets the index of the first fields to have the specified duration,
196     * or -1 if the field is unsupported.
197     *
198     * @param type  the type to check, may be null which returns -1
199     * @return the index of the field, -1 if unsupported
200     */
201    protected int indexOf(DurationFieldType type) {
202        for (int i = 0, isize = size(); i < isize; i++) {
203            if (getFieldType(i).getDurationType() == type) {
204                return i;
205            }
206        }
207        return -1;
208    }
209 
210    /**
211     * Gets the index of the first fields to have the specified duration,
212     * throwing an exception if the field is unsupported.
213     *
214     * @param type  the type to check, not null
215     * @return the index of the field
216     * @throws IllegalArgumentException if the field is null or not supported
217     */
218    protected int indexOfSupported(DurationFieldType type) {
219        int index = indexOf(type);
220        if (index == -1) {
221            throw new IllegalArgumentException("Field '" + type + "' is not supported");
222        }
223        return index;
224    }
225 
226    //-----------------------------------------------------------------------
227    /**
228     * Resolves this partial against another complete instant to create a new
229     * full instant. The combination is performed using the chronology of the
230     * specified instant.
231     * <p>
232     * For example, if this partial represents a time, then the result of this
233     * method will be the datetime from the specified base instant plus the
234     * time from this partial.
235     *
236     * @param baseInstant  the instant that provides the missing fields, null means now
237     * @return the combined datetime
238     */
239    public DateTime toDateTime(ReadableInstant baseInstant) {
240        Chronology chrono = DateTimeUtils.getInstantChronology(baseInstant);
241        long instantMillis = DateTimeUtils.getInstantMillis(baseInstant);
242        long resolved = chrono.set(this, instantMillis);
243        return new DateTime(resolved, chrono);
244    }
245 
246    //-----------------------------------------------------------------------
247    /**
248     * Compares this ReadablePartial with another returning true if the chronology,
249     * field types and values are equal.
250     *
251     * @param partial  an object to check against
252     * @return true if fields and values are equal
253     */
254    public boolean equals(Object partial) {
255        if (this == partial) {
256            return true;
257        }
258        if (partial instanceof ReadablePartial == false) {
259            return false;
260        }
261        ReadablePartial other = (ReadablePartial) partial;
262        if (size() != other.size()) {
263            return false;
264        }
265        for (int i = 0, isize = size(); i < isize; i++) {
266            if (getValue(i) != other.getValue(i) || getFieldType(i) != other.getFieldType(i)) {
267                return false;
268            }
269        }
270        return FieldUtils.equals(getChronology(), other.getChronology());
271    }
272 
273    /**
274     * Gets a hash code for the ReadablePartial that is compatible with the 
275     * equals method.
276     *
277     * @return a suitable hash code
278     */
279    public int hashCode() {
280        int total = 157;
281        for (int i = 0, isize = size(); i < isize; i++) {
282            total = 23 * total + getValue(i);
283            total = 23 * total + getFieldType(i).hashCode();
284        }
285        total += getChronology().hashCode();
286        return total;
287    }
288 
289    //-----------------------------------------------------------------------
290    /**
291     * Compares this partial with another returning an integer
292     * indicating the order.
293     * <p>
294     * The fields are compared in order, from largest to smallest.
295     * The first field that is non-equal is used to determine the result.
296     * <p>
297     * The specified object must be a partial instance whose field types
298     * match those of this partial.
299     * <p>
300     * NOTE: This implementation violates the Comparable contract.
301     * This method will accept any instance of ReadablePartial as input.
302     * However, it is possible that some implementations of ReadablePartial
303     * exist that do not extend AbstractPartial, and thus will throw a
304     * ClassCastException if compared in the opposite direction.
305     * The cause of this problem is that ReadablePartial doesn't define
306     * the compareTo() method, however we can't change that until v2.0.
307     *
308     * @param partial  an object to check against
309     * @return negative if this is less, zero if equal, positive if greater
310     * @throws ClassCastException if the partial is the wrong class
311     *  or if it has field types that don't match
312     * @throws NullPointerException if the partial is null
313     * @since 1.1
314     */
315    public int compareTo(Object partial) {
316        if (this == partial) {
317            return 0;
318        }
319        ReadablePartial other = (ReadablePartial) partial;
320        if (size() != other.size()) {
321            throw new ClassCastException("ReadablePartial objects must have matching field types");
322        }
323        for (int i = 0, isize = size(); i < isize; i++) {
324            if (getFieldType(i) != other.getFieldType(i)) {
325                throw new ClassCastException("ReadablePartial objects must have matching field types");
326            }
327        }
328        // fields are ordered largest first
329        for (int i = 0, isize = size(); i < isize; i++) {
330            if (getValue(i) > other.getValue(i)) {
331                return 1;
332            }
333            if (getValue(i) < other.getValue(i)) {
334                return -1;
335            }
336        }
337        return 0;
338    }
339 
340    /**
341     * Is this partial later than the specified partial.
342     * <p>
343     * The fields are compared in order, from largest to smallest.
344     * The first field that is non-equal is used to determine the result.
345     * <p>
346     * You may not pass null into this method. This is because you need
347     * a time zone to accurately determine the current date.
348     *
349     * @param partial  a partial to check against, must not be null
350     * @return true if this date is after the date passed in
351     * @throws IllegalArgumentException if the specified partial is null
352     * @throws ClassCastException if the partial has field types that don't match
353     * @since 1.1
354     */
355    public boolean isAfter(ReadablePartial partial) {
356        if (partial == null) {
357            throw new IllegalArgumentException("Partial cannot be null");
358        }
359        return compareTo(partial) > 0;
360    }
361 
362    /**
363     * Is this partial earlier than the specified partial.
364     * <p>
365     * The fields are compared in order, from largest to smallest.
366     * The first field that is non-equal is used to determine the result.
367     * <p>
368     * You may not pass null into this method. This is because you need
369     * a time zone to accurately determine the current date.
370     *
371     * @param partial  a partial to check against, must not be null
372     * @return true if this date is before the date passed in
373     * @throws IllegalArgumentException if the specified partial is null
374     * @throws ClassCastException if the partial has field types that don't match
375     * @since 1.1
376     */
377    public boolean isBefore(ReadablePartial partial) {
378        if (partial == null) {
379            throw new IllegalArgumentException("Partial cannot be null");
380        }
381        return compareTo(partial) < 0;
382    }
383 
384    /**
385     * Is this partial the same as the specified partial.
386     * <p>
387     * The fields are compared in order, from largest to smallest.
388     * If all fields are equal, the result is true.
389     * <p>
390     * You may not pass null into this method. This is because you need
391     * a time zone to accurately determine the current date.
392     *
393     * @param partial  a partial to check against, must not be null
394     * @return true if this date is the same as the date passed in
395     * @throws IllegalArgumentException if the specified partial is null
396     * @throws ClassCastException if the partial has field types that don't match
397     * @since 1.1
398     */
399    public boolean isEqual(ReadablePartial partial) {
400        if (partial == null) {
401            throw new IllegalArgumentException("Partial cannot be null");
402        }
403        return compareTo(partial) == 0;
404    }
405 
406    //-----------------------------------------------------------------------
407    /**
408     * Uses the specified formatter to convert this partial to a String.
409     *
410     * @param formatter  the formatter to use, null means use <code>toString()</code>.
411     * @return the formatted string
412     * @since 1.1
413     */
414    public String toString(DateTimeFormatter formatter) {
415        if (formatter == null) {
416            return toString();
417        }
418        return formatter.print(this);
419    }
420 
421}

[all classes][org.joda.time.base]
EMMA 2.0.5312 (C) Vladimir Roubtsov