X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java index ac3dd0f..ae314b3 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java @@ -12,16 +12,23 @@ package net.sourceforge.phpdt.internal.core; import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import net.sourceforge.phpdt.core.ElementChangedEvent; +import net.sourceforge.phpdt.core.IClasspathEntry; +import net.sourceforge.phpdt.core.IElementChangedListener; import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaElementDelta; +import net.sourceforge.phpdt.core.IJavaModel; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -31,8 +38,18 @@ import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.QualifiedName; +import net.sourceforge.phpdt.internal.core.builder.PHPBuilder; + +import net.sourceforge.phpdt.internal.core.DeltaProcessingState; +import net.sourceforge.phpdt.internal.core.JavaElementDelta; +import net.sourceforge.phpdt.internal.core.JavaModelManager; +import net.sourceforge.phpdt.internal.core.util.Util; /** @@ -53,8 +70,11 @@ public class DeltaProcessor implements IResourceChangeListener { final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$ final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$ - final static int NON_JAVA_RESOURCE = -1; + private final static int NON_JAVA_RESOURCE = -1; + public static boolean DEBUG = false; + public static boolean VERBOSE = false; + public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks /** * The JavaElementDelta corresponding to the IResourceDelta being translated. */ @@ -88,14 +108,38 @@ public class DeltaProcessor implements IResourceChangeListener { * This is used as a stack of java elements (using getParent() to pop it, and * using the various get*(...) to push it. */ Openable currentElement; - + /* + * Queue of deltas created explicily by the Java Model that + * have yet to be fired. + */ + public ArrayList javaModelDeltas= new ArrayList(); + /* + * Queue of reconcile deltas on working copies that have yet to be fired. + * This is a table form IWorkingCopy to IJavaElementDelta + */ + public HashMap reconcileDeltas = new HashMap(); + + /* + * Turns delta firing on/off. By default it is on. + */ + private boolean isFiring= true; + + public HashMap externalTimeStamps = new HashMap(); public HashSet projectsToUpdate = new HashSet(); // list of root projects which namelookup caches need to be updated for dependents // TODO: (jerome) is it needed? projectsToUpdate might be sufficient public HashSet projectsForDependentNamelookupRefresh = new HashSet(); - JavaModelManager manager; + /* + * The global state of delta processing. + */ + private DeltaProcessingState state; + + /* + * The Java model manager + */ + private JavaModelManager manager; /* A table from IJavaProject to an array of IPackageFragmentRoot. * This table contains the pkg fragment roots of the project that are being deleted. @@ -107,7 +151,6 @@ public class DeltaProcessor implements IResourceChangeListener { * This is null if no refresh is needed. */ HashSet refreshedElements; - public static boolean VERBOSE = false; class OutputsInfo { IPath[] paths; @@ -185,10 +228,19 @@ public class DeltaProcessor implements IResourceChangeListener { } } - DeltaProcessor(JavaModelManager manager) { +// DeltaProcessor(JavaModelManager manager) { +// this.manager = manager; +// } + + /* + * Type of event that should be processed no matter what the real event type is. + */ + public int overridenEventType = -1; + + public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) { + this.state = state; this.manager = manager; } - /* * Adds the dependents of the given project to the list of the projects * to update. @@ -1061,75 +1113,75 @@ public class DeltaProcessor implements IResourceChangeListener { return file.lastModified() + file.length(); } -// public void initializeRoots() { -// // remember roots infos as old roots infos -// this.oldRoots = this.roots == null ? new HashMap() : this.roots; -// this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots; -// -// // recompute root infos only if necessary -// if (!rootsAreStale) return; -// -// this.roots = new HashMap(); -// this.otherRoots = new HashMap(); -// this.sourceAttachments = new HashMap(); -// -// IJavaModel model = this.manager.getJavaModel(); -// IJavaProject[] projects; -// try { -// projects = model.getJavaProjects(); -// } catch (JavaModelException e) { -// // nothing can be done -// return; -// } -// for (int i = 0, length = projects.length; i < length; i++) { -// IJavaProject project = projects[i]; -// IClasspathEntry[] classpath; -// try { -// classpath = project.getResolvedClasspath(true); -// } catch (JavaModelException e) { -// // continue with next project -// continue; -// } -// for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) { -// IClasspathEntry entry = classpath[j]; -// if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; -// - // root path -// IPath path = entry.getPath(); -// if (this.roots.get(path) == null) { -// this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); -// } else { -// ArrayList rootList = (ArrayList)this.otherRoots.get(path); -// if (rootList == null) { -// rootList = new ArrayList(); -// this.otherRoots.put(path, rootList); -// } -// rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); -// } -// -// // source attachment path -// if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue; -// QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$; -// String propertyString = null; -// try { -// propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); -// } catch (CoreException e) { -// continue; -// } -// IPath sourceAttachmentPath; + public void initializeRoots() { + // remember roots infos as old roots infos + this.oldRoots = this.roots == null ? new HashMap() : this.roots; + this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots; + + // recompute root infos only if necessary + if (!rootsAreStale) return; + + this.roots = new HashMap(); + this.otherRoots = new HashMap(); + this.sourceAttachments = new HashMap(); + + IJavaModel model = this.manager.getJavaModel(); + IJavaProject[] projects; + try { + projects = model.getJavaProjects(); + } catch (JavaModelException e) { + // nothing can be done + return; + } + for (int i = 0, length = projects.length; i < length; i++) { + IJavaProject project = projects[i]; + IClasspathEntry[] classpath; + try { + classpath = project.getResolvedClasspath(true); + } catch (JavaModelException e) { + // continue with next project + continue; + } + for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) { + IClasspathEntry entry = classpath[j]; + if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue; + +// root path + IPath path = entry.getPath(); + if (this.roots.get(path) == null) { + this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); + } else { + ArrayList rootList = (ArrayList)this.otherRoots.get(path); + if (rootList == null) { + rootList = new ArrayList(); + this.otherRoots.put(path, rootList); + } + rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars())); + } + + // source attachment path + if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue; + QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$; + String propertyString = null; + try { + propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName); + } catch (CoreException e) { + continue; + } + IPath sourceAttachmentPath; // if (propertyString != null) { // int index= propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER); // sourceAttachmentPath = (index < 0) ? new Path(propertyString) : new Path(propertyString.substring(0, index)); // } else { -// sourceAttachmentPath = entry.getSourceAttachmentPath(); + sourceAttachmentPath = entry.getSourceAttachmentPath(); // } -// if (sourceAttachmentPath != null) { -// this.sourceAttachments.put(sourceAttachmentPath, path); -// } -// } -// } -// this.rootsAreStale = false; -// } + if (sourceAttachmentPath != null) { + this.sourceAttachments.put(sourceAttachmentPath, path); + } + } + } + this.rootsAreStale = false; + } /* * Returns whether a given delta contains some information relevant to the JavaModel, @@ -1198,7 +1250,73 @@ public class DeltaProcessor implements IResourceChangeListener { } return false; } - + /* + * Merges all awaiting deltas. + */ + private IJavaElementDelta mergeDeltas(Collection deltas) { + if (deltas.size() == 0) return null; + if (deltas.size() == 1) return (IJavaElementDelta)deltas.iterator().next(); + + if (VERBOSE) { + System.out.println("MERGING " + deltas.size() + " DELTAS ["+Thread.currentThread()+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + Iterator iterator = deltas.iterator(); + JavaElementDelta rootDelta = new JavaElementDelta(this.manager.javaModel); + boolean insertedTree = false; + while (iterator.hasNext()) { + JavaElementDelta delta = (JavaElementDelta)iterator.next(); + if (VERBOSE) { + System.out.println(delta.toString()); + } + IJavaElement element = delta.getElement(); + if (this.manager.javaModel.equals(element)) { + IJavaElementDelta[] children = delta.getAffectedChildren(); + for (int j = 0; j < children.length; j++) { + JavaElementDelta projectDelta = (JavaElementDelta) children[j]; + rootDelta.insertDeltaTree(projectDelta.getElement(), projectDelta); + insertedTree = true; + } + IResourceDelta[] resourceDeltas = delta.getResourceDeltas(); + if (resourceDeltas != null) { + for (int i = 0, length = resourceDeltas.length; i < length; i++) { + rootDelta.addResourceDelta(resourceDeltas[i]); + insertedTree = true; + } + } + } else { + rootDelta.insertDeltaTree(element, delta); + insertedTree = true; + } + } + if (insertedTree) return rootDelta; + return null; + } + 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 + Platform.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 { + listener.elementChanged(extraEvent); + } + }); + if (VERBOSE) { + System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + } /** * Generic processing for elements with changed contents: