]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - eclipse/plugins/org.argeo.slc.ide.ui/src/main/java/org/argeo/slc/ide/ui/launch/osgi/OsgiLaunchHelper.java
Save current state even if not completely stable
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.ide.ui / src / main / java / org / argeo / slc / ide / ui / launch / osgi / OsgiLaunchHelper.java
index 253a82afff007924286368ea02da6fe9aa596228..d69ed53946467335ff0790840be7dcc2c356e088 100644 (file)
@@ -5,14 +5,22 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 import java.util.StringTokenizer;
+import java.util.TreeSet;
 
 import org.argeo.slc.ide.ui.SlcIdeUiPlugin;
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.variables.IStringVariableManager;
@@ -25,115 +33,282 @@ import org.eclipse.jdt.launching.IVMInstall2;
 import org.eclipse.jdt.launching.IVMInstallType;
 import org.eclipse.jdt.launching.JavaRuntime;
 import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
-import org.eclipse.pde.ui.launcher.OSGiLaunchConfigurationInitializer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.PluginRegistry;
+import org.eclipse.pde.internal.build.IPDEBuildConstants;
+import org.eclipse.pde.launching.IPDELauncherConstants;
 import org.eclipse.swt.widgets.Display;
-
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Most of the actual logic is concentrated in this class which manipulates
+ * {@link ILaunchConfigurationWorkingCopy}. Static method are used since the
+ * shortcut and launch configuration classes are already extending PDE classes.
+ */
+@SuppressWarnings("restriction")
 public class OsgiLaunchHelper implements OsgiLauncherConstants {
-       private static Boolean debug = false;
+       private static Boolean debug = true;
 
-       /** Expect properties file to be set as mapped resources */
-       public static void updateLaunchConfiguration(
-                       ILaunchConfigurationWorkingCopy configuration) {
+       private final static String DEFAULT_DATA_DIR = "data";
+       private final static String DEFAULT_EXEC_DIR = "exec";
+       private final static String DEFAULT_VMARGS = "-Xmx128m";
+       private final static String DEFAULT_PROGRAM_ARGS = "-console";
+
+       /** Sets default values on this configuration. */
+       public static void setDefaults(ILaunchConfigurationWorkingCopy wc,
+                       Boolean isEclipse) {
                try {
-                       IFile propertiesFile = (IFile) configuration.getMappedResources()[0];
+                       if (isEclipse) {
+                               wc.setAttribute(IPDELauncherConstants.USE_DEFAULT, false);
+                               wc.setAttribute(IPDELauncherConstants.USE_PRODUCT, false);
+                       }
+
+                       wc.setAttribute(ATTR_ADD_JVM_PATHS, false);
+                       wc.setAttribute(ATTR_ADDITIONAL_VM_ARGS, DEFAULT_VMARGS);
+                       wc.setAttribute(ATTR_ADDITIONAL_PROGRAM_ARGS, DEFAULT_PROGRAM_ARGS);
+
+                       // Defaults
+                       String originalVmArgs = wc.getAttribute(
+                                       IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "");
+                       wc.setAttribute(ATTR_DEFAULT_VM_ARGS, originalVmArgs);
+                       wc.setAttribute(IPDELauncherConstants.CONFIG_CLEAR_AREA, false);
+               } catch (CoreException e) {
+                       Shell shell = Display.getCurrent().getActiveShell();
+                       ErrorDialog.openError(shell, "Error",
+                                       "Cannot execute initalize configuration", e.getStatus());
+               }
+       }
+
+       /** Find the working directory based on this properties file. */
+       public static String findWorkingDirectory(IFile propertiesFile) {
+               try {
+                       IProject project = propertiesFile.getProject();
+                       IPath parent = propertiesFile.getProjectRelativePath()
+                                       .removeLastSegments(1);
+                       IFolder execFolder = project.getFolder(parent
+                                       .append(DEFAULT_EXEC_DIR));
+                       if (!execFolder.exists())
+                               execFolder.create(true, true, null);
+                       IFolder launchFolder = project.getFolder(execFolder
+                                       .getProjectRelativePath().append(
+                                                       extractName(propertiesFile)));
+                       if (!launchFolder.exists())
+                               launchFolder.create(true, true, null);
+                       return "${workspace_loc:"
+                                       + launchFolder.getFullPath().toString().substring(1) + "}";
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       throw new RuntimeException("Cannot create working directory", e);
+               }
+       }
+
+       /** Extract the launch configuration name from the properties file. */
+       public static String extractName(IFile propertiesFile) {
+               IPath path = propertiesFile.getFullPath();
+               IPath pathNoExt = path.removeFileExtension();
+               return pathNoExt.segment(pathNoExt.segmentCount() - 1);
 
-                       Properties properties = OsgiLaunchHelper
-                                       .readProperties(propertiesFile);
+       }
+
+       /** Expects properties file to be set as mapped resources */
+       public static void updateLaunchConfiguration(
+                       ILaunchConfigurationWorkingCopy wc, Boolean isEclipse) {
+               try {
+                       // Finds the properties file and load it
+                       IFile propertiesFile = (IFile) wc.getMappedResources()[0];
+                       propertiesFile.refreshLocal(IResource.DEPTH_ONE, null);
+                       Properties properties = readProperties(propertiesFile);
 
+                       // Extract information from the properties file
                        List<String> bundlesToStart = new ArrayList<String>();
                        Map<String, String> systemPropertiesToAppend = new HashMap<String, String>();
-                       OsgiLaunchHelper.interpretProperties(properties, bundlesToStart,
-                                       systemPropertiesToAppend);
-
-                       // Reinitialize using standard OSGi launch shortcut
-                       // Kind of a hack but it lacks extension capabilities and it is
-                       // still
-                       // cleaner than forking the code (which would imply a lot of fork
-                       // indeed
-                       // because of all the internal classes)
-                       // new OSGiLaunchShortcut() {
-                       // @Override
-                       // public void initializeConfiguration(
-                       // ILaunchConfigurationWorkingCopy configuration) {
-                       // // TODO Auto-generated method stub
-                       // super.initializeConfiguration(configuration);
-                       // }
-                       // }.initializeConfiguration(configuration);
-
-                       // initializeConfiguration(configuration);
-
-                       File workingDir = getWorkingDirectory(configuration);
-                       File dataDir = new File(workingDir, "data");
-
-                       OsgiLaunchHelper.updateLaunchConfiguration(configuration,
-                                       bundlesToStart, systemPropertiesToAppend, dataDir
-                                                       .getAbsolutePath());
+                       String applicationId = interpretProperties(properties,
+                                       bundlesToStart, systemPropertiesToAppend);
+
+                       if (applicationId != null)
+                               wc.setAttribute(IPDELauncherConstants.APPLICATION,
+                                               applicationId);
+                       else {
+                               if (isEclipse)
+                                       throw new Exception("No application defined,"
+                                                       + " please set the 'eclipse.application' property"
+                                                       + " in the properties file");
+                       }
+
+                       // Define directories
+                       File workingDir = getWorkingDirectory(wc);
+                       File dataDir = new File(workingDir, DEFAULT_DATA_DIR);
+
+                       // Update the launch configuration accordingly
+                       updateLaunchConfiguration(wc, bundlesToStart,
+                                       systemPropertiesToAppend, dataDir.getAbsolutePath(),
+                                       isEclipse);
                } catch (Exception e) {
-                       ErrorDialog.openError(Display.getCurrent().getActiveShell(),
-                                       "Error", "Cannot read properties",
+                       e.printStackTrace();
+                       Shell shell = SlcIdeUiPlugin.getDefault().getWorkbench()
+                                       .getActiveWorkbenchWindow().getShell();
+                       // Shell shell= Display.getCurrent().getActiveShell();
+                       ErrorDialog.openError(shell, "Error",
+                                       "Cannot prepare launch configuration",
                                        new Status(IStatus.ERROR, SlcIdeUiPlugin.ID,
                                                        e.getMessage(), e));
                        return;
                }
        }
 
-       public static void updateLaunchConfiguration(
-                       ILaunchConfigurationWorkingCopy configuration,
-                       List<String> bundlesToStart,
-                       Map<String, String> systemPropertiesToAppend, String dataDir)
-                       throws CoreException {
+       /**
+        * Actually modifies the launch configuration in order to reflect the
+        * current state read from the properties file and the launch configuration
+        * UI.
+        */
+       protected static void updateLaunchConfiguration(
+                       ILaunchConfigurationWorkingCopy wc, List<String> bundlesToStart,
+                       Map<String, String> systemPropertiesToAppend, String dataDir,
+                       Boolean isEclipse) throws CoreException {
                // Convert bundle lists
-               String targetBundles = configuration.getAttribute(
-                               IPDELauncherConstants.TARGET_BUNDLES, "");
-               configuration.setAttribute(IPDELauncherConstants.TARGET_BUNDLES,
+               final String targetBundles;
+               final String wkSpaceBundles;
+               if (wc.getAttribute(ATTR_SYNC_BUNDLES, true)) {
+                       StringBuffer tBuf = new StringBuffer();
+                       for (IPluginModelBase model : PluginRegistry.getExternalModels()) {
+                               tBuf.append(model.getBundleDescription().getSymbolicName());
+                               tBuf.append(',');
+                       }
+                       targetBundles = tBuf.toString();
+                       StringBuffer wBuf = new StringBuffer();
+                       models: for (IPluginModelBase model : PluginRegistry
+                                       .getWorkspaceModels()) {
+                               if (model.getBundleDescription() == null) {
+                                       System.err.println("No bundle description for " + model);
+                                       continue models;
+                               }
+                               wBuf.append(model.getBundleDescription().getSymbolicName());
+                               wBuf.append(',');
+                       }
+                       wkSpaceBundles = wBuf.toString();
+               } else {
+                       targetBundles = wc.getAttribute(targetBundlesAttr(isEclipse), "");
+                       wkSpaceBundles = wc.getAttribute(workspaceBundlesAttr(isEclipse),
+                                       "");
+               }
+               wc.setAttribute(targetBundlesAttr(isEclipse),
                                convertBundleList(bundlesToStart, targetBundles));
 
-               String wkSpaceBundles = configuration.getAttribute(
-                               IPDELauncherConstants.WORKSPACE_BUNDLES, "");
-               configuration.setAttribute(IPDELauncherConstants.WORKSPACE_BUNDLES,
+               wc.setAttribute(workspaceBundlesAttr(isEclipse),
                                convertBundleList(bundlesToStart, wkSpaceBundles));
 
                // Update other default information
-               configuration.setAttribute(IPDELauncherConstants.DEFAULT_AUTO_START,
-                               false);
-               String defaultVmArgs = configuration.getAttribute(
+               wc.setAttribute(IPDELauncherConstants.DEFAULT_AUTO_START, false);
+
+               // VM arguments (system properties)
+               String defaultVmArgs = wc.getAttribute(
                                OsgiLauncherConstants.ATTR_DEFAULT_VM_ARGS, "");
                StringBuffer vmArgs = new StringBuffer(defaultVmArgs);
-               vmArgs.append(" "
-                               + configuration.getAttribute(ATTR_ADDITIONAL_VM_ARGS, ""));
+
+               // Data dir system property
+               if (dataDir != null) {
+                       addSysProperty(vmArgs, OsgiLauncherConstants.ARGEO_OSGI_DATA_DIR,
+                                       dataDir);
+                       if (isEclipse) {
+                               wc.setAttribute(IPDELauncherConstants.LOCATION, dataDir);
+                       }
+               }
 
                // Add locations of JVMs
-               if (configuration.getAttribute(ATTR_ADD_JVM_PATHS, false))
+               if (wc.getAttribute(ATTR_ADD_JVM_PATHS, false))
                        addVms(vmArgs);
 
                // Add other system properties
                for (String key : systemPropertiesToAppend.keySet())
                        addSysProperty(vmArgs, key, systemPropertiesToAppend.get(key));
 
-               if (dataDir != null)
-                       addSysProperty(vmArgs, OsgiLauncherConstants.ARGEO_OSGI_DATA_DIR,
-                                       dataDir);
+               vmArgs.append(" ").append(wc.getAttribute(ATTR_ADDITIONAL_VM_ARGS, ""));
 
-               configuration.setAttribute(
-                               IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs
-                                               .toString());
+               wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
+                               vmArgs.toString());
 
                // Program arguments
-               StringBuffer progArgs = new StringBuffer(configuration.getAttribute(
-                               OsgiLauncherConstants.ATTR_ADDITIONAL_PROGRAM_ARGS, ""));
+               StringBuffer progArgs = new StringBuffer("");
                if (dataDir != null) {
-                       progArgs.append(" -data ");
+                       progArgs.append("-data ");
                        progArgs.append(surroundSpaces(dataDir));
+
+                       if (wc.getAttribute(ATTR_CLEAR_DATA_DIRECTORY, false)) {
+                               File dataDirFile = new File(dataDir);
+                               deleteDir(dataDirFile);
+                               dataDirFile.mkdirs();
+                       }
                }
-               configuration.setAttribute(
+               String additionalProgramArgs = wc.getAttribute(
+                               OsgiLauncherConstants.ATTR_ADDITIONAL_PROGRAM_ARGS, "");
+               progArgs.append(' ').append(additionalProgramArgs);
+               wc.setAttribute(
                                IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
                                progArgs.toString());
+       }
+
+       /** The launch configuration attribute to use for target bundles */
+       protected static String targetBundlesAttr(Boolean isEclipse) {
+               return isEclipse ? IPDELauncherConstants.SELECTED_TARGET_PLUGINS
+                               : IPDELauncherConstants.TARGET_BUNDLES;
+       }
+
+       /** The launch configuration attribute to use for workspace bundles */
+       protected static String workspaceBundlesAttr(Boolean isEclipse) {
+               return isEclipse ? IPDELauncherConstants.SELECTED_WORKSPACE_PLUGINS
+                               : IPDELauncherConstants.WORKSPACE_BUNDLES;
+       }
 
-               // String dir = findWorkingDirectory();
+       /**
+        * Interprets special properties and register the others as system
+        * properties to append.
+        * 
+        * @return the application id defined by
+        *         {@link OsgiLauncherConstants#ECLIPSE_APPLICATION}, or null if not
+        *         found
+        */
+       protected static String interpretProperties(Properties properties,
+                       List<String> bundlesToStart,
+                       Map<String, String> systemPropertiesToAppend) {
+               String argeoOsgiStart = properties
+                               .getProperty(OsgiLauncherConstants.ARGEO_OSGI_START);
+               if (argeoOsgiStart != null) {
+                       StringTokenizer st = new StringTokenizer(argeoOsgiStart, ",");
+                       while (st.hasMoreTokens())
+                               bundlesToStart.add(st.nextToken());
+               }
 
+               String applicationId = null;
+               propKeys: for (Object keyObj : properties.keySet()) {
+                       String key = keyObj.toString();
+                       if (OsgiLauncherConstants.ARGEO_OSGI_START.equals(key))
+                               continue propKeys;
+                       else if (OsgiLauncherConstants.ARGEO_OSGI_BUNDLES.equals(key))
+                               continue propKeys;
+                       else if (OsgiLauncherConstants.ARGEO_OSGI_LOCATIONS.equals(key))
+                               continue propKeys;
+                       else if (OsgiLauncherConstants.OSGI_BUNDLES.equals(key))
+                               continue propKeys;
+                       else if (OsgiLauncherConstants.ECLIPSE_APPLICATION.equals(key))
+                               applicationId = properties.getProperty(key);
+                       else
+                               systemPropertiesToAppend.put(key, properties.getProperty(key));
+               }
+               return applicationId;
        }
 
+       /** Adds a regular system property. */
+       protected static void addSysProperty(StringBuffer vmArgs, String key,
+                       String value) {
+               surroundSpaces(value);
+               String str = "-D" + key + "=" + value;
+               vmArgs.append(' ').append(str);
+       }
+
+       /** Adds JVMS registered in the workspace as special system properties. */
        protected static void addVms(StringBuffer vmArgs) {
                addVmSysProperty(vmArgs, "default", JavaRuntime.getDefaultVMInstall());
                IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes();
@@ -153,28 +328,22 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
                                        while (st.hasMoreTokens())
                                                tokens.add(st.nextToken());
                                        if (tokens.size() >= 2)
-                                               addVmSysProperty(vmArgs, tokens.get(0) + "."
-                                                               + tokens.get(1), vmInstall);
+                                               addVmSysProperty(vmArgs,
+                                                               tokens.get(0) + "." + tokens.get(1), vmInstall);
                                }
                        }
                }
 
        }
 
+       /** Adds a special system property pointing to one of the registered JVMs. */
        protected static void addVmSysProperty(StringBuffer vmArgs, String suffix,
                        IVMInstall vmInstall) {
                addSysProperty(vmArgs, OsgiLauncherConstants.VMS_PROPERTY_PREFIX + "."
                                + suffix, vmInstall.getInstallLocation().getPath());
        }
 
-       protected static void addSysProperty(StringBuffer vmArgs, String key,
-                       String value) {
-               surroundSpaces(value);
-               String str = "-D" + key + "=" + value;
-               // surroundSpaces(str);
-               vmArgs.append(" " + str);
-       }
-
+       /** Surround the string with quotes if it contains spaces. */
        protected static String surroundSpaces(String str) {
                if (str.indexOf(' ') >= 0)
                        return '\"' + str + '\"';
@@ -182,30 +351,54 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
                        return str;
        }
 
+       /**
+        * Reformat the bundle list in order to reflect which bundles have to be
+        * started.
+        */
        protected static String convertBundleList(List<String> bundlesToStart,
                        String original) {
-               StringBuffer bufBundles = new StringBuffer(1024);
+               if (debug)
+                       System.out.println("Original bundle list: " + original);
+
                StringTokenizer stComa = new StringTokenizer(original, ",");
-               boolean first = true;
+               // sort by bundle symbolic name
+               Set<String> bundleIds = new TreeSet<String>();
                bundles: while (stComa.hasMoreTokens()) {
-                       if (first)
-                               first = false;
-                       else
-                               bufBundles.append(',');
 
                        String bundleId = stComa.nextToken();
+                       if (bundleId.indexOf('*') >= 0)
+                               throw new RuntimeException(
+                                               "Bundle id "
+                                                               + bundleId
+                                                               + " not properly formatted, clean your workspace projects");
+
                        int indexAt = bundleId.indexOf('@');
-                       boolean modified = false;
                        if (indexAt >= 0) {
                                bundleId = bundleId.substring(0, indexAt);
                        }
 
+                       // We can now rely on bundleId value
+
                        if (bundleId.endsWith(".source")) {
                                if (debug)
                                        System.out.println("Skip source bundle " + bundleId);
                                continue bundles;
+                       } else if (bundleId
+                                       .equals(IPDEBuildConstants.BUNDLE_SIMPLE_CONFIGURATOR)) {
+                               // skip simple configurator in order to avoid side-effects
+                               continue bundles;
                        }
+                       bundleIds.add(bundleId);
+               }
 
+               StringBuffer bufBundles = new StringBuffer(1024);
+               boolean first = true;
+               for (String bundleId : bundleIds) {
+                       if (first)
+                               first = false;
+                       else
+                               bufBundles.append(',');
+                       boolean modified = false;
                        if (bundlesToStart.contains(bundleId)) {
                                bufBundles.append(bundleId).append('@').append("default:true");
                                modified = true;
@@ -215,12 +408,27 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
 
                        if (!modified)
                                bufBundles.append(bundleId);
+
                }
                String output = bufBundles.toString();
                return output;
        }
 
-       protected static Properties readProperties(IFile file) throws CoreException {
+       // UTILITIES
+       /** Recursively deletes a directory tree. */
+       private static void deleteDir(File dir) {
+               File[] files = dir.listFiles();
+               for (File file : files) {
+                       if (file.isDirectory())
+                               deleteDir(file);
+                       else
+                               file.delete();
+               }
+               dir.delete();
+       }
+
+       /** Loads a properties file. */
+       private static Properties readProperties(IFile file) throws CoreException {
                Properties props = new Properties();
 
                InputStream in = null;
@@ -241,36 +449,9 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
                return props;
        }
 
-       protected static void interpretProperties(Properties properties,
-                       List<String> bundlesToStart,
-                       Map<String, String> systemPropertiesToAppend) {
-               String argeoOsgiStart = properties
-                               .getProperty(OsgiLauncherConstants.ARGEO_OSGI_START);
-               if (argeoOsgiStart != null) {
-                       StringTokenizer st = new StringTokenizer(argeoOsgiStart, ",");
-                       while (st.hasMoreTokens())
-                               bundlesToStart.add(st.nextToken());
-               }
-
-               propKeys: for (Object keyObj : properties.keySet()) {
-                       String key = keyObj.toString();
-                       if (OsgiLauncherConstants.ARGEO_OSGI_START.equals(key))
-                               continue propKeys;
-                       else if (OsgiLauncherConstants.ARGEO_OSGI_BUNDLES.equals(key))
-                               continue propKeys;
-                       else if (OsgiLauncherConstants.ARGEO_OSGI_LOCATIONS.equals(key))
-                               continue propKeys;
-                       else if (OsgiLauncherConstants.OSGI_BUNDLES.equals(key))
-                               continue propKeys;
-                       else
-                               systemPropertiesToAppend.put(key, properties.getProperty(key));
-               }
-
-       }
-
        // Hacked from
        // org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper.getWorkingDirectory(ILaunchConfiguration)
-       public static File getWorkingDirectory(ILaunchConfiguration configuration)
+       private static File getWorkingDirectory(ILaunchConfiguration configuration)
                        throws CoreException {
                String working;
                try {
@@ -280,7 +461,15 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
                } catch (IOException e) {
                        working = "${workspace_loc}/../"; //$NON-NLS-1$
                }
-               File dir = new File(getSubstitutedString(working));
+               File dir;
+               try {
+                       dir = new File(getSubstitutedString(working));
+               } catch (Exception e) {
+                       // the directory was most probably deleted
+                       IFile propertiesFile = (IFile) configuration.getMappedResources()[0];
+                       working = findWorkingDirectory(propertiesFile);
+                       dir = new File(getSubstitutedString(working));
+               }
                if (!dir.exists())
                        dir.mkdirs();
                return dir;
@@ -297,9 +486,63 @@ public class OsgiLaunchHelper implements OsgiLauncherConstants {
                return mgr.performStringSubstitution(text);
        }
 
-       static void initializeConfiguration(
-                       ILaunchConfigurationWorkingCopy configuration) {
-               new OSGiLaunchConfigurationInitializer().initialize(configuration);
+       /**
+        * Not used anymore, but kept because this routine may be useful in the
+        * future.
+        */
+       protected void addSelectedProjects(StringBuffer name, ISelection selection,
+                       List<String> bundlesToStart) {
+               Assert.isNotNull(selection);
+
+               Map<String, IPluginModelBase> bundleProjects = new HashMap<String, IPluginModelBase>();
+               for (IPluginModelBase modelBase : PluginRegistry.getWorkspaceModels()) {
+                       IProject bundleProject = modelBase.getUnderlyingResource()
+                                       .getProject();
+                       bundleProjects.put(bundleProject.getName(), modelBase);
+               }
+
+               IStructuredSelection sSelection = (IStructuredSelection) selection;
+               for (Iterator<?> it = sSelection.iterator(); it.hasNext();) {
+                       Object obj = it.next();
+                       if (obj instanceof IProject) {
+                               IProject project = (IProject) obj;
+                               if (bundleProjects.containsKey(project.getName())) {
+                                       IPluginModelBase modelBase = bundleProjects.get(project
+                                                       .getName());
+
+                                       BundleDescription bundleDescription = null;
+                                       if (modelBase.isFragmentModel()) {
+                                               BundleDescription[] hosts = modelBase
+                                                               .getBundleDescription().getHost().getHosts();
+                                               for (BundleDescription bd : hosts) {
+                                                       if (debug)
+                                                               System.out.println("Host for "
+                                                                               + modelBase.getBundleDescription()
+                                                                                               .getSymbolicName() + ": "
+                                                                               + bd.getSymbolicName());
+                                                       bundleDescription = bd;
+                                               }
+                                       } else {
+                                               bundleDescription = modelBase.getBundleDescription();
+                                       }
+
+                                       if (bundleDescription != null) {
+                                               String symbolicName = bundleDescription
+                                                               .getSymbolicName();
+                                               String bundleName = bundleDescription.getName();
+
+                                               bundlesToStart.add(symbolicName);
+
+                                               if (name.length() > 0)
+                                                       name.append(" ");
+                                               if (bundleName != null)
+                                                       name.append(bundleName);
+                                               else
+                                                       name.append(symbolicName);
+                                       }
+                               }
+                       }
+               }
        }
 
 }