KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > events > ResourceDeltaFactory


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.events;
12
13 import java.util.Map JavaDoc;
14 import org.eclipse.core.internal.dtree.DeltaDataTree;
15 import org.eclipse.core.internal.dtree.NodeComparison;
16 import org.eclipse.core.internal.resources.*;
17 import org.eclipse.core.internal.watson.ElementTree;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResourceDelta;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.Path;
22
23 /**
24  * This class is used for calculating and building resource delta trees for notification
25  * and build purposes.
26  */

27 public class ResourceDeltaFactory {
28     /**
29      * Singleton indicating no delta children
30      */

31     protected static final ResourceDelta[] NO_CHILDREN = new ResourceDelta[0];
32
33     /**
34      * Returns the resource delta representing the changes made between the given old and new trees,
35      * starting from the given root element.
36      * @param markerGeneration the start generation for which deltas should be computed, or -1
37      * if marker deltas should not be provided.
38      */

39     public static ResourceDelta computeDelta(Workspace workspace, ElementTree oldTree, ElementTree newTree, IPath root, long markerGeneration) {
40         //compute the underlying delta tree.
41
ResourceComparator comparator = markerGeneration >= 0 ? ResourceComparator.getNotificationComparator() : ResourceComparator.getBuildComparator();
42         newTree.immutable();
43         DeltaDataTree delta = null;
44         if (Path.ROOT.equals(root))
45             delta = newTree.getDataTree().compareWith(oldTree.getDataTree(), comparator);
46         else
47             delta = newTree.getDataTree().compareWith(oldTree.getDataTree(), comparator, root);
48
49         delta = delta.asReverseComparisonTree(comparator);
50         IPath pathInTree = root.isRoot() ? Path.ROOT : root;
51         IPath pathInDelta = Path.ROOT;
52
53         // get the marker deltas for the delta info object....if needed
54
Map JavaDoc allMarkerDeltas = null;
55         if (markerGeneration >= 0)
56             allMarkerDeltas = workspace.getMarkerManager().getMarkerDeltas(markerGeneration);
57
58         //recursively walk the delta and create a tree of ResourceDelta objects.
59
ResourceDeltaInfo deltaInfo = new ResourceDeltaInfo(workspace, allMarkerDeltas, comparator);
60         ResourceDelta result = createDelta(workspace, delta, deltaInfo, pathInTree, pathInDelta);
61
62         //compute node ID map and fix up moves
63
deltaInfo.setNodeIDMap(computeNodeIDMap(result, new NodeIDMap()));
64         result.fixMovesAndMarkers(oldTree);
65
66         // check all the projects and if they were added and opened then tweek the flags
67
// so the delta reports both.
68
int segmentCount = result.getFullPath().segmentCount();
69         if (segmentCount <= 1)
70             checkForOpen(result, segmentCount);
71         return result;
72     }
73
74     /**
75      * Checks to see if added projects were also opens and tweaks the flags
76      * accordingly. Should only be called for root and projects. Pass the segment count
77      * in since we've already calculated it before.
78      */

79     protected static void checkForOpen(ResourceDelta delta, int segmentCount) {
80         if (delta.getKind() == IResourceDelta.ADDED)
81             if (delta.newInfo.isSet(ICoreConstants.M_OPEN))
82                 delta.status |= IResourceDelta.OPEN;
83         // return for PROJECT
84
if (segmentCount == 1)
85             return;
86         // recurse for ROOT
87
IResourceDelta[] children = delta.children;
88         for (int i = 0; i < children.length; i++)
89             checkForOpen((ResourceDelta) children[i], 1);
90     }
91
92     /**
93      * Creates the map from node id to element id for the old and new states.
94      * Used for recognizing moves. Returns the map.
95      */

96     protected static NodeIDMap computeNodeIDMap(ResourceDelta delta, NodeIDMap nodeIDMap) {
97         IResourceDelta[] children = delta.children;
98         for (int i = 0; i < children.length; i++) {
99             ResourceDelta child = (ResourceDelta) children[i];
100             IPath path = child.getFullPath();
101             switch (child.getKind()) {
102                 case IResourceDelta.ADDED :
103                     nodeIDMap.putNewPath(child.newInfo.getNodeId(), path);
104                     break;
105                 case IResourceDelta.REMOVED :
106                     nodeIDMap.putOldPath(child.oldInfo.getNodeId(), path);
107                     break;
108                 case IResourceDelta.CHANGED :
109                     long oldID = child.oldInfo.getNodeId();
110                     long newID = child.newInfo.getNodeId();
111                     //don't add entries to the map if nothing has changed.
112
if (oldID != newID) {
113                         nodeIDMap.putOldPath(oldID, path);
114                         nodeIDMap.putNewPath(newID, path);
115                     }
116                     break;
117             }
118             //recurse
119
computeNodeIDMap(child, nodeIDMap);
120         }
121         return nodeIDMap;
122     }
123
124     /**
125      * Recursively creates the tree of ResourceDelta objects rooted at
126      * the given path.
127      */

128     protected static ResourceDelta createDelta(Workspace workspace, DeltaDataTree delta, ResourceDeltaInfo deltaInfo, IPath pathInTree, IPath pathInDelta) {
129         // create the delta and fill it with information
130
ResourceDelta result = new ResourceDelta(pathInTree, deltaInfo);
131
132         // fill the result with information
133
NodeComparison compare = (NodeComparison) delta.getData(pathInDelta);
134         int comparison = compare.getUserComparison();
135         result.setStatus(comparison);
136         if (comparison == IResourceDelta.NO_CHANGE || Path.ROOT.equals(pathInTree)) {
137             ResourceInfo info = workspace.getResourceInfo(pathInTree, true, false);
138             result.setOldInfo(info);
139             result.setNewInfo(info);
140         } else {
141             result.setOldInfo((ResourceInfo) compare.getOldData());
142             result.setNewInfo((ResourceInfo) compare.getNewData());
143         }
144         // recurse over the children
145
IPath[] childKeys = delta.getChildren(pathInDelta);
146         int numChildren = childKeys.length;
147         if (numChildren == 0) {
148             result.setChildren(NO_CHILDREN);
149         } else {
150             ResourceDelta[] children = new ResourceDelta[numChildren];
151             for (int i = 0; i < numChildren; i++) {
152                 //reuse the delta path if tree-relative and delta-relative are the same
153
IPath newTreePath = pathInTree == pathInDelta ? childKeys[i] : pathInTree.append(childKeys[i].lastSegment());
154                 children[i] = createDelta(workspace, delta, deltaInfo, newTreePath, childKeys[i]);
155             }
156             result.setChildren(children);
157         }
158
159         // if this delta has children but no other changes, mark it as changed
160
int status = result.status;
161         if ((status & IResourceDelta.ALL_WITH_PHANTOMS) == 0 && numChildren != 0)
162             result.setStatus(status |= IResourceDelta.CHANGED);
163
164         // return the delta
165
return result;
166     }
167
168     /**
169      * Returns an empty build delta describing the fact that no
170      * changes occurred in the given project. The returned delta
171      * is not appropriate for use as a notification delta because
172      * it is rooted at a project, and does not contain marker deltas.
173      */

174     public static IResourceDelta newEmptyDelta(IProject project) {
175         ResourceDelta result = new ResourceDelta(project.getFullPath(), new ResourceDeltaInfo(((Workspace) project.getWorkspace()), null, ResourceComparator.getBuildComparator()));
176         result.setStatus(0);
177         result.setChildren(NO_CHILDREN);
178         ResourceInfo info = ((Project) project).getResourceInfo(true, false);
179         result.setOldInfo(info);
180         result.setNewInfo(info);
181         return result;
182     }
183 }
184
Popular Tags