KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > syncinfo > CVSResourceVariantTree


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.ccvs.core.syncinfo;
12
13 import java.util.*;
14
15 import org.eclipse.core.resources.*;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.core.runtime.jobs.Job;
18 import org.eclipse.osgi.util.NLS;
19 import org.eclipse.team.core.RepositoryProvider;
20 import org.eclipse.team.core.TeamException;
21 import org.eclipse.team.core.variants.*;
22 import org.eclipse.team.internal.ccvs.core.*;
23 import org.eclipse.team.internal.ccvs.core.resources.*;
24
25 /**
26  * CVS Specific refresh operation
27  */

28 public class CVSResourceVariantTree extends ResourceVariantTree {
29
30     private CVSTag tag;
31     private boolean cacheFileContentsHint;
32     private CVSSyncTreeSubscriber subscriber;
33
34     public CVSResourceVariantTree(ResourceVariantByteStore cache, CVSTag tag, boolean cacheFileContentsHint) {
35         super(cache);
36         this.tag = tag;
37         this.cacheFileContentsHint = cacheFileContentsHint;
38     }
39
40     /* (non-Javadoc)
41      * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache()
42      */

43     public ResourceVariantByteStore getByteStore() {
44         return super.getByteStore();
45     }
46
47     /* (non-Javadoc)
48      * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource)
49      */

50     protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException {
51         if (remote != null) {
52             return super.getBytes(local, remote);
53         } else {
54             if (local.getType() == IResource.FOLDER) {
55                 // If there is no remote, use the local sync for the folder
56
return getBaseBytes((IContainer)local, getTag(local));
57             }
58             return null;
59         }
60     }
61
62     /* (non-Javadoc)
63      * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteChildren(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.core.runtime.IProgressMonitor)
64      */

65     protected IResourceVariant[] fetchMembers(IResourceVariant remote, IProgressMonitor progress) throws TeamException {
66         ICVSRemoteResource[] children = remote != null ? (ICVSRemoteResource[])((RemoteResource)remote).members(progress) : new ICVSRemoteResource[0];
67         IResourceVariant[] result = new IResourceVariant[children.length];
68         for (int i = 0; i < children.length; i++) {
69             result[i] = (IResourceVariant)children[i];
70         }
71         return result;
72     }
73
74     /* (non-Javadoc)
75      * @see org.eclipse.team.core.subscribers.RefreshOperation#buildRemoteTree(org.eclipse.core.resources.IResource, int, boolean, org.eclipse.core.runtime.IProgressMonitor)
76      */

77     protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
78         return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, getTag(resource), isCacheFileContentsHint(), depth, monitor);
79     }
80     
81     /* (non-Javadoc)
82      * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefreshOperation#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor)
83      */

84     public IResource[] collectChanges(IResource local,
85             IResourceVariant remote, int depth, IProgressMonitor monitor)
86             throws TeamException {
87         return super.collectChanges(local, remote, depth, monitor);
88     }
89
90     public IResource[] members(IResource resource) throws TeamException {
91         if (resource.getType() == IResource.FILE) {
92             return new IResource[0];
93         }
94         // Must ensure that any shared folders are included
95
Set members = new HashSet();
96         members.addAll(Arrays.asList(super.members(resource)));
97         try {
98             IResource[] localMembers = EclipseSynchronizer.getInstance().members((IContainer) resource); //((IContainer)resource).members(true);
99
for (int i = 0; i < localMembers.length; i++) {
100                 IResource local = localMembers[i];
101                 if (local.getType() != IResource.FILE) {
102                     ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local);
103                     if (folder.isCVSFolder()) {
104                         members.add(local);
105                     }
106                 }
107             }
108         } catch (CoreException e) {
109             throw CVSException.wrapException(e);
110         }
111         return (IResource[]) members.toArray(new IResource[members.size()]);
112     }
113     
114     /* (non-Javadoc)
115      * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#roots()
116      */

117     public IResource[] roots() {
118         return subscriber.roots();
119     }
120
121     /* (non-Javadoc)
122      * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource)
123      */

