KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > CVSProjectSetCapability


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  * Dan Rubel - initial API and implementation
10  * IBM Corporation - maintenance and modifications
11  *******************************************************************************/

12
13 package org.eclipse.team.internal.ccvs.core;
14
15 import java.io.File JavaDoc;
16 import java.net.URI JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Collection JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 import org.eclipse.core.resources.*;
27 import org.eclipse.core.runtime.*;
28 import org.eclipse.core.runtime.jobs.ISchedulingRule;
29 import org.eclipse.core.runtime.jobs.MultiRule;
30 import org.eclipse.team.core.*;
31 import org.eclipse.team.internal.ccvs.core.client.*;
32 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
33 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
34 import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
35 import org.eclipse.team.internal.ccvs.core.filesystem.CVSURI;
36 import org.eclipse.team.internal.ccvs.core.resources.*;
37 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
38 import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;
39
40 /**
41  * An object for serializing and deserializing
42  * of references to CVS based projects. Given a project, it can produce a
43  * UTF-8 encoded String which can be stored in a file.
44  * Given this String, it can load a project into the workspace.
45  *
46  * @since 3.0
47  */

48 public class CVSProjectSetCapability extends ProjectSetCapability {
49
50     /**
51      * Override superclass implementation to return an array of project references.
52      *
53      * @see ProjectSetSerializer#asReference(IProject[], ProjectSetSerializationContext, IProgressMonitor)
54      */

55     public String JavaDoc[] asReference(
56         IProject[] projects,
57         ProjectSetSerializationContext context,
58         IProgressMonitor monitor)
59         throws TeamException {
60         
61         String JavaDoc[] result = new String JavaDoc[projects.length];
62         for (int i = 0; i < projects.length; i++)
63             result[i] = asReference(projects[i]);
64         return result;
65     }
66
67     /**
68      * Answer a string representing the specified project
69      *
70      * @param project the project (not <code>null</code>)
71      * @return the project reference (not <code>null</code>)
72      * @throws CVSException
73      */

74     private String JavaDoc asReference(IProject project) throws TeamException {
75         CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(project);
76         CVSWorkspaceRoot root = provider.getCVSWorkspaceRoot();
77         CVSRepositoryLocation location = CVSRepositoryLocation.fromString(root.getRemoteLocation().getLocation(false));
78         location.setUserMuteable(true);
79         ICVSFolder folder = root.getLocalRoot();
80         return asReference(location, folder, project);
81     }
82     
83     private String JavaDoc asReference(CVSRepositoryLocation location, ICVSFolder folder, IProject project) throws TeamException {
84         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
85         buffer.append("1.0,"); //$NON-NLS-1$
86

87         String JavaDoc repoLocation = location.getLocation();
88         buffer.append(repoLocation);
89         buffer.append(","); //$NON-NLS-1$
90

91         FolderSyncInfo syncInfo = folder.getFolderSyncInfo();
92         String JavaDoc module = syncInfo.getRepository();
93         buffer.append(module);
94         buffer.append(","); //$NON-NLS-1$
95

96         String JavaDoc projectName = project.getName();
97         buffer.append(projectName);
98         CVSTag tag = syncInfo.getTag();
99         if (tag != null) {
100             if (tag.getType() != CVSTag.DATE) {
101                 buffer.append(","); //$NON-NLS-1$
102
String JavaDoc tagName = tag.getName();
103                 buffer.append(tagName);
104             }
105         }
106         return buffer.toString();
107     }
108
109     /**
110      * Override superclass implementation to load the referenced projects into the workspace.
111      *
112      * @see org.eclipse.team.core.ProjectSetSerializer#addToWorkspace(java.lang.String[], org.eclipse.team.core.ProjectSetSerializationContext, org.eclipse.core.runtime.IProgressMonitor)
113      */

114     public IProject[] addToWorkspace(
115         String JavaDoc[] referenceStrings,
116         ProjectSetSerializationContext context,
117         IProgressMonitor monitor)
118         throws TeamException {
119         
120         monitor = Policy.monitorFor(monitor);
121         Policy.checkCanceled(monitor);
122
123         // Confirm the projects to be loaded
124
Map JavaDoc infoMap = new HashMap JavaDoc(referenceStrings.length);
125         IProject[] projects = asProjects(referenceStrings, infoMap);
126         projects = confirmOverwrite(context, projects);
127         if (projects == null)
128             throw new OperationCanceledException();
129
130         // Load the projects
131
return checkout(projects, infoMap, monitor);
132     }
133
134     /**
135      * Translate the reference strings into projects to be loaded
136      * and build a mapping of project to project load information.
137      *
138      * @param referenceStrings project references
139      * @param infoMap a mapping of project to project load information
140      * @return the projects to be loaded
141      */

142     private IProject[] asProjects(String JavaDoc[] referenceStrings, Map JavaDoc infoMap) throws CVSException {
143         Collection JavaDoc result = new ArrayList JavaDoc();
144         for (int i = 0; i < referenceStrings.length; i++) {
145             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(referenceStrings[i], ","); //$NON-NLS-1$
146
String JavaDoc version = tokenizer.nextToken();
147             // If this is a newer version, then ignore it
148
if (!version.equals("1.0")) //$NON-NLS-1$
149
continue;
150             LoadInfo info = new LoadInfo(tokenizer);
151             IProject proj = info.getProject();
152             result.add(proj);
153             infoMap.put(proj, info);
154         }
155         return (IProject[]) result.toArray(new IProject[result.size()]);
156     }
157
158     /**
159      * Checkout projects from the CVS repository
160      *
161      * @param projects the projects to be loaded from the repository
162      * @param infoMap a mapping of project to project load information
163      * @param monitor the progress monitor (not <code>null</code>)
164      */

165     private IProject[] checkout(
166         final IProject[] projects,
167         final Map JavaDoc infoMap,
168         IProgressMonitor monitor)
169         throws TeamException {
170         
171         final List JavaDoc result = new ArrayList JavaDoc();
172         try {
173             ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
174                 public void run(IProgressMonitor monitor) throws CoreException {
175                     monitor.beginTask("", 1000 * projects.length); //$NON-NLS-1$
176
try {
177                         for (int i = 0; i < projects.length; i++) {
178                             if (monitor.isCanceled())
179                                 break;
180                             IProject project = projects[i];
181                             LoadInfo info = (LoadInfo) infoMap.get(project);
182                             if (info != null && info.checkout(new SubProgressMonitor(monitor, 1000)))
183                                 result.add(project);
184                         }
185                     }
186                     finally {
187                         monitor.done();
188                     }
189                 }
190             }, getCheckoutRule(projects), IResource.NONE, monitor);
191         } catch (CoreException e) {
192             throw TeamException.asTeamException(e);
193         }
194         return (IProject[])result.toArray(new IProject[result.size()]);
195     }
196
197     /**
198      * Internal class for adding projects to the workspace
199      */

