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

}
