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

COVERAGE SUMMARY FOR SOURCE FILE [PeriodFormatter.java]

nameclass, %method, %block, %line, %
PeriodFormatter.java100% (1/1)100% (19/19)100% (233/233)100% (60/60)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PeriodFormatter100% (1/1)100% (19/19)100% (233/233)100% (60/60)
PeriodFormatter (PeriodPrinter, PeriodParser): void 100% (1/1)100% (15/15)100% (6/6)
PeriodFormatter (PeriodPrinter, PeriodParser, Locale, PeriodType): void 100% (1/1)100% (15/15)100% (6/6)
checkParser (): void 100% (1/1)100% (9/9)100% (3/3)
checkPeriod (ReadablePeriod): void 100% (1/1)100% (8/8)100% (3/3)
checkPrinter (): void 100% (1/1)100% (9/9)100% (3/3)
getLocale (): Locale 100% (1/1)100% (3/3)100% (1/1)
getParseType (): PeriodType 100% (1/1)100% (3/3)100% (1/1)
getParser (): PeriodParser 100% (1/1)100% (3/3)100% (1/1)
getPrinter (): PeriodPrinter 100% (1/1)100% (3/3)100% (1/1)
isParser (): boolean 100% (1/1)100% (7/7)100% (1/1)
isPrinter (): boolean 100% (1/1)100% (7/7)100% (1/1)
parseInto (ReadWritablePeriod, String, int): int 100% (1/1)100% (14/14)100% (3/3)
parseMutablePeriod (String): MutablePeriod 100% (1/1)100% (37/37)100% (8/8)
parsePeriod (String): Period 100% (1/1)100% (7/7)100% (2/2)
print (ReadablePeriod): String 100% (1/1)100% (26/26)100% (6/6)
printTo (StringBuffer, ReadablePeriod): void 100% (1/1)100% (13/13)100% (4/4)
printTo (Writer, ReadablePeriod): void 100% (1/1)100% (13/13)100% (4/4)
withLocale (Locale): PeriodFormatter 100% (1/1)100% (24/24)100% (3/3)
withParseType (PeriodType): PeriodFormatter 100% (1/1)100% (17/17)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.format;
17 
18import java.io.IOException;
19import java.io.Writer;
20import java.util.Locale;
21 
22import org.joda.time.MutablePeriod;
23import org.joda.time.Period;
24import org.joda.time.PeriodType;
25import org.joda.time.ReadWritablePeriod;
26import org.joda.time.ReadablePeriod;
27 
28/**
29 * Controls the printing and parsing of a time period to and from a string.
30 * <p>
31 * This class is the main API for printing and parsing used by most applications.
32 * Instances of this class are created via one of three factory classes:
33 * <ul>
34 * <li>{@link PeriodFormat} - formats by pattern and style</li>
35 * <li>{@link ISOPeriodFormat} - ISO8601 formats</li>
36 * <li>{@link PeriodFormatterBuilder} - complex formats created via method calls</li>
37 * </ul>
38 * <p>
39 * An instance of this class holds a reference internally to one printer and
40 * one parser. It is possible that one of these may be null, in which case the
41 * formatter cannot print/parse. This can be checked via the {@link #isPrinter()}
42 * and {@link #isParser()} methods.
43 * <p>
44 * The underlying printer/parser can be altered to behave exactly as required
45 * by using a decorator modifier:
46 * <ul>
47 * <li>{@link #withLocale(Locale)} - returns a new formatter that uses the specified locale</li>
48 * </ul>
49 * This returns a new formatter (instances of this class are immutable).
50 * <p>
51 * The main methods of the class are the <code>printXxx</code> and
52 * <code>parseXxx</code> methods. These are used as follows:
53 * <pre>
54 * // print using the default locale
55 * String periodStr = formatter.print(period);
56 * // print using the French locale
57 * String periodStr = formatter.withLocale(Locale.FRENCH).print(period);
58 * 
59 * // parse using the French locale
60 * Period date = formatter.withLocale(Locale.FRENCH).parsePeriod(str);
61 * </pre>
62 *
63 * @author Brian S O'Neill
64 * @author Stephen Colebourne
65 * @since 1.0
66 */
67public class PeriodFormatter {
68 
69    /** The internal printer used to output the datetime. */
70    private final PeriodPrinter iPrinter;
71    /** The internal parser used to output the datetime. */
72    private final PeriodParser iParser;
73    /** The locale to use for printing and parsing. */
74    private final Locale iLocale;
75    /** The period type used in parsing. */
76    private final PeriodType iParseType;
77 
78    /**
79     * Creates a new formatter, however you will normally use the factory
80     * or the builder.
81     * 
82     * @param printer  the internal printer, null if cannot print
83     * @param parser  the internal parser, null if cannot parse
84     */
85    public PeriodFormatter(
86            PeriodPrinter printer, PeriodParser parser) {
87        super();
88        iPrinter = printer;
89        iParser = parser;
90        iLocale = null;
91        iParseType = null;
92    }
93 
94    /**
95     * Constructor.
96     * 
97     * @param printer  the internal printer, null if cannot print
98     * @param parser  the internal parser, null if cannot parse
99     * @param locale  the locale to use
100     * @param type  the parse period type
101     */
102    private PeriodFormatter(
103            PeriodPrinter printer, PeriodParser parser,
104            Locale locale, PeriodType type) {
105        super();
106        iPrinter = printer;
107        iParser = parser;
108        iLocale = locale;
109        iParseType = type;
110    }
111 
112    //-----------------------------------------------------------------------
113    /**
114     * Is this formatter capable of printing.
115     * 
116     * @return true if this is a printer
117     */
118    public boolean isPrinter() {
119        return (iPrinter != null);
120    }
121 
122    /**
123     * Gets the internal printer object that performs the real printing work.
124     * 
125     * @return the internal printer
126     */
127    public PeriodPrinter getPrinter() {
128        return iPrinter;
129    }
130 
131    /**
132     * Is this formatter capable of parsing.
133     * 
134     * @return true if this is a parser
135     */
136    public boolean isParser() {
137        return (iParser != null);
138    }
139 
140    /**
141     * Gets the internal parser object that performs the real parsing work.
142     * 
143     * @return the internal parser
144     */
145    public PeriodParser getParser() {
146        return iParser;
147    }
148 
149    //-----------------------------------------------------------------------
150    /**
151     * Returns a new formatter with a different locale that will be used
152     * for printing and parsing.
153     * <p>
154     * A PeriodFormatter is immutable, so a new instance is returned,
155     * and the original is unaltered and still usable.
156     * 
157     * @param locale  the locale to use
158     * @return the new formatter
159     */
160    public PeriodFormatter withLocale(Locale locale) {
161        if (locale == getLocale() || (locale != null && locale.equals(getLocale()))) {
162            return this;
163        }
164        return new PeriodFormatter(iPrinter, iParser, locale, iParseType);
165    }
166 
167    /**
168     * Gets the locale that will be used for printing and parsing.
169     * 
170     * @return the locale to use
171     */
172    public Locale getLocale() {
173        return iLocale;
174    }
175 
176    //-----------------------------------------------------------------------
177    /**
178     * Returns a new formatter with a different PeriodType for parsing.
179     * <p>
180     * A PeriodFormatter is immutable, so a new instance is returned,
181     * and the original is unaltered and still usable.
182     * 
183     * @param type  the type to use in parsing
184     * @return the new formatter
185     */
186    public PeriodFormatter withParseType(PeriodType type) {
187        if (type == iParseType) {
188            return this;
189        }
190        return new PeriodFormatter(iPrinter, iParser, iLocale, type);
191    }
192 
193    /**
194     * Gets the PeriodType that will be used for parsing.
195     * 
196     * @return the parse type to use
197     */
198    public PeriodType getParseType() {
199        return iParseType;
200    }
201 
202    //-----------------------------------------------------------------------
203    /**
204     * Prints a ReadablePeriod to a StringBuffer.
205     *
206     * @param buf  the formatted period is appended to this buffer
207     * @param period  the period to format, not null
208     */
209    public void printTo(StringBuffer buf, ReadablePeriod period) {
210        checkPrinter();
211        checkPeriod(period);
212        
213        getPrinter().printTo(buf, period, iLocale);
214    }
215 
216    /**
217     * Prints a ReadablePeriod to a Writer.
218     *
219     * @param out  the formatted period is written out
220     * @param period  the period to format, not null
221     */
222    public void printTo(Writer out, ReadablePeriod period) throws IOException {
223        checkPrinter();
224        checkPeriod(period);
225        
226        getPrinter().printTo(out, period, iLocale);
227    }
228 
229    /**
230     * Prints a ReadablePeriod to a new String.
231     *
232     * @param period  the period to format, not null
233     * @return the printed result
234     */
235    public String print(ReadablePeriod period) {
236        checkPrinter();
237        checkPeriod(period);
238        
239        PeriodPrinter printer = getPrinter();
240        StringBuffer buf = new StringBuffer(printer.calculatePrintedLength(period, iLocale));
241        printer.printTo(buf, period, iLocale);
242        return buf.toString();
243    }
244 
245    /**
246     * Checks whether printing is supported.
247     * 
248     * @throws UnsupportedOperationException if printing is not supported
249     */
250    private void checkPrinter() {
251        if (iPrinter == null) {
252            throw new UnsupportedOperationException("Printing not supported");
253        }
254    }
255 
256    /**
257     * Checks whether the period is non-null.
258     * 
259     * @throws IllegalArgumentException if the period is null
260     */
261    private void checkPeriod(ReadablePeriod period) {
262        if (period == null) {
263            throw new IllegalArgumentException("Period must not be null");
264        }
265    }
266 
267    //-----------------------------------------------------------------------
268    /**
269     * Parses a period from the given text, at the given position, saving the
270     * result into the fields of the given ReadWritablePeriod. If the parse
271     * succeeds, the return value is the new text position. Note that the parse
272     * may succeed without fully reading the text.
273     * <p>
274     * The parse type of the formatter is not used by this method.
275     * <p>
276     * If it fails, the return value is negative, but the period may still be
277     * modified. To determine the position where the parse failed, apply the
278     * one's complement operator (~) on the return value.
279     *
280     * @param period  a period that will be modified
281     * @param text  text to parse
282     * @param position position to start parsing from
283     * @return new position, if negative, parse failed. Apply complement
284     * operator (~) to get position of failure
285     * @throws IllegalArgumentException if any field is out of range
286     */
287    public int parseInto(ReadWritablePeriod period, String text, int position) {
288        checkParser();
289        checkPeriod(period);
290        
291        return getParser().parseInto(period, text, position, iLocale);
292    }
293 
294    /**
295     * Parses a period from the given text, returning a new Period.
296     *
297     * @param text  text to parse
298     * @return parsed value in a Period object
299     * @throws IllegalArgumentException if any field is out of range
300     */
301    public Period parsePeriod(String text) {
302        checkParser();
303        
304        return parseMutablePeriod(text).toPeriod();
305    }
306 
307    /**
308     * Parses a period from the given text, returning a new MutablePeriod.
309     *
310     * @param text  text to parse
311     * @return parsed value in a MutablePeriod object
312     * @throws IllegalArgumentException if any field is out of range
313     */
314    public MutablePeriod parseMutablePeriod(String text) {
315        checkParser();
316        
317        MutablePeriod period = new MutablePeriod(0, iParseType);
318        int newPos = getParser().parseInto(period, text, 0, iLocale);
319        if (newPos >= 0) {
320            if (newPos >= text.length()) {
321                return period;
322            }
323        } else {
324            newPos = ~newPos;
325        }
326        throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
327    }
328 
329    /**
330     * Checks whether parsing is supported.
331     * 
332     * @throws UnsupportedOperationException if parsing is not supported
333     */
334    private void checkParser() {
335        if (iParser == null) {
336            throw new UnsupportedOperationException("Parsing not supported");
337        }
338    }
339 
340}

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