/** * Copyright (c) 2009 - 2010 AppWork UG(haftungsbeschränkt) <e-mail@appwork.org> * * This file is part of org.appwork.utils.event * * This software is licensed under the Artistic License 2.0, * see the LICENSE file or http://www.opensource.org/licenses/artistic-license-2.0.php * for details */ package org.appwork.utils.event; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; //import java.net.URISyntaxException; //import java.net.URL; import java.util.ArrayList; import java.util.EventListener; //import org.appwork.utils.swing.dialog.Dialog; //import org.appwork.utils.swing.dialog.DialogCanceledException; //import org.appwork.utils.swing.dialog.DialogClosedException; //import org.appwork.utils.swing.dialog.ExtFileChooserDialog; //import org.appwork.utils.swing.dialog.FileChooserSelectionMode; //import org.appwork.utils.swing.dialog.FileChooserType; /** * The Eventsenderclass is the core of the Eventsystem. it can be used to design * new Eventbroadcaster Systems easily. * * Guidelines:<br> * 1. CReate a new MyEventSender extends * org.appwork.utils.event.Eventsender<ListenerType, EventType> <br> * 2. Create MyListenerType extends java.util.EventListener<br> * 3. CReate MyEvent extends org.appwork.utils.event.SimpleEvent<CallerType, * ParameterType, TypeEnumType><br> * * <br> * TypeEnumType is usually a intern enum which defines all available eventtypes * * @author $Author: unknown$ * */ public abstract class Eventsender<ListenerType extends EventListener, EventType extends DefaultEvent> { /** * List of registered Eventlistener */ transient volatile protected java.util.List<ListenerType> strongListeners = null; transient volatile protected java.util.List<WeakReference<ListenerType>> weakListener = null; private final Object LOCK = new Object(); /** * List of Listeners that are requested for removal * */ /** * Creates a new Eventsender Instance */ public Eventsender() { this.strongListeners = new ArrayList<ListenerType>(); this.weakListener = new ArrayList<WeakReference<ListenerType>>(); } /** * Adds a list of listeners * * @param listener */ public void addAllListener(final java.util.List<ListenerType> listener) { this.addAllListener(listener, false); } public void addAllListener(final java.util.List<ListenerType> listener, final boolean weak) { for (final ListenerType l : listener) { this.addListener(l, weak); } } public void addListener(final ListenerType t) { this.addListener(t, false); } /** * Add a single Listener * * @param listener */ public void addListener(final ListenerType t, final boolean weak) { if (t == null) { return; } synchronized (this.LOCK) { boolean added = false; if (weak == false) { /* update strong listeners */ final java.util.List<ListenerType> newStrongListener = new ArrayList<ListenerType>(this.strongListeners); if (!newStrongListener.contains(t)) { newStrongListener.add(t); } this.strongListeners = newStrongListener; } /* update weak listeners */ ListenerType l = null; final java.util.List<WeakReference<ListenerType>> newWeakListener = new ArrayList<WeakReference<ListenerType>>(this.weakListener.size()); for (final WeakReference<ListenerType> listener : this.weakListener) { if ((l = listener.get()) == null) { /* remove weak listener because it is gone */ } else if (l == t) { /* list already contains t, no need to add it again */ added = true; newWeakListener.add(listener); } else { newWeakListener.add(listener); } } if (added == false) { newWeakListener.add(new WeakReference<ListenerType>(t)); } this.weakListener = newWeakListener; } } public void cleanup() { synchronized (this.LOCK) { final java.util.List<WeakReference<ListenerType>> newWeakListener = new ArrayList<WeakReference<ListenerType>>(this.weakListener.size()); for (final WeakReference<ListenerType> listener : this.weakListener) { if (listener.get() == null) { /* weak item is gone */ continue; } else { newWeakListener.add(listener); } } this.weakListener = newWeakListener; } } public boolean containsListener(final ListenerType t) { if (t == null) { return false; } synchronized (this.LOCK) { for (final ListenerType tmp : this.strongListeners) { if (tmp == t) { return true; } } ListenerType l = null; for (final WeakReference<ListenerType> listener : this.weakListener) { if ((l = listener.get()) == null) { /* weak item is gone */ continue; } else if (l == t) { return true; } } return false; } } final public void fireEvent(final EventType event) { if (event == null) { return; } ListenerType t = null; boolean cleanup = false; final java.util.List<WeakReference<ListenerType>> listeners = this.weakListener; for (final WeakReference<ListenerType> listener : listeners) { t = listener.get(); if (t == null) { cleanup = true; continue; } this.fireEvent(t, event); } if (cleanup && listeners.size() > 0) { this.cleanup(); } } /** * Fires an Event to all registered Listeners * * @param event * @return */ final public void fireEvent(final int id, final Object... parameters) { ListenerType t = null; boolean cleanup = false; final java.util.List<WeakReference<ListenerType>> listeners = this.weakListener; for (final WeakReference<ListenerType> listener : listeners) { t = listener.get(); if (t == null) { cleanup = true; continue; } this.fireEvent(t, id, parameters); } if (cleanup && listeners.size() > 0) { this.cleanup(); } } /** * Abstract fire Event Method. * * @param listener * @param event */ protected abstract void fireEvent(ListenerType listener, EventType event); /** * * @param t * @param id * @param parameters */ protected void fireEvent(final ListenerType listener, final int id, final Object... parameters) { throw new RuntimeException("Not implemented. Overwrite org.appwork.utils.event.Eventsender.fireEvent(T, int, Object...) to use this"); } public java.util.List<ListenerType> getListener() { final java.util.List<WeakReference<ListenerType>> listeners = this.weakListener; boolean cleanup = true; final java.util.List<ListenerType> ret = new ArrayList<ListenerType>(listeners.size()); ListenerType t = null; for (final WeakReference<ListenerType> listener : listeners) { t = listener.get(); if (t != null) { ret.add(t); } else { cleanup = true; } } if (cleanup && listeners.size() > 0) { this.cleanup(); } return ret; } public boolean hasListener() { final java.util.List<WeakReference<ListenerType>> listeners = this.weakListener; for (final WeakReference<ListenerType> listener : listeners) { if (listener.get() != null) { return true; } } return false; } public void removeListener(final ListenerType t) { if (t == null) { return; } synchronized (this.LOCK) { ListenerType l = null; final java.util.List<WeakReference<ListenerType>> newWeakListener = new ArrayList<WeakReference<ListenerType>>(this.weakListener.size()); final java.util.List<ListenerType> newStrongListener = new ArrayList<ListenerType>(this.strongListeners); for (final WeakReference<ListenerType> listener : this.weakListener) { if ((l = listener.get()) == null) { /* weak item is gone */ continue; } else if (l != t) { newWeakListener.add(listener); } } /* remove strong item */ newStrongListener.remove(t); this.weakListener = newWeakListener; this.strongListeners = newStrongListener; } } }