KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > operations > BranchOperation


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.ui.operations;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14
15 import org.eclipse.core.resources.*;
16 import org.eclipse.core.resources.mapping.ResourceMapping;
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.jface.operation.IRunnableWithProgress;
19 import org.eclipse.jface.window.Window;
20 import org.eclipse.osgi.util.NLS;
21 import org.eclipse.team.core.TeamException;
22 import org.eclipse.team.internal.ccvs.core.*;
23 import org.eclipse.team.internal.ccvs.core.client.Command;
24 import org.eclipse.team.internal.ccvs.core.client.Session;
25 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
26 import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
27 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
28 import org.eclipse.team.internal.ccvs.core.syncinfo.*;
29 import org.eclipse.team.internal.ccvs.ui.*;
30 import org.eclipse.team.internal.ccvs.ui.Policy;
31 import org.eclipse.team.internal.ccvs.ui.actions.CVSAction;
32 import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager;
33 import org.eclipse.team.internal.ccvs.ui.tags.BranchPromptDialog;
34 import org.eclipse.ui.IWorkbenchPart;
35 import org.eclipse.ui.PlatformUI;
36
37 /**
38  * Perform a CVS branch operaiton
39  */

40 public class BranchOperation extends RepositoryProviderOperation {
41     
42     private boolean update;
43     private CVSTag rootVersionTag;
44     private CVSTag branchTag;
45     
46     public BranchOperation(IWorkbenchPart part, ResourceMapping[] mappers) {
47         super(part, mappers);
48     }
49     
50     public void setTags(CVSTag rootVersionTag, CVSTag branchTag, boolean updateToBranch) {
51         this.rootVersionTag = rootVersionTag;
52         this.branchTag = branchTag;
53         this.update = updateToBranch;
54     }
55     
56     /* (non-Javadoc)
57      * @see org.eclipse.team.ui.TeamOperation#shouldRun()
58      */

59     protected boolean shouldRun() {
60         try {
61             PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() {
62                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc,
63                         InterruptedException JavaDoc {
64                     try {
65                         buildScope(monitor);
66                     } catch (CVSException e) {
67                         throw new InvocationTargetException JavaDoc(e);
68                     }
69                 }
70             });
71         } catch (InvocationTargetException JavaDoc e1) {
72             CVSUIPlugin.openError(getShell(), null, null, e1);
73         } catch (InterruptedException JavaDoc e1) {
74             throw new OperationCanceledException();
75         }
76         
77         IResource[] resources = getTraversalRoots();
78         boolean allSticky = areAllResourcesSticky(resources);
79         String JavaDoc initialVersionName = calculateInitialVersionName(resources,allSticky);
80         final BranchPromptDialog dialog = new BranchPromptDialog(getShell(),
81                                             CVSUIMessages.BranchWizard_title,
82                                             resources,
83                                             allSticky,
84                                             initialVersionName);
85         if (dialog.open() != Window.OK) return false;
86         
87         // Capture the dialog info in local variables
88
final String JavaDoc tagString = dialog.getBranchTagName();
89         update = dialog.getUpdate();
90         branchTag = new CVSTag(tagString, CVSTag.BRANCH);
91         
92         // Only set the root version tag if the name from the dialog differs from the initial name
93
String JavaDoc versionString = dialog.getVersionTagName();
94         if (versionString != null
95                 && (initialVersionName == null || !versionString.equals(initialVersionName))) {
96             rootVersionTag = new CVSTag(versionString, CVSTag.VERSION);
97         }
98                                 
99         // For non-projects determine if the tag being loaded is the same as the resource's parent
100
// If it's not, warn the user that they will be mixing tags
101
if (update) {
102             try {
103                 if(!CVSAction.checkForMixingTags(getShell(), resources, branchTag)) {
104                     return false;
105                 }
106             } catch (CVSException e) {
107                 CVSUIPlugin.log(e);
108             }
109         }
110         return super.shouldRun();
111     }
112
113     /* (non-Javadoc)
114      * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#execute(org.eclipse.team.internal.ccvs.core.CVSTeamProvider, org.eclipse.core.resources.IResource[], org.eclipse.core.runtime.IProgressMonitor)
115      */

