KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > mapping > CompoundResourceTraversal


1 /*******************************************************************************
2  * Copyright (c) 2006 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.team.internal.core.mapping;
12
13 import java.util.*;
14
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.resources.mapping.ResourceTraversal;
17 import org.eclipse.core.runtime.IPath;
18
19 /**
20  * Helper class that accumulates several traversals in order
21  * to generate a final set of traversals and to perform certain
22  * queries on a set of traversals.
23  */

24 public class CompoundResourceTraversal {
25     
26     private Set deepFolders = new HashSet();
27     private Set shallowFolders = new HashSet();
28     private Set zeroFolders = new HashSet();
29     private Set files = new HashSet();
30     
31     public synchronized void addTraversals(ResourceTraversal[] traversals) {
32         for (int i = 0; i < traversals.length; i++) {
33             ResourceTraversal traversal = traversals[i];
34             addTraversal(traversal);
35         }
36     }
37
38     public synchronized void addTraversal(ResourceTraversal traversal) {
39         IResource[] resources = traversal.getResources();
40         for (int i = 0; i < resources.length; i++) {
41             IResource resource = resources[i];
42             addResource(resource, traversal.getDepth());
43         }
44     }
45
46     public synchronized void addResource(IResource resource, int depth) {
47         if (resource.getType() == IResource.FILE) {
48             if (!isCovered(resource, IResource.DEPTH_ZERO))
49                 files.add(resource);
50         }
51         switch (depth) {
52         case IResource.DEPTH_INFINITE:
53             addDeepFolder(resource);
54             break;
55         case IResource.DEPTH_ONE:
56             addShallowFolder(resource);
57             break;
58         case IResource.DEPTH_ZERO:
59             addZeroFolder(resource);
60             break;
61         }
62     }
63
64     private void addShallowFolder(IResource resource) {
65         if (!isCovered(resource, IResource.DEPTH_ONE)) {
66             shallowFolders.add(resource);
67             removeDescendants(resource, IResource.DEPTH_ONE);
68         }
69     }
70
71     public synchronized boolean isCovered(IResource resource, int depth) {
72         IPath fullPath = resource.getFullPath();
73         // Regardless of the depth, look for a deep folder that covers the resource
74
for (Iterator iter = deepFolders.iterator(); iter.hasNext();) {
75             IResource deepFolder = (IResource) iter.next();
76             if (deepFolder.getFullPath().isPrefixOf(fullPath)) {
77                 return true;
78             }
79         }
80         // For files, look in the shallow folders and files
81
if (resource.getType() == IResource.FILE) {
82             return (shallowFolders.contains(resource.getParent()) || files.contains(resource));
83         }
84         // For folders, look in appropriate sets
85
switch (depth) {
86         case IResource.DEPTH_ONE:
87             return (shallowFolders.contains(resource));
88         case IResource.DEPTH_ZERO:
89             return (shallowFolders.contains(resource.getParent()) || zeroFolders.contains(resource));
90         }
91         return false;
92     }
93
94     private void addZeroFolder(IResource resource) {
95         if (!isCovered(resource, IResource.DEPTH_ZERO))
96             zeroFolders.add(resource);
97     }
98
99     private void addDeepFolder(IResource resource) {
100         if (!isCovered(resource, IResource.DEPTH_INFINITE)) {
101             deepFolders.add(resource);
102             removeDescendants(resource, IResource.DEPTH_INFINITE);
103         }
104     }
105
106     private void removeDescendants(IResource resource, int depth) {
107         IPath fullPath = resource.getFullPath();
108         // First, remove any files that are now covered
109
for (Iterator iter = files.iterator(); iter.hasNext();) {
110             IResource child = (IResource) iter.next();
111             switch (depth) {
112             case IResource.DEPTH_INFINITE:
113                 if (fullPath.isPrefixOf(child.getFullPath())) {
114                     iter.remove();
115                 }
116                 break;
117             case IResource.DEPTH_ONE:
118                 if (fullPath.equals(child.getFullPath().removeLastSegments(1))) {
119                     iter.remove();
120                 }
121                 break;
122             }
123         }
124         // Now, remove any shallow folders
125
if (depth == IResource.DEPTH_INFINITE) {
126             for (Iterator iter = shallowFolders.iterator(); iter.hasNext();) {
127                 IResource child = (IResource) iter.next();
128                 if (fullPath.isPrefixOf(child.getFullPath())) {
129                     iter.remove();
130                 }
131             }
132         }
133         // Finally, remove any zero folders
134
for (Iterator iter = zeroFolders.iterator(); iter.hasNext();) {
135             IResource child = (IResource) iter.next();
136             switch (depth) {
137             case IResource.DEPTH_INFINITE:
138                 if (fullPath.isPrefixOf(child.getFullPath())) {
139                     iter.remove();
140                 }
141                 break;
142             case IResource.DEPTH_ONE:
143                 // TODO: Is a zero folder covered by a shallow folder?
144
if (fullPath.equals(child.getFullPath().removeLastSegments(1))) {
145                     iter.remove();
146                 }
147                 break;
148             }
149         }
150     }
151
152     public synchronized void add(CompoundResourceTraversal compoundTraversal) {
153         // Technically, this code should synchronize on compoundTraversal.
154
// However, this makes deadlock possible and, in practive, I don't think that
155
// the provided traversal will be modified after it is passed to this method.
156
addResources(
157                 (IResource[]) compoundTraversal.deepFolders.toArray(new IResource[compoundTraversal.deepFolders.size()]),
158                 IResource.DEPTH_INFINITE);
159         addResources(
160                 (IResource[]) compoundTraversal.shallowFolders.toArray(new IResource[compoundTraversal.shallowFolders.size()]),
161                 IResource.DEPTH_ONE);
162         addResources(
163                 (IResource[]) compoundTraversal.zeroFolders.toArray(new IResource[compoundTraversal.zeroFolders.size()]),
164                 IResource.DEPTH_ZERO);
165         addResources(
166                 (IResource[]) compoundTraversal.files.toArray(new IResource[compoundTraversal.files.size()]),
167                 IResource.DEPTH_ZERO);
168     }
169
170     public synchronized void addResources(IResource[] resources, int depth) {
171         for (int i = 0; i < resources.length; i++) {
172             IResource resource = resources[i];
173             addResource(resource, depth);
174         }
175         
176     }
177
178     /**
179      * Return the resources contained in the given traversals that are not covered by this traversal
180      * @param traversals the traversals being testes
181      * @return the resources contained in the given traversals that are not covered by this traversal
182      */

183     public synchronized IResource[] getUncoveredResources(ResourceTraversal[] traversals) {
184         CompoundResourceTraversal newTraversals = new CompoundResourceTraversal();
185         newTraversals.addTraversals(traversals);
186         return getUncoveredResources(newTraversals);
187     }
188
189     /*
190      * Return any resources in the other traversal that are not covered by this traversal
191      */

192     private IResource[] getUncoveredResources(CompoundResourceTraversal otherTraversal) {
193         Set result = new HashSet();
194         for (Iterator iter = otherTraversal.files.iterator(); iter.hasNext();) {
195             IResource resource = (IResource) iter.next();
196             if (!isCovered(resource, IResource.DEPTH_ZERO)) {
197                 result.add(resource);
198             }
199         }
200         for (Iterator iter = otherTraversal.zeroFolders.iterator(); iter.hasNext();) {
201             IResource resource = (IResource) iter.next();
202             if (!isCovered(resource, IResource.DEPTH_ZERO)) {
203                 result.add(resource);
204             }
205         }
206         for (Iterator iter = otherTraversal.shallowFolders.iterator(); iter.hasNext();) {
207             IResource resource = (IResource) iter.next();
208             if (!isCovered(resource, IResource.DEPTH_ONE)) {
209                 result.add(resource);
210             }
211         }
212         for (Iterator iter = otherTraversal.deepFolders.iterator(); iter.hasNext();) {
213             IResource resource = (IResource) iter.next();
214             if (!isCovered(resource, IResource.DEPTH_INFINITE)) {
215                 result.add(resource);
216             }
217         }
218         return (IResource[]) result.toArray(new IResource[result.size()]);
219     }
220
221     public synchronized ResourceTraversal[] asTraversals() {
222         List result = new ArrayList();
223         if (!files.isEmpty() || ! zeroFolders.isEmpty()) {
224             Set combined = new HashSet();
225             combined.addAll(files);
226             combined.addAll(zeroFolders);
227             result.add(new ResourceTraversal((IResource[]) combined.toArray(new IResource[combined.size()]), IResource.DEPTH_ZERO, IResource.NONE));
228         }
229         if (!shallowFolders.isEmpty()) {
230             result.add(new ResourceTraversal((IResource[]) shallowFolders.toArray(new IResource[shallowFolders.size()]), IResource.DEPTH_ONE, IResource.NONE));
231         }
232         if (!deepFolders.isEmpty()) {
233             result.add(new ResourceTraversal((IResource[]) deepFolders.toArray(new IResource[deepFolders.size()]), IResource.DEPTH_INFINITE, IResource.NONE));
234         }
235         return (ResourceTraversal[]) result.toArray(new ResourceTraversal[result.size()]);
236     }
237
238     public synchronized IResource[] getRoots() {
239         List result = new ArrayList();
240         result.addAll(files);
241         result.addAll(zeroFolders);
242         result.addAll(shallowFolders);
243         result.addAll(deepFolders);
244         return (IResource[]) result.toArray(new IResource[result.size()]);
245     }
246
247     public synchronized ResourceTraversal[] getUncoveredTraversals(ResourceTraversal[] traversals) {
248         CompoundResourceTraversal other = new CompoundResourceTraversal();
249         other.addTraversals(traversals);
250         return getUncoveredTraversals(other);
251     }
252
253     public ResourceTraversal[] getUncoveredTraversals(CompoundResourceTraversal otherTraversal) {
254         synchronized (otherTraversal) {
255             CompoundResourceTraversal uncovered = new CompoundResourceTraversal();
256             for (Iterator iter = otherTraversal.files.iterator(); iter.hasNext();) {
257                 IResource resource = (IResource) iter.next();
258                 if (!isCovered(resource, IResource.DEPTH_ZERO)) {
259                     uncovered.addResource(resource, IResource.DEPTH_ZERO);
260                 }
261             }
262             for (Iterator iter = otherTraversal.zeroFolders.iterator(); iter.hasNext();) {
263                 IResource resource = (IResource) iter.next();
264                 if (!isCovered(resource, IResource.DEPTH_ZERO)) {
265                     uncovered.addResource(resource, IResource.DEPTH_ZERO);
266                 }
267             }
268             for (Iterator iter = otherTraversal.shallowFolders.iterator(); iter.hasNext();) {
269                 IResource resource = (IResource) iter.next();
270                 if (!isCovered(resource, IResource.DEPTH_ONE)) {
271                     uncovered.addResource(resource, IResource.DEPTH_ONE);
272                 }
273             }
274             for (Iterator iter = otherTraversal.deepFolders.iterator(); iter.hasNext();) {
275                 IResource resource = (IResource) iter.next();
276                 if (!isCovered(resource, IResource.DEPTH_INFINITE)) {
277                     uncovered.addResource(resource, IResource.DEPTH_INFINITE);
278                 }
279             }
280             return uncovered.asTraversals();
281         }
282     }
283
284     public synchronized void clear() {
285         deepFolders.clear();
286         shallowFolders.clear();
287         zeroFolders.clear();
288         files.clear();
289     }
290
291 }
292
Popular Tags