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