200     class LoadInfo {
201         private final ICVSRepositoryLocation repositoryLocation;
202         private final String JavaDoc module;
203         private final IProject project;
204         private final CVSTag tag;
205
206         /**
207          * Construct a new instance wrappering the specified project reference
208          *
209          * @param projRef the project reference
210          */

211         LoadInfo(StringTokenizer JavaDoc tokenizer) throws CVSException {
212             String JavaDoc repo = tokenizer.nextToken();
213             repositoryLocation = getRepositoryLocationFromString(repo);
214             module = tokenizer.nextToken();
215             String JavaDoc projectName = tokenizer.nextToken();
216             project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
217             if (tokenizer.hasMoreTokens()) {
218                 String JavaDoc tagName = tokenizer.nextToken();
219                 tag = new CVSTag(tagName, CVSTag.BRANCH);
220             }
221             else {
222                 tag = null;
223             }
224         }
225
226         /**
227          * Answer the project referenced by this object.
228          * The project may or may not already exist.
229          *
230          * @return the project (not <code>null</code>)
231          */

232         private IProject getProject() {
233             return project;
234         }
235         
236         /**
237          * Checkout the project specified by this reference.
238          *
239          * @param monitor project monitor
240          * @return true if loaded, else false
241          * @throws TeamException
242          */

243         boolean checkout(IProgressMonitor monitor) throws TeamException {
244             if (repositoryLocation == null)
245                 return false;
246             CVSProjectSetCapability.checkout(
247                 repositoryLocation,
248                 project,
249                 module,
250                 tag,
251                 monitor);
252             return true;
253         }
254     }
255
256     /**
257      * Extract the CVS repository location information from the specified string
258      *
259      * @param repo the repository location as a string
260      * @return the CVS repository information
261      * @throws CVSException
262      */

