blob: a7749bd731359e79c76a1a89bb94e3db212e48cf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.utility.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.EventListener;
/**
* Maintain a thread-safe list of listeners that does not allow duplicates.
*/
public class ListenerList<L extends EventListener>
implements Serializable
{
private transient volatile L[] listeners;
private static final long serialVersionUID = 1L;
public ListenerList(Class<L> listenerClass) {
super();
this.listeners = this.buildEmptyArray(listenerClass);
}
@SuppressWarnings("unchecked")
private L[] buildEmptyArray(Class<L> listenerClass) {
return (L[]) Array.newInstance(listenerClass, 0);
}
public L[] getListeners() {
return this.listeners;
}
public int size() {
return this.listeners.length;
}
public boolean isEmpty() {
return this.listeners.length == 0;
}
public synchronized void add(L listener) {
if (listener == null) {
throw new NullPointerException();
}
if (CollectionTools.contains(this.listeners, listener)) {
return;//throw new IllegalArgumentException("duplicate listener: " + listener); //$NON-NLS-1$
}
this.listeners = CollectionTools.add(this.listeners, listener);
}
public synchronized void remove(L listener) {
if (listener == null) {
throw new NullPointerException();
}
int index = CollectionTools.indexOf(this.listeners, listener);
if (index == -1) {
return;//throw new IllegalArgumentException("unregistered listener: " + listener); //$NON-NLS-1$
}
this.listeners = CollectionTools.removeElementAtIndex(this.listeners, index);
}
public synchronized void clear() {
this.listeners = CollectionTools.clear(this.listeners);
}
@Override
public String toString() {
return Arrays.toString(this.listeners);
}
// ********** serialization **********
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
// write out any hidden stuff
s.defaultWriteObject();
@SuppressWarnings("unchecked")
Class<L> listenerClass = (Class<L>) this.listeners.getClass().getComponentType();
s.writeObject(listenerClass);
// only write out serializable listeners
for (L listener : this.listeners) {
if (listener instanceof Serializable) {
s.writeObject(listener);
}
}
s.writeObject(null);
}
@SuppressWarnings("unchecked")
private synchronized void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
// read in any hidden stuff
s.defaultReadObject();
Class<L> listenerClass = (Class<L>) s.readObject();
this.listeners = this.buildEmptyArray(listenerClass);
Object o;
while ((o = s.readObject()) != null) {
this.add((L) o);
}
}
}