/* 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);
}
}
}