116     protected void execute(CVSTeamProvider provider, IResource[] providerResources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException JavaDoc {
117         try {
118             monitor.beginTask(null, 100);
119             makeBranch(provider, providerResources, rootVersionTag, branchTag, update, recurse, Policy.subMonitorFor(monitor, 90));
120             updateRememberedTags(providerResources);
121             if (update) {
122                 updateWorkspaceSubscriber(provider, getCVSArguments(providerResources), recurse, Policy.subMonitorFor(monitor, 10));
123             }
124             collectStatus(Status.OK_STATUS);
125         } catch (TeamException e) {
126             // Accumulate the status which will be displayed by CVSAction#endOperation(IAction)
127
collectStatus(e.getStatus());
128         } finally {
129             monitor.done();
130         }
131     }
132
133     private void makeBranch(CVSTeamProvider provider, IResource[] resources, final CVSTag versionTag, final CVSTag branchTag, boolean moveToBranch, boolean recurse, IProgressMonitor monitor) throws TeamException {
134         
135         // Determine the total amount of work
136
int totalWork = (versionTag!= null ? 60 : 40) + (moveToBranch ? 20 : 0);
137         monitor.beginTask(CVSUIMessages.CVSTeamProvider_makeBranch, totalWork);
138         try {
139             // Build the arguments list
140
ICVSResource[] arguments = getCVSArguments(resources);
141             LocalOption[] localOptions = getLocalOptions(recurse);
142             
143             // Tag the remote resources
144
IStatus status = null;
145             if (versionTag != null) {
146                 // Version using a custom tag command that skips added but not commited reesources
147
Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */);
148                 session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */);
149                 try {
150                     status = Command.CUSTOM_TAG.execute(
151                         session,
152                         Command.NO_GLOBAL_OPTIONS,
153                         localOptions,
154                         versionTag,
155                         arguments,
156                         null,
157                         Policy.subMonitorFor(monitor, 35));
158                 } finally {
159                     session.close();
160                 }
161                 if (status.isOK()) {
162                     // Branch using the tag
163
session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */);
164                     session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */);
165                     try {
166                         status = Command.CUSTOM_TAG.execute(
167                             session,
168                             Command.NO_GLOBAL_OPTIONS,
169                             localOptions,
170                             branchTag,
171                             arguments,
172                             null,
173                         Policy.subMonitorFor(monitor, 15));
174                     } finally {
175                         session.close();
176                     }
177                 }
178             } else {
179                 // Just branch using tag
180
Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */);
181                 session.open(Policy.subMonitorFor(monitor, 5), true /* open for modification */);
182                 try {
183                     status = Command.CUSTOM_TAG.execute(
184                         session,
185                         Command.NO_GLOBAL_OPTIONS,
186                         localOptions,
187                         branchTag,
188                         arguments,
189                         null,
190                         Policy.subMonitorFor(monitor, 35));
191                 } finally {
192                     session.close();
193                 }
194
195             }
196             if ( ! status.isOK()) {
197                 throw new CVSServerException(status);
198             }
199             
200             // Set the tag of the local resources to the branch tag (The update command will not
201
// properly update "cvs added" and "cvs removed" resources so a custom visitor is used
202
if (moveToBranch) {
203                 setTag(provider, resources, branchTag, recurse, Policy.subMonitorFor(monitor, 20));
204             }
205         } finally {
206             monitor.done();
207         }
208     }
209     
210     /*
211      * This method sets the tag for a project.
212      * It expects to be passed an InfiniteSubProgressMonitor
213      */