263     private static ICVSRepositoryLocation getRepositoryLocationFromString(String JavaDoc repo) throws CVSException {
264         // create the new location
265
ICVSRepositoryLocation newLocation = CVSRepositoryLocation.fromString(repo);
266         if (newLocation.getUsername() == null || newLocation.getUsername().length() == 0) {
267             // look for an existing location that matched
268
ICVSRepositoryLocation[] locations = CVSProviderPlugin.getPlugin().getKnownRepositories();
269             for (int i = 0; i < locations.length; i++) {
270                 ICVSRepositoryLocation location = locations[i];
271                 if (location.getMethod() == newLocation.getMethod()
272                     && location.getHost().equals(newLocation.getHost())
273                     && location.getPort() == newLocation.getPort()
274                     && location.getRootDirectory().equals(newLocation.getRootDirectory()))
275                         return location;
276             }
277         }
278         // No existing location was found so add this location to the list of known repositories
279
KnownRepositories.getInstance().addRepository(newLocation, true);
280         return newLocation;
281     }
282     
283     /**
284      * Checkout a CVS module.
285      *
286      * The provided project represents the target project. Any existing contents
287      * may or may not get overwritten. If project is <code>null</code> then a project
288      * will be created based on the provided sourceModule. If soureModule is null,
289      * then the project name will be used as the module to
290      * check out. If both are absent, an exception is thrown.
291      *
292      * Resources existing in the local file system at the target project location but now
293      * known to the workbench will be overwritten.
294      *
295      * After the successful completion of this method, the project will exist
296      * and be open.
297      */

298     public static void checkout(
299         ICVSRepositoryLocation repository,
300         IProject project,
301         String JavaDoc sourceModule,
302         CVSTag tag,
303         IProgressMonitor monitor)
304         throws TeamException {
305         
306         if (sourceModule == null)
307             sourceModule = project.getName();
308         checkout(new ICVSRemoteFolder[] { new RemoteFolder(null, repository, sourceModule, tag)},
309             new IProject[] { project }, monitor);
310     }
311
312     /**
313      * Checkout the remote resources into the local workspace. Each resource will
314      * be checked out into the corresponding project. If the corresponding project is
315      * null or if projects is null, the name of the remote resource is used as the name of the project.
316      *
317      * Resources existing in the local file system at the target project location but now
318      * known to the workbench will be overwritten.
319      */

320     public static void checkout(final ICVSRemoteFolder[] resources, final IProject[] projects, final IProgressMonitor monitor) throws TeamException {
321         final TeamException[] eHolder = new TeamException[1];
322         try {
323             IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
324                 public void run(IProgressMonitor pm) throws CoreException {
325                     try {
326                         pm.beginTask(null, 1000 * resources.length);
327                         
328                         // Get the location of the workspace root
329
ICVSFolder root = CVSWorkspaceRoot.getCVSFolderFor(ResourcesPlugin.getWorkspace().getRoot());
330                         
331                         for (int i=0;i<resources.length;i++) {
332                             IProject project = null;
333                             RemoteFolder resource = (RemoteFolder)resources[i];
334                             
335                             // Determine the provided target project if there is one
336
if (projects != null)
337                                 project = projects[i];
338                             
339                             // Determine the remote module to be checked out
340
String JavaDoc moduleName;
341                             if (resource instanceof RemoteModule) {
342                                 moduleName = ((RemoteModule)resource).getName();
343                             } else {
344                                 moduleName = resource.getRepositoryRelativePath();
345                             }
346                             
347                             // Open a connection session to the repository
348
ICVSRepositoryLocation repository = resource.getRepository();
349                             Session session = new Session(repository, root);
350                             try {
351                                 session.open(Policy.subMonitorFor(pm, 50), false /* read-only */);
352                                 
353                                 // Determine the local target projects (either the project provider or the module expansions)
354
final Set JavaDoc targetProjects = new HashSet JavaDoc();
355                                 if (project == null) {
356                                     
357                                     // Fetch the module expansions
358
IStatus status = Request.EXPAND_MODULES.execute(session, new String JavaDoc[] {moduleName}, Policy.subMonitorFor(pm, 50));
359                                     if (status.getCode() == CVSStatus.SERVER_ERROR) {
360                                         throw new CVSServerException(status);
361                                     }
362                                     
363                                     // Convert the module expansions to local projects
364
String JavaDoc[] expansions = session.getModuleExpansions();
365                                     for (int j = 0; j < expansions.length; j++) {
366                                         targetProjects.add(ResourcesPlugin.getWorkspace().getRoot().getProject(new Path(null, expansions[j]).segment(0)));
367                                     }
368                                     
369                                 } else {
370                                     targetProjects.add(project);
371                                 }
372                                 
373                                 // Prepare the target projects to receive resources
374
root.run(new ICVSRunnable() {
375                                     public void run(IProgressMonitor monitor) throws CVSException {
376                                         scrubProjects((IProject[]) targetProjects.toArray(new IProject[targetProjects.size()]), monitor);
377                                     }
378                                 }, Policy.subMonitorFor(pm, 100));
379                             
380                                 // Build the local options
381
List JavaDoc localOptions = new ArrayList JavaDoc();
382                                 // Add the option to load into the target project if one was supplied
383
if (project != null) {
384                                     localOptions.add(Checkout.makeDirectoryNameOption(project.getName()));
385                                 }
386                                 // Prune empty directories if pruning enabled
387
if (CVSProviderPlugin.getPlugin().getPruneEmptyDirectories())
388                                     localOptions.add(Command.PRUNE_EMPTY_DIRECTORIES);
389                                 // Add the options related to the CVSTag
390
CVSTag tag = resource.getTag();
391                                 if (tag == null) {
392                                     // A null tag in a remote resource indicates HEAD
393
tag = CVSTag.DEFAULT;
394                                 }
395                                 localOptions.add(Update.makeTagOption(tag));
396         
397                                 // Perform the checkout
398
IStatus status = Command.CHECKOUT.execute(session,
399                                     Command.NO_GLOBAL_OPTIONS,
400                                     (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]),
401                                     new String JavaDoc[]{moduleName},
402                                     null,
403                                     Policy.subMonitorFor(pm, 800));
404                                 if (status.getCode() == CVSStatus.SERVER_ERROR) {
405                                     // XXX Should we cleanup any partially checked out projects?
406
throw new CVSServerException(status);
407                                 }
408                                 
409                                 // Bring the project into the workspace
410
refreshProjects((IProject[])targetProjects.toArray(new IProject[targetProjects.size()]), Policy.subMonitorFor(pm, 100));
411
412                             } finally {
413                                 session.close();
414                             }
415                         }
416                     }
417                     catch (TeamException e) {
418                         // Pass it outside the workspace runnable
419
eHolder[0] = e;
420                     } finally {
421                         pm.done();
422                     }
423                     // CoreException and OperationCanceledException are propagated
424
}
425             };
426             ResourcesPlugin.getWorkspace().run(workspaceRunnable, getCheckoutRule(projects), 0, monitor);
427         } catch (CoreException e) {
428             throw CVSException.wrapException(e);
429         } finally {
430             monitor.done();
431         }
432         // Re-throw the TeamException, if one occurred
433
if (eHolder[0] != null) {
434             throw eHolder[0];
435         }
436     }
437
438     private static ISchedulingRule getCheckoutRule(final IProject[] projects) {
439         if (projects.length == 1) {
440             return ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(projects[0]);
441         } else {
442             Set JavaDoc rules = new HashSet JavaDoc();
443             for (int i = 0; i < projects.length; i++) {
444                 ISchedulingRule modifyRule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(projects[i]);
445                 if (modifyRule instanceof IResource && ((IResource)modifyRule).getType() == IResource.ROOT) {
446                     // One of the projects is mapped to a provider that locks the workspace.
447
// Just return the workspace root rule
448
return modifyRule;
449                 }
450                 rules.add(modifyRule);
451             }
452             return new MultiRule((ISchedulingRule[]) rules.toArray(new ISchedulingRule[rules.size()]));
453         }
454     }
455     /*
456      * Bring the provied projects into the workspace
457      */

458     /* internal use only */ static void refreshProjects(IProject[] projects, IProgressMonitor monitor) throws CoreException, TeamException {
459         monitor.beginTask(CVSMessages.CVSProvider_Creating_projects_2, projects.length * 100);
460         try {
461             for (int i = 0; i < projects.length; i++) {
462                 IProject project = projects[i];
463                 // Register the project with Team
464
RepositoryProvider.map(project, CVSProviderPlugin.getTypeId());
465                 CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId());
466                 provider.setWatchEditEnabled(CVSProviderPlugin.getPlugin().isWatchEditEnabled());
467             }
468             
469         } finally {
470             monitor.done();
471         }
472     }
473     
474     /*
475      * Delete the target projects before checking out
476      */

