KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > resources > EclipseFolder


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.ccvs.core.resources;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.resources.*;
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.core.runtime.jobs.ISchedulingRule;
19 import org.eclipse.osgi.util.NLS;
20 import org.eclipse.team.core.RepositoryProvider;
21 import org.eclipse.team.internal.ccvs.core.*;
22 import org.eclipse.team.internal.ccvs.core.client.Session;
23 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
24 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
25 import org.eclipse.team.internal.ccvs.core.util.Util;
26
27 /**
28  * Implements the ICVSFolder interface on top of an
29  * instance of the ICVSFolder interface
30  *
31  * @see ICVSFolder
32  */

33 class EclipseFolder extends EclipseResource implements ICVSFolder {
34
35     protected EclipseFolder(IContainer container) {
36         super(container);
37     }
38     
39     /**
40      * @see ICVSFolder#members(int)
41      */

42     public ICVSResource[] members(int flags) throws CVSException {
43         final List JavaDoc result = new ArrayList JavaDoc();
44         IResource[] resources = EclipseSynchronizer.getInstance().members((IContainer)resource);
45         boolean includeFiles = (((flags & FILE_MEMBERS) != 0) || ((flags & (FILE_MEMBERS | FOLDER_MEMBERS)) == 0));
46         boolean includeFolders = (((flags & FOLDER_MEMBERS) != 0) || ((flags & (FILE_MEMBERS | FOLDER_MEMBERS)) == 0));
47         boolean includeManaged = (((flags & MANAGED_MEMBERS) != 0) || ((flags & (MANAGED_MEMBERS | UNMANAGED_MEMBERS | IGNORED_MEMBERS)) == 0));
48         boolean includeUnmanaged = (((flags & UNMANAGED_MEMBERS) != 0) || ((flags & (MANAGED_MEMBERS | UNMANAGED_MEMBERS | IGNORED_MEMBERS)) == 0));
49         boolean includeIgnored = ((flags & IGNORED_MEMBERS) != 0);
50         boolean includeExisting = (((flags & EXISTING_MEMBERS) != 0) || ((flags & (EXISTING_MEMBERS | PHANTOM_MEMBERS)) == 0));
51         boolean includePhantoms = (((flags & PHANTOM_MEMBERS) != 0) || ((flags & (EXISTING_MEMBERS | PHANTOM_MEMBERS)) == 0));
52         for (int i = 0; i < resources.length; i++) {
53             IResource resource = resources[i];
54             int type = resource.getType();
55             if ((includeFiles && (type==IResource.FILE))
56                     || (includeFolders && (type==IResource.FOLDER))) {
57                 boolean exists = resource.exists();
58                 if ((includeExisting && exists) || (includePhantoms && !exists)) {
59                     ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
60                     boolean includeResource = false;
61                     if ((includeManaged && includeUnmanaged && includeIgnored)) {
62                         includeResource = true;
63                     } else {
64                         boolean isManaged = cvsResource.isManaged();
65                         if (isManaged && includeManaged) {
66                             includeResource = true;
67                         } else if (exists) {
68                             boolean isIgnored = cvsResource.isIgnored();
69                             if (isIgnored && includeIgnored) {
70                                 includeResource = true;
71                             } else if (! isManaged && ! isIgnored && includeUnmanaged) {
72                                 includeResource = true;
73                             }
74                         }
75                     }
76                     if (includeResource) {
77                         result.add(cvsResource);
78                     }
79                 }
80             }
81         }
82         return (ICVSResource[]) result.toArray(new ICVSResource[result.size()]);
83     }
84
85     /**
86      * @see ICVSFolder#createFolder(String)
87      */

88     public ICVSFolder getFolder(String JavaDoc name) throws CVSException {
89         if ((CURRENT_LOCAL_FOLDER.equals(name)) || ((CURRENT_LOCAL_FOLDER + SEPARATOR).equals(name)))
90             return this;
91         IPath path = new Path(null, name);
92         if(resource.getType()==IResource.ROOT && path.segmentCount()==1) {
93             return new EclipseFolder(((IWorkspaceRoot)resource).getProject(name));
94         } else {
95             return new EclipseFolder(((IContainer)resource).getFolder(path));
96         }
97     }
98
99     /**
100      * @see ICVSFolder#createFile(String)
101      */

102     public ICVSFile getFile(String JavaDoc name) throws CVSException {
103         return new EclipseFile(((IContainer)resource).getFile(new Path(null, name)));
104     }
105
106     /**
107      * @see ICVSFolder#mkdir()
108      */

109     public void mkdir() throws CVSException {
110         ISchedulingRule rule = null;
111         try {
112             rule = EclipseSynchronizer.getInstance().beginBatching(resource, null);
113             if(resource.getType()==IResource.PROJECT) {
114                 IProject project = (IProject)resource;
115                 project.create(null);
116                 project.open(null);
117             } else {
118                 ((IFolder)resource).create(false /*don't force*/, true /*make local*/, null);
119                 // We need to signal the creation to the synchronizer immediately because
120
// we may do additional CVS operations on the folder before the next delta
121
// occurs.
122
EclipseSynchronizer.getInstance().created(getIResource());;
123             }
124         } catch (CoreException e) {
125             throw CVSException.wrapException(resource, NLS.bind(CVSMessages.EclipseFolder_problem_creating, new String JavaDoc[] { resource.getFullPath().toString(), e.getStatus().getMessage() }), e);
126         } finally {
127             if (rule != null)
128                 EclipseSynchronizer.getInstance().endBatching(rule, null);
129         }
130     }
131         
132     /**
133      * @see ICVSResource#isFolder()
134      */

135     public boolean isFolder() {
136         return true;
137     }
138         
139     /**
140      * @see ICVSFolder#acceptChildren(ICVSResourceVisitor)
141      */

142     public void acceptChildren(ICVSResourceVisitor visitor) throws CVSException {
143         
144         // Visit files and then folders
145
ICVSResource[] subFiles = members(FILE_MEMBERS);
146         for (int i=0; i<subFiles.length; i++) {
147             subFiles[i].accept(visitor);
148         }
149         ICVSResource[] subFolders = members(FOLDER_MEMBERS);
150         for (int i=0; i<subFolders.length; i++) {
151             subFolders[i].accept(visitor);
152         }
153     }
154
155     /**
156      * @see ICVSResource#accept(ICVSResourceVisitor)
157      */

158     public void accept(ICVSResourceVisitor visitor) throws CVSException {
159         visitor.visitFolder(this);
160     }
161     
162     /**
163      * @see ICVSResource#accept(ICVSResourceVisitor, boolean)
164      */

165     public void accept(ICVSResourceVisitor visitor, boolean recurse) throws CVSException {
166         visitor.visitFolder(this);
167         ICVSResource[] resources;
168         if (recurse) {
169             resources = members(ICVSFolder.ALL_MEMBERS);
170         } else {
171             resources = members(ICVSFolder.FILE_MEMBERS);
172         }
173         for (int i = 0; i < resources.length; i++) {
174             resources[i].accept(visitor, recurse);
175         }
176     }
177
178     /**
179      * @see ICVSResource#getRemoteLocation(ICVSFolder)
180      */

181     public String JavaDoc getRemoteLocation(ICVSFolder stopSearching) throws CVSException {
182                 
183         if (getFolderSyncInfo() != null) {
184             return getFolderSyncInfo().getRemoteLocation();
185         }
186
187         ICVSFolder parent = getParent();
188         if(parent!=null && !equals(stopSearching)) {
189             String JavaDoc parentLocation;
190             parentLocation = parent.getRemoteLocation(stopSearching);
191             if (parentLocation!=null) {
192                 return parentLocation + SEPARATOR + getName();
193             }
194         }
195         return null;
196     }
197
198     /*
199      * @see ICVSFolder#getFolderInfo()
200      */

201     public FolderSyncInfo getFolderSyncInfo() throws CVSException {
202         if (resource.getType() != IResource.ROOT && !resource.getProject().isAccessible()) {
203             return null;
204         }
205         return EclipseSynchronizer.getInstance().getFolderSync((IContainer)resource);
206     }
207
208     /*
209      * @see ICVSFolder#setFolderInfo(FolderSyncInfo)
210      */

211     public void setFolderSyncInfo(final FolderSyncInfo folderInfo) throws CVSException {
212         // ignore folder sync on the root (i.e. CVSROOT/config/TopLevelAdmin=yes but we just ignore it)
213
if (resource.getType() == IResource.ROOT) return;
214         run(new ICVSRunnable() {
215             public void run(IProgressMonitor monitor) throws CVSException {
216                 EclipseSynchronizer synchronizer = EclipseSynchronizer.getInstance();
217                 synchronizer.setFolderSync((IContainer)resource, folderInfo);
218                 // the server won't add directories as sync info, therefore it must be done when
219
// a directory is shared with the repository.
220
byte[] newSyncBytes = new ResourceSyncInfo(getName()).getBytes();
221                 byte[] oldSyncBytes = getSyncBytes();
222                 // only set the bytes if the new differes from the old.
223
// this avoids unnecessary saving of sync files
224
if (oldSyncBytes == null || ! Util.equals(newSyncBytes, oldSyncBytes))
225                     setSyncBytes(newSyncBytes);
226             }
227         }, null);
228
229     }
230
231     /*
232      * @see ICVSFolder#isCVSFolder()
233      */

234     public boolean isCVSFolder() throws CVSException {
235         return EclipseSynchronizer.getInstance().getFolderSync((IContainer)resource) != null;
236     }
237
238     /*
239      * @see ICVSResource#unmanage()
240      */

241     public void unmanage(IProgressMonitor monitor) throws CVSException {
242         run(new ICVSRunnable() {
243             public void run(IProgressMonitor monitor) throws CVSException {
244                 monitor = Policy.monitorFor(monitor);
245                 monitor.beginTask(null, 100);
246                 recursiveUnmanage((IContainer) resource, Policy.subMonitorFor(monitor, 99));
247                 EclipseFolder.super.unmanage(Policy.subMonitorFor(monitor, 1));
248                 monitor.done();
249             }
250         }, Policy.subMonitorFor(monitor, 99));
251     }
252     
253     /* private */ static void recursiveUnmanage(IContainer container, IProgressMonitor monitor) {
254         try {
255             monitor.beginTask(null, 10);
256             monitor.subTask(NLS.bind(CVSMessages.EclipseFolder_0, new String JavaDoc[] {container.getFullPath().toString() }));
257             EclipseSynchronizer.getInstance().deleteFolderSync(container);
258     
259             IResource[] members = container.members(true);
260             for (int i = 0; i < members.length; i++) {
261                 monitor.worked(1);
262                 IResource resource = members[i];
263                 if (resource.getType() == IResource.FILE) {
264                     ResourceAttributes attrs = resource.getResourceAttributes();
265                     if (attrs != null && attrs.isReadOnly()) {
266                         attrs.setReadOnly(false);
267                         resource.setResourceAttributes(attrs);
268                     }
269                 } else {
270                     recursiveUnmanage((IContainer) resource, monitor);
271                 }
272             }
273         } catch (CoreException e) {
274             // Just ignore and continue
275
} finally {
276             monitor.done();
277         }
278     }
279     
280     /*
281      * @see ICVSResource#isIgnored()
282      */

283     public boolean isIgnored() throws CVSException {
284         if(isCVSFolder()) {
285             return false;
286         }
287         return super.isIgnored();
288     }
289     
290     /*
291      * @see ICVSFolder#getChild(String)
292      */

293     public ICVSResource getChild(String JavaDoc namedPath) throws CVSException {
294         if (namedPath.equals(Session.CURRENT_LOCAL_FOLDER)) {
295             return this;
296         }
297         IPath path = new Path(null, namedPath);
298         if(path.segmentCount()==0) {
299              return this;
300         }
301         IResource child = ((IContainer)resource).findMember(path, true /* include phantoms */);
302         if(child!=null) {
303             if(child.getType()==IResource.FILE) {
304                 return new EclipseFile((IFile)child);
305             } else {
306                 return new EclipseFolder((IContainer)child);
307             }
308         }
309         return null;
310     }
311     
312     /**
313      * @see ICVSFolder#fetchChildren(IProgressMonitor)
314      */

315     public ICVSResource[] fetchChildren(IProgressMonitor monitor) throws CVSException {
316         return members(FILE_MEMBERS | FOLDER_MEMBERS);
317     }
318     /**
319      * @see org.eclipse.team.internal.ccvs.core.ICVSResource#delete()
320      */

321     public void delete() throws CVSException {
322         if (!exists()) return;
323         try {
324             resource.delete(false /*force*/, null);
325         } catch(CoreException e) {
326             throw new CVSException(e.getStatus());
327         }
328     }
329     
330     /**
331      * Assumption this is only called from decorator and isIgnored() is purposely
332      * ommitted here for performance reasons.
333      */

334     public boolean isModified(IProgressMonitor monitor) throws CVSException {
335         try {
336             monitor = Policy.monitorFor(monitor);
337             monitor.beginTask(NLS.bind(CVSMessages.EclipseFolder_isModifiedProgress, new String JavaDoc[] { resource.getFullPath().toString() }), 1000);
338             
339             IContainer container = (IContainer)getIResource();
340             
341             if(RepositoryProvider.getProvider(container.getProject(), CVSProviderPlugin.getTypeId()) == null) {
342                 return false;
343             }
344             
345             // Added optimization to avoid loading sync info if possible
346
// This will place a modified indicator on non-cvs folders
347
// (i.e. the call to getModifiedState will cache a session property)
348
int state = EclipseSynchronizer.getInstance().getModificationState(getIResource());
349             
350             boolean modified;
351             if (state == ICVSFile.UNKNOWN) {
352                 
353                 if (!isCVSFolder() && container.getType() == IResource.FOLDER) {
354                     return container.exists();
355                 }
356                 
357                 // We have no cached info for the folder. We'll need to check directly,
358
// caching as go. This will recursively determined the modified state
359
// for all child resources until a modified child is found.
360
modified = calculateAndSaveChildModificationStates(monitor);
361                 EclipseSynchronizer.getInstance().setModified(this, modified);
362             } else {
363                 modified = (state == ICVSFile.DIRTY);
364             }
365             return modified;
366         } finally {
367             monitor.done();
368         }
369     }
370     
371     public void handleModification(boolean forAddition) throws CVSException {
372         // For non-additions, we are only interested in sync info changes
373
if (isIgnored() || !forAddition) return;
374
375         // the folder is an addition.
376
FolderSyncInfo info = getFolderSyncInfo();
377         // if the folder has sync info, it was handled is setFolderInfo
378
// otherwise, flush the ancestors to recalculate
379
if (info == null) {
380             EclipseSynchronizer.getInstance().setDirtyIndicator(getIResource(), true);
381         }
382     }
383     
384     /**
385      * Determines the modification state of the receiver by examining it's children.
386      * This method may result in modification state being cached with the children but
387      * does not cache it for the receiver.
388      */

389     private boolean calculateAndSaveChildModificationStates(IProgressMonitor monitor) throws CVSException {
390         ICVSResource[] children = members(ALL_UNIGNORED_MEMBERS);
391
392         for (int i = 0; i < children.length; i++) {
393             ICVSResource resource = children[i];
394             if (resource.isModified(null)) {
395                 // if a child resource is dirty consider the parent dirty as well, there
396
// is no need to continue checking other siblings.
397
return true;
398             }
399             monitor.worked(1);
400         }
401             
402         return false;
403     }
404
405     /* (non-Javadoc)
406      * @see org.eclipse.team.internal.ccvs.core.ICVSResource#getRepositoryRelativePath()
407      */

408     public String JavaDoc getRepositoryRelativePath() throws CVSException {
409         FolderSyncInfo info = getFolderSyncInfo();
410         if (info == null) return null;
411         // The REPOSITORY property of the folder info is the repository relative path
412
return info.getRepository();
413     }
414 }
415
Popular Tags