All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.odell.glazedlists.PluggableList Maven / Gradle / Ivy

/* Glazed Lists                                                 (c) 2003-2006 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
package ca.odell.glazedlists;

import ca.odell.glazedlists.event.ListEvent;
import ca.odell.glazedlists.event.ListEventPublisher;
import ca.odell.glazedlists.util.concurrent.ReadWriteLock;

/**
 * An {@link EventList} which delegates all List methods to a given source
 * {@link EventList} that may be replaced at runtime using
 * {@link #setSource(EventList)}.
 *
 * 

Note that the source {@link EventList} must use the same * {@link ListEventPublisher} and {@link ReadWriteLock}, particularly if this * {@link EventList} is to be used by multiple threads concurrently. To * construct an {@link EventList} that shares the {@link ListEventPublisher} * and {@link ReadWriteLock} with this {@link PluggableList}, use * {@link #createSourceList()}. * *

Warning: This class is * thread ready but not thread safe. See {@link EventList} for an example * of thread safe code. * *

* * * * * * * *
EventList Overview
Writable:yes
Concurrency:only {@link #setSource(EventList)}
Performance:delegates to source EventList
Memory:N/A
Unit Tests:N/A
Issues:
* * @author James Lemieux */ public class PluggableList extends TransformedList { /** * Constructs a PluggableList which uses the given publisher * and lock. The PluggableList will default to use a * {@link BasicEventList} that also uses the same publisher * and lock. * * @param publisher the {@link ListEventPublisher} to use within the {@link PluggableList} * @param lock the {@link ReadWriteLock} to use within the {@link PluggableList} */ public PluggableList(ListEventPublisher publisher, ReadWriteLock lock) { this(new BasicEventList(publisher, lock)); } /** * Constructs a PluggableList which delegates all List methods to the given * source. At some future time, the source EventList may be * replaced using {@link #setSource(EventList)} and this PluggableList will * produce a {@link ListEvent} describing the change in data. * * @param source the source of data to this PluggableList */ public PluggableList(EventList source) { super(source); source.addListEventListener(this); } /** * Creates a new {@link EventList} that shares its * {@link ca.odell.glazedlists.util.concurrent.ReadWriteLock} and * {@link ca.odell.glazedlists.event.ListEventPublisher} with this * {@link PluggableList}. This is necessary when this {@link PluggableList} * will be used by multiple threads. * *

Note that the created {@link EventList} must be explicitly set as the * source of this {@link PluggableList} using {@link #setSource(EventList)}. * * @return a new EventList appropriate for use as the * {@link #setSource(EventList) source} of this PluggableList */ public EventList createSourceList() { return new BasicEventList(getPublisher(), getReadWriteLock()); } /** * Sets the source EventList to which this PluggableList will delegate all * calls. This method is the entire reason that PluggableList exists. It * allows the data source of the remaining pipeline to be altered. *

* To ensure correct behaviour when this {@link PluggableList} is used by * multiple threads, the given source must * share the same {@link ca.odell.glazedlists.util.concurrent.ReadWriteLock} and * {@link ca.odell.glazedlists.event.ListEventPublisher} with this PluggableList. * * @param source the new source of data for this PluggableList, and all * downstream EventLists * @throws IllegalStateException if this PluggableList is already disposed * @throws IllegalArgumentException if any of the following are true *

    *
  • the given source is null
  • *
  • the given source has a different ListEventPublisher than this PluggableList
  • *
  • the given source has a different ReadWriteLock than this PluggableList
  • *
*/ public void setSource(EventList source) { // lock the pipeline while the source list is swapped getReadWriteLock().writeLock().lock(); try { if (this.source == null) throw new IllegalStateException("setSource may not be called on a disposed PluggableList"); if (source == null) throw new IllegalArgumentException("source may not be null"); if (!getReadWriteLock().equals(source.getReadWriteLock())) throw new IllegalArgumentException("source list must share lock with PluggableList"); if (!getPublisher().equals(source.getPublisher())) throw new IllegalArgumentException("source list must share publisher with PluggableList"); if (this.source == source) return; updates.beginEvent(); // add deletions to the ListEvent for all the elements in the old source for (int i = 0, n = size(); i < n; i++) updates.elementDeleted(0, get(i)); this.source.removeListEventListener(this); this.source = source; this.source.addListEventListener(this); // add insertions to the ListEvent for all the elements in the new source for (int i = 0, n = size(); i < n; i++) updates.elementInserted(i, get(i)); // broadcast the ListEvent that describes the data change updates.commitEvent(); } finally { getReadWriteLock().writeLock().unlock(); } } /** @inheritDoc */ @Override protected boolean isWritable() { return true; } /** @inheritDoc */ @Override public void listChanged(ListEvent listChanges) { updates.forwardEvent(listChanges); } /** @inheritDoc */ @Override public void dispose() { if (source != null) source.removeListEventListener(this); source = null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy