001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.util;
028    
029    
030    
031    import java.io.OutputStream;
032    
033    import static org.opends.server.loggers.debug.DebugLogger.*;
034    import org.opends.server.loggers.debug.DebugTracer;
035    import org.opends.server.types.DebugLogLevel;
036    
037    
038    /**
039     * This class defines a simple {@code OutputStream} object that can be used to
040     * write all messages to multiple targets at the same time, much like the UNIX
041     * "tee" command.  Note that this class will never throw any exceptions
042     */
043    @org.opends.server.types.PublicAPI(
044         stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
045         mayInstantiate=true,
046         mayExtend=false,
047         mayInvoke=true)
048    public final class MultiOutputStream
049           extends OutputStream
050    {
051      /**
052       * The tracer object for the debug logger.
053       */
054      private static final DebugTracer TRACER = getTracer();
055    
056    
057    
058      // The set of target output streams to which all messages will be written;
059      private final OutputStream[] targetStreams;
060    
061    
062    
063      /**
064       * Creates a new {@code MultiOutputStream} object that will write all messages
065       * to all of the target streams.
066       *
067       * @param  targetStreams  The set of print streams to which all messages
068       *                        should be written.  This must not be {@code null},
069       *                        nor may it contain any {@code null} elements.
070       */
071      public MultiOutputStream(OutputStream... targetStreams)
072      {
073        Validator.ensureNotNull(targetStreams);
074    
075        this.targetStreams = targetStreams;
076      }
077    
078    
079    
080      /**
081       * Closes all of the underlying output streams.
082       */
083      public void close()
084      {
085        for (OutputStream s : targetStreams)
086        {
087          try
088          {
089            s.close();
090          }
091          catch (Exception e)
092          {
093            if (debugEnabled())
094            {
095              TRACER.debugCaught(DebugLogLevel.ERROR, e);
096            }
097          }
098        }
099      }
100    
101    
102    
103      /**
104       * Flushes all of the underlying output streams.
105       */
106      public void flush()
107      {
108        for (OutputStream s : targetStreams)
109        {
110          try
111          {
112            s.flush();
113          }
114          catch (Exception e)
115          {
116            if (debugEnabled())
117            {
118              TRACER.debugCaught(DebugLogLevel.ERROR, e);
119            }
120          }
121        }
122      }
123    
124    
125    
126      /**
127       * Writes the contents of the provided byte array to all of the underlying
128       * output streams.
129       *
130       * @param  b  The byte array containing the data to be written.
131       */
132      public void write(byte[] b)
133      {
134        for (OutputStream s : targetStreams)
135        {
136          try
137          {
138            s.write(b);
139          }
140          catch (Exception e)
141          {
142            if (debugEnabled())
143            {
144              TRACER.debugCaught(DebugLogLevel.ERROR, e);
145            }
146          }
147        }
148      }
149    
150    
151    
152      /**
153       * Writes the specified portion of the provided byte array to all of the
154       * underlying output streams.
155       *
156       * @param  b    The byte array containing the data to be written.
157       * @param  off  The position at which the data to write begins in the array.
158       * @param  len  The number of bytes to b written.
159       */
160      public void write(byte[] b, int off, int len)
161      {
162        for (OutputStream s : targetStreams)
163        {
164          try
165          {
166            s.write(b, off, len);
167          }
168          catch (Exception e)
169          {
170            if (debugEnabled())
171            {
172              TRACER.debugCaught(DebugLogLevel.ERROR, e);
173            }
174          }
175        }
176      }
177    
178    
179    
180      /**
181       * Writes the specified byte to the set of target output streams.
182       *
183       * @param  b  The byte to be written.
184       */
185      public void write(int b)
186      {
187        for (OutputStream s : targetStreams)
188        {
189          try
190          {
191            s.write(b);
192          }
193          catch (Exception e)
194          {
195            if (debugEnabled())
196            {
197              TRACER.debugCaught(DebugLogLevel.ERROR, e);
198            }
199          }
200        }
201      }
202    }
203