All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.internal.events.ResourceChangeListenerList Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.events;

import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.resources.IResourceChangeListener;

/**
 * This class is used to maintain a list of listeners. It is a fairly lightweight object,
 * occupying minimal space when no listeners are registered.
 * 

* Note that the add method checks for and eliminates * duplicates based on identity (not equality). Likewise, the * remove method compares based on identity. *

*

* This implementation is thread safe. The listener list is copied every time * it is modified, so readers do not need to copy or synchronize. This optimizes * for frequent reads and infrequent writes, and assumes that readers can * be trusted not to modify the returned array. */ public class ResourceChangeListenerList { static final class ListenerEntry { final int eventMask; final IResourceChangeListener listener; ListenerEntry(IResourceChangeListener listener, int eventMask) { this.listener = listener; this.eventMask = eventMask; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Listener [eventMask="); //$NON-NLS-1$ sb.append(eventMask); sb.append(", "); //$NON-NLS-1$ sb.append(listener); sb.append("]"); //$NON-NLS-1$ return sb.toString(); } } private volatile int count1 = 0; private volatile int count2 = 0; private volatile int count4 = 0; private volatile int count8 = 0; private volatile int count16 = 0; private volatile int count32 = 0; /** * The list of listeners. */ private final CopyOnWriteArrayList listeners = new CopyOnWriteArrayList<>(); /** * Adds the given listener to this list. If an identical listener is already * registered the mask is updated. * * @param listener the listener * @param mask event types */ public synchronized void add(IResourceChangeListener listener, int mask) { Objects.requireNonNull(listener); if (mask == 0) { remove(listener); return; } ResourceChangeListenerList.ListenerEntry entry = new ResourceChangeListenerList.ListenerEntry(listener, mask); final int oldSize = listeners.size(); // check for duplicates using identity for (int i = 0; i < oldSize; ++i) { ListenerEntry oldEntry = listeners.get(i); if (oldEntry.listener == listener) { removing(oldEntry.eventMask); adding(mask); listeners.set(i, entry); return; } } adding(mask); listeners.add(entry); } private void adding(int mask) { if ((mask & 1) != 0) count1++; if ((mask & 2) != 0) count2++; if ((mask & 4) != 0) count4++; if ((mask & 8) != 0) count8++; if ((mask & 16) != 0) count16++; if ((mask & 32) != 0) count32++; } /** * Returns a copy of the registered listeners. * @return the list of registered listeners that must not be modified */ public ListenerEntry[] getListeners() { return listeners.toArray(ListenerEntry[]::new); } public boolean hasListenerFor(int event) { switch (event) { case 1: return count1 > 0; case 2: return count2 > 0; case 4: return count4 > 0; case 8: return count8 > 0; case 16: return count16 > 0; case 32: return count32 > 0; default: return false; } } /** * Removes the given listener from this list. Has no effect if an identical * listener was not already registered. * * @param listener the listener to remove */ public synchronized void remove(IResourceChangeListener listener) { Objects.requireNonNull(listener); final int oldSize = listeners.size(); for (int i = 0; i < oldSize; ++i) { ListenerEntry oldEntry = listeners.get(i); if (oldEntry.listener == listener) { removing(oldEntry.eventMask); listeners.remove(i); return; } } } public synchronized void clear() { listeners.clear(); count1 = 0; count2 = 0; count4 = 0; count8 = 0; count16 = 0; count32 = 0; } private void removing(int mask) { if ((mask & 1) != 0) count1--; if ((mask & 2) != 0) count2--; if ((mask & 4) != 0) count4--; if ((mask & 8) != 0) count8--; if ((mask & 16) != 0) count16--; if ((mask & 32) != 0) count32--; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("ResourceChangeListenerList ["); //$NON-NLS-1$ if (listeners != null) { builder.append("listeners="); //$NON-NLS-1$ builder.append(listeners.toString()); } builder.append("]"); //$NON-NLS-1$ return builder.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy