Source Code Cross Referenced for LineFormat.java in  » GIS » GeoTools-2.4.1 » org » geotools » io » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, GeoTools Project Managment Committee (PMC)
005:         *    (C) 2001, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation;
010:         *    version 2.1 of the License.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.io;
018:
019:        // Text format
020:        import java.lang.reflect.Array;
021:        import java.text.FieldPosition;
022:        import java.text.Format;
023:        import java.text.NumberFormat;
024:        import java.text.ParseException;
025:        import java.text.ParsePosition;
026:        import java.util.Arrays;
027:        import java.util.Locale;
028:
029:        // Geotools dependencies
030:        import org.geotools.resources.ClassChanger;
031:        import org.geotools.resources.XArray;
032:        import org.geotools.resources.i18n.Errors;
033:        import org.geotools.resources.i18n.ErrorKeys;
034:
035:        /**
036:         * Parses a line of text data. This class is mostly used for parsing lines in a matrix or a table.
037:         * Each column may contains numbers, dates, or other objects parseable by some {@link Format}
038:         * implementations. The example below reads dates in the first column and numbers in all
039:         * remaining columns.
040:         *
041:         * <blockquote><pre>
042:         * final LineParser parser = new LineFormat(new Format[] {
043:         *     {@link java.text.DateFormat#getDateTimeInstance()},
044:         *     {@link java.text.NumberFormat#getNumberInstance()}
045:         * });
046:         * </pre></blockquote>
047:         *
048:         * {@code LineFormat} may be used for reading a matrix with an unknow number of columns,
049:         * while requiring that all lines have the same number of columns. The example below gets the
050:         * number of columns while reading the first line, and ensure that all subsequent lines have
051:         * the same number of columns. If one line violate this condition, then a {@link ParseException}
052:         * will be thrown. The check if performed by the {@code getValues(double[])} method when
053:         * the {@code data} array is non-nul.
054:         *
055:         * <blockquote><pre>
056:         * &nbsp;double[] data=null;
057:         * &nbsp;final {@link java.io.BufferedReader} in = new {@link java.io.BufferedReader}(new {@link java.io.FileReader}("MATRIX.TXT"));
058:         * &nbsp;for ({@link String} line; (line=in.readLine()) != null;) {
059:         * &nbsp;    parser.setLine(line);
060:         * &nbsp;    data = parser.getValues(data);
061:         * &nbsp;    // ... process 'data' here ...
062:         * &nbsp;});
063:         * </pre></blockquote>
064:         *
065:         * This code can work as well with dates instead of numbers. In this case, the values returned
066:         * will be microseconds ellapsed since January 1st, 1970.
067:         * <p>
068:         * A {@link ParseException} may be thrown because a string can't be parsed, because an object
069:         * can't be converted into a number or because a line don't have the expected number of columns.
070:         * In all case, it is possible to gets the index of the first problem found using
071:         * {@link ParseException#getErrorOffset}.
072:         *
073:         * @since 2.0
074:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/io/LineFormat.java $
075:         * @version $Id: LineFormat.java 25467 2007-05-08 16:30:30Z desruisseaux $
076:         * @author Martin Desruisseaux
077:         */
078:        public class LineFormat extends Format {
079:            /**
080:             * Nombre de données valides dans le tableau {@link #data}.
081:             * Il s'agit du nombre de données lues lors du dernier appel
082:             * de la méthode {@link #setLine(String)}.
083:             */
084:            private int count;
085:
086:            /**
087:             * Données lus lors du dernier appel de la méthode {@link #setLine(String)}.
088:             * Ces données seront restitués par des appels à {@link #getValues(float[])}.
089:             */
090:            private Object[] data;
091:
092:            /**
093:             * Tableau de formats à utiliser. Chaque format de ce tableau correspond à une
094:             * colonne. Par exemple la donnée {@code data[4]} aura été lu avec le format
095:             * {@code format[4]}. Il n'est toutefois pas obligatoire qu'il y ait autant
096:             * de format que de colonnes. Si {@link #data} et plus long que {@link #format},
097:             * alors le dernier format sera réutilisé pour toutes les colonnes restantes.
098:             */
099:            private final Format[] format;
100:
101:            /**
102:             * Objet {@link ParsePosition} utilisé lors de la lecture pour spécifier quelle
103:             * partie de la chaîne doit être interprétée.
104:             */
105:            private final ParsePosition position = new ParsePosition(0);
106:
107:            /**
108:             * Index du caractère auquel commençaient les éléments qui ont été lus. Par exemple
109:             * {@code index[0]} contient l'index du premier caractère qui a été lu pour la
110:             * donnée {@code data[0]}, et ainsi de suite. Ce tableau doit <u>toujours</u>
111:             * avoir une longueur de <code>{@link #data}.length + 1</code>. Le dernier élément
112:             * de ce tableau sera la longueur de la ligne.
113:             */
114:            private int[] limits;
115:
116:            /**
117:             * Dernière ligne de texte à avoir été spécifiée à la méthode {@link #setLine(String)}.
118:             */
119:            private String line;
120:
121:            /**
122:             * Constructs a new line parser for the default locale.
123:             */
124:            public LineFormat() {
125:                this (NumberFormat.getNumberInstance());
126:            }
127:
128:            /**
129:             * Constructs a new line parser for the specified locale. For example {@link Locale#US}
130:             * may be used for reading numbers using the dot as decimal separator.
131:             */
132:            public LineFormat(final Locale locale) {
133:                this (NumberFormat.getNumberInstance(locale));
134:            }
135:
136:            /**
137:             * Constructs a new line parser using the specified format for every columns.
138:             *
139:             * @param format The format to use.
140:             * @throws IllegalArgumentException if {@code format} is null.
141:             */
142:            public LineFormat(final Format format)
143:                    throws IllegalArgumentException {
144:                this .data = new Object[16];
145:                this .limits = new int[data.length + 1];
146:                this .format = new Format[] { format };
147:                if (format == null) {
148:                    final Integer one = new Integer(1);
149:                    throw new IllegalArgumentException(Errors.format(
150:                            ErrorKeys.NULL_FORMAT_$2, one, one));
151:                }
152:            }
153:
154:            /**
155:             * Constructs a new line parser using the specified format objects. For example the first
156:             * column will be parsed using {@code formats[0]}; the second column will be parsed using
157:             * {@code formats[1]}, <cite>etc.</cite> If there is more columns than formats, then the
158:             * last format object is reused for all remaining columns.
159:             *
160:             * @param  formats The formats to use for parsing.
161:             * @throws IllegalArgumentException if {@code formats} is null or an element of
162:             *         {@code format} is null.
163:             */
164:            public LineFormat(final Format[] formats)
165:                    throws IllegalArgumentException {
166:                this .data = new Object[formats.length];
167:                this .format = new Format[formats.length];
168:                this .limits = new int[formats.length + 1];
169:                System.arraycopy(formats, 0, format, 0, formats.length);
170:                for (int i = 0; i < format.length; i++) {
171:                    if (format[i] == null) {
172:                        throw new IllegalArgumentException(Errors.format(
173:                                ErrorKeys.NULL_FORMAT_$2, new Integer(i + 1),
174:                                new Integer(format.length)));
175:                    }
176:                }
177:            }
178:
179:            /**
180:             * Clear this parser. Next call to {@link #getValueCount} will returns 0.
181:             */
182:            public void clear() {
183:                line = null;
184:                Arrays.fill(data, null);
185:                count = 0;
186:            }
187:
188:            /**
189:             * Parse the specified line. The content is immediately parsed and values
190:             * can be obtained using one of the {@code getValues(...)} method.
191:             *
192:             * @param  line The line to parse.
193:             * @return The number of elements parsed in the specified line.
194:             *         The same information can be obtained with {@link #getValueCount}.
195:             * @throws ParseException If at least one column can't be parsed.
196:             */
197:            public int setLine(final String line) throws ParseException {
198:                return setLine(line, 0, line.length());
199:            }
200:
201:            /**
202:             * Parse a substring of the specified line. The content is immediately parsed
203:             * and values can be obtained using one of the {@code getValues(...)} method.
204:             *
205:             * @param  line  The line to parse.
206:             * @param  lower Index of the first character in {@code line} to parse.
207:             * @param  upper Index after the last character in {@code line} to parse.
208:             * @return The number of elements parsed in the specified line.
209:             *         The same information can be obtained with {@link #getValueCount}.
210:             * @throws ParseException If at least one column can't be parsed.
211:             */
212:            public int setLine(final String line, int lower, final int upper)
213:                    throws ParseException {
214:                /*
215:                 * Retient la ligne que l'utilisateur nous demande
216:                 * de lire et oublie toutes les anciennes valeurs.
217:                 */
218:                this .line = line;
219:                Arrays.fill(data, null);
220:                count = 0;
221:                /*
222:                 * Procède au balayage de toutes les valeurs qui se trouvent sur la ligne spécifiée.
223:                 * Le balayage s'arrêtera lorsque {@code lower} aura atteint {@code upper}.
224:                 */
225:                load: while (true) {
226:                    while (true) {
227:                        if (lower >= upper) {
228:                            break load;
229:                        }
230:                        if (!Character.isWhitespace(line.charAt(lower)))
231:                            break;
232:                        lower++;
233:                    }
234:                    /*
235:                     * Procède à la lecture de la donnée. Si la lecture échoue, on produira un message d'erreur
236:                     * qui apparaîtra éventuellement en HTML afin de pouvoir souligner la partie fautive.
237:                     */
238:                    position.setIndex(lower);
239:                    final Object datum = format[Math.min(count,
240:                            format.length - 1)].parseObject(line, position);
241:                    final int next = position.getIndex();
242:                    if (datum == null || next <= lower) {
243:                        final int error = position.getErrorIndex();
244:                        int end = error;
245:                        while (end < upper
246:                                && !Character.isWhitespace(line.charAt(end)))
247:                            end++;
248:                        throw new ParseException(Errors.format(
249:                                ErrorKeys.PARSE_EXCEPTION_$2, line.substring(
250:                                        lower, end).trim(), line.substring(
251:                                        error, Math.min(error + 1, end))),
252:                                error);
253:                    }
254:                    /*
255:                     * Mémorise la nouvelle donnée, en agrandissant
256:                     * l'espace réservée en mémoire si c'est nécessaire.
257:                     */
258:                    if (count >= data.length) {
259:                        data = XArray
260:                                .resize(data, count + Math.min(count, 256));
261:                        limits = XArray.resize(limits, data.length + 1);
262:                    }
263:                    limits[count] = lower;
264:                    data[count++] = datum;
265:                    lower = next;
266:                }
267:                limits[count] = lower;
268:                return count;
269:            }
270:
271:            /**
272:             * Returns the number of elements found in the last line parsed by
273:             * {@link #setLine(String)}.
274:             */
275:            public int getValueCount() {
276:                return count;
277:            }
278:
279:            /**
280:             * Set all values in the current line. The {@code values} argument must be an array,
281:             * which may be of primitive type.
282:             *
283:             * @param  values The array to set as values.
284:             * @throws IllegalArgumentException if {@code values} is not an array.
285:             *
286:             * @since 2.4
287:             */
288:            public void setValues(final Object values)
289:                    throws IllegalArgumentException {
290:                final int length = Array.getLength(values);
291:                data = XArray.resize(data, length);
292:                for (int i = 0; i < length; i++) {
293:                    data[i] = Array.get(values, i);
294:                }
295:                count = length;
296:            }
297:
298:            /**
299:             * Set or add a value to current line. The index should be in the range 0 to
300:             * {@link #getValueCount} inclusively. If the index is equals to {@link #getValueCount},
301:             * then {@code value} will be appended as a new column after existing data.
302:             *
303:             * @param  index Index of the value to add or modify.
304:             * @param  value The new value.
305:             * @throws ArrayIndexOutOfBoundsException If the index is outside the expected range.
306:             */
307:            public void setValue(final int index, final Object value)
308:                    throws ArrayIndexOutOfBoundsException {
309:                if (index > count) {
310:                    throw new ArrayIndexOutOfBoundsException(index);
311:                }
312:                if (value == null) {
313:                    throw new IllegalArgumentException(Errors.format(
314:                            ErrorKeys.NULL_ARGUMENT_$1, "value"));
315:                }
316:                if (index == count) {
317:                    if (index == data.length) {
318:                        data = XArray
319:                                .resize(data, index + Math.min(index, 256));
320:                    }
321:                    count++;
322:                }
323:                data[index] = value;
324:            }
325:
326:            /**
327:             * Returns the value at the specified index. The index should be in the range
328:             * 0 inclusively to {@link #getValueCount} exclusively.
329:             *
330:             * @param  index Index of the value to fetch.
331:             * @return The value at the specified index.
332:             * @throws ArrayIndexOutOfBoundsException If the index is outside the expected range.
333:             */
334:            public Object getValue(final int index)
335:                    throws ArrayIndexOutOfBoundsException {
336:                if (index < count) {
337:                    return data[index];
338:                }
339:                throw new ArrayIndexOutOfBoundsException(index);
340:            }
341:
342:            /**
343:             * Returns all values.
344:             */
345:            private Object getValues() {
346:                final Object[] values = new Object[count];
347:                System.arraycopy(data, 0, values, 0, count);
348:                return values;
349:            }
350:
351:            /**
352:             * Retourne sous forme de nombre la valeur à l'index {@code index}.
353:             *
354:             * @param  index Index de la valeur demandée.
355:             * @return La valeur demandée sous forme d'objet {@link Number}.
356:             * @throws ParseException si la valeur n'est pas convertible en objet {@link Number}.
357:             */
358:            private Number getNumber(final int index) throws ParseException {
359:                Exception error = null;
360:                if (data[index] instanceof  Comparable) {
361:                    try {
362:                        return ClassChanger.toNumber((Comparable) data[index]);
363:                    } catch (ClassNotFoundException exception) {
364:                        error = exception;
365:                    }
366:                }
367:                ParseException exception = new ParseException(Errors.format(
368:                        ErrorKeys.UNPARSABLE_NUMBER_$1, data[index]),
369:                        limits[index]);
370:                if (error != null) {
371:                    exception.initCause(error);
372:                }
373:                throw exception;
374:            }
375:
376:            /**
377:             * Copies all values to the specified array. This method is typically invoked after
378:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
379:             * null, this method creates and returns a new array with a length equals to number
380:             * of elements parsed. If {@code array} is not null, then this method will thrown an
381:             * exception if the array length is not exactly equals to the number of elements
382:             * parsed.
383:             *
384:             * @param  array The array to copy values into.
385:             * @return {@code array} if it was not null, or a new array otherwise.
386:             * @throws ParseException If {@code array} was not null and its length is not equals to
387:             *         the number of elements parsed, or if at least one element can't be parsed.
388:             */
389:            public double[] getValues(double[] array) throws ParseException {
390:                if (array != null) {
391:                    checkLength(array.length);
392:                } else {
393:                    array = new double[count];
394:                }
395:                for (int i = 0; i < count; i++) {
396:                    array[i] = getNumber(i).doubleValue();
397:                }
398:                return array;
399:            }
400:
401:            /**
402:             * Copies all values to the specified array. This method is typically invoked after
403:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
404:             * null, this method creates and returns a new array with a length equals to number
405:             * of elements parsed. If {@code array} is not null, then this method will thrown an
406:             * exception if the array length is not exactly equals to the number of elements
407:             * parsed.
408:             *
409:             * @param  array The array to copy values into.
410:             * @return {@code array} if it was not null, or a new array otherwise.
411:             * @throws ParseException If {@code array} was not null and its length is not equals to
412:             *         the number of elements parsed, or if at least one element can't be parsed.
413:             */
414:            public float[] getValues(float[] array) throws ParseException {
415:                if (array != null) {
416:                    checkLength(array.length);
417:                } else {
418:                    array = new float[count];
419:                }
420:                for (int i = 0; i < count; i++) {
421:                    array[i] = getNumber(i).floatValue();
422:                }
423:                return array;
424:            }
425:
426:            /**
427:             * Copies all values to the specified array. This method is typically invoked after
428:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
429:             * null, this method creates and returns a new array with a length equals to number
430:             * of elements parsed. If {@code array} is not null, then this method will thrown an
431:             * exception if the array length is not exactly equals to the number of elements
432:             * parsed.
433:             *
434:             * @param  array The array to copy values into.
435:             * @return {@code array} if it was not null, or a new array otherwise.
436:             * @throws ParseException If {@code array} was not null and its length is not equals to
437:             *         the number of elements parsed, or if at least one element can't be parsed.
438:             */
439:            public long[] getValues(long[] array) throws ParseException {
440:                if (array != null) {
441:                    checkLength(array.length);
442:                } else {
443:                    array = new long[count];
444:                }
445:                for (int i = 0; i < count; i++) {
446:                    final Number n = getNumber(i);
447:                    if ((array[i] = n.longValue()) != n.doubleValue()) {
448:                        throw notAnInteger(i);
449:                    }
450:                }
451:                return array;
452:            }
453:
454:            /**
455:             * Copies all values to the specified array. This method is typically invoked after
456:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
457:             * null, this method creates and returns a new array with a length equals to number
458:             * of elements parsed. If {@code array} is not null, then this method will thrown an
459:             * exception if the array length is not exactly equals to the number of elements
460:             * parsed.
461:             *
462:             * @param  array The array to copy values into.
463:             * @return {@code array} if it was not null, or a new array otherwise.
464:             * @throws ParseException If {@code array} was not null and its length is not equals to
465:             *         the number of elements parsed, or if at least one element can't be parsed.
466:             */
467:            public int[] getValues(int[] array) throws ParseException {
468:                if (array != null) {
469:                    checkLength(array.length);
470:                } else {
471:                    array = new int[count];
472:                }
473:                for (int i = 0; i < count; i++) {
474:                    final Number n = getNumber(i);
475:                    if ((array[i] = n.intValue()) != n.doubleValue()) {
476:                        throw notAnInteger(i);
477:                    }
478:                }
479:                return array;
480:            }
481:
482:            /**
483:             * Copies all values to the specified array. This method is typically invoked after
484:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
485:             * null, this method creates and returns a new array with a length equals to number
486:             * of elements parsed. If {@code array} is not null, then this method will thrown an
487:             * exception if the array length is not exactly equals to the number of elements
488:             * parsed.
489:             *
490:             * @param  array The array to copy values into.
491:             * @return {@code array} if it was not null, or a new array otherwise.
492:             * @throws ParseException If {@code array} was not null and its length is not equals to
493:             *         the number of elements parsed, or if at least one element can't be parsed.
494:             */
495:            public short[] getValues(short[] array) throws ParseException {
496:                if (array != null) {
497:                    checkLength(array.length);
498:                } else {
499:                    array = new short[count];
500:                }
501:                for (int i = 0; i < count; i++) {
502:                    final Number n = getNumber(i);
503:                    if ((array[i] = n.shortValue()) != n.doubleValue()) {
504:                        throw notAnInteger(i);
505:                    }
506:                }
507:                return array;
508:            }
509:
510:            /**
511:             * Copies all values to the specified array. This method is typically invoked after
512:             * {@link #setLine(String)} for fetching the values just parsed. If {@code array} is
513:             * null, this method creates and returns a new array with a length equals to number
514:             * of elements parsed. If {@code array} is not null, then this method will thrown an
515:             * exception if the array length is not exactly equals to the number of elements
516:             * parsed.
517:             *
518:             * @param  array The array to copy values into.
519:             * @return {@code array} if it was not null, or a new array otherwise.
520:             * @throws ParseException If {@code array} was not null and its length is not equals to
521:             *         the number of elements parsed, or if at least one element can't be parsed.
522:             */
523:            public byte[] getValues(byte[] array) throws ParseException {
524:                if (array != null) {
525:                    checkLength(array.length);
526:                } else {
527:                    array = new byte[count];
528:                }
529:                for (int i = 0; i < count; i++) {
530:                    final Number n = getNumber(i);
531:                    if ((array[i] = n.byteValue()) != n.doubleValue()) {
532:                        throw notAnInteger(i);
533:                    }
534:                }
535:                return array;
536:            }
537:
538:            /**
539:             * Vérifie si le nombre de données lues correspond au nombre de données
540:             * attendues. Si ce n'est pas le cas, une exception sera lancée.
541:             *
542:             * @throws ParseException si le nombre de données lues ne correspond pas au nombre de données attendues.
543:             */
544:            private void checkLength(final int expected) throws ParseException {
545:                if (count != expected) {
546:                    final int lower = limits[Math.min(count, expected)];
547:                    final int upper = limits[Math.min(count, expected + 1)];
548:                    throw new ParseException(Errors.format(
549:                            count < expected ? ErrorKeys.LINE_TOO_SHORT_$2
550:                                    : ErrorKeys.LINE_TOO_LONG_$3, new Integer(
551:                                    count), new Integer(expected), line
552:                                    .substring(lower, upper).trim()), lower);
553:                }
554:            }
555:
556:            /**
557:             * Creates an exception for a value not being an integer.
558:             *
559:             * @param  i the value index.
560:             * @return The exception.
561:             */
562:            private ParseException notAnInteger(final int i) {
563:                return new ParseException(Errors.format(
564:                        ErrorKeys.NOT_AN_INTEGER_$1, line.substring(limits[i],
565:                                limits[i + 1])), limits[i]);
566:            }
567:
568:            /**
569:             * Returns a string representation of current line. All columns are formatted using
570:             * the {@link Format} object specified at construction time. Columns are separated
571:             * by tabulation.
572:             */
573:            //@Override
574:            public String toString() {
575:                return toString(new StringBuffer()).toString();
576:            }
577:
578:            /**
579:             * Formats a string representation of current line. All columns are formatted using
580:             * the {@link Format} object specified at construction time. Columns are separated
581:             * by tabulation.
582:             */
583:            private StringBuffer toString(StringBuffer buffer) {
584:                final FieldPosition field = new FieldPosition(0);
585:                for (int i = 0; i < count; i++) {
586:                    if (i != 0) {
587:                        buffer.append('\t');
588:                    }
589:                    buffer = format[Math.min(format.length - 1, i)].format(
590:                            data[i], buffer, field);
591:                }
592:                return buffer;
593:            }
594:
595:            /**
596:             * Formats an object and appends the resulting text to a given string buffer.
597:             * This method invokes <code>{@linkplain #setValues setValues}(values)</code>,
598:             * then formats all columns using the {@link Format} object specified at
599:             * construction time. Columns are separated by tabulation.
600:             *
601:             * @since 2.4
602:             */
603:            public StringBuffer format(final Object values,
604:                    final StringBuffer toAppendTo, final FieldPosition position) {
605:                setValues(values);
606:                return toString(toAppendTo);
607:            }
608:
609:            /**
610:             * Returns the index of the end of the specified line.
611:             */
612:            private static int getLineEnd(final String source, int offset,
613:                    final boolean s) {
614:                final int length = source.length();
615:                while (offset < length) {
616:                    final char c = source.charAt(offset);
617:                    if ((c == '\r' || c == '\n') == s) {
618:                        break;
619:                    }
620:                    offset++;
621:                }
622:                return offset;
623:            }
624:
625:            /**
626:             * Parses text from a string to produce an object.
627:             *
628:             * @since 2.4
629:             */
630:            public Object parseObject(final String source,
631:                    final ParsePosition position) {
632:                final int lower = position.getIndex();
633:                final int upper = getLineEnd(source, lower, true);
634:                try {
635:                    setLine(source.substring(lower, upper));
636:                    position.setIndex(getLineEnd(source, upper, false));
637:                    return getValues();
638:                } catch (ParseException e) {
639:                    position.setErrorIndex(e.getErrorOffset());
640:                    return null; // As of java.text.Format contract.
641:                }
642:            }
643:
644:            /**
645:             * Parses text from the beginning of the given string to produce an object. 
646:             *
647:             * @since 2.4
648:             */
649:            //@Override
650:            public Object parseObject(final String source)
651:                    throws ParseException {
652:                setLine(source.substring(0, getLineEnd(source, 0, true)));
653:                return getValues();
654:            }
655:
656:            /**
657:             * Returns a clone of this parser. In current implementation, this
658:             * clone is <strong>not</strong> for usage in concurrent thread.
659:             */
660:            //@Override
661:            public Object clone() {
662:                final LineFormat copy = (LineFormat) super .clone();
663:                copy.data = (Object[]) data.clone();
664:                copy.limits = (int[]) limits.clone();
665:                return copy;
666:            }
667:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.