com.gemstone.gemfire.internal.io.CompositeOutputStream Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.internal.io;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* Delegates all operations to a collection of OutputStreams.
*
* @author Kirk Lund
* @since 7.0
*/
public class CompositeOutputStream extends OutputStream implements Iterable {
protected final Object lock = new Object();
private volatile Set streams = Collections.emptySet();
/**
* Constructs a new instance of CompositeOutputStream with zero or more OutputStreams.
*
* @param out zero or more OutputStreams to add to the new instance of CompositeOutputStream
*/
public CompositeOutputStream(OutputStream... out) {
final Set newSet = new HashSet();
for (OutputStream stream : out) {
newSet.add(stream);
}
this.streams = newSet;
}
/**
* @return true if this CompositeOutputStream did not already contain the specified OutputStream
*/
public boolean addOutputStream(OutputStream out) {
synchronized(this.lock) {
final Set oldSet = this.streams;
if (oldSet.contains(out)) {
return false;
} else {
final Set newSet = new HashSet(oldSet);
final boolean added = newSet.add(out);
this.streams = newSet;
return added;
}
}
}
/**
* @return true if this CompositeOutputStream contained the specified OutputStream
*/
public boolean removeOutputStream(OutputStream out) {
synchronized(this.lock) {
final Set oldSet = this.streams;
if (!oldSet.contains(out)) {
return false;
} else if (oldSet.size() == 1) {
this.streams = Collections.emptySet();
return true;
} else {
final Set newSet = new HashSet(oldSet);
final boolean removed = newSet.remove(out);
this.streams = newSet;
return removed;
}
}
}
/**
* Returns true if this CompositeOutputStream contains no OutputStreams.
*
* @return true if this CompositeOutputStream contains no OutputStreams
*/
public boolean isEmpty() {
return this.streams.isEmpty();
}
/**
* Returns the number of OutputStreams in this CompositeOutputStream (its cardinality).
*
* @return the number of OutputStreams in this CompositeOutputStream (its cardinality)
*/
public int size() {
return this.streams.size();
}
public Iterator iterator() {
return this.streams.iterator();
}
/**
* Writes the specified byte
to this output stream.
*
* The write
method of FilterOutputStream
* calls the write
method of its underlying output stream,
* that is, it performs out.write(b).
*
* Implements the abstract write method of OutputStream.
*
* @param b the byte
.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
Set outputStreams = this.streams;
for (OutputStream out : outputStreams) {
out.write(b);
}
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be written out to the stream.
*
* The flush
method of FilterOutputStream
* calls the flush
method of its underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public void flush() throws IOException {
Set outputStreams = this.streams;
for (OutputStream out : outputStreams) {
out.flush();
}
}
/**
* Closes this output stream and releases any system resources
* associated with the stream.
*
* The close
method of FilterOutputStream
* calls its flush
method, and then calls the
* close
method of its underlying output stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#flush()
* @see java.io.FilterOutputStream#out
*/
public void close() throws IOException {
Set outputStreams = this.streams;
for (OutputStream out : outputStreams) {
try {
out.flush();
} catch (IOException ignored) {
}
out.close();
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder(getClass().getSimpleName());
sb.append("@").append(System.identityHashCode(this)).append("{");
sb.append("size=").append(this.streams.size());
return sb.append("}").toString();
}
}