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

org.eclipse.core.internal.events.ResourceDeltaFactory 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, 2011 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
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *******************************************************************************/
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.ICoreConstants;
import org.eclipse.core.internal.resources.MarkerSet;
import org.eclipse.core.internal.resources.Project;
import org.eclipse.core.internal.resources.ResourceInfo;
import org.eclipse.core.internal.resources.Workspace;
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;

/**
 * This class is used for calculating and building resource delta trees for notification
 * and build purposes.
 */
public class ResourceDeltaFactory {
	/**
	 * Singleton indicating no delta children
	 */
	protected static final ResourceDelta[] NO_CHILDREN = new ResourceDelta[0];

	/**
	 * Returns the resource delta representing the changes made between the given old and new trees,
	 * starting from the given root element.
	 * @param markerGeneration the start generation for which deltas should be computed, or -1
	 * if marker deltas should not be provided.
	 */
	public static ResourceDelta computeDelta(Workspace workspace, ElementTree oldTree, ElementTree newTree, IPath root, long markerGeneration) {
		//compute the underlying delta tree.
		ResourceComparator comparator = markerGeneration >= 0 ? ResourceComparator.getNotificationComparator() : ResourceComparator.getBuildComparator();
		newTree.immutable();
		DeltaDataTree delta = null;
		if (IPath.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() ? IPath.ROOT : root;
		IPath pathInDelta = IPath.ROOT;

		// get the marker deltas for the delta info object....if needed
		Map allMarkerDeltas = null;
		if (markerGeneration >= 0)
			allMarkerDeltas = workspace.getMarkerManager().getMarkerDeltas(markerGeneration);

		//recursively walk the delta and create a tree of ResourceDelta objects.
		ResourceDeltaInfo deltaInfo = new ResourceDeltaInfo(workspace, allMarkerDeltas, comparator);
		ResourceDelta result = createDelta(workspace, delta, deltaInfo, pathInTree, pathInDelta);

		//compute node ID map and fix up moves
		deltaInfo.setNodeIDMap(computeNodeIDMap(result, new NodeIDMap()));
		result.fixMovesAndMarkers(oldTree);

		// check all the projects and if they were added and opened then tweek the flags
		// so the delta reports both.
		int segmentCount = result.getFullPath().segmentCount();
		if (segmentCount <= 1)
			checkForOpen(result, segmentCount);
		return result;
	}

	/**
	 * Checks to see if added projects were also opens and tweaks the flags
	 * accordingly. Should only be called for root and projects. Pass the segment count
	 * in since we've already calculated it before.
	 */
	protected static void checkForOpen(ResourceDelta delta, int segmentCount) {
		if (delta.getKind() == IResourceDelta.ADDED)
			if (delta.newInfo.isSet(ICoreConstants.M_OPEN))
				delta.status |= IResourceDelta.OPEN;
		// return for PROJECT
		if (segmentCount == 1)
			return;
		// recurse for ROOT
		IResourceDelta[] children = delta.children;
		for (IResourceDelta element : children)
			checkForOpen((ResourceDelta) element, 1);
	}

	/**
	 * Creates the map from node id to element id for the old and new states.
	 * Used for recognizing moves.  Returns the map.
	 */
	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();
					//don't add entries to the map if nothing has changed.
					if (oldID != newID) {
						nodeIDMap.putOldPath(oldID, path);
						nodeIDMap.putNewPath(newID, path);
					}
					break;
			}
			//recurse
			computeNodeIDMap(child, nodeIDMap);
		}
		return nodeIDMap;
	}

	/**
	 * Recursively creates the tree of ResourceDelta objects rooted at
	 * the given path.
	 */
	protected static ResourceDelta createDelta(Workspace workspace, DeltaDataTree delta, ResourceDeltaInfo deltaInfo, IPath pathInTree, IPath pathInDelta) {
		// create the delta and fill it with information
		ResourceDelta result = new ResourceDelta(pathInTree, deltaInfo);

		// fill the result with information
		NodeComparison compare = (NodeComparison) delta.getData(pathInDelta);
		int comparison = compare.getUserComparison();
		result.setStatus(comparison);
		if (comparison == IResourceDelta.NO_CHANGE || IPath.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());
		}
		// recurse over the children
		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++) {
				//reuse the delta path if tree-relative and delta-relative are the same
				IPath newTreePath = pathInTree == pathInDelta ? childKeys[i] : pathInTree.append(childKeys[i].lastSegment());
				children[i] = createDelta(workspace, delta, deltaInfo, newTreePath, childKeys[i]);
			}
			result.setChildren(children);
		}

		// if this delta has children but no other changes, mark it as changed
		int status = result.status;
		if ((status & IResourceDelta.ALL_WITH_PHANTOMS) == 0 && numChildren != 0)
			result.setStatus(status |= IResourceDelta.CHANGED);

		// return the delta
		return result;
	}

	/**
	 * Returns an empty build delta describing the fact that no
	 * changes occurred in the given project.  The returned delta
	 * is not appropriate for use as a notification delta because
	 * it is rooted at a project, and does not contain marker deltas.
	 */
	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;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy