source: src/main/java/weka/core/Tee.java @ 24

Last change on this file since 24 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 13.1 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * Tee.java
19 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.core;
24
25import java.io.PrintStream;
26import java.util.Date;
27import java.util.Vector;
28
29/**
30* This class pipelines print/println's to several PrintStreams. Useful for
31* redirecting System.out and System.err to files etc.<br/>
32* E.g., for redirecting stderr/stdout to files with timestamps and:<br/>
33* <pre>
34*    import java.io.*;
35*    import weka.core.Tee;
36*
37*    ...
38*    // stdout
39*    Tee teeOut = new Tee(System.out);
40*    teeOut.add(new PrintStream(new FileOutputStream("out.txt")), true);
41*    System.setOut(teeOut);
42*   
43*    // stderr
44*    Tee teeErr = new Tee(System.err);
45*    teeErr.add(new PrintStream(new FileOutputStream("err.txt")), true);
46*    System.setOut(teeErr);
47*    ...
48* </pre>
49*
50* @author   FracPete (fracpete at waikato dot ac dot nz)
51* @version  $Revision: 5953 $
52*/
53
54public class Tee
55  extends PrintStream
56  implements RevisionHandler {
57 
58  /** the different PrintStreams. */
59  protected Vector<PrintStream> m_Streams = new Vector<PrintStream>();
60 
61  /** whether to add timestamps or not. */
62  protected Vector<Boolean> m_Timestamps = new Vector<Boolean>();
63 
64  /** whether to add a prefix or not. */
65  protected Vector<String> m_Prefixes = new Vector<String>();
66 
67  /** the default printstream. */
68  protected PrintStream m_Default = null;
69
70  /**
71   * initializes the object, with a default printstream.
72   */
73  public Tee() {
74    this(null);
75  }
76
77  /**
78   * initializes the object with the given default printstream, e.g.,
79   * System.out.
80   *
81   * @param def     the default printstream, remains also after calling clear()
82   */
83  public Tee(PrintStream def) {
84    super(def);
85
86    m_Default = def;
87    clear();
88  }
89
90  /**
91   * removes all streams and places the default printstream, if any, again in
92   * the list.
93   *
94   * @see #getDefault()
95   */
96  public void clear() {
97    m_Streams.clear();
98    m_Timestamps.clear();
99    m_Prefixes.clear();
100   
101    if (getDefault() != null)
102      add(getDefault());
103  }
104
105  /**
106   * returns the default printstrean, can be NULL.
107   *
108   * @return the default printstream
109   * @see #m_Default
110   */
111  public PrintStream getDefault() {
112    return m_Default;
113  }
114
115  /**
116   * adds the given PrintStream to the list of streams, with NO timestamp and
117   * NO prefix.
118   *
119   * @param p       the printstream to add
120   */
121  public void add(PrintStream p) {
122    add(p, false);
123  }
124
125  /**
126   * adds the given PrintStream to the list of streams, with NO prefix.
127   *
128   * @param p           the printstream to add
129   * @param timestamp   whether to use timestamps or not
130   */
131  public void add(PrintStream p, boolean timestamp) {
132    add(p, timestamp, "");
133  }
134
135  /**
136   * adds the given PrintStream to the list of streams.
137   *
138   * @param p           the printstream to add
139   * @param timestamp   whether to use timestamps or not
140   * @param prefix      the prefix to use
141   */
142  public void add(PrintStream p, boolean timestamp, String prefix) {
143    if (m_Streams.contains(p))
144      remove(p);
145
146    // make sure it's not null
147    if (prefix == null)
148      prefix = "";
149
150    m_Streams.add(p);
151    m_Timestamps.add(new Boolean(timestamp));
152    m_Prefixes.add(prefix);
153  }
154
155  /**
156   * returns the specified PrintStream from the list.
157   *
158   * @param index the index of the PrintStream to return
159   * @return the specified PrintStream, or null if invalid index
160   */
161  public PrintStream get(int index) {
162    if ( (index >= 0) && (index < size()) )
163      return (PrintStream) m_Streams.get(index);
164    else
165      return null;
166  }
167
168  /**
169   * removes the given PrintStream from the list.
170   *
171   * @param p the PrintStream to remove
172   * @return returns the removed PrintStream if it could be removed, null otherwise
173   */
174  public PrintStream remove(PrintStream p) {
175    int         index;
176
177    if (contains(p)) {
178      index = m_Streams.indexOf(p);
179      m_Timestamps.remove(index);
180      m_Prefixes.remove(index);
181      return (PrintStream) m_Streams.remove(index);
182    }
183    else {
184      return null;
185    }
186  }
187
188  /**
189   * removes the given PrintStream from the list.
190   *
191   * @param index the index of the PrintStream to remove
192   * @return returns the removed PrintStream if it could be removed, null otherwise
193   */
194  public PrintStream remove(int index) {
195    if ( (index >= 0) && (index < size()) ) {
196      m_Timestamps.remove(index);
197      m_Prefixes.remove(index);
198      return (PrintStream) m_Streams.remove(index);
199    }
200    else {
201      return null;
202    }
203  }
204
205  /**
206   * checks whether the given PrintStream is already in the list.
207   *
208   * @param p the PrintStream to look for
209   * @return true if the PrintStream is in the list
210   */
211  public boolean contains(PrintStream p) {
212    return m_Streams.contains(p);
213  }
214
215  /**
216   * returns the number of streams currently in the list.
217   *
218   * @return the number of streams in the list
219   */
220  public int size() {
221    return m_Streams.size();
222  }
223
224  /**
225   * prints the prefix/timestamp (timestampe only to those streams that want
226   * one).
227   */
228  private void printHeader() {
229    for (int i = 0; i < size(); i++) {
230      // prefix
231      if (!((String) m_Prefixes.get(i)).equals(""))
232        ((PrintStream) m_Streams.get(i)).print("[" + m_Prefixes.get(i) + "]\t");
233     
234      // timestamp
235      if (((Boolean) m_Timestamps.get(i)).booleanValue())
236        ((PrintStream) m_Streams.get(i)).print("[" + new Date() + "]\t");
237    }
238  }
239
240  /**
241   * flushes all the printstreams.
242   */
243  public void flush() {
244    for (int i = 0; i < size(); i++)
245      ((PrintStream) m_Streams.get(i)).flush();
246  }
247
248  /**
249   * prints the given int to the streams.
250   *
251   * @param x the object to print
252   */
253  public void print(int x) {
254    printHeader();
255    for (int i = 0; i < size(); i++)
256      ((PrintStream) m_Streams.get(i)).print(x);
257    flush();
258  }
259
260  /**
261   * prints the given long to the streams.
262   *
263   * @param x the object to print
264   */
265  public void print(long x) {
266    printHeader();
267    for (int i = 0; i < size(); i++)
268      ((PrintStream) m_Streams.get(i)).print(x);
269    flush();
270  }
271
272  /**
273   * prints the given float to the streams.
274   *
275   * @param x the object to print
276   */
277  public void print(float x) {
278    printHeader();
279    for (int i = 0; i < size(); i++)
280      ((PrintStream) m_Streams.get(i)).print(x);
281    flush();
282  }
283
284  /**
285   * prints the given double to the streams.
286   *
287   * @param x the object to print
288   */
289  public void print(double x) {
290    printHeader();
291    for (int i = 0; i < size(); i++)
292      ((PrintStream) m_Streams.get(i)).print(x);
293    flush();
294  }
295
296  /**
297   * prints the given boolean to the streams.
298   *
299   * @param x the object to print
300   */
301  public void print(boolean x) {
302    printHeader();
303    for (int i = 0; i < size(); i++)
304      ((PrintStream) m_Streams.get(i)).print(x);
305    flush();
306  }
307
308  /**
309   * prints the given char to the streams.
310   *
311   * @param x the object to print
312   */
313  public void print(char x) {
314    printHeader();
315    for (int i = 0; i < size(); i++)
316      ((PrintStream) m_Streams.get(i)).print(x);
317    flush();
318  }
319
320  /**
321   * prints the given char array to the streams.
322   *
323   * @param x the object to print
324   */
325  public void print(char[] x) {
326    printHeader();
327    for (int i = 0; i < size(); i++)
328      ((PrintStream) m_Streams.get(i)).print(x);
329    flush();
330  }
331
332  /**
333   * prints the given string to the streams.
334   *
335   * @param x the object to print
336   */
337  public void print(String x) {
338    printHeader();
339    for (int i = 0; i < size(); i++)
340      ((PrintStream) m_Streams.get(i)).print(x);
341    flush();
342  }
343
344  /**
345   * prints the given object to the streams.
346   *
347   * @param x the object to print
348   */
349  public void print(Object x) {
350    printHeader();
351    for (int i = 0; i < size(); i++)
352      ((PrintStream) m_Streams.get(i)).print(x);
353    flush();
354  }
355
356  /**
357   * prints a new line to the streams.
358   */
359  public void println() {
360    printHeader();
361    for (int i = 0; i < size(); i++)
362      ((PrintStream) m_Streams.get(i)).println();
363    flush();
364  }
365
366  /**
367   * prints the given int to the streams.
368   *
369   * @param x the object to print
370   */
371  public void println(int x) {
372    printHeader();
373    for (int i = 0; i < size(); i++)
374      ((PrintStream) m_Streams.get(i)).println(x);
375    flush();
376  }
377
378  /**
379   * prints the given long to the streams.
380   *
381   * @param x the object to print
382   */
383  public void println(long x) {
384    printHeader();
385    for (int i = 0; i < size(); i++)
386      ((PrintStream) m_Streams.get(i)).println(x);
387    flush();
388  }
389
390  /**
391   * prints the given float to the streams.
392   *
393   * @param x the object to print
394   */
395  public void println(float x) {
396    printHeader();
397    for (int i = 0; i < size(); i++)
398      ((PrintStream) m_Streams.get(i)).println(x);
399    flush();
400  }
401
402  /**
403   * prints the given double to the streams.
404   *
405   * @param x the object to print
406   */
407  public void println(double x) {
408    printHeader();
409    for (int i = 0; i < size(); i++)
410      ((PrintStream) m_Streams.get(i)).println(x);
411    flush();
412  }
413
414  /**
415   * prints the given boolean to the streams.
416   *
417   * @param x the object to print
418   */
419  public void println(boolean x) {
420    printHeader();
421    for (int i = 0; i < size(); i++)
422      ((PrintStream) m_Streams.get(i)).println(x);
423    flush();
424  }
425
426  /**
427   * prints the given char to the streams.
428   *
429   * @param x the object to print
430   */
431  public void println(char x) {
432    printHeader();
433    for (int i = 0; i < size(); i++)
434      ((PrintStream) m_Streams.get(i)).println(x);
435    flush();
436  }
437
438  /**
439   * prints the given char array to the streams.
440   *
441   * @param x the object to print
442   */
443  public void println(char[] x) {
444    printHeader();
445    for (int i = 0; i < size(); i++)
446      ((PrintStream) m_Streams.get(i)).println(x);
447    flush();
448  }
449
450  /**
451   * prints the given string to the streams.
452   *
453   * @param x the object to print
454   */
455  public void println(String x) {
456    printHeader();
457    for (int i = 0; i < size(); i++)
458      ((PrintStream) m_Streams.get(i)).println(x);
459    flush();
460  }
461
462  /**
463   * prints the given object to the streams (for Throwables we print the stack
464   * trace).
465   *
466   * @param x the object to print
467   */
468  public void println(Object x) {
469    String                  line;
470    Throwable               t;
471    StackTraceElement[]     trace;
472    int                     i;
473
474    if (x instanceof Throwable) {
475      t     = (Throwable) x;
476      trace = t.getStackTrace();
477      line  = t.toString() + "\n";
478      for (i = 0; i < trace.length; i++)
479        line += "\t" + trace[i].toString() + "\n";
480      x = line;
481    }
482
483    printHeader();
484    for (i = 0; i < size(); i++)
485      ((PrintStream) m_Streams.get(i)).println(x);
486    flush();
487  }
488
489  /**
490   * Writes <code>len</code> bytes from the specified byte array starting at
491   * offset <code>off</code> to this stream.  If automatic flushing is
492   * enabled then the <code>flush</code> method will be invoked.
493   *
494   * <p> Note that the bytes will be written as given; to write characters
495   * that will be translated according to the platform's default character
496   * encoding, use the <code>print(char)</code> or <code>println(char)</code>
497   * methods.
498   *
499   * @param  buf   A byte array
500   * @param  off   Offset from which to start taking bytes
501   * @param  len   Number of bytes to write
502   */
503  public void write(byte buf[], int off, int len) {
504    printHeader();
505    for (int i = 0; i < size(); i++)
506      ((PrintStream) m_Streams.get(i)).write(buf, off, len);
507    flush();
508  }
509
510  /**
511   * Writes the specified byte to this stream.  If the byte is a newline and
512   * automatic flushing is enabled then the <code>flush</code> method will be
513   * invoked.
514   *
515   * <p> Note that the byte is written as given; to write a character that
516   * will be translated according to the platform's default character
517   * encoding, use the <code>print(char)</code> or <code>println(char)</code>
518   * methods.
519   *
520   * @param  b  The byte to be written
521   * @see #print(char)
522   * @see #println(char)
523   */
524  public void write(int b) {
525    printHeader();
526    for (int i = 0; i < size(); i++)
527      ((PrintStream) m_Streams.get(i)).write(b);
528    flush();
529  }
530
531  /**
532   * returns only the classname and the number of streams.
533   *
534   * @return only the classname and the number of streams
535   */
536  public String toString() {
537    return this.getClass().getName() + ": " + m_Streams.size();
538  }
539 
540  /**
541   * Returns the revision string.
542   *
543   * @return            the revision
544   */
545  public String getRevision() {
546    return RevisionUtils.extract("$Revision: 5953 $");
547  }
548}
Note: See TracBrowser for help on using the repository browser.