[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Subclipse PSF enhancement

From: Magnus Naeslund(t) <mag_at_fbab.net>
Date: 2005-02-08 22:07:10 CET

I've tried to submit earlier versions of this code through the issue
tracker, but I haven't gotten any response back so I thought this forum
might be better suited. This is my first post here.

This patch makes these two things work:

1) The possibility to import stuff from the filesystem that are already
checked out via other means (svn commandline, TortoiseSVN).
This is pretty neat because you can then work with commandline tools,
check out trees and what not and then still use them in Eclipse in a
good way. If you want any more details on why this is important, I can
give you a real life example.

2) Add relative paths support to PSF handling.
This makes it simple to make PSF files works with "external" trees, for
example it isn't affected by branching as the URL scheme is.

I would very much like some feedback on this code, I'm not terribly
familiar with either Eclipse or Subclipse code. If this idea is totally
out the window, please tell me why!

The patch is against 0.9.27 and applies on subclipse-3 trunk.

Regards,
Magnus

Index: /svnmeck/subclipse-3-0.9.27/core/src/org/tigris/subversion/subclipse/core/SVNProjectSetCapability.java
===================================================================
--- /svnmeck/subclipse-3-0.9.27/core/src/org/tigris/subversion/subclipse/core/SVNProjectSetCapability.java (revision 1236)
+++ /svnmeck/subclipse-3-0.9.27/core/src/org/tigris/subversion/subclipse/core/SVNProjectSetCapability.java (working copy)
@@ -9,10 +9,13 @@
 
  Dan Rubel - initial API and implementation
  Panagiotis Korros (pkorros@bigfoot.com) - modified for Subversion
+ Magnus Naeslund (mag@kite.se) - added support for externally checked out projects and relative paths
  **********************************************************************/
 
 package org.tigris.subversion.subclipse.core;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -21,8 +24,11 @@
 import java.util.StringTokenizer;
 
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.team.core.ProjectSetCapability;
 import org.eclipse.team.core.ProjectSetSerializationContext;
@@ -96,7 +102,7 @@
 
                 // Confirm the projects to be loaded
                 Map infoMap = new HashMap(referenceStrings.length);
