changeset 117:4d787bcff36c

Show local bundles in new bundle dialog Identify all bundles in all open projects in the current workspace and offer them as possible candidates in the new bundle dialog.
author Omair Majid <omajid@redhat.com>
date Wed, 05 Mar 2014 13:36:27 -0500
parents b48371bbae86
children 96c81fcd180c
files TODO.md com.redhat.thermostat.tools.eclipse.plugin.tests/src/com/redhat/thermostat/tools/eclipse/plugin/tests/BundleFinderTest.java com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/BundleFinder.java com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/NewBundleDialog.java
diffstat 4 files changed, 196 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/TODO.md	Tue Mar 04 18:08:11 2014 -0500
+++ b/TODO.md	Wed Mar 05 13:36:27 2014 -0500
@@ -13,3 +13,6 @@
 
 - Add support for creating multi-project plugin. Possibly make use of
   maven archetype from `thermostat`.
+
+- Replace various `Exception.printStackTrace()` calls with either logging or
+  user-visible prompts.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/com.redhat.thermostat.tools.eclipse.plugin.tests/src/com/redhat/thermostat/tools/eclipse/plugin/tests/BundleFinderTest.java	Wed Mar 05 13:36:27 2014 -0500
@@ -0,0 +1,34 @@
+package com.redhat.thermostat.tools.eclipse.plugin.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.tools.eclipse.plugin.BundleFinder;
+import com.redhat.thermostat.tools.eclipse.plugin.BundleInformation;
+
+public class BundleFinderTest {
+
+    private IProgressMonitor progressMonitor;
+
+    @Before
+    public void setUp() {
+        progressMonitor = new NullProgressMonitor();
+    }
+
+    @Test
+    public void testNoArgumentVariantDoesNothing() {
+        BundleFinder finder = new BundleFinder(new IProject[0], progressMonitor);
+        Collection<BundleInformation> result = finder.find();
+        assertNotNull(result);
+        assertTrue(result.isEmpty());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/BundleFinder.java	Wed Mar 05 13:36:27 2014 -0500
@@ -0,0 +1,90 @@
+package com.redhat.thermostat.tools.eclipse.plugin;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Finds bundles in all open projects.
+ * <p>
+ * There is no way to do this reliably using an API. So fall back to finding
+ * jars and checking for bundle information in them.
+ */
+public class BundleFinder {
+
+    // TODO add progress monitor support
+
+    private static final String SYMBOLIC_NAME = "Bundle-SymbolicName";
+    private static final String VERSION = "Bundle-Version";
+
+    private File workspaceRoot;
+    private IProject[] projects;
+
+    public BundleFinder(IProject[] projects, IProgressMonitor progressMonitor) {
+        this.projects = projects;
+        initialize();
+    }
+
+    private void initialize() {
+        workspaceRoot = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile();
+    }
+
+    public Collection<BundleInformation> find() {
+        final List<IPath> jarPaths = new ArrayList<>();
+
+        for (IProject project : this.projects) {
+            try {
+                project.accept(new IResourceVisitor() {
+                    @Override
+                    public boolean visit(IResource resource) throws CoreException {
+                        if (resource.getName().endsWith(".jar")) {
+                            jarPaths.add(resource.getFullPath());
+                        }
+                        return true;
+                    }
+                });
+            } catch (CoreException e) {
+                e.printStackTrace();
+            }
+        }
+
+        List<BundleInformation> result = new ArrayList<>();
+
+        for (IPath jarPath : jarPaths) {
+            File jarFile = jarPath.toFile();
+            File completeFile = new File(workspaceRoot, jarFile.toString());
+            try (JarInputStream in = new JarInputStream(new FileInputStream(completeFile))) {
+                Manifest manifest = in.getManifest();
+                Attributes attrs = manifest.getMainAttributes();
+                String symbolicName = attrs.getValue(SYMBOLIC_NAME);
+                String version = attrs.getValue(VERSION);
+                if (symbolicName != null && version != null) {
+                    result.add(new BundleInformation(symbolicName, version));
+                }
+            } catch (FileNotFoundException e) {
+                throw new AssertionError("A file that was found is now gone: " + completeFile);
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        return result;
+    }
+}
--- a/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/NewBundleDialog.java	Tue Mar 04 18:08:11 2014 -0500
+++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/NewBundleDialog.java	Wed Mar 05 13:36:27 2014 -0500
@@ -1,10 +1,19 @@
 package com.redhat.thermostat.tools.eclipse.plugin.editor;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -19,6 +28,7 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 
+import com.redhat.thermostat.tools.eclipse.plugin.BundleFinder;
 import com.redhat.thermostat.tools.eclipse.plugin.BundleInformation;
 import com.redhat.thermostat.tools.eclipse.plugin.BundleInformationExtractor;
 import com.redhat.thermostat.tools.eclipse.plugin.Messages;
@@ -33,6 +43,11 @@
     private BundleInformation bundleInfo = new BundleInformation();
 
     private ThermostatBundleInformation thermostatInfo = new ThermostatBundleInformation();
+    private BundleFinder projectBundleFinder;
+
+    private Button projectBundlesSelector;
+    private Combo projectBundles;
+    private ComboViewer projectBundlesViewer;
 
     private Button thermostatBundlesSelector;
     private Combo thermostatBundleVersion;
@@ -48,6 +63,22 @@
 
     public NewBundleDialog(Shell parentShell) {
         super(parentShell);
+
+        projectBundleFinder = new BundleFinder(getOpenProjects(), new NullProgressMonitor());
+    }
+
+    private IProject[] getOpenProjects() {
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+        IProject[] allProjects = root.getProjects();
+        List<IProject> openProjects = new ArrayList<>();
+        for (IProject project: allProjects) {
+            if (project.isOpen()) {
+                openProjects.add(project);
+            }
+        }
+
+        return openProjects.toArray(new IProject[openProjects.size()]);
     }
 
     @Override
@@ -71,8 +102,38 @@
         containerLayout.marginLeft = 5;
         container.setLayout(containerLayout);
 
+        projectBundlesSelector = new Button(container, SWT.RADIO);
+        projectBundlesSelector.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                disableInputWidgets();
+
+                projectBundles.setEnabled(true);
+            }
+        });
+        projectBundlesSelector.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
+        projectBundlesSelector.setText("Current workspace projects");
+
+        Label projectBundlesLabel = new Label(container, SWT.None);
+        projectBundlesLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+        projectBundlesLabel.setText("Bundle");
+
+        projectBundles = new Combo(container, SWT.READ_ONLY | SWT.DROP_DOWN);
+        GridData projectBundlesLayoutData = new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1);
+        projectBundles.setLayoutData(projectBundlesLayoutData);
+
+        projectBundlesViewer = new ComboViewer(projectBundles);
+        projectBundlesViewer.setContentProvider(new ArrayContentProvider());
+        projectBundlesViewer.setInput(projectBundleFinder.find());
+        projectBundlesViewer.setLabelProvider(new ColumnLabelProvider() {
+            @Override
+            public String getText(Object element) {
+                BundleInformation bundle = (BundleInformation) element;
+                return bundle.getName() + " = " + bundle.getVersion();
+            }
+        });
+
         thermostatBundlesSelector = new Button(container, SWT.RADIO);
-        thermostatBundlesSelector.setSelection(true);
         thermostatBundlesSelector.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
@@ -173,12 +234,14 @@
         });
 
         // invoke manually on startup to enable/disable other widgets
-        thermostatBundlesSelector.setSelection(true);
+        projectBundlesSelector.setSelection(true);
 
         return area;
     }
 
     private void disableInputWidgets() {
+        projectBundles.setEnabled(false);
+
         thermostatBundleVersion.setEnabled(false);
         thermostatBundleName.setEnabled(false);
 
@@ -201,7 +264,10 @@
     }
 
     private void saveInput() {
-        if (thermostatBundlesSelector.getSelection()) {
+        if (projectBundlesSelector.getSelection()) {
+            IStructuredSelection selection = (IStructuredSelection) projectBundlesViewer.getSelection();
+            bundleInfo = (BundleInformation) selection.getFirstElement();
+        } else if (thermostatBundlesSelector.getSelection()) {
             bundleInfo = new BundleInformation(thermostatBundleName.getText(), thermostatBundleVersion.getText());
         } else if (manualBundleSelector.getSelection()) {
             bundleInfo = new BundleInformation(manualBundleName.getText(), manualBundleVersion.getText());