blob: 6bd8cfae4379da0f6b2b2be018e3fe2a917c3e1b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.search;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.ISearchResultListener;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.ITextSearchResult;
import org.eclipse.search.ui.text.Match;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.JavaCore;
/**
* @author Thomas Mäder
*
*/
public class SearchResultUpdater implements IElementChangedListener, ISearchResultListener {
ITextSearchResult fResult;
private static final int REMOVED_FLAGS= IJavaElementDelta.F_MOVED_TO |
IJavaElementDelta.F_REMOVED_FROM_CLASSPATH |
IJavaElementDelta.F_CLOSED |
IJavaElementDelta.F_CONTENT;
public SearchResultUpdater(ITextSearchResult result) {
fResult= result;
NewSearchUI.getSearchManager().addSearchResultListener(this);
JavaCore.addElementChangedListener(this);
// TODO make this work with resources
}
public void elementChanged(ElementChangedEvent event) {
//long t0= System.currentTimeMillis();
IJavaElementDelta delta= event.getDelta();
Set removedElements= new HashSet();
Set potentiallyRemovedElements= new HashSet();
collectRemoved(potentiallyRemovedElements, removedElements, delta);
if (removedElements.size() > 0)
handleRemoved(removedElements, false);
if (potentiallyRemovedElements.size() > 0)
handleRemoved(potentiallyRemovedElements, true);
//System.out.println(this+"handled delta in: "+(System.currentTimeMillis()-t0));
}
private void handleRemoved(Set removedElements, boolean checkExistence) {
Object[] elements= fResult.getElements();
for (int i= 0; i < elements.length; i++) {
if (isContainedInRemoved(removedElements, elements[i])) {
if (elements[i] instanceof IJavaElement) {
IJavaElement je= (IJavaElement)elements[i];
if (!je.exists()) {
//System.out.println("removing: "+je+" in "+fResult.getUserData());
Match[] matches= fResult.getMatches(elements[i]);
for (int j= 0; j < matches.length; j++) {
fResult.removeMatch(matches[j]);
}
}
} else if (elements[i] instanceof IResource) {
IResource resource= (IResource)elements[i];
if (!resource.exists()) {
//System.out.println("removing: "+resource+" in "+fResult.getUserData());
Match[] matches= fResult.getMatches(elements[i]);
for (int j= 0; j < matches.length; j++) {
fResult.removeMatch(matches[j]);
}
}
}
}
}
}
private boolean isContainedInRemoved(Set removedElements, Object object) {
for (Iterator elements= removedElements.iterator(); elements.hasNext();) {
if (isParentOf(elements.next(), object))
return true;
}
return false;
}
/**
* @param object
* @param object2
* @return
*/
private boolean isParentOf(Object ancestor, Object descendant) {
while (descendant != null && !ancestor.equals(descendant))
descendant= getParent(descendant);
return descendant != null;
}
private Object getParent(Object object) {
if (object instanceof IJavaElement)
return ((IJavaElement)object).getParent();
else
return ((IResource)object).getParent();
}
private void collectRemoved(Set potentiallyRemovedSet, Set removedElements, IJavaElementDelta delta) {
if (delta.getKind() == IJavaElementDelta.REMOVED)
removedElements.add(delta.getElement());
else if (delta.getKind() == IJavaElementDelta.CHANGED) {
int flags= delta.getFlags();
if ((flags & REMOVED_FLAGS) != 0) {
potentiallyRemovedSet.add(delta.getElement());
} else {
IJavaElementDelta[] childDeltas= delta.getAffectedChildren();
for (int i= 0; i < childDeltas.length; i++) {
collectRemoved(potentiallyRemovedSet, removedElements, childDeltas[i]);
}
}
}
IResourceDelta[] resourceDeltas= delta.getResourceDeltas();
if (resourceDeltas != null) {
for (int i= 0; i < resourceDeltas.length; i++) {
collectRemovals(removedElements, resourceDeltas[i]);
}
}
}
public void searchResultAdded(ISearchResult search) {
// don't care
}
public void searchResultRemoved(ISearchResult search) {
if (search.equals(fResult))
JavaCore.removeElementChangedListener(this);
}
private void collectRemovals(Set removals, IResourceDelta delta) {
if (delta.getKind() == IResourceDelta.REMOVED)
removals.add(delta.getResource());
else {
IResourceDelta[] children= delta.getAffectedChildren();
for (int i= 0; i < children.length; i++) {
collectRemovals(removals, children[i]);
}
}
}
}