214     private void setTag(final CVSTeamProvider provider, final IResource[] resources, final CVSTag tag, final boolean recurse, IProgressMonitor monitor) throws TeamException {
215         getLocalRoot(provider).run(new ICVSRunnable() {
216             public void run(IProgressMonitor progress) throws CVSException {
217                 try {
218                     // 512 ticks gives us a maximum of 2048 which seems reasonable for folders and files in a project
219
progress.beginTask(null, 100);
220                     final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100);
221                     monitor.beginTask(NLS.bind(CVSUIMessages.CVSTeamProvider_folderInfo, new String JavaDoc[] { provider.getProject().getName() }), 512);
222                     
223                     // Visit all the children folders in order to set the root in the folder sync info
224
for (int i = 0; i < resources.length; i++) {
225                         CVSWorkspaceRoot.getCVSResourceFor(resources[i]).accept(new ICVSResourceVisitor() {
226                             public void visitFile(ICVSFile file) throws CVSException {
227                                 monitor.worked(1);
228                                 //ResourceSyncInfo info = file.getSyncInfo();
229
byte[] syncBytes = file.getSyncBytes();
230                                 if (syncBytes != null) {
231                                     monitor.subTask(NLS.bind(CVSUIMessages.CVSTeamProvider_updatingFile, new String JavaDoc[] { file.getName() }));
232                                     file.setSyncBytes(ResourceSyncInfo.setTag(syncBytes, tag), ICVSFile.UNKNOWN);
233                                 }
234                             }
235                             public void visitFolder(ICVSFolder folder) throws CVSException {
236                                 monitor.worked(1);
237                                 FolderSyncInfo info = folder.getFolderSyncInfo();
238                                 if (info != null) {
239                                     monitor.subTask(NLS.bind(CVSUIMessages.CVSTeamProvider_updatingFolder, new String JavaDoc[] { info.getRepository() }));
240                                     MutableFolderSyncInfo newInfo = info.cloneMutable();
241                                     newInfo.setTag(tag);
242                                     folder.setFolderSyncInfo(newInfo);
243                                 }
244                             }
245                         }, recurse);
246                     }
247                 } finally {
248                     progress.done();
249                 }
250             }
251         }, monitor);
252     }
253     
254     private void updateRememberedTags(IResource[] providerResources) throws CVSException {
255         if (rootVersionTag != null || update) {
256             for (int i = 0; i < providerResources.length; i++) {
257                 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(providerResources[i]);
258                 RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager();
259
260                 if (rootVersionTag != null) {
261                     manager.addTags(cvsResource, new CVSTag[] { rootVersionTag });
262                 }
263                 if (update) {
264                     manager.addTags(cvsResource, new CVSTag[] { branchTag });
265                 }
266             }
267         }
268     }
269     
270     /* (non-Javadoc)
271      * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName()
272      */

273     protected String JavaDoc getTaskName() {
274         return CVSUIMessages.BranchOperation_0;
275     }
276     
277     /* (non-Javadoc)
278      * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#getTaskName(org.eclipse.team.internal.ccvs.core.CVSTeamProvider)
279      */

280     protected String JavaDoc getTaskName(CVSTeamProvider provider) {
281         return NLS.bind(CVSUIMessages.BranchOperation_1, new String JavaDoc[] { provider.getProject().getName() });
282     }
283     
284     /**
285      * Answers <code>true</code> if all resources in the array have a sticky tag
286      */

287     private boolean areAllResourcesSticky(IResource[] resources) {
288         for (int i = 0; i < resources.length; i++) {
289             if(!hasStickyTag(resources[i])) return false;
290         }
291         return true;
292     }
293     
294     /**
295      * Answers <code>true</code> if the resource has a sticky tag
296      */

297     private boolean hasStickyTag(IResource resource) {
298         try {
299             ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
300             CVSTag tag;
301             if(cvsResource.isFolder()) {
302                 FolderSyncInfo folderInfo = ((ICVSFolder)cvsResource).getFolderSyncInfo();
303                 tag = folderInfo.getTag();
304             } else {
305                 ResourceSyncInfo info = cvsResource.getSyncInfo();
306                 tag = info.getTag();
307             }
308             if(tag!=null) {
309                 int tagType = tag.getType();
310                 if(tagType==CVSTag.VERSION) {
311                     return true;
312                 }
313             }
314         } catch(CVSException e) {
315             CVSUIPlugin.log(e);
316             return false;
317         }
318         return false;
319     }
320     
321     private String JavaDoc calculateInitialVersionName(IResource[] resources, boolean allSticky) {
322         String JavaDoc versionName = ""; //$NON-NLS-1$
323
try {
324             if(allSticky) {
325                 IResource stickyResource = resources[0];
326                 if(stickyResource.getType()==IResource.FILE) {
327                     ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)stickyResource);
328                     versionName = cvsFile.getSyncInfo().getTag().getName();
329                 } else {
330                     ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)stickyResource);
331                     versionName = cvsFolder.getFolderSyncInfo().getTag().getName();
332                 }
333             }
334         } catch(CVSException e) {
335             CVSUIPlugin.log(e);
336             versionName = ""; //$NON-NLS-1$
337
}
338         return versionName;
339     }
340     
341     protected boolean isReportableError(IStatus status) {
342         return super.isReportableError(status)
343                 || status.getCode() == CVSStatus.TAG_ALREADY_EXISTS;
344     }
345 }
346
Popular Tags