NotifyingTable.java

package org.microspace.table;

import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;

import org.microspace.specific.CurrentTimeProvider;
import org.microspace.table.column.Accessor;

/**
 * Same as normal table, but it can have listeners to notify data changes.
 * @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
 * @version 2012-06-23
 */
public class NotifyingTable<T> extends SimpleUnsafeTable<T> {
	
	LinkedList<WeakReference<TableListener<T>>> listeners = new LinkedList<WeakReference<TableListener<T>>> ();

	public NotifyingTable(Accessor<T> accessor, CurrentTimeProvider currentTimeProvider) {
		super(accessor, currentTimeProvider);
	}

	public NotifyingTable(Class<T> clazz, CurrentTimeProvider currentTimeProvider) {
		super(clazz, currentTimeProvider);
	}
	
	public void addTableListener (TableListener<T> listener){
		listeners.add(new WeakReference<TableListener<T>> (listener));
	}
	
	public void removeTableListener (TableListener<T> listener) {
		Iterator<WeakReference<TableListener<T>>> iterator = listeners.iterator();
		while (iterator.hasNext()) {
			WeakReference<TableListener<T>> wref = iterator.next();
			TableListener<T> l = wref.get();
			if (l == null || l == listener) iterator.remove();
		}
	}

	@Override
	public void setEntry(Entry<T> container) {
		fireTableChangeEvent (getEntry(container.getPrimaryKey()), container);
		super.setEntry(container);
	}
	
	private void fireTableChangeEvent (Entry<T> oldEntry, Entry<T> newEntry) {
		Iterator<WeakReference<TableListener<T>>> iterator = listeners.iterator();
		while (iterator.hasNext()) {
			WeakReference<TableListener<T>> wref = iterator.next();
			TableListener<T> l = wref.get();
			if (l == null) {
				iterator.remove();
				continue;
			}
			l.tableChangeEvent(this, oldEntry, newEntry);
		}
	}

}