477     /* internal use only */ static void scrubProjects(IProject[] projects, IProgressMonitor monitor) throws CVSException {
478         if (projects == null) {
479             monitor.done();
480             return;
481         }
482         monitor.beginTask(CVSMessages.CVSProvider_Scrubbing_projects_1, projects.length * 100);
483         try {
484             for (int i=0;i<projects.length;i++) {
485                 IProject project = projects[i];
486                 if (project != null && project.exists()) {
487                     if(!project.isOpen()) {
488                         project.open(Policy.subMonitorFor(monitor, 10));
489                     }
490                     // We do not want to delete the project to avoid a project deletion delta
491
// We do not want to delete the .project to avoid core exceptions
492
monitor.subTask(CVSMessages.CVSProvider_Scrubbing_local_project_1);
493                     // unmap the project from any previous repository provider
494
if (RepositoryProvider.getProvider(project) != null)
495                         RepositoryProvider.unmap(project);
496                     IResource[] children = project.members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
497                     IProgressMonitor subMonitor = Policy.subMonitorFor(monitor, 80);
498                     subMonitor.beginTask(null, children.length * 100);
499                     try {
500                         for (int j = 0; j < children.length; j++) {
501                             if ( ! children[j].getName().equals(".project")) {//$NON-NLS-1$
502
children[j].delete(true /*force*/, Policy.subMonitorFor(subMonitor, 100));
503                             }
504                         }
505                     } finally {
506                         subMonitor.done();
507                     }
508                 } else if (project != null) {
509                     // Make sure there is no directory in the local file system.
510
File JavaDoc location = new File JavaDoc(project.getParent().getLocation().toFile(), project.getName());
511                     if (location.exists()) {
512                         deepDelete(location);
513                     }
514                 }
515             }
516         } catch (CoreException e) {
517             throw CVSException.wrapException(e);
518         } finally {
519             monitor.done();
520         }
521     }
522     
523     private static void deepDelete(File JavaDoc resource) {
524         if (resource.isDirectory()) {
525             File JavaDoc[] fileList = resource.listFiles();
526             for (int i = 0; i < fileList.length; i++) {
527                 deepDelete(fileList[i]);
528             }
529         }
530         resource.delete();
531     }
532     
533     public String JavaDoc getProject(String JavaDoc referenceString) {
534         //team provider, cvs folder, project name
535
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(referenceString, ","); //$NON-NLS-1$
536
String JavaDoc version = tokenizer.nextToken();
537         // If this is a newer version, then ignore it
538
if (!version.equals("1.0")) //$NON-NLS-1$
539
return null;
540         try {
541             LoadInfo info = new LoadInfo(tokenizer);
542             return info.getProject().getName();
543         } catch (CVSException e) {
544             CVSProviderPlugin.log(e);
545             return null;
546         }
547     }
548     
549     public URI JavaDoc getURI(String JavaDoc referenceString) {
550         //team provider, cvs folder, project name
551
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(referenceString, ","); //$NON-NLS-1$
552
String JavaDoc version = tokenizer.nextToken();
553         // If this is a newer version, then ignore it
554
if (!version.equals("1.0")) //$NON-NLS-1$
555
return null;
556         try {
557             LoadInfo info = new LoadInfo(tokenizer);
558             CVSURI cvsURI = new CVSURI(info.repositoryLocation,new Path(info.module),info.tag);
559             return cvsURI.toURI();
560         } catch (CVSException e) {
561             CVSProviderPlugin.log(e);
562             return null;
563         }
564     }
565     
566     /* (non-Javadoc)
567      * @see org.eclipse.team.core.ProjectSetCapability#asReference(java.net.URI, java.lang.String)
568      */

569     public String JavaDoc asReference(URI JavaDoc uri, String JavaDoc projectName) {
570         try {
571             CVSURI cvsURI = CVSURI.fromUri(uri);
572             ICVSRepositoryLocation location = cvsURI.getRepository();
573             ICVSFolder folder = cvsURI.toFolder();
574             IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
575             return asReference((CVSRepositoryLocation)location, folder, project);
576         } catch (TeamException e) {
577             CVSProviderPlugin.log(e);
578             return null;
579         }
580     }
581
582 }
583
Popular Tags