124     public IResourceVariant getResourceVariant(IResource resource) throws TeamException {
125         byte[] remoteBytes = getByteStore().getBytes(resource);
126         if (remoteBytes == null) {
127             // There is no remote handle for this resource
128
return null;
129         } else {
130             if (resource.getType() == IResource.FILE) {
131                 byte[] parentBytes = getParentBytes(resource);
132                 if (parentBytes == null) {
133                     IProject project = resource.getProject();
134                     if (project.exists() && RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()) != null) {
135                         IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR,NLS.bind(CVSMessages.ResourceSynchronizer_missingParentBytesOnGet, new String JavaDoc[] { getSyncName(getByteStore()).toString(), resource.getFullPath().toString() }),resource);
136                         CVSProviderPlugin.log(status);
137                         // Assume there is no remote and the problem is a programming error
138
}
139                     return null;
140                 }
141                 return RemoteFile.fromBytes(resource, remoteBytes, parentBytes);
142             } else {
143                 return RemoteFolder.fromBytes(resource, remoteBytes);
144             }
145         }
146     }
147
148     private String JavaDoc getSyncName(ResourceVariantByteStore cache) {
149         if (cache instanceof PersistantResourceVariantByteStore) {
150             return ((PersistantResourceVariantByteStore)cache).getSyncName().toString();
151         }
152         return cache.getClass().getName();
153     }
154     
155     
156     private byte[] getParentBytes(IResource resource) throws TeamException {
157         IContainer parent = resource.getParent();
158         byte[] bytes = getByteStore().getBytes(parent);
159         if (bytes == null ) {
160             bytes = getBaseBytes(parent, getTag(resource));
161         }
162         return bytes;
163     }
164
165     private byte[] getBaseBytes(IContainer parent, CVSTag tag) throws CVSException {
166         byte[] bytes;
167         // Look locally for the folder bytes
168
ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(parent);
169         FolderSyncInfo info = local.getFolderSyncInfo();
170         if (info == null) {
171             bytes = null;
172         } else {
173             // Use the folder sync from the workspace and the tag from the store
174
MutableFolderSyncInfo newInfo = info.cloneMutable();
175             newInfo.setTag(tag);
176             newInfo.setStatic(false);
177             bytes = newInfo.getBytes();
178         }
179         return bytes;
180     }
181     
182     private boolean hasLocalSyncInfo(IContainer folder) {
183         ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(folder);
184         try {
185             return local.getFolderSyncInfo() != null;
186         } catch (CVSException e) {
187             // Say that there is sync info and let the failure occur elsewhere
188
return true;
189         }
190     }
191
192     public CVSTag getTag(IResource resource) {
193         return tag;
194     }
195
196     /**
197      * Dispose of the underlying byte store
198      */

199     public void dispose() {
200         getByteStore().dispose();
201     }
202     
203     /* (non-Javadoc)
204      * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setVariant(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant)
205      */

206     protected boolean setVariant(IResource local, IResourceVariant remote) throws TeamException {
207         if (local.getType() == IResource.FOLDER && remote != null
208                 && !hasLocalSyncInfo((IFolder)local)
209                 && hasLocalSyncInfo(local.getParent())) {
210             // Manage the folder locally since folders exist in all versions, etc
211
// Use the info from the remote except get the tag from the local parent
212
CVSTag tag = CVSWorkspaceRoot.getCVSFolderFor(local.getParent()).getFolderSyncInfo().getTag();
213             FolderSyncInfo info = null;
214             try{
215                 info = FolderSyncInfo.getFolderSyncInfo(remote.asBytes());
216             } catch (CVSException e){
217                 Status status = new Status(Status.ERROR, CVSProviderPlugin.ID,
218                         NLS.bind(CVSMessages.CVSResourceVariantTree_GettingSyncInfoError, local.getProjectRelativePath().toString()),
219                         e);
220                 throw new CVSException(status);
221             }
222             MutableFolderSyncInfo newInfo = info.cloneMutable();
223             newInfo.setTag(tag);
224             ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IFolder)local);
225             cvsFolder.setFolderSyncInfo(newInfo);
226         }
227         if (remote == null && !isManaged(local)) {
228             // Do not record the lack of existence of a remote for unmanaged local files
229
// Instead, just flush the remote bytes if there are any
230
boolean changed = getByteStore().getBytes(local) != null;
231             flushVariants(local, IResource.DEPTH_ZERO);
232             return changed;
233         } else {
234             boolean changed = super.setVariant(local, remote);
235             if (local.getType() == IResource.FILE && getByteStore().getBytes(local) != null && !parentHasSyncBytes(local)) {
236                 // Log a warning if there is no sync bytes available for the resource's
237
// parent but there is valid sync bytes for the child
238
CVSProviderPlugin.log(new TeamException(NLS.bind(CVSMessages.ResourceSynchronizer_missingParentBytesOnSet, new String JavaDoc[] { getSyncName(getByteStore()), local.getFullPath().toString() })));
239             }
240             return changed;
241         }
242     }
243     
244     private boolean isManaged(IResource local) {
245         try {
246             return CVSWorkspaceRoot.getCVSResourceFor(local).isManaged();
247         } catch (CVSException e) {
248             return false;
249         }
250     }
251
252     private boolean parentHasSyncBytes(IResource resource) throws TeamException {
253         if (resource.getType() == IResource.PROJECT) return true;
254         return getParentBytes(resource) != null;
255     }
256     
257     /* (non-Javadoc)
258      * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#collectedMembers(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource[])
259      */

