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

COVERAGE SUMMARY FOR SOURCE FILE [StringConverter.java]

nameclass, %method, %block, %line, %
StringConverter.java100% (1/1)100% (8/8)98%  (449/458)99%  (81.9/83)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StringConverter100% (1/1)100% (8/8)98%  (449/458)99%  (81.9/83)
setInto (ReadWritablePeriod, Object, Chronology): void 100% (1/1)83%  (34/41)89%  (8/9)
setInto (ReadWritableInterval, Object, Chronology): void 100% (1/1)99%  (186/188)100% (37.9/38)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
StringConverter (): void 100% (1/1)100% (3/3)100% (2/2)
getDurationMillis (Object): long 100% (1/1)100% (181/181)100% (25/25)
getInstantMillis (Object, Chronology): long 100% (1/1)100% (11/11)100% (3/3)
getPartialValues (ReadablePartial, Object, Chronology, DateTimeFormatter): in... 100% (1/1)100% (20/20)100% (4/4)
getSupportedType (): Class 100% (1/1)100% (9/9)100% (1/1)

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 */
16package org.joda.time.convert;
17 
18import org.joda.time.Chronology;
19import org.joda.time.DateTime;
20import org.joda.time.Period;
21import org.joda.time.ReadWritableInterval;
22import org.joda.time.ReadWritablePeriod;
23import org.joda.time.ReadablePartial;
24import org.joda.time.field.FieldUtils;
25import org.joda.time.format.DateTimeFormatter;
26import org.joda.time.format.ISODateTimeFormat;
27import org.joda.time.format.ISOPeriodFormat;
28import org.joda.time.format.PeriodFormatter;
29 
30/**
31 * StringConverter converts from a String to an instant, partial,
32 * duration, period or interval..
33 *
34 * @author Stephen Colebourne
35 * @author Brian S O'Neill
36 * @since 1.0
37 */
38class StringConverter extends AbstractConverter
39        implements InstantConverter, PartialConverter, DurationConverter, PeriodConverter, IntervalConverter {
40 
41    /**
42     * Singleton instance.
43     */
44    static final StringConverter INSTANCE = new StringConverter();
45 
46    /**
47     * Restricted constructor.
48     */
49    protected StringConverter() {
50        super();
51    }
52 
53    //-----------------------------------------------------------------------
54    /**
55     * Gets the millis, which is the ISO parsed string value.
56     * 
57     * @param object  the String to convert, must not be null
58     * @param chrono  the chronology to use, non-null result of getChronology
59     * @return the millisecond value
60     * @throws IllegalArgumentException if the value if invalid
61     */
62    public long getInstantMillis(Object object, Chronology chrono) {
63        String str = (String) object;
64        DateTimeFormatter p = ISODateTimeFormat.dateTimeParser();
65        return p.withChronology(chrono).parseMillis(str);
66    }
67 
68    /**
69     * Extracts the values of the partial from an object of this converter's type.
70     * This method checks if the parser has a zone, and uses it if present.
71     * This is most useful for parsing local times with UTC.
72     * 
73     * @param fieldSource  a partial that provides access to the fields.
74     *  This partial may be incomplete and only getFieldType(int) should be used
75     * @param object  the object to convert
76     * @param chrono  the chronology to use, which is the non-null result of getChronology()
77     * @param parser the parser to use, may be null
78     * @return the array of field values that match the fieldSource, must be non-null valid
79     * @throws ClassCastException if the object is invalid
80     * @throws IllegalArgumentException if the value if invalid
81     * @since 1.3
82     */
83    public int[] getPartialValues(ReadablePartial fieldSource, Object object, Chronology chrono, DateTimeFormatter parser) {
84        if (parser.getZone() != null) {
85            chrono = chrono.withZone(parser.getZone());
86        }
87        long millis = parser.withChronology(chrono).parseMillis((String) object);
88        return chrono.get(fieldSource, millis);
89    }
90 
91    //-----------------------------------------------------------------------
92    /**
93     * Gets the duration of the string using the standard type.
94     * This matches the toString() method of ReadableDuration.
95     * 
96     * @param object  the String to convert, must not be null
97     * @throws ClassCastException if the object is invalid
98     */
99    public long getDurationMillis(Object object) {
100        // parse here because duration could be bigger than the int supported
101        // by the period parser
102        String original = (String) object;
103        String str = original;
104        int len = str.length();
105        if (len >= 4 &&
106            (str.charAt(0) == 'P' || str.charAt(0) == 'p') &&
107            (str.charAt(1) == 'T' || str.charAt(1) == 't') &&
108            (str.charAt(len - 1) == 'S' || str.charAt(len - 1) == 's')) {
109            // ok
110        } else {
111            throw new IllegalArgumentException("Invalid format: \"" + original + '"');
112        }
113        str = str.substring(2, len - 1);
114        int dot = -1;
115        for (int i = 0; i < str.length(); i++) {
116            if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') ||
117                (i == 0 && str.charAt(0) == '-')) {
118                // ok
119            } else if (i > 0 && str.charAt(i) == '.' && dot == -1) {
120                // ok
121                dot = i;
122            } else {
123                throw new IllegalArgumentException("Invalid format: \"" + original + '"');
124            }
125        }
126        long millis = 0, seconds = 0;
127        if (dot > 0) {
128            seconds = Long.parseLong(str.substring(0, dot));
129            str = str.substring(dot + 1);
130            if (str.length() != 3) {
131                str = (str + "000").substring(0, 3);
132            }
133            millis = Integer.parseInt(str);
134        } else {
135            seconds = Long.parseLong(str);
136        }
137        if (seconds < 0) {
138            return FieldUtils.safeAdd(FieldUtils.safeMultiply(seconds, 1000), -millis);
139        } else {
140            return FieldUtils.safeAdd(FieldUtils.safeMultiply(seconds, 1000), millis);
141        }
142    }
143 
144    //-----------------------------------------------------------------------
145    /**
146     * Extracts duration values from an object of this converter's type, and
147     * sets them into the given ReadWritableDuration.
148     *
149     * @param period  period to get modified
150     * @param object  the String to convert, must not be null
151     * @param chrono  the chronology to use
152     * @return the millisecond duration
153     * @throws ClassCastException if the object is invalid
154     */
155    public void setInto(ReadWritablePeriod period, Object object, Chronology chrono) {
156        String str = (String) object;
157        PeriodFormatter parser = ISOPeriodFormat.standard();
158        period.clear();
159        int pos = parser.parseInto(period, str, 0);
160        if (pos < str.length()) {
161            if (pos < 0) {
162                // Parse again to get a better exception thrown.
163                parser.withParseType(period.getPeriodType()).parseMutablePeriod(str);
164            }
165            throw new IllegalArgumentException("Invalid format: \"" + str + '"');
166        }
167    }
168 
169    //-----------------------------------------------------------------------
170    /**
171     * Sets the value of the mutable interval from the string.
172     * 
173     * @param writableInterval  the interval to set
174     * @param object  the String to convert, must not be null
175     * @param chrono  the chronology to use, may be null
176     */
177    public void setInto(ReadWritableInterval writableInterval, Object object, Chronology chrono) {
178        String str = (String) object;
179 
180        int separator = str.indexOf('/');
181        if (separator < 0) {
182            throw new IllegalArgumentException("Format requires a '/' separator: " + str);
183        }
184 
185        String leftStr = str.substring(0, separator);
186        if (leftStr.length() <= 0) {
187            throw new IllegalArgumentException("Format invalid: " + str);
188        }
189        String rightStr = str.substring(separator + 1);
190        if (rightStr.length() <= 0) {
191            throw new IllegalArgumentException("Format invalid: " + str);
192        }
193 
194        DateTimeFormatter dateTimeParser = ISODateTimeFormat.dateTimeParser();
195        dateTimeParser = dateTimeParser.withChronology(chrono);
196        PeriodFormatter periodParser = ISOPeriodFormat.standard();
197        long startInstant = 0, endInstant = 0;
198        Period period = null;
199        Chronology parsedChrono = null;
200        
201        // before slash
202        char c = leftStr.charAt(0);
203        if (c == 'P' || c == 'p') {
204            period = periodParser.withParseType(getPeriodType(leftStr)).parsePeriod(leftStr);
205        } else {
206            DateTime start = dateTimeParser.parseDateTime(leftStr);
207            startInstant = start.getMillis();
208            parsedChrono = start.getChronology();
209        }
210        
211        // after slash
212        c = rightStr.charAt(0);
213        if (c == 'P' || c == 'p') {
214            if (period != null) {
215                throw new IllegalArgumentException("Interval composed of two durations: " + str);
216            }
217            period = periodParser.withParseType(getPeriodType(rightStr)).parsePeriod(rightStr);
218            chrono = (chrono != null ? chrono : parsedChrono);
219            endInstant = chrono.add(period, startInstant, 1);
220        } else {
221            DateTime end = dateTimeParser.parseDateTime(rightStr);
222            endInstant = end.getMillis();
223            parsedChrono = (parsedChrono != null ? parsedChrono : end.getChronology());
224            chrono = (chrono != null ? chrono : parsedChrono);
225            if (period != null) {
226                startInstant = chrono.add(period, endInstant, -1);
227            }
228        }
229        
230        writableInterval.setInterval(startInstant, endInstant);
231        writableInterval.setChronology(chrono);
232    }
233 
234    //-----------------------------------------------------------------------
235    /**
236     * Returns String.class.
237     * 
238     * @return String.class
239     */
240    public Class getSupportedType() {
241        return String.class;
242    }
243 
244}

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