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<>(); 018 019 /** Default constructor. */ 020 public CleanupPool() {} 021 022 /** 023 * Registers an object in the object stack for cleanup. 024 * 025 * @param <T> The object type 026 * @param object The object to register 027 * @return The registered object 028 */ 029 public <T extends AutoCloseable> T register(T object) { 030 ErrorMessages.requireNonNullParam(object, "object", "register"); 031 m_closers.addFirst(object); 032 return object; 033 } 034 035 /** 036 * Removes an object from the cleanup stack. 037 * 038 * @param object the object to remove 039 */ 040 public void remove(AutoCloseable object) { 041 m_closers.remove(object); 042 } 043 044 /** Closes all objects in the stack. */ 045 @Override 046 @SuppressWarnings("PMD.AvoidCatchingGenericException") 047 public void close() { 048 for (AutoCloseable autoCloseable : m_closers) { 049 try { 050 autoCloseable.close(); 051 } catch (Exception e) { 052 // Swallow any exceptions on close 053 e.printStackTrace(); 054 } 055 } 056 m_closers.clear(); 057 } 058}