1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54:
55: import ;
56:
57:
85: public final class Formatter
86: implements Closeable, Flushable
87: {
88:
89:
92: private StringBuilder out;
93:
94:
97: private Locale locale;
98:
99:
102: private boolean closed;
103:
104:
107: private IOException ioException;
108:
109:
110:
113: private String format;
114:
115:
118: private int index;
119:
120:
123: private int length;
124:
125:
128: private Locale fmtLocale;
129:
130:
131:
132:
133:
134:
137: private static final String FLAGS = "--#+ 0,(";
138:
139:
142: private static final String lineSeparator
143: = SystemProperties.getProperty("line.separator");
144:
145:
149: public Formatter()
150: {
151: this(null, Locale.getDefault());
152: }
153:
154:
162: public Formatter(Locale loc)
163: {
164: this(null, loc);
165: }
166:
167:
173: public Formatter(StringBuilder app)
174: {
175: this(app, Locale.getDefault());
176: }
177:
178:
186: public Formatter(StringBuilder app, Locale loc)
187: {
188: this.out = app == null ? new StringBuilder() : app;
189: this.locale = loc;
190: }
191:
192:
200: public void close()
201: {
202: if (closed)
203: return;
204: closed = true;
205: }
206:
207:
214: public void flush()
215: {
216: if (closed)
217: throw new FormatterClosedException();
218: }
219:
220:
226: private String getName(int flags)
227: {
228:
229:
230: int bit = Integer.numberOfTrailingZeros(flags);
231: return FLAGS.substring(bit, bit + 1);
232: }
233:
234:
241: private void checkFlags(int flags, int allowed, char conversion)
242: {
243: flags &= ~allowed;
244: if (flags != 0)
245: throw new FormatFlagsConversionMismatchException(getName(flags),
246: conversion);
247: }
248:
249:
254: private void noPrecision(int precision)
255: {
256: if (precision != -1)
257: throw new IllegalFormatPrecisionException(precision);
258: }
259:
260:
268: private void applyLocalization(StringBuilder builder, int flags, int width,
269: boolean isNegative)
270: {
271: DecimalFormatSymbols dfsyms;
272: if (fmtLocale == null)
273: dfsyms = new DecimalFormatSymbols();
274: else
275: dfsyms = new DecimalFormatSymbols(fmtLocale);
276:
277:
278: char zeroDigit = dfsyms.getZeroDigit();
279: int decimalOffset = -1;
280: for (int i = builder.length() - 1; i >= 0; --i)
281: {
282: char c = builder.charAt(i);
283: if (c >= '0' && c <= '9')
284: builder.setCharAt(i, (char) (c - '0' + zeroDigit));
285: else if (c == '.')
286: {
287: assert decimalOffset == -1;
288: decimalOffset = i;
289: }
290: }
291:
292:
293: if (decimalOffset != -1)
294: {
295: builder.deleteCharAt(decimalOffset);
296: builder.insert(decimalOffset, dfsyms.getDecimalSeparator());
297: }
298:
299:
300: if ((flags & FormattableFlags.COMMA) != 0)
301: {
302: char groupSeparator = dfsyms.getGroupingSeparator();
303: int groupSize = 3;
304: int offset = (decimalOffset == -1) ? builder.length() : decimalOffset;
305:
306:
307: for (int i = offset - groupSize; i > 0; i -= groupSize)
308: builder.insert(i, groupSeparator);
309: }
310:
311: if ((flags & FormattableFlags.ZERO) != 0)
312: {
313:
314:
315: for (int i = width - builder.length(); i > 0; --i)
316: builder.insert(0, zeroDigit);
317: }
318:
319: if (isNegative)
320: {
321: if ((flags & FormattableFlags.PAREN) != 0)
322: {
323: builder.insert(0, '(');
324: builder.append(')');
325: }
326: else
327: builder.insert(0, '-');
328: }
329: else if ((flags & FormattableFlags.PLUS) != 0)
330: builder.insert(0, '+');
331: else if ((flags & FormattableFlags.SPACE) != 0)
332: builder.insert(0, ' ');
333: }
334:
335:
345: private void genericFormat(String arg, int flags, int width, int precision)
346: throws IOException
347: {
348: if ((flags & FormattableFlags.UPPERCASE) != 0)
349: {
350: if (fmtLocale == null)
351: arg = arg.toUpperCase();
352: else
353: arg = arg.toUpperCase(fmtLocale);
354: }
355:
356: if (precision >= 0 && arg.length() > precision)
357: arg = arg.substring(0, precision);
358:
359: boolean leftJustify = (flags & FormattableFlags.LEFT_JUSTIFY) != 0;
360: if (leftJustify && width == -1)
361: throw new MissingFormatWidthException("fixme");
362: if (! leftJustify && arg.length() < width)
363: {
364: for (int i = width - arg.length(); i > 0; --i)
365: out.append(' ');
366: }
367: out.append(arg);
368: if (leftJustify && arg.length() < width)
369: {
370: for (int i = width - arg.length(); i > 0; --i)
371: out.append(' ');
372: }
373: }
374:
375:
385: private void booleanFormat(Object arg, int flags, int width, int precision,
386: char conversion)
387: throws IOException
388: {
389: checkFlags(flags,
390: FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
391: conversion);
392: String result;
393: if (arg instanceof Boolean)
394: result = String.valueOf((Boolean) arg);
395: else
396: result = arg == null ? "false" : "true";
397: genericFormat(result, flags, width, precision);
398: }
399:
400:
410: private void hashCodeFormat(Object arg, int flags, int width, int precision,
411: char conversion)
412: throws IOException
413: {
414: checkFlags(flags,
415: FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
416: conversion);
417: genericFormat(arg == null ? "null" : Integer.toHexString(arg.hashCode()),
418: flags, width, precision);
419: }
420:
421:
431: private void stringFormat(Object arg, int flags, int width, int precision,
432: char conversion)
433: throws IOException
434: {
435: if (arg instanceof Formattable)
436: {
437: checkFlags(flags,
438: (FormattableFlags.LEFT_JUSTIFY
439: | FormattableFlags.UPPERCASE
440: | FormattableFlags.ALTERNATE),
441: conversion);
442: Formattable fmt = (Formattable) arg;
443: fmt.formatTo(this, flags, width, precision);
444: }
445: else
446: {
447: checkFlags(flags,
448: FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
449: conversion);
450: genericFormat(arg == null ? "null" : arg.toString(), flags, width,
451: precision);
452: }
453: }
454:
455:
465: private void characterFormat(Object arg, int flags, int width, int precision,
466: char conversion)
467: throws IOException
468: {
469: checkFlags(flags,
470: FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
471: conversion);
472: noPrecision(precision);
473:
474: int theChar;
475: if (arg instanceof Character)
476: theChar = ((Character) arg).charValue();
477: else if (arg instanceof Byte)
478: theChar = (char) (((Byte) arg).byteValue ());
479: else if (arg instanceof Short)
480: theChar = (char) (((Short) arg).shortValue ());
481: else if (arg instanceof Integer)
482: {
483: theChar = ((Integer) arg).intValue();
484: if (! Character.isValidCodePoint(theChar))
485: throw new IllegalFormatCodePointException(theChar);
486: }
487: else
488: throw new IllegalFormatConversionException(conversion, arg.getClass());
489: String result = new String(Character.toChars(theChar));
490: genericFormat(result, flags, width, precision);
491: }
492:
493:
501: private void percentFormat(int flags, int width, int precision)
502: throws IOException
503: {
504: checkFlags(flags, FormattableFlags.LEFT_JUSTIFY, '%');
505: noPrecision(precision);
506: genericFormat("%", flags, width, precision);
507: }
508:
509:
517: private void newLineFormat(int flags, int width, int precision)
518: throws IOException
519: {
520: checkFlags(flags, 0, 'n');
521: noPrecision(precision);
522: if (width != -1)
523: throw new IllegalFormatWidthException(width);
524: genericFormat(lineSeparator, flags, width, precision);
525: }
526:
527:
539: private StringBuilder basicIntegralConversion(Object arg, int flags,
540: int width, int precision,
541: int radix, char conversion)
542: {
543: assert radix == 8 || radix == 10 || radix == 16;
544: noPrecision(precision);
545:
546:
547: if ((flags & FormattableFlags.ZERO) != 0
548: && (flags & FormattableFlags.LEFT_JUSTIFY) == 0)
549: throw new IllegalFormatFlagsException(getName(flags));
550: if ((flags & FormattableFlags.PLUS) != 0
551: && (flags & FormattableFlags.SPACE) != 0)
552: throw new IllegalFormatFlagsException(getName(flags));
553:
554: if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0 && width == -1)
555: throw new MissingFormatWidthException("fixme");
556:
557:
558: String result;
559: int basicFlags = (FormattableFlags.LEFT_JUSTIFY
560:
561:
562: | FormattableFlags.UPPERCASE
563: | FormattableFlags.ZERO);
564: if (radix == 10)
565: basicFlags |= (FormattableFlags.PLUS
566: | FormattableFlags.SPACE
567: | FormattableFlags.COMMA
568: | FormattableFlags.PAREN);
569: else
570: basicFlags |= FormattableFlags.ALTERNATE;
571:
572: if (arg instanceof BigInteger)
573: {
574: checkFlags(flags,
575: (basicFlags
576: | FormattableFlags.PLUS
577: | FormattableFlags.SPACE
578: | FormattableFlags.PAREN),
579: conversion);
580: BigInteger bi = (BigInteger) arg;
581: result = bi.toString(radix);
582: }
583: else if (arg instanceof Number
584: && ! (arg instanceof Float)
585: && ! (arg instanceof Double))
586: {
587: checkFlags(flags, basicFlags, conversion);
588: long value = ((Number) arg).longValue ();
589: if (radix == 8)
590: result = Long.toOctalString(value);
591: else if (radix == 16)
592: result = Long.toHexString(value);
593: else
594: result = Long.toString(value);
595: }
596: else
597: throw new IllegalFormatConversionException(conversion, arg.getClass());
598:
599: return new StringBuilder(result);
600: }
601:
602:
613: private void hexOrOctalConversion(Object arg, int flags, int width,
614: int precision, int radix,
615: char conversion)
616: throws IOException
617: {
618: assert radix == 8 || radix == 16;
619:
620: StringBuilder builder = basicIntegralConversion(arg, flags, width,
621: precision, radix,
622: conversion);
623: int insertPoint = 0;
624:
625:
626: if (builder.charAt(0) == '-')
627: {
628:
629:
630:
631: ++insertPoint;
632: }
633: else if ((flags & FormattableFlags.PLUS) != 0)
634: {
635: builder.insert(insertPoint, '+');
636: ++insertPoint;
637: }
638: else if ((flags & FormattableFlags.SPACE) != 0)
639: {
640: builder.insert(insertPoint, ' ');
641: ++insertPoint;
642: }
643:
644:
645: if ((flags & FormattableFlags.ALTERNATE) != 0)
646: {
647: builder.insert(insertPoint, radix == 8 ? "0" : "0x");
648: insertPoint += radix == 8 ? 1 : 2;
649: }
650:
651:
652: int resultWidth = builder.length();
653: if (resultWidth < width)
654: {
655: char fill = ((flags & FormattableFlags.ZERO) != 0) ? '0' : ' ';
656: if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0)
657: {
658:
659: if (fill == ' ')
660: insertPoint = builder.length();
661: }
662: else
663: {
664:
665:
666: insertPoint = 0;
667: }
668: while (resultWidth++ < width)
669: builder.insert(insertPoint, fill);
670: }
671:
672: String result = builder.toString();
673: if ((flags & FormattableFlags.UPPERCASE) != 0)
674: {
675: if (fmtLocale == null)
676: result = result.toUpperCase();
677: else
678: result = result.toUpperCase(fmtLocale);
679: }
680:
681: out.append(result);
682: }
683:
684:
694: private void decimalConversion(Object arg, int flags, int width,
695: int precision, char conversion)
696: throws IOException
697: {
698: StringBuilder builder = basicIntegralConversion(arg, flags, width,
699: precision, 10,
700: conversion);
701: boolean isNegative = false;
702: if (builder.charAt(0) == '-')
703: {
704:
705: builder.deleteCharAt(0);
706: isNegative = true;
707: }
708:
709: applyLocalization(builder, flags, width, isNegative);
710: genericFormat(builder.toString(), flags, width, precision);
711: }
712:
713:
721: private void singleDateTimeConversion(StringBuilder builder, Calendar cal,
722: char conversion,
723: DateFormatSymbols syms)
724: {
725: int oldLen = builder.length();
726: int digits = -1;
727: switch (conversion)
728: {
729: case 'H':
730: builder.append(cal.get(Calendar.HOUR_OF_DAY));
731: digits = 2;
732: break;
733: case 'I':
734: builder.append(cal.get(Calendar.HOUR));
735: digits = 2;
736: break;
737: case 'k':
738: builder.append(cal.get(Calendar.HOUR_OF_DAY));
739: break;
740: case 'l':
741: builder.append(cal.get(Calendar.HOUR));
742: break;
743: case 'M':
744: builder.append(cal.get(Calendar.MINUTE));
745: digits = 2;
746: break;
747: case 'S':
748: builder.append(cal.get(Calendar.SECOND));
749: digits = 2;
750: break;
751: case 'N':
752:
753: digits = 9;
754: break;
755: case 'p':
756: {
757: int ampm = cal.get(Calendar.AM_PM);
758: builder.append(syms.getAmPmStrings()[ampm]);
759: }
760: break;
761: case 'z':
762: {
763: int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60);
764: builder.append(zone);
765: digits = 4;
766:
767: if (zone < 0)
768: ++oldLen;
769: }
770: break;
771: case 'Z':
772: {
773:
774: int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60);
775: String[][] zs = syms.getZoneStrings();
776: builder.append(zs[zone + 12][1]);
777: }
778: break;
779: case 's':
780: {
781: long val = cal.getTime().getTime();
782: builder.append(val / 1000);
783: }
784: break;
785: case 'Q':
786: {
787: long val = cal.getTime().getTime();
788: builder.append(val);
789: }
790: break;
791: case 'B':
792: {
793: int month = cal.get(Calendar.MONTH);
794: builder.append(syms.getMonths()[month]);
795: }
796: break;
797: case 'b':
798: case 'h':
799: {
800: int month = cal.get(Calendar.MONTH);
801: builder.append(syms.getShortMonths()[month]);
802: }
803: break;
804: case 'A':
805: {
806: int day = cal.get(Calendar.DAY_OF_WEEK);
807: builder.append(syms.getWeekdays()[day]);
808: }
809: break;
810: case 'a':
811: {
812: int day = cal.get(Calendar.DAY_OF_WEEK);
813: builder.append(syms.getShortWeekdays()[day]);
814: }
815: break;
816: case 'C':
817: builder.append(cal.get(Calendar.YEAR) / 100);
818: digits = 2;
819: break;
820: case 'Y':
821: builder.append(cal.get(Calendar.YEAR));
822: digits = 4;
823: break;
824: case 'y':
825: builder.append(cal.get(Calendar.YEAR) % 100);
826: digits = 2;
827: break;
828: case 'j':
829: builder.append(cal.get(Calendar.DAY_OF_YEAR));
830: digits = 3;
831: break;
832: case 'm':
833: builder.append(cal.get(Calendar.MONTH) + 1);
834: digits = 2;
835: break;
836: case 'd':
837: builder.append(cal.get(Calendar.DAY_OF_MONTH));
838: digits = 2;
839: break;
840: case 'e':
841: builder.append(cal.get(Calendar.DAY_OF_MONTH));
842: break;
843: case 'R':
844: singleDateTimeConversion(builder, cal, 'H', syms);
845: builder.append(':');
846: singleDateTimeConversion(builder, cal, 'M', syms);
847: break;
848: case 'T':
849: singleDateTimeConversion(builder, cal, 'H', syms);
850: builder.append(':');
851: singleDateTimeConversion(builder, cal, 'M', syms);
852: builder.append(':');
853: singleDateTimeConversion(builder, cal, 'S', syms);
854: break;
855: case 'r':
856: singleDateTimeConversion(builder, cal, 'I', syms);
857: builder.append(':');
858: singleDateTimeConversion(builder, cal, 'M', syms);
859: builder.append(':');
860: singleDateTimeConversion(builder, cal, 'S', syms);
861: builder.append(' ');
862: singleDateTimeConversion(builder, cal, 'p', syms);
863: break;
864: case 'D':
865: singleDateTimeConversion(builder, cal, 'm', syms);
866: builder.append('/');
867: singleDateTimeConversion(builder, cal, 'd', syms);
868: builder.append('/');
869: singleDateTimeConversion(builder, cal, 'y', syms);
870: break;
871: case 'F':
872: singleDateTimeConversion(builder, cal, 'Y', syms);
873: builder.append('-');
874: singleDateTimeConversion(builder, cal, 'm', syms);
875: builder.append('-');
876: singleDateTimeConversion(builder, cal, 'd', syms);
877: break;
878: case 'c':
879: singleDateTimeConversion(builder, cal, 'a', syms);
880: builder.append(' ');
881: singleDateTimeConversion(builder, cal, 'b', syms);
882: builder.append(' ');
883: singleDateTimeConversion(builder, cal, 'd', syms);
884: builder.append(' ');
885: singleDateTimeConversion(builder, cal, 'T', syms);
886: builder.append(' ');
887: singleDateTimeConversion(builder, cal, 'Z', syms);
888: builder.append(' ');
889: singleDateTimeConversion(builder, cal, 'Y', syms);
890: break;
891: default:
892: throw new UnknownFormatConversionException(String.valueOf(conversion));
893: }
894:
895: if (digits > 0)
896: {
897: int newLen = builder.length();
898: int delta = newLen - oldLen;
899: while (delta++ < digits)
900: builder.insert(oldLen, '0');
901: }
902: }
903:
904:
915: private void dateTimeConversion(Object arg, int flags, int width,
916: int precision, char conversion,
917: char subConversion)
918: throws IOException
919: {
920: noPrecision(precision);
921: checkFlags(flags,
922: FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
923: conversion);
924:
925: Calendar cal;
926: if (arg instanceof Calendar)
927: cal = (Calendar) arg;
928: else
929: {
930: Date date;
931: if (arg instanceof Date)
932: date = (Date) arg;
933: else if (arg instanceof Long)
934: date = new Date(((Long) arg).longValue());
935: else
936: throw new IllegalFormatConversionException(conversion,
937: arg.getClass());
938: if (fmtLocale == null)
939: cal = Calendar.getInstance();
940: else
941: cal = Calendar.getInstance(fmtLocale);
942: cal.setTime(date);
943: }
944:
945:
946: DateFormatSymbols syms;
947: if (fmtLocale == null)
948: syms = new DateFormatSymbols();
949: else
950: syms = new DateFormatSymbols(fmtLocale);
951:
952: StringBuilder result = new StringBuilder();
953: singleDateTimeConversion(result, cal, subConversion, syms);
954:
955: genericFormat(result.toString(), flags, width, precision);
956: }
957:
958:
964: private void advance()
965: {
966: ++index;
967: if (index >= length)
968: {
969:
970: throw new IllegalArgumentException();
971: }
972: }
973:
974:
980: private int parseInt()
981: {
982: int start = index;
983: while (Character.isDigit(format.charAt(index)))
984: advance();
985: if (start == index)
986: return -1;
987: return Integer.decode(format.substring(start, index)).intValue();
988: }
989:
990:
997: private int parseArgumentIndex()
998: {
999: int result = -1;
1000: int start = index;
1001: if (format.charAt(index) == '<')
1002: {
1003: result = 0;
1004: advance();
1005: }
1006: else if (Character.isDigit(format.charAt(index)))
1007: {
1008: result = parseInt();
1009: if (format.charAt(index) == '$')
1010: advance();
1011: else
1012: {
1013:
1014: index = start;
1015: result = -1;
1016: }
1017: }
1018: return result;
1019: }
1020:
1021:
1028: private int parseFlags()
1029: {
1030: int value = 0;
1031: int start = index;
1032: while (true)
1033: {
1034: int x = FLAGS.indexOf(format.charAt(index));
1035: if (x == -1)
1036: break;
1037: int newValue = 1 << x;
1038: if ((value & newValue) != 0)
1039: throw new DuplicateFormatFlagsException(format.substring(start,
1040: index + 1));
1041: value |= newValue;
1042: advance();
1043: }
1044: return value;
1045: }
1046:
1047:
1053: private int parseWidth()
1054: {
1055: return parseInt();
1056: }
1057:
1058:
1064: private int parsePrecision()
1065: {
1066: if (format.charAt(index) != '.')
1067: return -1;
1068: advance();
1069: int precision = parseInt();
1070: if (precision == -1)
1071:
1072: throw new IllegalArgumentException();
1073: return precision;
1074: }
1075:
1076:
1093: public Formatter format(Locale loc, String fmt, Object[] args)
1094: {
1095: if (closed)
1096: throw new FormatterClosedException();
1097:
1098:
1099: int implicitArgumentIndex = 1;
1100: int previousArgumentIndex = 0;
1101:
1102: try
1103: {
1104: fmtLocale = loc;
1105: format = fmt;
1106: length = format.length();
1107: for (index = 0; index < length; ++index)
1108: {
1109: char c = format.charAt(index);
1110: if (c != '%')
1111: {
1112: out.append(c);
1113: continue;
1114: }
1115:
1116: int start = index;
1117: advance();
1118:
1119:
1120:
1121:
1122: int argumentIndex = parseArgumentIndex();
1123:
1124: int flags = parseFlags();
1125: int width = parseWidth();
1126: int precision = parsePrecision();
1127: char origConversion = format.charAt(index);
1128: char conversion = origConversion;
1129: if (Character.isUpperCase(conversion))
1130: {
1131: flags |= FormattableFlags.UPPERCASE;
1132: conversion = Character.toLowerCase(conversion);
1133: }
1134:
1135: Object argument = null;
1136: if (conversion == '%' || conversion == 'n')
1137: {
1138: if (argumentIndex != -1)
1139: {
1140:
1141: throw new UnknownFormatConversionException("FIXME");
1142: }
1143: }
1144: else
1145: {
1146: if (argumentIndex == -1)
1147: argumentIndex = implicitArgumentIndex++;
1148: else if (argumentIndex == 0)
1149: argumentIndex = previousArgumentIndex;
1150:
1151: --argumentIndex;
1152: if (argumentIndex < 0 || argumentIndex >= args.length)
1153: throw new MissingFormatArgumentException(format.substring(start, index));
1154: argument = args[argumentIndex];
1155: }
1156:
1157: switch (conversion)
1158: {
1159: case 'b':
1160: booleanFormat(argument, flags, width, precision,
1161: origConversion);
1162: break;
1163: case 'h':
1164: hashCodeFormat(argument, flags, width, precision,
1165: origConversion);
1166: break;
1167: case 's':
1168: stringFormat(argument, flags, width, precision,
1169: origConversion);
1170: break;
1171: case 'c':
1172: characterFormat(argument, flags, width, precision,
1173: origConversion);
1174: break;
1175: case 'd':
1176: checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'd');
1177: decimalConversion(argument, flags, width, precision,
1178: origConversion);
1179: break;
1180: case 'o':
1181: checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'o');
1182: hexOrOctalConversion(argument, flags, width, precision, 8,
1183: origConversion);
1184: break;
1185: case 'x':
1186: hexOrOctalConversion(argument, flags, width, precision, 16,
1187: origConversion);
1188: case 'e':
1189:
1190: break;
1191: case 'f':
1192:
1193: break;
1194: case 'g':
1195:
1196: break;
1197: case 'a':
1198:
1199: break;
1200: case 't':
1201: advance();
1202: char subConversion = format.charAt(index);
1203: dateTimeConversion(argument, flags, width, precision,
1204: origConversion, subConversion);
1205: break;
1206: case '%':
1207: percentFormat(flags, width, precision);
1208: break;
1209: case 'n':
1210: newLineFormat(flags, width, precision);
1211: break;
1212: default:
1213: throw new UnknownFormatConversionException(String.valueOf(origConversion));
1214: }
1215: }
1216: }
1217: catch (IOException exc)
1218: {
1219: ioException = exc;
1220: }
1221: return this;
1222: }
1223:
1224:
1236: public Formatter format(String format, Object[] args)
1237: {
1238: return format(locale, format, args);
1239: }
1240:
1241:
1248: public IOException ioException()
1249: {
1250: return ioException;
1251: }
1252:
1253:
1259: public Locale locale()
1260: {
1261: if (closed)
1262: throw new FormatterClosedException();
1263: return locale;
1264: }
1265:
1266:
1272: public StringBuilder out()
1273: {
1274: if (closed)
1275: throw new FormatterClosedException();
1276: return out;
1277: }
1278:
1279:
1288: public String toString()
1289: {
1290: if (closed)
1291: throw new FormatterClosedException();
1292: return out.toString();
1293: }
1294: }