package org.eclipse.core.internal.events;
import java.util.Map;
import org.eclipse.core.internal.dtree.DeltaDataTree;
import org.eclipse.core.internal.dtree.NodeComparison;
import org.eclipse.core.internal.resources.*;
import org.eclipse.core.internal.watson.ElementTree;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
public class ResourceDeltaFactory {
protected static final ResourceDelta[] NO_CHILDREN = new ResourceDelta[0];
public static ResourceDelta computeDelta(Workspace workspace, ElementTree oldTree, ElementTree newTree, IPath root, long markerGeneration) {
ResourceComparator comparator = markerGeneration >= 0 ? ResourceComparator.getNotificationComparator() : ResourceComparator.getBuildComparator();
newTree.immutable();
DeltaDataTree delta = null;
if (Path.ROOT.equals(root))
delta = newTree.getDataTree().compareWith(oldTree.getDataTree(), comparator);
else
delta = newTree.getDataTree().compareWith(oldTree.getDataTree(), comparator, root);
delta = delta.asReverseComparisonTree(comparator);
IPath pathInTree = root.isRoot() ? Path.ROOT : root;
IPath pathInDelta = Path.ROOT;
Map<IPath, MarkerSet> allMarkerDeltas = null;
if (markerGeneration >= 0)
allMarkerDeltas = workspace.getMarkerManager().getMarkerDeltas(markerGeneration);
ResourceDeltaInfo deltaInfo = new ResourceDeltaInfo(workspace, allMarkerDeltas, comparator);
ResourceDelta result = createDelta(workspace, delta, deltaInfo, pathInTree, pathInDelta);
deltaInfo.setNodeIDMap(computeNodeIDMap(result, new NodeIDMap()));
result.fixMovesAndMarkers(oldTree);
int segmentCount = result.getFullPath().segmentCount();
if (segmentCount <= 1)
checkForOpen(result, segmentCount);
return result;
}
protected static void checkForOpen(ResourceDelta delta, int segmentCount) {
if (delta.getKind() == IResourceDelta.ADDED)
if (delta.newInfo.isSet(ICoreConstants.M_OPEN))
delta.status |= IResourceDelta.OPEN;
if (segmentCount == 1)
return;
IResourceDelta[] children = delta.children;
for (IResourceDelta element : children)
checkForOpen((ResourceDelta) element, 1);
}
protected static NodeIDMap computeNodeIDMap(ResourceDelta delta, NodeIDMap nodeIDMap) {
IResourceDelta[] children = delta.children;
for (IResourceDelta element : children) {
ResourceDelta child = (ResourceDelta) element;
IPath path = child.getFullPath();
switch (child.getKind()) {
case IResourceDelta.ADDED :
nodeIDMap.putNewPath(child.newInfo.getNodeId(), path);
break;
case IResourceDelta.REMOVED :
nodeIDMap.putOldPath(child.oldInfo.getNodeId(), path);
break;
case IResourceDelta.CHANGED :
long oldID = child.oldInfo.getNodeId();
long newID = child.newInfo.getNodeId();
if (oldID != newID) {
nodeIDMap.putOldPath(oldID, path);
nodeIDMap.putNewPath(newID, path);
}
break;
}
computeNodeIDMap(child, nodeIDMap);
}
return nodeIDMap;
}
protected static ResourceDelta createDelta(Workspace workspace, DeltaDataTree delta, ResourceDeltaInfo deltaInfo, IPath pathInTree, IPath pathInDelta) {
ResourceDelta result = new ResourceDelta(pathInTree, deltaInfo);
NodeComparison compare = (NodeComparison) delta.getData(pathInDelta);
int comparison = compare.getUserComparison();
result.setStatus(comparison);
if (comparison == IResourceDelta.NO_CHANGE || Path.ROOT.equals(pathInTree)) {
ResourceInfo info = workspace.getResourceInfo(pathInTree, true, false);
result.setOldInfo(info);
result.setNewInfo(info);
} else {
result.setOldInfo((ResourceInfo) compare.getOldData());
result.setNewInfo((ResourceInfo) compare.getNewData());
}
IPath[] childKeys = delta.getChildren(pathInDelta);
int numChildren = childKeys.length;
if (numChildren == 0) {
result.setChildren(NO_CHILDREN);
} else {
ResourceDelta[] children = new ResourceDelta[numChildren];
for (int i = 0; i < numChildren; i++) {
IPath newTreePath = pathInTree == pathInDelta ? childKeys[i] : pathInTree.append(childKeys[i].lastSegment());
children[i] = createDelta(workspace, delta, deltaInfo, newTreePath, childKeys[i]);
}
result.setChildren(children);
}
int status = result.status;
if ((status & IResourceDelta.ALL_WITH_PHANTOMS) == 0 && numChildren != 0)
result.setStatus(status |= IResourceDelta.CHANGED);
return result;
}
public static IResourceDelta newEmptyDelta(IProject project) {
ResourceDelta result = new ResourceDelta(project.getFullPath(), new ResourceDeltaInfo(((Workspace) project.getWorkspace()), null, ResourceComparator.getBuildComparator()));
result.setStatus(0);
result.setChildren(NO_CHILDREN);
ResourceInfo info = ((Project) project).getResourceInfo(true, false);
result.setOldInfo(info);
result.setNewInfo(info);
return result;
}
}