/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.nmedit.nomad.core.registry; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import javax.swing.event.EventListenerList; import net.sf.nmedit.nmutils.collections.UnmodifiableIterator; public class Registry<T> implements Iterable<T> { private List<T> items = new ArrayList<T>(); private EventListenerList listenerList = new EventListenerList(); public void add(T item) { if (items.contains(item)) return ; if (items.add(item)) fireItemEvent(item, RegistryEvent.ITEM_REGISTERED); } public void remove(T item) { if (items.remove(item)) { fireItemEvent(item, RegistryEvent.ITEM_UNREGISTERED); } } public int size() { return items.size(); } public void addRegistryListener(RegistryListener l) { listenerList.add(RegistryListener.class, l); } public void removeRegistryListener(RegistryListener l) { listenerList.remove(RegistryListener.class, l); } private void fireItemEvent(T item, int id) { RegistryEvent event = null; // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==RegistryListener.class) { // Lazily create the event: if (event == null) event = new RegistryEvent(this, id, item); RegistryListener l = ((RegistryListener)listeners[i+1]); if (id == RegistryEvent.ITEM_REGISTERED) l.itemRegistered(event); else l.itemUnregistered(event); } } } public Iterator<T> iterator() { return new UnmodifiableIterator<T>(items.iterator()); } public <S extends T> Iterator<S> iterator(final Class<S> clazz) { return new Iterator<S>() { Iterator<T> iter = items.iterator(); S next; public boolean hasNext() { while (next == null && iter.hasNext()) { T n = iter.next(); if (clazz.isInstance(n)) next = clazz.cast(n); } return next != null; } public S next() { if (!hasNext()) throw new NoSuchElementException(); S result = next; next = null; return result; } public void remove() { throw new UnsupportedOperationException(); } }; } }