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