260     protected IResource[] collectedMembers(IResource local, IResource[] members) throws TeamException {
261         // Look for resources that have sync bytes but are not in the resources we care about
262
IResource[] resources = getStoredMembers(local);
263         List children = new ArrayList();
264         List changedResources = new ArrayList();
265         children.addAll(Arrays.asList(members));
266         for (int i = 0; i < resources.length; i++) {
267             IResource resource = resources[i];
268             if (!children.contains(resource)) {
269                 // These sync bytes are stale. Purge them
270
flushVariants(resource, IResource.DEPTH_INFINITE);
271                 changedResources.add(resource);
272             }
273         }
274         return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
275     }
276     
277     /**
278      * Return all the members of that have resource variant information associated with them,
279      * such as members that are explicitly flagged as not having a resource variant. This list
280      * is used by the collection algorithm to flush variants for which there is no local and
281      * no remote.
282      * @param local the locla resource
283      * @return the local children that have resource variant information cached
284      * @throws TeamException
285      */

286     private IResource[] getStoredMembers(IResource local) throws TeamException {
287         try {
288             if (local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) {
289                 IResource[] allChildren = ((IContainer)local).members(true /* include phantoms */);
290                 List childrenWithSyncBytes = new ArrayList();
291                 for (int i = 0; i < allChildren.length; i++) {
292                     IResource resource = allChildren[i];
293                     if (getByteStore().getBytes(resource) != null) {
294                         childrenWithSyncBytes.add(resource);
295                     }
296                 }
297                 return (IResource[]) childrenWithSyncBytes.toArray(
298                         new IResource[childrenWithSyncBytes.size()]);
299             }
300         } catch (CoreException e) {
301             throw TeamException.asTeamException(e);
302         }
303         return new IResource[0];
304     }
305     
306     /* (non-Javadoc)
307      * @see org.eclipse.team.core.variants.AbstractResourceVariantTree#refresh(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor)
308      */

309     protected IResource[] refresh(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
310         IResource[] changedResources = null;
311         monitor.beginTask(null, 100);
312         // Wait while a build is running
313
// Initially wait for a short time and then increase the wait
314
// if the build is still running
315
int count = 0;
316         int waitTime = 10;
317         while (count < 15
318                 && (isJobInFamilyRunning(ResourcesPlugin.FAMILY_AUTO_BUILD)
319                 || isJobInFamilyRunning(ResourcesPlugin.FAMILY_MANUAL_BUILD))) {
320             try {
321                 Thread.sleep(waitTime);
322             } catch (InterruptedException JavaDoc e) {
323                 // Conitinue
324
}
325             count++;
326             if (count >= 10) {
327                 waitTime = 1000;
328             } else if (count >= 5) {
329                 waitTime = 100;
330             }
331             Policy.checkCanceled(monitor);
332         }
333         try {
334             changedResources = super.refresh(resource, depth, Policy.subMonitorFor(monitor, 99));
335         } catch (TeamException e) {
336             // Try to properly handle exceptions that are due to project modifications
337
// performed while the refresh was happening
338
if (!resource.getProject().isAccessible()) {
339                 // The project is closed so silently skip it
340
return new IResource[0];
341             }
342             throw e;
343         } finally {
344             monitor.done();
345         }
346         if (changedResources == null) return new IResource[0];
347         return changedResources;
348     }
349     
350     private boolean isJobInFamilyRunning(Object JavaDoc family) {
351         Job[] jobs = Job.getJobManager().find(family);
352         if (jobs != null && jobs.length > 0) {
353             for (int i = 0; i < jobs.length; i++) {
354                 Job job = jobs[i];
355                 if (job.getState() != Job.NONE) {
356                     return true;
357                 }
358             }
359         }
360         return false;
361     }
362     
363     
364     public ICVSRemoteResource buildTree(RemoteFolderTree parent, IResource resource, boolean immutable, IProgressMonitor monitor) throws TeamException {
365         
366         Policy.checkCanceled(monitor);
367         
368         byte[] remoteBytes = getByteStore().getBytes(resource);
369         if (remoteBytes == null) {
370             // There is no remote handle for this resource
371
return null;
372         }
373         
374         if (resource.getType() == IResource.FILE) {
375             if (immutable) {
376                 remoteBytes = ResourceSyncInfo.setTag(remoteBytes, new CVSTag(ResourceSyncInfo.getRevision(remoteBytes), CVSTag.VERSION));
377             }
378             if (parent == null) {
379                 return (ICVSRemoteResource)getResourceVariant(resource);
380             }
381             return new RemoteFile(parent, remoteBytes);
382         } else {
383             RemoteFolderTree remote = RemoteFolderTree.fromBytes(parent, resource, remoteBytes);
384             IResource[] members = members(resource);
385             List children = new ArrayList();
386             for (int i = 0; i < members.length; i++) {
387                 IResource member = members[i];
388                 ICVSRemoteResource child = buildTree(remote, member, immutable, monitor);
389                 if (child != null)
390                     children.add(child);
391             }
392             
393             // Add the children to the remote folder tree
394
remote.setChildren((ICVSRemoteResource[])children.toArray(new ICVSRemoteResource[children.size()]));
395             return remote;
396         }
397     }
398
399     public boolean isCacheFileContentsHint() {
400         return cacheFileContentsHint;
401     }
402 }
403
Popular Tags