/******************************************************************************* * Copyright (c) 2008, 2010 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.osgi.internal.serviceregistry; import java.util.*; /** * A Shrinkable Collection. This class provides a wrapper for a list of collections * that allows items to be removed from the wrapped collections (shrinking) but * does not allow items to be added to the wrapped collections. * *

* The collections must act as sets in that each collection in the list * must not have two entries which are equal. * *

* All the optional Collection operations except * add and addAll are supported. Attempting to add to the * collection will result in an UnsupportedOperationException. * */ public class ShrinkableCollection implements Collection { private final Collection collection; private final List> list; public ShrinkableCollection(Collection c) { if (c == null) { throw new NullPointerException(); } @SuppressWarnings("unchecked") List> empty = Collections.EMPTY_LIST; list = empty; collection = c; } public ShrinkableCollection(Collection c1, Collection c2) { list = new ArrayList>(2); list.add(c1); list.add(c2); collection = initComposite(list); } public ShrinkableCollection(List> l) { list = new ArrayList>(l); collection = initComposite(list); } private static Collection initComposite(List> collections) { int size = 0; for (Collection c : collections) { assert verifyNoDuplicates(c); size += c.size(); } Collection result = new ArrayList(size); for (Collection c : collections) { for (E e : c) { if (!result.contains(e)) { result.add(e); } } } return result; } private static boolean verifyNoDuplicates(Collection c) { for (E e : c) { int count = 0; for (E f : c) { if (e == null) { if (f == null) { count++; } } else { if (e.equals(f)) { count++; } } } if (count != 1) { return false; } } return true; } public boolean add(E e) { throw new UnsupportedOperationException(); } public boolean addAll(Collection c) { throw new UnsupportedOperationException(); } public void clear() { collection.clear(); for (Collection c : list) { c.clear(); } } public boolean contains(Object o) { return collection.contains(o); } public boolean containsAll(Collection c) { return collection.containsAll(c); } public boolean isEmpty() { return collection.isEmpty(); } public Iterator iterator() { @SuppressWarnings("unchecked") final Iterator iter = (Iterator) collection.iterator(); final List> collections = list; if (collections.isEmpty()) { return iter; } return new Iterator() { private E last; public boolean hasNext() { return iter.hasNext(); } public E next() { last = iter.next(); return last; } public void remove() { iter.remove(); for (Collection c : collections) { c.remove(last); } } }; } public boolean remove(Object o) { final boolean result = collection.remove(o); if (result) { for (Collection c : list) { c.remove(o); } } return result; } public boolean removeAll(Collection c) { final boolean result = collection.removeAll(c); if (result) { for (Collection cc : list) { cc.removeAll(c); } } return result; } public boolean retainAll(Collection c) { final boolean result = collection.retainAll(c); if (result) { for (Collection cc : list) { cc.retainAll(c); } } return result; } public int size() { return collection.size(); } public Object[] toArray() { return collection.toArray(); } public T[] toArray(T[] var0) { return collection.toArray(var0); } public String toString() { return collection.toString(); } }