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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.util;
028
029
030
031import java.io.OutputStream;
032
033import org.forgerock.util.Reject;
034import org.forgerock.i18n.slf4j.LocalizedLogger;
035
036
037/**
038 * This class defines a simple {@code OutputStream} object that can be used to
039 * write all messages to multiple targets at the same time, much like the UNIX
040 * "tee" command.  Note that this class will never throw any exceptions
041 */
042@org.opends.server.types.PublicAPI(
043     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
044     mayInstantiate=true,
045     mayExtend=false,
046     mayInvoke=true)
047public final class MultiOutputStream
048       extends OutputStream
049{
050  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
051
052
053
054  /** The set of target output streams to which all messages will be written. */
055  private final OutputStream[] targetStreams;
056
057
058
059  /**
060   * Creates a new {@code MultiOutputStream} object that will write all messages
061   * to all of the target streams.
062   *
063   * @param  targetStreams  The set of print streams to which all messages
064   *                        should be written.  This must not be {@code null},
065   *                        nor may it contain any {@code null} elements.
066   */
067  public MultiOutputStream(OutputStream... targetStreams)
068  {
069    Reject.ifNull(targetStreams);
070
071    this.targetStreams = targetStreams;
072  }
073
074
075
076  /**
077   * Closes all of the underlying output streams.
078   */
079  public void close()
080  {
081    for (OutputStream s : targetStreams)
082    {
083      try
084      {
085        s.close();
086      }
087      catch (Exception e)
088      {
089        logger.traceException(e);
090      }
091    }
092  }
093
094
095
096  /**
097   * Flushes all of the underlying output streams.
098   */
099  public void flush()
100  {
101    for (OutputStream s : targetStreams)
102    {
103      try
104      {
105        s.flush();
106      }
107      catch (Exception e)
108      {
109        logger.traceException(e);
110      }
111    }
112  }
113
114
115
116  /**
117   * Writes the contents of the provided byte array to all of the underlying
118   * output streams.
119   *
120   * @param  b  The byte array containing the data to be written.
121   */
122  public void write(byte[] b)
123  {
124    for (OutputStream s : targetStreams)
125    {
126      try
127      {
128        s.write(b);
129      }
130      catch (Exception e)
131      {
132        logger.traceException(e);
133      }
134    }
135  }
136
137
138
139  /**
140   * Writes the specified portion of the provided byte array to all of the
141   * underlying output streams.
142   *
143   * @param  b    The byte array containing the data to be written.
144   * @param  off  The position at which the data to write begins in the array.
145   * @param  len  The number of bytes to b written.
146   */
147  public void write(byte[] b, int off, int len)
148  {
149    for (OutputStream s : targetStreams)
150    {
151      try
152      {
153        s.write(b, off, len);
154      }
155      catch (Exception e)
156      {
157        logger.traceException(e);
158      }
159    }
160  }
161
162
163
164  /**
165   * Writes the specified byte to the set of target output streams.
166   *
167   * @param  b  The byte to be written.
168   */
169  public void write(int b)
170  {
171    for (OutputStream s : targetStreams)
172    {
173      try
174      {
175        s.write(b);
176      }
177      catch (Exception e)
178      {
179        logger.traceException(e);
180      }
181    }
182  }
183}
184