/* NotableLinkedList.java Purpose: Description: History: Fri Sep 10 09:03:59 TST 2010, Created by tomyeh Copyright (C) 2010 Potix Corporation. All Rights Reserved. */ package org.zkoss.util; import java.util.List; import java.util.ListIterator; import java.util.LinkedList; import java.util.AbstractSequentialList; /** * Linked list implementation of the <tt>List</tt> interface * that provides the callback methods such as {@link #onAdd}, {@link #onSet} * and {@link #onRemove}. * @author tomyeh * @since 5.0.8 */ public class NotableLinkedList<E> extends AbstractSequentialList<E> implements List<E>, Cloneable, java.io.Serializable { private final LinkedList<E> _list = new LinkedList<E>(); public NotableLinkedList() { } public int size() { return _list.size(); } public ListIterator<E> listIterator(int index) { return new ListIter(index); } /** Called each time an new element is about being added into the array. * * <p>Deriving classes usually put checking codes here. * And, throws exception if failure and nothing will be affected. * * @param newElement the element to be added * @param followingElement the element that will 'follow' the new element. * In other words, newElement will be inserted <b>before</b> * followingElement. If null, it means newElement is appended at the end */ protected void onAdd(E newElement, E followingElement) { } /** Called each time an element is about being assigned into the array * and replace an existence one (by ListIterator.set). * * <p>Deriving classes usually put checking codes here. * And, throws exception if failure and nothing will be affected. * * @param newElement the element to be added * @param replaced the element to be replaced */ protected void onSet(E newElement, E replaced) { } /** Called each time an element is about being removed from the array. * Deriving classes usually put checking codes here. * And, throws exception if failure. */ protected void onRemove(E element) { } private class ListIter implements ListIterator<E> { private final ListIterator<E> _iter; private E _last; private boolean _lastReady; private ListIter(int index) { _iter = _list.listIterator(index); } public void add(E o) { final E nxt; if (hasNext()) { nxt = next(); previous(); } else { nxt = null; } onAdd(o, nxt); _iter.add(o); } public boolean hasNext() { return _iter.hasNext(); } public boolean hasPrevious() { return _iter.hasPrevious(); } public E next() { _last = _iter.next(); _lastReady = true; return _last; } public E previous() { _last = _iter.previous(); _lastReady = true; return _last; } public int nextIndex() { return _iter.nextIndex(); } public int previousIndex() { return _iter.previousIndex(); } public void remove() { if (_lastReady) onRemove(_last); _iter.remove(); _lastReady = false; } public void set(E o) { if (_lastReady) onSet(o, _last); _iter.set(o); } } }