- IProject[] projects = asProjects(referenceStrings, infoMap);
+ IProject[] projects = asProjects(context, referenceStrings, infoMap);
                 projects = confirmOverwrite(context, projects);
                 if (projects == null){
                         return new IProject[0];
@@ -109,13 +115,16 @@
          * Translate the reference strings into projects to be loaded and build a
          * mapping of project to project load information.
          *
+ * @param context
+ * the context of where the references came from
          * @param referenceStrings
          * project references
          * @param infoMap
          * a mapping of project to project load information
          * @return the projects to be loaded
          */
- private IProject[] asProjects(String[] referenceStrings, Map infoMap)
+ private IProject[] asProjects(ProjectSetSerializationContext context,
+ String[] referenceStrings, Map infoMap)
                         throws SVNException {
                 Collection result = new ArrayList();
                 for (int i = 0; i < referenceStrings.length; i++) {
@@ -126,7 +135,7 @@
                         if (!version.equals("0.9.3")){ //$NON-NLS-1$
                                 continue;
                         }
- LoadInfo info = new LoadInfo(tokenizer);
+ LoadInfo info = new LoadInfo(context, tokenizer);
                         IProject proj = info.getProject();
                         result.add(proj);
                         infoMap.put(proj, info);
@@ -173,19 +182,58 @@
         class LoadInfo {
                 private final ISVNRepositoryLocation repositoryLocation;
                 private final IProject project;
-
+ private final boolean fromFileSystem;
+ private final String directory; // Only used when fromFileSystem is true
+
                 /**
                  * Construct a new instance wrappering the specified project reference
                  *
+ * @param context
+ * the context of where the reference came from
                  * @param projRef
                  * the project reference
                  */
- LoadInfo(StringTokenizer tokenizer) throws SVNException {
+ LoadInfo(ProjectSetSerializationContext context, StringTokenizer tokenizer) throws SVNException {
                         String repo = tokenizer.nextToken();
- repositoryLocation = SVNRepositoryLocation.fromString(repo);
                         String projectName = tokenizer.nextToken();
+
                         project = ResourcesPlugin.getWorkspace().getRoot().getProject(
                                         projectName);
+
+ if (repo.indexOf("://") != -1){ //$NON-NLS-1$
+ //A normal URL
+ repositoryLocation = SVNRepositoryLocation.fromString(repo);
+ fromFileSystem = false;
+ directory = null;
+ } else {
+ // Assume this is an already checked out project, from the filesystem
+ repositoryLocation = null;
+ fromFileSystem = true;
+
+ // Is it relative? If so, expand it from the psf file location
+ if (!Path.fromOSString(repo).isAbsolute()) {
+ String baseDir;
+
+ if (context.getFilename() != null){
+ baseDir = new File(context.getFilename()).getParent();
+ }else{
+ // Use the workspace root directory as basedir, this shouldn't happen
+ baseDir = project.getWorkspace().getRoot().getLocation().toOSString();
+ }
+ try {
+ directory = new File(baseDir + File.separatorChar
+ + repo).getCanonicalPath();
+ } catch (IOException ioe) {
+ throw new SVNException(
+ "Path expansion/canonicalization failed", ioe);
+ }
+
+ } else {
+ directory = repo;
+ }
+
+ }
+
                 }
 
                 /**
@@ -207,14 +255,87 @@
                  * @throws TeamException
                  */
                 boolean checkout(IProgressMonitor monitor) throws TeamException {
- if (repositoryLocation == null){
+ if (fromFileSystem){
+ return importExistingProject(monitor);
+ } else {
+ if (repositoryLocation == null){
+ return false;
+ }
+ CheckoutCommand command = new CheckoutCommand(new ISVNRemoteFolder[]{(ISVNRemoteFolder) repositoryLocation
+ .getRootFolder()}, new IProject[]{project});
+ command.run(monitor);
+ return true;
+ }
+ }
+
+ /**
+ * Imports a existing SVN Project to the workbench
+ *
+ * @param monitor
+ * project monitor
+ * @return true if loaded, else false
+ * @throws TeamException
+ */
+
+ boolean importExistingProject(IProgressMonitor monitor) throws TeamException {
+ if (directory == null){
                                 return false;
                         }
- CheckoutCommand command = new CheckoutCommand(new ISVNRemoteFolder[]{(ISVNRemoteFolder) repositoryLocation
- .getRootFolder()}, new IProject[]{project});
- command.run(monitor);
- return true;
+ try{
+
+ monitor.beginTask("Importing", 3 * 1000);
+
+ createExistingProject(new SubProgressMonitor(monitor, 1000));
+
+ monitor.subTask("Refreshing "+project.getName());
+ RepositoryProvider.map(project, SVNProviderPlugin.getTypeId());
+ SVNTeamProvider provider =
+ (SVNTeamProvider) RepositoryProvider.getProvider(project,
+ SVNProviderPlugin.getTypeId());
+ monitor.worked(1000);
+ SVNWorkspaceRoot.setSharing(project, new SubProgressMonitor(
+ monitor, 1000));
+
+ return true;
+ }catch(CoreException ce){
+ throw new SVNException("Failed to import External SVN Project" +ce, ce);
+ }finally{
+ monitor.done();
+ }
                 }
+
+ /**
+ * Creates a new project in the workbench from an existing one
+ *
+ * @param monitor
+ * @throws CoreException
+ */
+
+
+ void createExistingProject(IProgressMonitor monitor)
+ throws CoreException {
+ String projectName = project.getName();
+ IProjectDescription description;
+
+ try {
+ monitor.beginTask("Creating " + projectName, 2 * 1000);
+
+ description = ResourcesPlugin.getWorkspace()
+ .loadProjectDescription(
+ new Path(directory + File.separatorChar
+ + ".project")); //$NON-NLS-1$
+
+ description.setName(projectName);
+ project.create(description, new SubProgressMonitor(monitor,
+ 1000));
+ project.open(new SubProgressMonitor(monitor, 1000));
+ } finally {
+ monitor.done();
+ }
+ }
+
+
+
         }
 
 }
\ No newline at end of file
Received on Wed Feb 9 08:07:10 2005

This is an archived mail posted to the Subclipse Dev mailing list.