/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.sokan.index.notify; import java.util.LinkedHashSet; import java.util.Set; import org.reuseware.sokan.ID; import org.reuseware.sokan.index.LoopBreaker; /** * The index notifier manages the index listeners and can * be instructed to inform all listeners about an update. */ public class IndexNotifier extends LoopBreaker { private Set<IndexListener> allListeners; private Set<IndexListener> activeListeners; /** * The constructor. */ public IndexNotifier() { super(); allListeners = new LinkedHashSet<IndexListener>(); activeListeners = new LinkedHashSet<IndexListener>(); } /** * Registers the given index listener. * * @param listener the index listener */ public void add(IndexListener listener) { allListeners.add(listener); } /** * Unregisters the given index listener. * * @param listener the index listener */ public void remove(IndexListener listener) { allListeners.remove(listener); activeListeners.remove(listener); } /** * Notifies all registered indexers that the indexed information of * all artifacts with the given IDs have been updated. * * @param delta the updated artifact IDs */ public void notifyListeners(Set<ID> delta) { if (allListeners.isEmpty() || delta.isEmpty()) { return; } Object last = super.lastCallee; if (checkForInvokationLoop()) { activeListeners.add((IndexListener) last); return; } boolean goOn; do { goOn = false; Set<IndexListener> toNotify; toNotify = new LinkedHashSet<IndexListener>(); toNotify.addAll(activeListeners); toNotify.addAll(allListeners); for (IndexListener listener : toNotify) { if (super.wasCalledBefore(listener)) { continue; } listener.indexChanged(delta); if (super.thisCausedInvokationLoop()) { goOn = true; break; } } } while (goOn); } }