/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2008 - 2009, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.util.collection; import java.util.ArrayList; import java.util.Collection; import org.apache.sis.measure.NumberRange; /** * Abstract synchronized list that define notify methods called when * objects are added or removed. * * @author Johann Sorel (Geomatys) * @module */ public abstract class NotifiedCheckedList<E> extends CheckedArrayList<E>{ public NotifiedCheckedList(final Class<E> type) { super(type); } public NotifiedCheckedList(final Class<E> type, final int capacity) { super(type,capacity); } protected abstract void notifyAdd(final E item, int index); protected abstract void notifyAdd(final Collection<? extends E> items, NumberRange<Integer> range); protected abstract void notifyChange(final E oldItem, E newItem, int index); protected abstract void notifyRemove(final E item, int index); protected abstract void notifyRemove(final Collection<? extends E> items, NumberRange<Integer> range); @Override public boolean add(final E element) throws IllegalArgumentException, UnsupportedOperationException { if(element == null) return false; final boolean added = super.add(element); if (added) { final int index = super.size() - 1; notifyAdd(element, index); } return added; } @Override public void add(final int index, final E element) throws IllegalArgumentException, UnsupportedOperationException { super.add(index, element); notifyAdd(element, index); } @Override public E set(int index, E element) throws IllegalArgumentException, UnsupportedOperationException { final E old = super.set(index, element); notifyChange(old, element, index); return old; } @Override public boolean addAll(final Collection<? extends E> collection) throws IllegalArgumentException, UnsupportedOperationException { final int startIndex = super.size(); final boolean added = super.addAll(collection); if (added) { notifyAdd(collection, NumberRange.create(startIndex, true, super.size()-1, true) ); } return added; } @Override public boolean addAll(final int index, final Collection<? extends E> collection) throws IllegalArgumentException, UnsupportedOperationException { final boolean added = super.addAll(index, collection); if (added) { notifyAdd(collection, NumberRange.create(index, true, index + collection.size(), true) ); } return added; } @Override public boolean remove(final Object o) throws UnsupportedOperationException { final int index = super.indexOf(o); if (index >= 0) { super.remove(index); notifyRemove(super.getElementType().cast(o), index ); return true; } return false; } @Override public E remove(final int index) throws UnsupportedOperationException { final E removed = super.remove(index); notifyRemove(removed, index ); return removed; } @Override public boolean removeAll(final Collection<?> c) throws UnsupportedOperationException { //TODO handle remove by collection events if possible // to avoid several calls to remove boolean valid = false; for(final Object i : c){ final boolean val = remove(i); if(val) valid = val; } return valid; } @Override public void clear() throws UnsupportedOperationException { if(!isEmpty()){ final Collection<E> copy = new ArrayList<E>(this); final NumberRange<Integer> range = NumberRange.create(0, true, copy.size()-1, true); super.clear(); notifyRemove(copy, range); } } }