001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.util.cleanup; 006 007import edu.wpi.first.util.ErrorMessages; 008import java.util.ArrayDeque; 009import java.util.Deque; 010 011/** 012 * An object containing a Stack of AutoCloseable objects that are closed when this object is closed. 013 */ 014public class CleanupPool implements AutoCloseable { 015 // Use a Deque instead of a Stack, as Stack's iterators go the wrong way, and docs 016 // state ArrayDeque is faster anyway. 017 private final Deque<AutoCloseable> m_closers = new ArrayDeque<AutoCloseable>(); 018 019 /** 020 * Registers an object in the object stack for cleanup. 021 * 022 * @param <T> The object type 023 * @param object The object to register 024 * @return The registered object 025 */ 026 public <T extends AutoCloseable> T register(T object) { 027 ErrorMessages.requireNonNullParam(object, "object", "register"); 028 m_closers.addFirst(object); 029 return object; 030 } 031 032 /** 033 * Removes an object from the cleanup stack. 034 * 035 * @param object the object to remove 036 */ 037 public void remove(AutoCloseable object) { 038 m_closers.remove(object); 039 } 040 041 /** Closes all objects in the stack. */ 042 @Override 043 @SuppressWarnings("PMD.AvoidCatchingGenericException") 044 public void close() { 045 for (AutoCloseable autoCloseable : m_closers) { 046 try { 047 autoCloseable.close(); 048 } catch (Exception e) { 049 // Swallow any exceptions on close 050 e.printStackTrace(); 051 } 052 } 053 m_closers.clear(); 054 } 055}