/******************************************************************************* * Copyright (c) 2009 Oracle. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0, which accompanies this distribution * and is available at http://www.eclipse.org/legal/epl-v10.html. * * Contributors: * Oracle - initial API and implementation ******************************************************************************/ package org.eclipse.jpt.common.utility.internal; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; /** * Thread-safe implementation of the {@link Bag} interface. */ public class SynchronizedBag implements Bag, Serializable { /** Backing bag. */ private final Bag bag; /** Object to synchronize on. */ private final Object mutex; private static final long serialVersionUID = 1L; // ********** constructors ********** /** * Construct a synchronized bag that wraps the * specified bag and locks on the specified mutex. */ public SynchronizedBag(Bag bag, Object mutex) { super(); if (bag == null) { throw new NullPointerException(); } this.bag = bag; this.mutex = mutex; } /** * Construct a synchronized bag that wraps the * specified bag and locks on itself. */ public SynchronizedBag(Bag bag) { super(); if (bag == null) { throw new NullPointerException(); } this.bag = bag; this.mutex = this; } /** * Construct a synchronized bag that locks on the specified mutex. */ public SynchronizedBag(Object mutex) { this(new HashBag(), mutex); } /** * Construct a synchronized bag that locks on itself. */ public SynchronizedBag() { this(new HashBag()); } // ********** Bag implementation ********** public boolean add(E o, int count) { synchronized (this.mutex) { return this.bag.add(o, count); } } public int count(Object o) { synchronized (this.mutex) { return this.bag.count(o); } } public Iterator> entries() { synchronized (this.mutex) { return this.bag.entries(); } } public boolean remove(Object o, int count) { synchronized (this.mutex) { return this.bag.remove(o, count); } } public int uniqueCount() { synchronized (this.mutex) { return this.bag.uniqueCount(); } } public Iterator uniqueIterator() { synchronized (this.mutex) { return this.bag.uniqueIterator(); } } // ********** Collection implementation ********** public boolean add(E e) { synchronized (this.mutex) { return this.bag.add(e); } } public boolean addAll(Collection c) { synchronized (this.mutex) { return this.bag.addAll(c); } } public void clear() { synchronized (this.mutex) { this.bag.clear(); } } public boolean contains(Object o) { synchronized (this.mutex) { return this.bag.contains(o); } } public boolean containsAll(Collection c) { synchronized (this.mutex) { return this.bag.containsAll(c); } } public boolean isEmpty() { synchronized (this.mutex) { return this.bag.isEmpty(); } } public Iterator iterator() { synchronized (this.mutex) { return this.bag.iterator(); } } public boolean remove(Object o) { synchronized (this.mutex) { return this.bag.remove(o); } } public boolean removeAll(Collection c) { synchronized (this.mutex) { return this.bag.removeAll(c); } } public boolean retainAll(Collection c) { synchronized (this.mutex) { return this.bag.retainAll(c); } } public int size() { synchronized (this.mutex) { return this.bag.size(); } } public Object[] toArray() { synchronized (this.mutex) { return this.bag.toArray(); } } public T[] toArray(T[] a) { synchronized (this.mutex) { return this.bag.toArray(a); } } // ********** additional public protocol ********** /** * Return the object the stack locks on while performing * its operations. */ public Object getMutex() { return this.mutex; } // ********** Object overrides ********** @Override public String toString() { synchronized (this.mutex) { return this.bag.toString(); } } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { synchronized (this.mutex) { s.defaultWriteObject(); } } }