KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > util > MoveDeleteHook


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.util;
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.resources.team.*;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.team.core.RepositoryProvider;
20 import org.eclipse.team.internal.ccvs.core.*;
21 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
22 import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
23
24 /**
25  * This hook exists to ensure that folders deletions will be recorded so that outgoing file
26  * deletions can be properly communicated to the server.
27  */

28 public class MoveDeleteHook implements IMoveDeleteHook {
29     
30     /**
31      * @see IMoveDeleteHook#deleteFile(IResourceTree, IFile, int, IProgressMonitor)
32      */

33     public boolean deleteFile(
34         final IResourceTree tree,
35         final IFile file,
36         final int updateFlags,
37         IProgressMonitor monitor) {
38         
39         try {
40             monitor.beginTask(null, 100);
41
42             // No special handling required for team-private members
43
if (file.isTeamPrivateMember()) return false;
44
45             // If the file is ignored by CVS then we can just delete it.
46
ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
47             if (cvsFile.isIgnored()) return false;
48
49             // If we can't check out the files, return.
50
if (!checkOutFiles(tree, new IFile[] {file}, Policy.subMonitorFor(monitor, 30))) {
51                 // Return that the delete was handled because the checkout
52
// will have reported the error to the IResourceTree
53
return true;
54             }
55
56             // Otherwise, we need to prepare properly for the delete
57
EclipseSynchronizer.getInstance().performMoveDelete(new ICVSRunnable() {
58                 public void run(IProgressMonitor monitor) throws CVSException {
59                     try {
60                         monitor.beginTask(null, 100);
61                         EclipseSynchronizer.getInstance().prepareForDeletion(file, Policy.subMonitorFor(monitor, 40));
62                         tree.standardDeleteFile(file, updateFlags, Policy.subMonitorFor(monitor, 60));
63                     } finally {
64                         monitor.done();
65                     }
66                 }
67             }, Policy.subMonitorFor(monitor, 70));
68         } catch (CVSException e) {
69             tree.failed(e.getStatus());
70         } finally {
71             monitor.done();
72         }
73         return true;
74     }
75     
76     /**
77      * @see IMoveDeleteHook#deleteFolder(IResourceTree, IFolder, int, IProgressMonitor)
78      */

79     public boolean deleteFolder(
80         final IResourceTree tree,
81         final IFolder folder,
82         final int updateFlags,
83         IProgressMonitor monitor) {
84         
85         // No special handling required for team-private members
86
if (folder.isTeamPrivateMember()) return false;
87         monitor.beginTask(null, 100);
88         try {
89             final ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(folder);
90             if (cvsFolder.isCVSFolder() && ensureCheckedOut(new IFolder[] {folder}, tree, Policy.subMonitorFor(monitor, 30))) {
91                 EclipseSynchronizer.getInstance().performMoveDelete(new ICVSRunnable() {
92                     public void run(IProgressMonitor monitor) throws CVSException {
93                         try {
94                             monitor.beginTask(null, 100);
95                             EclipseSynchronizer.getInstance().prepareForDeletion(folder, Policy.subMonitorFor(monitor, 20));
96                             tree.standardDeleteFolder(folder, updateFlags, Policy.subMonitorFor(monitor, 50));
97                         } finally {
98                             monitor.done();
99                         }
100                     }
101                 }, Policy.subMonitorFor(monitor, 70));
102                 return true;
103             } else if (!cvsFolder.isIgnored()) {
104                 EclipseSynchronizer.getInstance().prepareForDeletion(cvsFolder.getIResource(), Policy.subMonitorFor(monitor, 70));
105             }
106         } catch (CVSException e) {
107             tree.failed(e.getStatus());
108         } finally {
109             monitor.done();
110         }
111         return false;
112     }
113
114     /**
115      * @see IMoveDeleteHook#deleteProject(IResourceTree, IProject, int, IProgressMonitor)
116      */

117     public boolean deleteProject(
118         IResourceTree tree,
119         IProject project,
120         int updateFlags,
121         IProgressMonitor monitor) {
122             
123         // We need to flush any remembered folder deletions for the deleted project.
124
// All other sync info is stored in session and persistant properties, which
125
// are deleted when the associated resources are deleted
126
try {
127             EclipseSynchronizer.getInstance().prepareForDeletion(project, monitor);
128         } catch (CVSException e) {
129             CVSProviderPlugin.log(e);
130         }
131         // todo: Perform a "cvs release" if there are any edits on the project
132
return false;
133     }
134
135     /**
136      * @see IMoveDeleteHook#moveFile(IResourceTree, IFile, IFile, int, IProgressMonitor)
137      */

138     public boolean moveFile(
139             final IResourceTree tree,
140             final IFile source,
141             final IFile destination,
142             final int updateFlags,
143             IProgressMonitor monitor) {
144         
145         try {
146             monitor.beginTask(null, 100);
147
148             // ensure we can write to both the source and the destination
149
IFile[] filesToCheckOut;
150             if (destination.exists()) {
151                 filesToCheckOut = new IFile[] {source, destination};
152             } else {
153                 filesToCheckOut = new IFile[] {source};
154             }
155             if (!checkOutFiles(tree, filesToCheckOut, Policy.subMonitorFor(monitor, 30))) {
156                 // Return that the move was handled because the checkout
157
// will have reported the error to the IResourceTree
158
return true;
159             }
160
161             // Perform the move
162
EclipseSynchronizer.getInstance().performMoveDelete(new ICVSRunnable() {
163                 public void run(IProgressMonitor monitor) throws CVSException {
164                     try {
165                         monitor.beginTask(null, 100);
166                         EclipseSynchronizer.getInstance().prepareForDeletion(source, Policy.subMonitorFor(monitor, 40));
167                         if (destination.exists()) {
168                             EclipseSynchronizer.getInstance().prepareForDeletion(destination, Policy.subMonitorFor(monitor, 20));
169                         }
170                         tree.standardMoveFile(source, destination, updateFlags, Policy.subMonitorFor(monitor, 40));
171                         EclipseSynchronizer.getInstance().postMove(destination);
172                     } finally {
173                         monitor.done();
174                     }
175                 }
176             }, Policy.subMonitorFor(monitor, 70));
177         } catch (CVSException e) {
178             tree.failed(e.getStatus());
179         } finally {
180             monitor.done();
181         }
182         return true;
183     }
184
185     /**
186      * @see IMoveDeleteHook#moveFolder(IResourceTree, IFolder, IFolder, int, IProgressMonitor)
187      */

188     public boolean moveFolder(
189         final IResourceTree tree,
190         final IFolder source,
191         final IFolder destination,
192         final int updateFlags,
193         IProgressMonitor monitor) {
194         
195         monitor.beginTask(null, 100);
196         try {
197             final ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(source);
198             if (cvsFolder.isManaged()) {
199                 if (!ensureCheckedOut(new IFolder[] {source, destination}, tree, Policy.subMonitorFor(monitor, 20))) return true;
200                 EclipseSynchronizer.getInstance().performMoveDelete(new ICVSRunnable() {
201                     public void run(IProgressMonitor monitor) throws CVSException {
202                         EclipseSynchronizer.getInstance().prepareForDeletion(source, Policy.subMonitorFor(monitor, 20));
203                         if (destination.exists()) {
204                             EclipseSynchronizer.getInstance().prepareForDeletion(destination, Policy.subMonitorFor(monitor, 20));
205                         }
206                         tree.standardMoveFolder(source, destination, updateFlags, Policy.subMonitorFor(monitor, 30));
207                         purgeCVSFolders(destination, Policy.subMonitorFor(monitor, 20));
208                         EclipseSynchronizer.getInstance().postMove(destination);
209                     }
210                     private void purgeCVSFolders(IFolder destination, final IProgressMonitor monitor) throws CVSException {
211                         // Delete any CVS folders
212
try {
213                             destination.accept(new IResourceVisitor() {
214                                 public boolean visit(IResource resource) throws CoreException {
215                                     if (resource.getType() == IResource.FOLDER && resource.getName().equals(SyncFileWriter.CVS_DIRNAME)) {
216                                         tree.standardDeleteFolder((IFolder)resource, updateFlags, monitor);
217                                         return false;
218                                     }
219                                     return true;
220                                 }
221                             }, IResource.DEPTH_INFINITE, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
222                         } catch (CoreException e) {
223                             throw CVSException.wrapException(e);
224                         }
225                     }
226                 }, Policy.subMonitorFor(monitor, 60));
227                 return true;
228             } else if (!cvsFolder.isIgnored()) {
229                 EclipseSynchronizer.getInstance().prepareForDeletion(cvsFolder.getIResource(), Policy.subMonitorFor(monitor, 60));
230             }
231         } catch (CVSException e) {
232             tree.failed(e.getStatus());
233             return true;
234         } finally {
235             monitor.done();
236         }
237             
238         return false;
239     }
240
241     /**
242      * @see IMoveDeleteHook#moveProject(IResourceTree, IProject, IProjectDescription, int, IProgressMonitor)
243      */

244     public boolean moveProject(
245         IResourceTree tree,
246         IProject source,
247         IProjectDescription description,
248         int updateFlags,
249         IProgressMonitor monitor) {
250             
251         // We need to move (or flush) any remembered folder deletions for the deleted project
252
// XXX We flush for now. This means that deleting a managed folder and then moving the
253
// project will mean that the file deletions will be lost. It also means that phantom
254
// folders are lost.
255
try {
256             EclipseSynchronizer.getInstance().prepareForDeletion(source, monitor);
257         } catch (CVSException e) {
258             CVSProviderPlugin.log(e);
259         }
260         return false;
261     }
262     
263     /**
264      * Ensure that the given file is checked out (i.e. not read only). Return
265      * true if it is OK to procede and false otherwise.
266      *
267      * @param tree
268      * @param file
269      * @return boolean
270      */

271     /* private */ boolean checkOutFiles(IResourceTree tree, IFile[] files, IProgressMonitor monitor) {
272         // Ensure that the file is "checked out" (i.e. not read-only
273
IFileModificationValidator validator = getFileModificationValidator(files);
274         if (validator instanceof ICVSFileModificationValidator) {
275             IStatus status = ((ICVSFileModificationValidator)validator).validateMoveDelete(files, monitor);
276             if (status.isOK()) {
277                 return true;
278             } else {
279                 tree.failed(status);
280                 return false;
281             }
282         }
283         return true;
284     }
285
286     private boolean ensureCheckedOut(IFolder[] folders, IResourceTree tree, IProgressMonitor monitor) {
287         final List JavaDoc readOnlyFiles = new ArrayList JavaDoc();
288         try {
289             // Find any read-only files
290
for (int i = 0; i < folders.length; i++) {
291                 IFolder folder = folders[i];
292                 if (folder.exists()) {
293                     folder.accept(new IResourceVisitor() {
294                         public boolean visit(IResource resource) throws CoreException {
295                             if (resource.getType() == IResource.FILE) {
296                                 IFile file = (IFile) resource;
297                                 if (file.isReadOnly()) {
298                                     readOnlyFiles.add(file);
299                                 }
300                             }
301                             return true;
302                         }
303                     });
304                 }
305             }
306             if (readOnlyFiles.isEmpty()) return true;
307             // Ensure read-only files are checked out
308
return checkOutFiles(tree, (IFile[]) readOnlyFiles.toArray(new IFile[readOnlyFiles.size()]), monitor);
309         } catch (CoreException e) {
310             tree.failed(e.getStatus());
311             return false;
312         }
313     }
314
315     private FileModificationValidator getFileModificationValidator(IFile[] files) {
316         return getProvider(files).getFileModificationValidator2();
317     }
318
319     private CVSTeamProvider getProvider(IFile[] files) {
320         CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(files[0].getProject(), CVSProviderPlugin.getTypeId());
321         return provider;
322     }
323 }
324
Popular Tags