001 package org.crsh.util;
002
003 import org.slf4j.Logger;
004 import org.slf4j.LoggerFactory;
005
006 import java.io.Closeable;
007 import java.util.ArrayList;
008 import java.util.concurrent.atomic.AtomicBoolean;
009
010 /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
011 public final class CloseableList implements Closeable {
012
013 /** . */
014 final Logger log = LoggerFactory.getLogger(CloseableList.class);
015
016 /** . */
017 private final ArrayList<Closeable> closeables;
018
019 /** . */
020 private final AtomicBoolean closed;
021
022 public CloseableList() {
023 this.closeables = new ArrayList<Closeable>();
024 this.closed = new AtomicBoolean(false);
025 }
026
027 public boolean isClosed() {
028 return closed.get();
029 }
030
031 /**
032 * Add a closeable to the list.
033 *
034 * @param closeable the closeable to add
035 * @throws IllegalStateException if the list is already closed
036 * @throws NullPointerException if the argument is null
037 */
038 public void add(Closeable closeable) throws IllegalStateException, NullPointerException {
039 if (closed.get()) {
040 throw new IllegalStateException("Already closed");
041 }
042 if (closeable == null) {
043 throw new NullPointerException("No null closeable accepted");
044 }
045 if (!closeables.contains(closeable)) {
046 closeables.add(closeable);
047 }
048 }
049
050 public void close() {
051 if (closed.compareAndSet(false, true)) {
052 for (Closeable closeable : closeables) {
053 log.debug("Closing " + closeable.getClass().getSimpleName());
054 Safe.close(closeable);
055 }
056 }
057 }
058 }