private void firePostChangeDelta( IJavaElementDelta deltaToNotify, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) { // post change deltas if (DEBUG) { System.out.println( "FIRING POST_CHANGE Delta [" + Thread.currentThread() + "]:"); // $NON-NLS-1$//$NON-NLS-2$ System.out.println( deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); // $NON-NLS-1$ } if (deltaToNotify != null) { // flush now so as to keep listener reactions to post their own deltas for subsequent // iteration flush(); // // mark the operation stack has not modifying resources since resource deltas are being // fired // JavaModelOperation.setAttribute(JavaModelOperation.HAS_MODIFIED_RESOURCE_ATTR, null); notifyListeners( deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount); } }
private void fireReconcileDelta( IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) { IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values()); if (DEBUG) { System.out.println( "FIRING POST_RECONCILE Delta [" + Thread.currentThread() + "]:"); // $NON-NLS-1$//$NON-NLS-2$ System.out.println( deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); // $NON-NLS-1$ } if (deltaToNotify != null) { // flush now so as to keep listener reactions to post their own deltas for subsequent // iteration this.reconcileDeltas = new HashMap(); notifyListeners( deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount); } }
private void notifyTypeHierarchies(IElementChangedListener[] listeners, int listenerCount) { for (int i = 0; i < listenerCount; i++) { final IElementChangedListener listener = listeners[i]; if (!(listener instanceof TypeHierarchy)) continue; // wrap callbacks with Safe runnable for subsequent listeners to be called when some are // causing grief SafeRunner.run( new ISafeRunnable() { public void handleException(Throwable exception) { Util.log( exception, "Exception occurred in listener of Java element change notification"); // $NON-NLS-1$ } public void run() throws Exception { TypeHierarchy typeHierarchy = (TypeHierarchy) listener; if (typeHierarchy.hasFineGrainChanges()) { // case of changes in primary working copies typeHierarchy.needsRefresh = true; typeHierarchy.fireChange(); } } }); } }
protected void init(IJavaProject project) { if (project == null || !project.exists() || !project.getResource().isAccessible()) throw new IllegalArgumentException("Invalid javaProject"); this.javaProject = project; getURLClassloader(); listener = new IElementChangedListener() { public void elementChanged(final ElementChangedEvent event) { if (ignoreClasspathChanges(event)) return; System.out.println("CLASSPATH CHANGED:" + event); // FIXME should release this classloader // what happend with current objects? we have 1 loader per // project, maybe se can filter some events? to have less // updates curlLoader = null; getURLClassloader(); if (events != null) events.firePropertyChange("classpath", false, true); } }; JavaCore.addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE); }
public static void fire(final ElementChangedEvent extraEvent) { for (int i = 0; i < elementChangedListenerCount; i++) { if ((elementChangedListenerMasks[i] & extraEvent.getType()) != 0) { final IElementChangedListener listener = elementChangedListeners[i]; // wrap callbacks with Safe runnable for subsequent listeners to // be called when some are causing grief SafeRunner.run(new ISafeRunnable() { @Override public void handleException(Throwable exception) { // Util.log(exception, "Exception occurred in listener // of Java element change notification"); //$NON-NLS-1$ } @Override public void run() throws Exception { listener.elementChanged(extraEvent); } }); } } }
public synchronized void removeElementChangedListener(IElementChangedListener listener) { for (int i = 0; i < this.elementChangedListenerCount; i++) { if (this.elementChangedListeners[i] == listener) { // need to clone defensively since we might be in the middle of listener notifications // (#fire) int length = this.elementChangedListeners.length; IElementChangedListener[] newListeners = new IElementChangedListener[length]; System.arraycopy(this.elementChangedListeners, 0, newListeners, 0, i); int[] newMasks = new int[length]; System.arraycopy(this.elementChangedListenerMasks, 0, newMasks, 0, i); // copy trailing listeners int trailingLength = this.elementChangedListenerCount - i - 1; if (trailingLength > 0) { System.arraycopy(this.elementChangedListeners, i + 1, newListeners, i, trailingLength); System.arraycopy(this.elementChangedListenerMasks, i + 1, newMasks, i, trailingLength); } // update manager listener state (#fire need to iterate over original listeners through a // local variable to hold onto // the original ones) this.elementChangedListeners = newListeners; this.elementChangedListenerMasks = newMasks; this.elementChangedListenerCount--; return; } } }
/** * Removes the given element changed listener. Has no affect if an identical listener is not registered. * * @param listener * the listener */ public static void removeElementChangedListener(IElementChangedListener listener) { for (int i = 0; i < elementChangedListenerCount; i++) { if (elementChangedListeners[i] == listener) { // need to clone defensively since we might be in the middle of // listener notifications (#fire) int length = elementChangedListeners.length; IElementChangedListener[] newListeners = new IElementChangedListener[length]; System.arraycopy(elementChangedListeners, 0, newListeners, 0, i); int[] newMasks = new int[length]; System.arraycopy(elementChangedListenerMasks, 0, newMasks, 0, i); // copy trailing listeners int trailingLength = elementChangedListenerCount - i - 1; if (trailingLength > 0) { System.arraycopy(elementChangedListeners, i + 1, newListeners, i, trailingLength); System.arraycopy(elementChangedListenerMasks, i + 1, newMasks, i, trailingLength); } // update manager listener state (#fire need to iterate over // original listeners through a local variable to hold onto // the original ones) elementChangedListeners = newListeners; elementChangedListenerMasks = newMasks; elementChangedListenerCount--; return; } } }
public void fire(IJavaElementDelta customDelta, int eventType) { if (!this.isFiring) return; if (DEBUG) { System.out.println( "-----------------------------------------------------------------------------------------------------------------------"); // $NON-NLS-1$ } IJavaElementDelta deltaToNotify; if (customDelta == null) { deltaToNotify = mergeDeltas(this.javaModelDeltas); } else { deltaToNotify = customDelta; } // Refresh internal scopes if (deltaToNotify != null) { Iterator scopes = this.manager.searchScopes.keySet().iterator(); while (scopes.hasNext()) { AbstractSearchScope scope = (AbstractSearchScope) scopes.next(); scope.processDelta(deltaToNotify, eventType); } JavaWorkspaceScope workspaceScope = this.manager.workspaceScope; if (workspaceScope != null) workspaceScope.processDelta(deltaToNotify, eventType); } // Notification // Important: if any listener reacts to notification by updating the listeners list or mask, // these lists will // be duplicated, so it is necessary to remember original lists in a variable (since field // values may change under us) IElementChangedListener[] listeners; int[] listenerMask; int listenerCount; synchronized (this.state) { listeners = this.state.elementChangedListeners; listenerMask = this.state.elementChangedListenerMasks; listenerCount = this.state.elementChangedListenerCount; } switch (eventType) { case DEFAULT_CHANGE_EVENT: case ElementChangedEvent.POST_CHANGE: firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount); fireReconcileDelta(listeners, listenerMask, listenerCount); break; } }
private void notifyListeners( IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) { final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType); for (int i = 0; i < listenerCount; i++) { if ((listenerMask[i] & eventType) != 0) { final IElementChangedListener listener = listeners[i]; long start = -1; if (VERBOSE) { System.out.print( "Listener #" + (i + 1) + "=" + listener.toString()); // $NON-NLS-1$//$NON-NLS-2$ start = System.currentTimeMillis(); } // wrap callbacks with Safe runnable for subsequent listeners to be called when some are // causing grief SafeRunner.run( new ISafeRunnable() { public void handleException(Throwable exception) { Util.log( exception, "Exception occurred in listener of Java element change notification"); // $NON-NLS-1$ } public void run() throws Exception { PerformanceStats stats = null; if (PERF) { // stats = PerformanceStats.getStats(JavaModelManager.DELTA_LISTENER_PERF, // listener); // stats.startRun(); } listener.elementChanged(extraEvent); if (PERF) { stats.endRun(); } } }); if (VERBOSE) { System.out.println( " -> " + (System.currentTimeMillis() - start) + "ms"); // $NON-NLS-1$ //$NON-NLS-2$ } } } }
/** * Adds the given listener for changes to Java elements. Has no effect if an identical listener is already * registered. * * This listener will only be notified during the POST_CHANGE resource change notification and any reconcile * operation (POST_RECONCILE). For finer control of the notification, use * <code>addElementChangedListener(IElementChangedListener,int)</code>, which allows to specify a different * eventMask. * * @param listener * the listener * @see ElementChangedEvent */ public static void addElementChangedListener(IElementChangedListener listener) { addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE); }