package com.robonobo.common.util; /* * Robonobo Common Utils * Copyright (C) 2008 Will Morton (macavity@well.com) & Ray Hilton (ray@wirestorm.net) * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import java.util.*;; /** * A set that allows add() and remove() to be called while the set is being iterated through. * setIterating(true) must be called before you start iterating through this set, and setIterating(false) * must be called when you have finished. * * @author macavity */ public class IteratorSafeSet extends HashSet { private static final long serialVersionUID = 2219978338396858696L; private boolean isIterating = false; private List toAdd = new ArrayList(); private List toRemove = new ArrayList(); public synchronized void setIterating(boolean isIterating) { this.isIterating = isIterating; if(isIterating == false) { Iterator i = toAdd.iterator(); while(i.hasNext()) add(i.next()); toAdd.clear(); i = toRemove.iterator(); while(i.hasNext()) remove(i.next()); toRemove.clear(); } } public synchronized boolean add(Object o) { if(isIterating) { boolean containedIt = contains(o); toAdd.add(o); return !containedIt; } return super.add(o); } public synchronized boolean addAll(Collection col) { if(isIterating) { boolean modified = false; Iterator i = col.iterator(); while(i.hasNext()) { if(add(i.next())) modified = true; } return modified; } return super.addAll(col); } public synchronized boolean remove(Object o) { if(isIterating) { boolean containedIt = contains(o); toRemove.add(o); return containedIt; } return super.remove(o); } public synchronized boolean removeAll(Collection col) { if(isIterating) { boolean modified = false; Iterator i = col.iterator(); while(i.hasNext()) { if(remove(i.next())) modified = true; } return modified; } return super.removeAll(col); } public synchronized boolean contains(Object o) { if(super.contains(o)) { if(toRemove.contains(o)) return false; else return true; } else { if(toAdd.contains(o)) return true; else return false; } } }