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

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

There is a newer version: 1.9.1
Show newest version
/* Glazed Lists                                                 (c) 2003-2006 */
/* http://publicobject.com/glazedlists/                      publicobject.com,*/
/*                                                     O'Dell Engineering Ltd.*/
package ca.odell.glazedlists;

// concurrency is similar to java.util.concurrent in J2SE 1.5
import ca.odell.glazedlists.util.concurrent.*;
import ca.odell.glazedlists.event.ListEventListener;
import ca.odell.glazedlists.event.ListEventPublisher;
// Java collections are used for underlying data storage
import java.util.*;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;

/**
 * An {@link EventList} that wraps any simple {@link List}, such as {@link ArrayList}
 * or {@link LinkedList}.
 *
 * 

Unlike most {@link EventList}s, this class is {@link Serializable}. When * {@link BasicEventList} is serialized, all of its elements are serialized * and all of its listeners that implement {@link Serializable}. Upon * deserialization, the new copy uses a different {@link #getReadWriteLock() lock} * than its source {@link BasicEventList}. * *

* * * * * * * *
EventList Overview
Writable:yes
Concurrency:thread ready, not thread safe
Performance:reads: O(1), writes O(1) amortized
Memory:O(N)
Unit Tests:N/A
Issues:N/A
* * @author Jesse Wilson */ public final class BasicEventList extends AbstractEventList implements Serializable { /** For versioning as a {@link Serializable} */ private static final long serialVersionUID = 4883958173323072345L; /** the underlying data list */ private List data; /** * Creates a {@link BasicEventList}. */ public BasicEventList() { this(LockFactory.DEFAULT.createReadWriteLock()); } /** * Creates a {@link BasicEventList} that uses the specified {@link ReadWriteLock} * for concurrent access. */ public BasicEventList(ReadWriteLock readWriteLock) { super(null); this.data = new ArrayList(); this.readWriteLock = readWriteLock; } /** * Creates an empty {@link BasicEventList} with the given * initialCapacity. */ public BasicEventList(int initalCapacity) { super(null); this.data = new ArrayList(initalCapacity); this.readWriteLock = LockFactory.DEFAULT.createReadWriteLock(); } /** * Creates a {@link BasicEventList} that uses the specified {@link List} as * the underlying implementation. * *

Warning: all editing to * the specified {@link List} must be done through via this * {@link BasicEventList} interface. Otherwise this {@link BasicEventList} will * become out of sync and operations will fail. * * @deprecated As of 2005/03/06, this constructor has been declared unsafe * because the source list is exposed. This allows it to be modified without * the required events being fired. This constructor has been replaced by * the factory method {@link GlazedLists#eventList(Collection)}. */ public BasicEventList(List list) { super(null); this.data = list; this.readWriteLock = LockFactory.DEFAULT.createReadWriteLock(); } /** * Creates a {@link BasicEventList} using the specified * {@link ListEventPublisher} and {@link ReadWriteLock}. * * @since 2006-June-12 */ public BasicEventList(ListEventPublisher publisher, ReadWriteLock readWriteLock) { super(publisher); this.data = new ArrayList(); this.readWriteLock = readWriteLock; } /** {@inheritDoc} */ public void add(int index, E element) { // create the change event updates.beginEvent(); updates.addInsert(index); // do the actual add data.add(index, element); // fire the event updates.commitEvent(); } /** {@inheritDoc} */ public boolean add(E element) { // create the change event updates.beginEvent(); updates.addInsert(size()); // do the actual add boolean result = data.add(element); // fire the event updates.commitEvent(); return result; } /** {@inheritDoc} */ public boolean addAll(Collection collection) { return addAll(size(), collection); } /** {@inheritDoc} */ public boolean addAll(int index, Collection collection) { // don't do an add of an empty set if(collection.size() == 0) return false; // create the change event updates.beginEvent(); updates.addInsert(index, index + collection.size() - 1); // do the actual add boolean result = data.addAll(index, collection); // fire the event updates.commitEvent(); return result; } /** {@inheritDoc} */ public E remove(int index) { // create the change event updates.beginEvent(); updates.addDelete(index); // do the actual remove E removed = data.remove(index); // fire the event updates.commitEvent(); return removed; } /** {@inheritDoc} */ public boolean remove(Object element) { int index = data.indexOf(element); if(index == -1) return false; remove(index); return true; } /** {@inheritDoc} */ public void clear() { // don't do a clear on an empty set if(isEmpty()) return; // create the change event updates.beginEvent(); updates.addDelete(0, size() - 1); // do the actual clear data.clear(); // fire the event updates.commitEvent(); } /** {@inheritDoc} */ public E set(int index, E element) { // create the change event updates.beginEvent(); updates.addUpdate(index); // do the actual set E previous = data.set(index, element); // fire the event updates.commitEvent(); return previous; } /** {@inheritDoc} */ public E get(int index) { return data.get(index); } /** {@inheritDoc} */ public int size() { return data.size(); } /** {@inheritDoc} */ public boolean removeAll(Collection collection) { boolean changed = false; updates.beginEvent(); for(Iterator i = collection.iterator(); i.hasNext(); ) { Object value = i.next(); int index = -1; while((index = indexOf(value)) != -1) { updates.addDelete(index); data.remove(index); changed = true; } } updates.commitEvent(); return changed; } /** {@inheritDoc} */ public boolean retainAll(Collection collection) { boolean changed = false; updates.beginEvent(); int index = 0; while(index < data.size()) { if(collection.contains(data.get(index))) { index++; } else { updates.addDelete(index); data.remove(index); changed = true; } } updates.commitEvent(); return changed; } /** * Although {@link EventList}s are not in general, {@link BasicEventList} is * {@link Serializable}. All of the {@link ListEventListener}s that are themselves * {@link Serializable} will be serialized, but others will not. Note that there * is no easy way to access the {@link ListEventListener}s of * an {@link EventList}, particularly after it has been serialized. * *

As of October 3, 2005, this is the wire format of serialized * {@link BasicEventList}s: *

  • An Object[] containing each of the list's elements *
  • A ListEventListener[] containing only the * listeners that themselves implement {@link Serializable}. Those that * do not will not be serialized. Note that {@link TransformedList}s * such as {@link FilterList} are not {@link Serializable} and will not * be serialized. */ private void writeObject(ObjectOutputStream out) throws IOException { // 1. The elements to write E[] elements = (E[])data.toArray(new Object[size()]); // 2. The Listeners to write List> serializableListeners = new ArrayList>(1); for(Iterator> i = updates.getListEventListeners().iterator(); i.hasNext(); ) { ListEventListener listener = i.next(); if(!(listener instanceof Serializable)) continue; serializableListeners.add(listener); } ListEventListener[] listeners = serializableListeners.toArray(new ListEventListener[serializableListeners.size()]); // 3. Write the listeners and elements out.writeObject(elements); out.writeObject(listeners); } /** * Peer method to {@link #writeObject(ObjectOutputStream)}. Note that this * is functionally equivalent to a constructor and should validate that * everything is in place including locks, etc. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // 1. Prepare the EventList helper members this.readWriteLock = LockFactory.DEFAULT.createReadWriteLock(); // 2. Read in the elements E[] elements = (E[])in.readObject(); ListEventListener[] listeners = (ListEventListener[])in.readObject(); // 3. Populate the EventList data this.data = new ArrayList(); this.data.addAll(Arrays.asList(elements)); // 4. Populate the listeners for(int i = 0; i < listeners.length; i++) { this.updates.addListEventListener(listeners[i]); } } }




  • © 2015 - 2024 Weber Informatics LLC | Privacy Policy