001package bradleyross.library.helpers;
002import java.io.PrintStream;
003import java.io.PrintWriter;
004import java.io.StringWriter;
005import java.io.Closeable;
006import java.io.Flushable;
007/**
008 * Allows a single set of code to output results to
009 * StringWriter, PrintStream and PrintWriter objects by providing a
010 * common wrapper.
011 * 
012 * <p>PrintStream  and PrintWriter implement Closeable, Flushable, and Appendable.  The 
013 *    method names and parameter types used by these methods are the same as
014 *    those in the PrintStream and PrintWriter classes.</p>
015 * <p>StringWriter is first encapsulated in a PrintWriter to enable it to be used as
016 *    an output device.</p>
017 * @see PrintStream
018 * @see PrintWriter
019 * @see StringWriter
020 * @author Bradley Ross
021 *
022 */
023public class GenericPrinter implements Appendable, Closeable, Flushable
024{
025        /**
026         * PrintWriter object.
027         * @see PrintWriter
028         */
029        PrintWriter writer = null;
030        /**
031         * PrintStream object.
032         * @see PrintStream
033         * 
034         */
035        PrintStream stream = null;
036        /**
037         * PrintStream, PrintWriter, or StringWriter
038         * object that was used in the constructor.
039         */
040        Object underlying = null;
041        /**
042         * Create printer for PrintWriter object
043         * @see PrintWriter
044         * @param value PrintWriter object
045         */
046        public GenericPrinter(PrintWriter value)
047        {
048                writer = value;
049                underlying = value;
050        }
051        /**
052         * Create printer for PrintStream object.
053         * @param value PrintStream object
054         */
055        public GenericPrinter (PrintStream value)
056        {
057                stream = value;
058                underlying = value;
059        }
060        /**
061         * Create printer for StringWriter object.
062         * @param value StringWriter object.
063         */
064        public GenericPrinter (StringWriter value)
065        {
066                writer = new PrintWriter(value);
067                underlying = value;
068        }
069        /**
070         * Return the underlying StringWriter, PrintStream or PrintWriter object
071         * for the GenericPrinter object.
072         * @return Underlying object
073         */
074        public Object getUnderlyingObject()
075        {
076                return underlying;              
077        }
078        /**
079         * Checks if an error has occurred on the output stream.
080         * @see PrintStream#checkError()
081         * @see PrintWriter#checkError()
082         * @return True if an error has occurred
083         */
084        public boolean checkError()
085        {
086                if (writer != null)
087                {
088                        return writer.checkError();
089                }
090                else if (stream != null)
091                {
092                        return stream.checkError();
093                }
094                else
095                {
096                        return false;
097                }
098        }
099        /**
100         * Place a byte containing the specified value to the stream.
101         * @see PrintStream#write(int)
102         * @see PrintWriter#write(int)
103         * @param n Value of byte to be written.
104         */
105        public void write(int n)
106        {
107                if (writer != null)
108                {
109                        writer.write(n);
110                }
111                else if (stream != null)
112                {
113                        stream.write(n);
114                }
115        }
116        /**
117         * Print string and then terminate the line.
118         * @see PrintStream#println(String)
119         * @see PrintWriter#println(String)
120         * @param value String to be printed
121         */
122        public void println(String value)
123        {
124                if (writer != null)
125                {
126                        writer.println(value);
127                }
128                else if (stream != null)
129                {
130                        stream.println(value);
131                }
132        }
133        /**
134         * Print string.
135         * 
136         * @see PrintStream#print(String)
137         * @see PrintWriter#print(String)
138         * 
139         * @param value String to be printed
140         */
141        public void print(String value)
142        {
143                if (writer != null)
144                {
145                        writer.print(value);
146                }
147                else if (stream != null)
148                {
149                        stream.print(value);
150                }
151        }
152        /**
153         * Print a character.
154         * @see PrintStream#print(char)
155         * @see PrintWriter#print(char)
156         * @param c Character to be printed
157         */
158        public void print(char c)
159        {
160                if (writer != null)
161                {
162                        writer.print(c);
163                }
164                else if (stream != null)
165                {
166                        stream.print(c);
167                }
168        }
169        /**
170         * Print a character and terminate the line.
171         * 
172         * @see PrintStream#println(String)
173         * @see PrintWriter#println(String)
174         * @param c Character to be printed
175         */
176        public void println(char c)
177        {
178                print(c);
179                println();
180        }
181        /**
182         * Print an array of  characters.
183         * @see PrintStream#print(char[])
184         * @see PrintWriter#print(char[])
185         * @param c Character to be printed
186         */
187        public void print(char c[])
188        {
189                if (writer != null)
190                {
191                        writer.print(c);
192                }
193                else if (stream != null)
194                {
195                        stream.print(c);
196                }
197        }
198        /**
199         * Print an array of  characters and then terminate the line.
200         * @see PrintStream#println(char[])
201         * @see PrintWriter#println(char[])
202         * @param c Character to be printed
203         */
204        public void println(char c[])
205        {
206                print(c);
207                println();
208        }
209        /**
210         * Terminate the line.
211         * @see PrintStream#println()
212         * @see PrintWriter#println()
213         */
214        public void println()
215        {
216                if (writer != null)
217                {
218                        writer.println();
219                }
220                else if (stream != null)
221                {
222                        stream.println();
223                }
224        }
225        /**
226         * Append a character.
227         * 
228         * @see PrintStream#append(char)
229         * @see PrintWriter#append(char)
230         * @return PrintStream or PrintWriter object
231         */
232        public Appendable append(char c)
233        {
234                if (writer != null)
235                {
236                        writer.append(c);
237                }
238                else if (stream != null)
239                {
240                        stream.append(c);
241                }
242                else
243                {
244                        return (Appendable) this;
245                }
246                return (Appendable) this;
247        }
248        /**
249         * Append a character sequence to the output stream.
250         * @see PrintStream#append(CharSequence)
251         * @see PrintWriter#append(CharSequence)
252         * @param csq The character sequence to be be appended.
253         *
254         */
255        public Appendable append(CharSequence csq)
256        {
257                if (writer != null)
258                {
259                        writer.append(csq);
260                }
261                else if (stream != null)
262                {
263                        stream.append(csq);
264                }
265                else
266                {
267                        return (Appendable) this;
268                }
269                return (Appendable) this;
270        }
271        /**
272         * Append a subsequence of the specified character sequence to the output stream.
273         * @see PrintStream#append(CharSequence,int,int)
274         * @see PrintWriter#append(CharSequence, int, int)
275         * @param csq The character sequence from which a subsequence will be appended.  If csq is null, 
276         *  then characters will be appended as if csq contained the four characters "null".
277         *  @param start The index of the first character in the subsequence
278         *  @param end The index of the character following the last character in the subsequence
279         */
280        public Appendable append(CharSequence csq, int start, int end) throws IndexOutOfBoundsException
281        {
282                if (writer != null)
283                {
284                        writer.append(csq, start, end);
285                }
286                else if (stream != null)
287                {
288                        stream.append(csq, start, end);
289                }
290                return (Appendable) this;
291        }
292        /**
293         * Close the output stream.
294         * @see PrintStream#close()
295         * @see PrintWriter#close()
296         */
297        public void close()
298        {
299                if (writer != null)
300                {
301                        writer.close();
302                        
303                }
304                else if (stream != null)
305                {
306                        stream.close();
307                }               
308        }
309        /**
310         * Flush the output stream.
311         * @see PrintStream#flush()
312         * @see PrintWriter#flush()
313         */
314        public void flush()
315        {
316                if (writer != null)
317                {
318                        writer.flush();
319                        
320                }
321                else if (stream != null)
322                {
323                        stream.flush();
324                }                       
325        }
326        /**
327         * Print an integer value.
328         * @see Integer#toString(int)
329         * @see PrintStream#print(int)
330         * @see PrintWriter#print(int)
331         * @param value integer value to be printed
332         */
333        public void print(int value)
334        {
335                print(Integer.toString(value));
336        }
337        /**
338         * Print an integer value and then terminate the line.
339         * @see Integer#toString(int)
340         * @see PrintStream#println(int)
341         * @see PrintWriter#println(int)
342         * @param value integer value to be printed
343         */
344        public void println(int value)
345        {
346                print(Integer.toString(value));
347                println();
348        }
349        /**
350         * Print a long integer value.
351         * @see Long#toString(long)
352         * @see PrintStream#println(long)
353         * @see PrintWriter#println(long)
354         * @param value long integer value to be printed
355         */
356        public void print(long value)
357        {
358                print(Long.toString(value));
359        }
360        /**
361         * Print a long integer value and then terminate the line.
362         * @see Long#toString(long)
363         * @see PrintStream#println(long)
364         * @see PrintWriter#println(long)
365         * @param value long integer value to be printed
366         */
367        public void println(long value)
368        {
369                print(Long.toString(value));
370                println();
371        }
372        /**
373         * Print a boolean value.
374         * @see Boolean#toString(boolean)
375         * @see PrintStream#print(boolean)
376         * @see PrintWriter#print(boolean)
377         * @param value boolean value to be printed
378         */
379        public void print(boolean value)
380        {
381                print(Boolean.toString(value));
382        }
383        /**
384         * Print a boolean value and then terminate the line.
385         * @see Boolean#toString(boolean)
386         * @see PrintStream#println(boolean)
387         * @see PrintWriter#println(boolean)
388         * @param value Boolean value to be printed
389         */
390        public void println(boolean value)
391        {
392                print(Boolean.toString(value));
393                println();
394        }
395        /**
396         * Print a double-precision floating-point number.
397         * @see PrintStream#print(double)
398         * @see PrintWriter#print(double)
399         * @param value Double-precision floating-point number to be printed
400         */
401        public void print(double value)
402        {
403                print(Double.toString(value));
404        }
405        /**
406         * Print a double-precision floating-point number and
407         * then terminate the line.
408         * @see PrintStream#println(double)
409         * @see PrintWriter#println(double)
410         * @param value Double-precision floating-point number to be printed
411         */
412        public void println(double value)
413        {
414                print(Double.toString(value));
415                println();
416        }
417        /**
418         * Print a floating-point number.
419         * 
420         * @see PrintStream#println(float)
421         * @see PrintWriter#println(float)
422         * @param value Floating-point number to be printed
423         */
424        public void print(float value)
425        {
426                print(Float.toString(value));
427        }
428        /**
429         * Print a floating-point number and
430         * then terminate the line.
431         * @see PrintStream#println(float)
432         * @see PrintWriter#println(float)
433         * @param value Floating-point number to be printed
434         */
435        public void println(float value)
436        {
437                print(Float.toString(value));
438                println();
439        }
440        /**
441         * Test driver.
442         * @param args Not used
443         * 
444         */
445        public static void main(String args[])
446        {
447                StringWriter writer;
448                System.out.println("Trying GenericPrinter for PrintStream System.out");
449                GenericPrinter instance = new GenericPrinter(System.out);
450                instance.println(instance.getUnderlyingObject().getClass().getName());
451                instance.println("Test");
452                instance.println(true);
453                System.out.println("Trying GenericPrinter for StringWriter");
454                writer = new StringWriter();
455                instance = new GenericPrinter(writer);
456                instance.println(instance.getUnderlyingObject().getClass().getName());
457                instance.println("Test");
458                instance.println(true);
459                System.out.println(instance.getUnderlyingObject().toString());
460                System.out.println("Using PrintWriter");
461                writer = new StringWriter();
462                instance = new GenericPrinter(new PrintWriter(writer));
463                instance.println(instance.getUnderlyingObject().getClass().getName());
464                instance.println("Test");
465                instance.println(true);
466                System.out.println(writer.toString());
467                System.out.println("End of program");
468        }
469}