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 }