001: /*
002: * Write files in comma separated value format.
003: * Copyright (C) 2001-2007 Stephen Ostermiller
004: * http://ostermiller.org/contact.pl?regarding=Java+Utilities
005: * Copyright (C) 2003 Pierre Dittgen <pierre dot dittgen at pass-tech dot fr>
006: *
007: * This program is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU General Public License as published by
009: * the Free Software Foundation; either version 2 of the License, or
010: * (at your option) any later version.
011: *
012: * This program 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
015: * GNU General Public License for more details.
016: *
017: * See COPYING.TXT for details.
018: */
019:
020: package com.Ostermiller.util;
021:
022: import java.io.*;
023:
024: /**
025: * Print values as a comma separated list.
026: * More information about this class is available from <a target="_top" href=
027: * "http://ostermiller.org/utils/CSV.html">ostermiller.org</a>.
028: *
029: * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities
030: * @author Pierre Dittgen <pierre dot dittgen at pass-tech dot fr>
031: * @since ostermillerutils 1.00.00
032: */
033: public class CSVPrinter implements CSVPrint {
034:
035: /**
036: * Default state of auto flush
037: */
038: private static final boolean AUTO_FLUSH_DEFAULT = true;
039:
040: /**
041: * If auto flushing is enabled.
042: *
043: * @since ostermillerutils 1.02.26
044: */
045: protected boolean autoFlush = AUTO_FLUSH_DEFAULT;
046:
047: /**
048: * Default state of always quote
049: */
050: private static final boolean ALWAYS_QUOTE_DEFAULT = false;
051:
052: /**
053: * If auto flushing is enabled.
054: *
055: * @since ostermillerutils 1.02.26
056: */
057: protected boolean alwaysQuote = ALWAYS_QUOTE_DEFAULT;
058:
059: /**
060: * true iff an error has occurred.
061: *
062: * @since ostermillerutils 1.02.26
063: */
064: protected boolean error = false;
065:
066: /**
067: * Default delimiter character
068: */
069: private static final char DELIMITER_DEFAULT = ',';
070:
071: /**
072: * Character written as field delimiter.
073: *
074: * @since ostermillerutils 1.02.18
075: */
076: protected char delimiterChar = DELIMITER_DEFAULT;
077:
078: /**
079: * Default quoting character
080: */
081: private static final char QUOTE_DEFAULT = '"';
082:
083: /**
084: * Quoting character.
085: *
086: * @since ostermillerutils 1.02.18
087: */
088: protected char quoteChar = QUOTE_DEFAULT;
089:
090: /**
091: * The place that the values get written.
092: *
093: * @since ostermillerutils 1.00.00
094: */
095: protected Writer out;
096:
097: /**
098: * True iff we just began a new line.
099: *
100: * @since ostermillerutils 1.00.00
101: */
102: protected boolean newLine = true;
103:
104: /**
105: * Default start of comments
106: */
107: private static final char COMMENT_START_DEFAULT = '#';
108:
109: /**
110: * Character used to start comments. (Default is '#')
111: *
112: * @since ostermillerutils 1.00.00
113: */
114: protected char commentStart = COMMENT_START_DEFAULT;
115:
116: /**
117: * Line ending default
118: */
119: private static final String LINE_ENDING_DEFAULT = "\n";
120:
121: /**
122: * Line ending indicating the system line ending should be chosen
123: */
124: private static final String LINE_ENDING_SYSTEM = null;
125:
126: /**
127: * The line ending, must be one of "\n", "\r", or "\r\n"
128: *
129: * @since ostermillerutils 1.06.01
130: */
131: protected String lineEnding = LINE_ENDING_DEFAULT;
132:
133: /**
134: * Change this printer so that it uses a new delimiter.
135: *
136: * @param newDelimiter The new delimiter character to use.
137: * @throws BadDelimiterException if the character cannot be used as a delimiter.
138: *
139: * @author Pierre Dittgen <pierre dot dittgen at pass-tech dot fr>
140: * @since ostermillerutils 1.02.18
141: */
142: public void changeDelimiter(char newDelimiter)
143: throws BadDelimiterException {
144: if (delimiterChar == newDelimiter)
145: return; // no need to do anything.
146: if (newDelimiter == '\n' || newDelimiter == '\r'
147: || newDelimiter == delimiterChar
148: || newDelimiter == quoteChar) {
149: throw new BadDelimiterException();
150: }
151: delimiterChar = newDelimiter;
152: }
153:
154: /**
155: * Change this printer so that it uses a new character for quoting.
156: *
157: * @param newQuote The new character to use for quoting.
158: * @throws BadQuoteException if the character cannot be used as a quote.
159: *
160: * @author Pierre Dittgen <pierre dot dittgen at pass-tech dot fr>
161: * @since ostermillerutils 1.02.18
162: */
163: public void changeQuote(char newQuote) throws BadQuoteException {
164: if (quoteChar == newQuote)
165: return; // no need to do anything.
166: if (newQuote == '\n' || newQuote == '\r'
167: || newQuote == delimiterChar || newQuote == quoteChar) {
168: throw new BadQuoteException();
169: }
170: quoteChar = newQuote;
171: }
172:
173: /**
174: * Change this printer so that it uses a new line ending.
175: * <p>
176: * A line ending must be one of "\n", "\r", or "\r\n".
177: * <p>
178: * The default line ending is the system line separator as specified by
179: * <code>System.getProperty("line.separator")</code>, or "\n" if the system
180: * line separator is not a legal line ending.
181: *
182: * @param lineEnding The new line ending, or null to use the default line ending.
183: * @throws BadLineEndingException if the line ending is not one of the three legal line endings.
184: *
185: * @since ostermillerutils 1.06.01
186: */
187: public void setLineEnding(String lineEnding)
188: throws BadLineEndingException {
189: boolean setDefault = lineEnding == null;
190: if (setDefault) {
191: lineEnding = System.getProperty("line.separator");
192: }
193: if (!"\n".equals(lineEnding) && !"\r".equals(lineEnding)
194: && !"\r\n".equals(lineEnding)) {
195: if (setDefault) {
196: lineEnding = LINE_ENDING_DEFAULT;
197: } else {
198: throw new BadLineEndingException();
199: }
200: }
201: this .lineEnding = lineEnding;
202: }
203:
204: /**
205: * Create a printer that will print values to the given
206: * stream. Character to byte conversion is done using
207: * the default character encoding. Comments will be
208: * written using the default comment character '#', the delimiter will
209: * be the comma, the line ending will be the default system line ending,
210: * the quote character will be double quotes,
211: * quotes will be used when needed, and auto flushing
212: * will be enabled.
213: *
214: * @param out stream to which to print.
215: *
216: * @since ostermillerutils 1.00.00
217: */
218: public CSVPrinter(OutputStream out) {
219: this (new OutputStreamWriter(out));
220: }
221:
222: /**
223: * Create a printer that will print values to the given
224: * stream. Comments will be
225: * written using the default comment character '#', the delimiter will
226: * be the comma, the line ending will be the default
227: * system line ending, the quote character will be double quotes,
228: * quotes will be used when needed, and auto flushing
229: * will be enabled.
230: *
231: * @param out stream to which to print.
232: *
233: * @since ostermillerutils 1.00.00
234: */
235: public CSVPrinter(Writer out) {
236: this (out, COMMENT_START_DEFAULT);
237: }
238:
239: /**
240: * Create a printer that will print values to the given
241: * stream. Character to byte conversion is done using
242: * the default character encoding. The delimiter will
243: * be the comma, the line ending will be the default system
244: * line ending, the quote character will be double quotes,
245: * quotes will be used when needed, and auto flushing
246: * will be enabled.
247: *
248: * @param out stream to which to print.
249: * @param commentStart Character used to start comments.
250: *
251: * @since ostermillerutils 1.00.00
252: */
253: public CSVPrinter(OutputStream out, char commentStart) {
254: this (new OutputStreamWriter(out), commentStart);
255: }
256:
257: /**
258: * Create a printer that will print values to the given
259: * stream. The delimiter will
260: * be the comma, the line ending will be the default
261: * system line ending, the quote character will be double quotes,
262: * quotes will be used when needed, and auto flushing
263: * will be enabled.
264: *
265: * @param out stream to which to print.
266: * @param commentStart Character used to start comments.
267: *
268: * @since ostermillerutils 1.00.00
269: */
270: public CSVPrinter(Writer out, char commentStart) {
271: this (out, commentStart, QUOTE_DEFAULT, DELIMITER_DEFAULT);
272: }
273:
274: /**
275: * Create a printer that will print values to the given
276: * stream. The comment character will be the number sign, the delimiter will
277: * be the comma, the line ending will be the default
278: * system line ending, and the quote character will be double quotes.
279: *
280: * @param out stream to which to print.
281: * @param alwaysQuote true if quotes should be used even when not strictly needed.
282: * @param autoFlush should auto flushing be enabled.
283: *
284: * @since ostermillerutils 1.02.26
285: */
286: public CSVPrinter(Writer out, boolean alwaysQuote, boolean autoFlush) {
287: this (out, COMMENT_START_DEFAULT, QUOTE_DEFAULT,
288: DELIMITER_DEFAULT, alwaysQuote, autoFlush);
289: }
290:
291: /**
292: * Create a printer that will print values to the given
293: * stream. The line ending will be the default system line
294: * ending, quotes will be used when needed, and auto flushing
295: * will be enabled.
296: *
297: * @param out stream to which to print.
298: * @param commentStart Character used to start comments.
299: * @param delimiter The new delimiter character to use.
300: * @param quote The new character to use for quoting.
301: * @throws BadQuoteException if the character cannot be used as a quote.
302: * @throws BadDelimiterException if the character cannot be used as a delimiter.
303: *
304: * @since ostermillerutils 1.02.26
305: */
306: public CSVPrinter(Writer out, char commentStart, char quote,
307: char delimiter) throws BadDelimiterException,
308: BadQuoteException {
309: this (out, commentStart, quote, delimiter, LINE_ENDING_SYSTEM);
310: }
311:
312: /**
313: * Create a printer that will print values to the given
314: * stream. Quotes will be used when needed, and auto flushing
315: * will be enabled.
316: *
317: * @param out stream to which to print.
318: * @param commentStart Character used to start comments.
319: * @param delimiter The new delimiter character to use.
320: * @param quote The new character to use for quoting.
321: * @param lineEnding The new line ending, or null to use the default line ending.
322: * @throws BadQuoteException if the character cannot be used as a quote.
323: * @throws BadDelimiterException if the character cannot be used as a delimiter.
324: * @throws BadLineEndingException if the line ending is not one of the three legal line endings.
325: *
326: * @since ostermillerutils 1.06.01
327: */
328: public CSVPrinter(Writer out, char commentStart, char quote,
329: char delimiter, String lineEnding)
330: throws BadDelimiterException, BadQuoteException,
331: BadLineEndingException {
332: this (out, commentStart, quote, delimiter, lineEnding,
333: ALWAYS_QUOTE_DEFAULT, AUTO_FLUSH_DEFAULT);
334: }
335:
336: /**
337: * Create a printer that will print values to the given
338: * stream. The line ending will be the default system line ending,
339: *
340: * @param out stream to which to print.
341: * @param commentStart Character used to start comments.
342: * @param delimiter The new delimiter character to use.
343: * @param quote The new character to use for quoting.
344: * @param alwaysQuote true if quotes should be used even when not strictly needed.
345: * @param autoFlush should auto flushing be enabled.
346: * @throws BadQuoteException if the character cannot be used as a quote.
347: * @throws BadDelimiterException if the character cannot be used as a delimiter.
348: *
349: * @since ostermillerutils 1.02.26
350: */
351: public CSVPrinter(Writer out, char commentStart, char quote,
352: char delimiter, boolean alwaysQuote, boolean autoFlush)
353: throws BadDelimiterException, BadQuoteException {
354: this (out, commentStart, quote, delimiter, LINE_ENDING_SYSTEM,
355: alwaysQuote, autoFlush);
356: }
357:
358: /**
359: * Create a printer that will print values to the given
360: * stream.
361: *
362: * @param out stream to which to print.
363: * @param commentStart Character used to start comments.
364: * @param delimiter The new delimiter character to use.
365: * @param lineEnding The new line ending, or null to use the default line ending.
366: * @param quote The new character to use for quoting.
367: * @param alwaysQuote true if quotes should be used even when not strictly needed.
368: * @param autoFlush should auto flushing be enabled.
369: * @throws BadQuoteException if the character cannot be used as a quote.
370: * @throws BadDelimiterException if the character cannot be used as a delimiter.
371: * @throws BadLineEndingException if the line ending is not one of the three legal line endings.
372: *
373: * @since ostermillerutils 1.06.01
374: */
375: public CSVPrinter(Writer out, char commentStart, char quote,
376: char delimiter, String lineEnding, boolean alwaysQuote,
377: boolean autoFlush) throws BadDelimiterException,
378: BadQuoteException, BadLineEndingException {
379: this .out = out;
380: this .commentStart = commentStart;
381: changeQuote(quote);
382: changeDelimiter(delimiter);
383: setLineEnding(lineEnding);
384: setAlwaysQuote(alwaysQuote);
385: setAutoFlush(autoFlush);
386: }
387:
388: /**
389: * Print the string as the last value on the line. The value
390: * will be quoted if needed.
391: * <p>
392: * This method never throws an I/O exception. The client may inquire as to whether
393: * any errors have occurred by invoking checkError(). If an I/O Exception is
394: * desired, the client should use the corresponding writeln method.
395: *
396: * @param value value to be outputted.
397: *
398: * @since ostermillerutils 1.00.00
399: */
400: public void println(String value) {
401: try {
402: writeln(value);
403: } catch (IOException iox) {
404: error = true;
405: }
406: }
407:
408: /**
409: * Print the string as the last value on the line. The value
410: * will be quoted if needed.
411: *
412: * @param value value to be outputted.
413: * @throws IOException if an error occurs while writing.
414: *
415: * @since ostermillerutils 1.02.26
416: */
417: public void writeln(String value) throws IOException {
418: try {
419: write(value);
420: writeln();
421: } catch (IOException iox) {
422: error = true;
423: throw iox;
424: }
425: }
426:
427: /**
428: * Output a blank line.
429: * <p>
430: * This method never throws an I/O exception. The client may inquire as to whether
431: * any errors have occurred by invoking checkError(). If an I/O Exception is
432: * desired, the client should use the corresponding writeln method.
433: *
434: * @since ostermillerutils 1.00.00
435: */
436: public void println() {
437: try {
438: writeln();
439: } catch (IOException iox) {
440: error = true;
441: }
442: }
443:
444: /**
445: * Output a blank line.
446: *
447: * @throws IOException if an error occurs while writing.
448: *
449: * @since ostermillerutils 1.02.26
450: */
451: public void writeln() throws IOException {
452: try {
453: out.write(lineEnding);
454: if (autoFlush)
455: flush();
456: newLine = true;
457: } catch (IOException iox) {
458: error = true;
459: throw iox;
460: }
461: }
462:
463: /**
464: * Print a single line of comma separated values.
465: * The values will be quoted if needed. Quotes and
466: * and other characters that need it will be escaped.
467: * <p>
468: * This method never throws an I/O exception. The client may inquire as to whether
469: * any errors have occurred by invoking checkError(). If an I/O Exception is
470: * desired, the client should use the corresponding writeln method.
471: *
472: * @param values values to be outputted.
473: *
474: * @since ostermillerutils 1.00.00
475: */
476: public void println(String[] values) {
477: try {
478: writeln(values);
479: } catch (IOException iox) {
480: error = true;
481: }
482: }
483:
484: /**
485: * Print a single line of comma separated values.
486: * The values will be quoted if needed. Quotes and
487: * and other characters that need it will be escaped.
488: *
489: * @param values values to be outputted.
490: * @throws IOException if an error occurs while writing.
491: *
492: * @since ostermillerutils 1.02.26
493: */
494: public void writeln(String[] values) throws IOException {
495: try {
496: print(values);
497: writeln();
498: } catch (IOException iox) {
499: error = true;
500: throw iox;
501: }
502: }
503:
504: /**
505: * Print a single line of comma separated values.
506: * The values will be quoted if needed. Quotes and
507: * and other characters that need it will be escaped.
508: * <p>
509: * This method never throws an I/O exception. The client may inquire as to whether
510: * any errors have occurred by invoking checkError(). If an I/O Exception is
511: * desired, the client should use the corresponding writeln method.
512: *
513: * @param values values to be outputted.
514: *
515: * @since ostermillerutils 1.00.00
516: */
517: public void print(String[] values) {
518: try {
519: write(values);
520: } catch (IOException iox) {
521: error = true;
522: }
523: }
524:
525: /**
526: * Print a single line of comma separated values.
527: * The values will be quoted if needed. Quotes and
528: * and other characters that need it will be escaped.
529: *
530: * @param values values to be outputted.
531: * @throws IOException if an error occurs while writing.
532: *
533: * @since ostermillerutils 1.02.26
534: */
535: public void write(String[] values) throws IOException {
536: try {
537: for (int i = 0; i < values.length; i++) {
538: write(values[i]);
539: }
540: } catch (IOException iox) {
541: error = true;
542: throw iox;
543: }
544: }
545:
546: /**
547: * Print several lines of comma separated values.
548: * The values will be quoted if needed. Quotes and
549: * newLine characters will be escaped.
550: * <p>
551: * This method never throws an I/O exception. The client may inquire as to whether
552: * any errors have occurred by invoking checkError(). If an I/O Exception is
553: * desired, the client should use the corresponding writeln method.
554: *
555: * @param values values to be outputted.
556: *
557: * @since ostermillerutils 1.00.00
558: */
559: public void println(String[][] values) {
560: try {
561: writeln(values);
562: } catch (IOException iox) {
563: error = true;
564: }
565: }
566:
567: /**
568: * Print several lines of comma separated values.
569: * The values will be quoted if needed. Quotes and
570: * newLine characters will be escaped.
571: *
572: * @param values values to be outputted.
573: * @throws IOException if an error occurs while writing.
574: *
575: * @since ostermillerutils 1.02.26
576: */
577: public void writeln(String[][] values) throws IOException {
578: try {
579: for (int i = 0; i < values.length; i++) {
580: writeln(values[i]);
581: }
582: if (values.length == 0) {
583: writeln();
584: }
585: } catch (IOException iox) {
586: error = true;
587: throw iox;
588: }
589: }
590:
591: /**
592: * Put a comment among the comma separated values.
593: * Comments will always begin on a new line and occupy a
594: * least one full line. The character specified to star
595: * comments and a space will be inserted at the beginning of
596: * each new line in the comment. If the comment is null,
597: * an empty comment is outputted.
598: * <p>
599: * This method never throws an I/O exception. The client may inquire as to whether
600: * any errors have occurred by invoking checkError(). If an I/O Exception is
601: * desired, the client should use the corresponding writelnComment method.
602: *
603: * @param comment the comment to output.
604: *
605: * @since ostermillerutils 1.00.00
606: */
607: public void printlnComment(String comment) {
608: try {
609: writelnComment(comment);
610: } catch (IOException iox) {
611: error = true;
612: }
613: }
614:
615: /**
616: * Put a comment among the comma separated values.
617: * Comments will always begin on a new line and occupy a
618: * least one full line. The character specified to star
619: * comments and a space will be inserted at the beginning of
620: * each new line in the comment. If the comment is null,
621: * an empty comment is outputted.
622: *
623: * @param comment the comment to output.
624: * @throws IOException if an error occurs while writing.
625: *
626: * @since ostermillerutils 1.02.26
627: */
628: public void writelnComment(String comment) throws IOException {
629: try {
630: if (comment == null)
631: comment = "";
632: if (!newLine) {
633: writeln();
634: }
635: out.write(commentStart);
636: out.write(' ');
637: for (int i = 0; i < comment.length(); i++) {
638: char c = comment.charAt(i);
639: switch (c) {
640: case '\r': {
641: if (i + 1 < comment.length()
642: && comment.charAt(i + 1) == '\n') {
643: i++;
644: }
645: } //break intentionally excluded.
646: case '\n': {
647: writeln();
648: out.write(commentStart);
649: out.write(' ');
650: }
651: break;
652: default: {
653: out.write(c);
654: }
655: break;
656: }
657: }
658: writeln();
659: } catch (IOException iox) {
660: error = true;
661: throw iox;
662: }
663: }
664:
665: /**
666: * Print the string as the next value on the line. The value
667: * will be quoted if needed. If value is null, an empty value is printed.
668: * <p>
669: * This method never throws an I/O exception. The client may inquire as to whether
670: * any errors have occurred by invoking checkError(). If an I/O Exception is
671: * desired, the client should use the corresponding println method.
672: *
673: * @param value value to be outputted.
674: *
675: * @since ostermillerutils 1.00.00
676: */
677: public void print(String value) {
678: try {
679: write(value);
680: } catch (IOException iox) {
681: error = true;
682: }
683: }
684:
685: /**
686: * Print the string as the next value on the line. The value
687: * will be quoted if needed. If value is null, an empty value is printed.
688: *
689: * @param value value to be outputted.
690: * @throws IOException if an error occurs while writing.
691: *
692: * @since ostermillerutils 1.02.26
693: */
694: public void write(String value) throws IOException {
695: try {
696: if (value == null)
697: value = "";
698: boolean quote = false;
699: if (alwaysQuote) {
700: quote = true;
701: } else if (value.length() > 0) {
702: char c = value.charAt(0);
703: if (newLine
704: && (c < '0' || (c > '9' && c < 'A')
705: || (c > 'Z' && c < 'a') || (c > 'z'))) {
706: quote = true;
707: }
708: if (c == ' ' || c == '\f' || c == '\t') {
709: quote = true;
710: }
711: for (int i = 0; i < value.length(); i++) {
712: c = value.charAt(i);
713: if (c == quoteChar || c == delimiterChar
714: || c == '\n' || c == '\r') {
715: quote = true;
716: }
717: }
718: if (c == ' ' || c == '\f' || c == '\t') {
719: quote = true;
720: }
721: } else if (newLine) {
722: // always quote an empty token that is the first
723: // on the line, as it may be the only thing on the
724: // line. If it were not quoted in that case,
725: // an empty line has no tokens.
726: quote = true;
727: }
728: if (newLine) {
729: newLine = false;
730: } else {
731: out.write(delimiterChar);
732: }
733: if (quote) {
734: out.write(escapeAndQuote(value));
735: } else {
736: out.write(value);
737: }
738: if (autoFlush)
739: flush();
740: } catch (IOException iox) {
741: error = true;
742: throw iox;
743: }
744: }
745:
746: /**
747: * Enclose the value in quotes and escape the quote
748: * and comma characters that are inside.
749: *
750: * @param value needs to be escaped and quoted
751: * @return the value, escaped and quoted.
752: *
753: * @since ostermillerutils 1.00.00
754: */
755: private String escapeAndQuote(String value) {
756: int count = 2;
757: for (int i = 0; i < value.length(); i++) {
758: char c = value.charAt(i);
759: switch (c) {
760: case '\n':
761: case '\r':
762: case '\\': {
763: count++;
764: }
765: break;
766: default: {
767: if (c == quoteChar) {
768: count++;
769: }
770: }
771: break;
772: }
773: }
774: StringBuffer sb = new StringBuffer(value.length() + count);
775: sb.append(quoteChar);
776: for (int i = 0; i < value.length(); i++) {
777: char c = value.charAt(i);
778: switch (c) {
779: case '\n': {
780: sb.append("\\n");
781: }
782: break;
783: case '\r': {
784: sb.append("\\r");
785: }
786: break;
787: case '\\': {
788: sb.append("\\\\");
789: }
790: break;
791: default: {
792: if (c == quoteChar) {
793: sb.append("\\" + quoteChar);
794: } else {
795: sb.append(c);
796: }
797: }
798: }
799: }
800: sb.append(quoteChar);
801: return (sb.toString());
802: }
803:
804: /**
805: * Flush any data written out to underlying streams.
806: *
807: * @throws IOException if IO error occurs
808: * @since ostermillerutils 1.02.26
809: */
810: public void flush() throws IOException {
811: out.flush();
812: }
813:
814: /**
815: * Close any underlying streams.
816: *
817: * @throws IOException if IO error occurs
818: * @since ostermillerutils 1.02.26
819: */
820: public void close() throws IOException {
821: out.close();
822: }
823:
824: /**
825: * Flush the stream if it's not closed and check its error state.
826: * Errors are cumulative; once the stream encounters an error,
827: * this routine will return true on all successive calls.
828: *
829: * @return True if the print stream has encountered an error,
830: * either on the underlying output stream or during a format conversion.
831: *
832: * @since ostermillerutils 1.02.26
833: */
834: public boolean checkError() {
835: try {
836: if (error)
837: return true;
838: flush();
839: if (error)
840: return true;
841: if (out instanceof PrintWriter) {
842: error = ((PrintWriter) out).checkError();
843: }
844: } catch (IOException iox) {
845: error = true;
846: }
847: return error;
848: }
849:
850: /**
851: * Set flushing behavior. Iff set, a flush command
852: * will be issued to any underlying stream after each
853: * print or write command.
854: *
855: * @param autoFlush should auto flushing be enabled.
856: *
857: * @since ostermillerutils 1.02.26
858: */
859: public void setAutoFlush(boolean autoFlush) {
860: this .autoFlush = autoFlush;
861: }
862:
863: /**
864: * Set whether values printers should always be quoted, or
865: * whether the printer may, at its discretion, omit quotes
866: * around the value.
867: *
868: * @param alwaysQuote true if quotes should be used even when not strictly needed.
869: *
870: * @since ostermillerutils 1.02.26
871: */
872: public void setAlwaysQuote(boolean alwaysQuote) {
873: this.alwaysQuote = alwaysQuote;
874: }
875: }
|