blob: 464dcdf5a97c2e876938c3880abf385eb238badf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 OPCoach and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Olivier Prouvost <olivier.prouvost@opcoach.com> - initial API and implementation (bug #451116)
* Simon Scholz <simon.scholz@vogella.com> - Bug 466785
*******************************************************************************/
package org.eclipse.e4.tools.bundles.spy;
import java.util.Iterator;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.internal.tools.bundles.spy.BundleDataFilter;
import org.eclipse.e4.internal.tools.bundles.spy.BundleDataProvider;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;
/**
* This class is the main part of the bundle spy. It displays a tableviewer with
* all bundles
*/
public class BundleSpyPart {
private static final String ICON_REFRESH = "icons/refresh.gif";
public static final String ICON_STATE_ACTIVE = "icons/state_active.gif";
public static final String ICON_STATE_STARTING = "icons/state_starting.gif";
public static final String ICON_STATE_STOPPING = "icons/state_stopping.gif";
public static final String ICON_STATE_RESOLVED = "icons/state_resolved.gif";
public static final String ICON_STATE_INSTALLED = "icons/state_installed.gif";
public static final String ICON_STATE_UNINSTALLED = "icons/state_uninstalled.gif";
public static final String ICON_START = "icons/start.gif";
public static final String ICON_STOP = "icons/stop.gif";
private TableViewer bundlesTableViewer;
private Text filterText;
private Button showOnlyFilteredElements;
private BundleDataFilter bundleFilter;
@Inject
private IEclipseContext ctx;
/** Store the values to set it when it is reopened */
private static String lastFilterText = null;
private static boolean lastShowFiltered = false;
/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
ImageRegistry imgReg = initializeImageRegistry();
// Set a filter in context (-> null at the begining).
bundleFilter = new BundleDataFilter();
ctx.set(BundleDataFilter.class, bundleFilter);
parent.setLayout(new GridLayout(1, false));
final Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(5, false));
Button refreshButton = new Button(comp, SWT.FLAT);
refreshButton.setImage(imgReg.get(ICON_REFRESH));
refreshButton.setToolTipText("Refresh the contexts");
refreshButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
bundlesTableViewer.refresh(true);
}
});
filterText = new Text(comp, SWT.SEARCH | SWT.ICON_SEARCH);
GridDataFactory.fillDefaults().hint(200, SWT.DEFAULT)
.applyTo(filterText);
filterText.setMessage("Search data");
filterText
.setToolTipText("Highlight the bundles where the contained objects contains this string.\n"
+ "Case is ignored.");
if (lastFilterText != null)
filterText.setText(lastFilterText);
bundleFilter.setPattern(lastFilterText);
filterText.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
String textToSearch = filterText.getText();
lastFilterText = textToSearch;
boolean enableButton = textToSearch.length() > 0;
// Enable/disable button for filtering
showOnlyFilteredElements.setEnabled(enableButton);
// Then update filters and viewers
bundleFilter.setPattern(textToSearch);
setFilter();
bundlesTableViewer.refresh(true);
}
});
showOnlyFilteredElements = new Button(comp, SWT.CHECK);
showOnlyFilteredElements.setText("Show Only Filtered");
showOnlyFilteredElements
.setToolTipText("Show only the filtered items in the bundle table ");
showOnlyFilteredElements.setEnabled((lastFilterText != null)
&& (lastFilterText.length() > 0));
showOnlyFilteredElements.setSelection(lastShowFiltered);
showOnlyFilteredElements.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
lastShowFiltered = showOnlyFilteredElements.getSelection();
setFilter();
}
});
startButton = new Button(comp, SWT.FLAT);
startButton.setImage(imgReg.get(ICON_START));
startButton
.setToolTipText("Start the selected bundles not yet started");
startButton.setEnabled(false);
startButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IStructuredSelection sel = (IStructuredSelection) bundlesTableViewer
.getSelection();
Iterator<?> iter = sel.iterator();
while (iter.hasNext()) {
Bundle b = (Bundle) iter.next();
try {
b.start();
} catch (BundleException e1) {
e1.printStackTrace();
}
}
bundlesTableViewer.refresh();
updateButtonStatuses(sel);
}
});
stopButton = new Button(comp, SWT.FLAT);
stopButton.setImage(imgReg.get(ICON_STOP));
stopButton.setToolTipText("Stop the selected bundles not yet stopped");
stopButton.setEnabled(false);
stopButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (MessageDialog.openConfirm(
((Control) e.getSource()).getShell(),
"Confirm Bundle Stop",
"Stopping a bundle may cause problems in your current application.\nUse this button only for your bundles under testing\n\nDo you confirm you want to stop the selected started bundle(s) ? ")) {
IStructuredSelection sel = (IStructuredSelection) bundlesTableViewer
.getSelection();
Iterator<?> iter = sel.iterator();
while (iter.hasNext()) {
Bundle b = (Bundle) iter.next();
try {
b.stop();
} catch (BundleException e1) {
e1.printStackTrace();
}
}
bundlesTableViewer.refresh();
updateButtonStatuses(sel);
}
}
});
// Create the customer table with 2 columns: firstname and name
bundlesTableViewer = new TableViewer(parent);
final Table cTable = bundlesTableViewer.getTable();
cTable.setHeaderVisible(true);
cTable.setLinesVisible(true);
GridData gd_cTable = new GridData(SWT.FILL, SWT.FILL, true, true);
// gd_cTable.verticalAlignment = SWT.TOP;
cTable.setLayoutData(gd_cTable);
// Create the first column for bundle name
addColumn(bundlesTableViewer, 35, "State", BundleDataProvider.COL_STATE);
addColumn(bundlesTableViewer, 200, "Bundle Name",
BundleDataProvider.COL_NAME);
addColumn(bundlesTableViewer, 200, "Version",
BundleDataProvider.COL_VERSION);
// Set input data and content provider (default ArrayContentProvider)
bundlesTableViewer.setContentProvider(ArrayContentProvider
.getInstance());
// Get the list of bundles in platform using bundle context...
BundleContext bc = BundleSpyActivator.getContext();
bundlesTableViewer.setInput(bc.getBundles());
bundlesTableViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
updateButtonStatuses((IStructuredSelection) event
.getSelection());
}
});
ColumnViewerToolTipSupport.enableFor(bundlesTableViewer);
}
/** Update the stop and start buttons depending on current selection */
protected void updateButtonStatuses(IStructuredSelection selection) {
// startButton is enabled if at least one bundle is not active
// stopButton is enabled if at least one bundle is active
boolean oneBundleIsActive = false;
boolean oneBundleIsNotActive = false;
Iterator<?> iter = selection.iterator();
while (iter.hasNext()) {
Bundle b = (Bundle) iter.next();
oneBundleIsActive = oneBundleIsActive
|| (b.getState() == Bundle.ACTIVE);
oneBundleIsNotActive = oneBundleIsNotActive
|| (b.getState() != Bundle.ACTIVE);
}
startButton.setEnabled(oneBundleIsNotActive);
stopButton.setEnabled(oneBundleIsActive);
}
private void addColumn(final TableViewer parentTable, int width, String title,
final int column) {
TableViewerColumn col = new TableViewerColumn(bundlesTableViewer,
SWT.NONE);
col.getColumn().setWidth(width);
col.getColumn().setText(title);
final BundleDataProvider bdp = ContextInjectionFactory.make(
BundleDataProvider.class, ctx);
bdp.setColumn(column);
col.setLabelProvider(bdp);
col.getColumn().addSelectionListener(new SelectionAdapter() {
private int turnAround = 1;
@Override
public void widgetSelected(SelectionEvent e) {
turnAround *= -1;
parentTable.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
if(BundleDataProvider.COL_STATE == column) {
Bundle b1 = (Bundle) e1;
Bundle b2 = (Bundle) e2;
return turnAround(Integer.compare(b1.getState(), b2.getState()));
}
return turnAround(bdp.getText(e1).compareTo(bdp.getText(e2)));
}
});
}
private int turnAround(int compare) {
return compare * turnAround;
}
});
}
private static final ViewerFilter[] NO_FILTER = new ViewerFilter[0];
private Button stopButton;
private Button startButton;
/** Set the filter on table */
public void setFilter() {
if (showOnlyFilteredElements.isEnabled()
&& showOnlyFilteredElements.getSelection()) {
bundlesTableViewer.setFilters(new ViewerFilter[]{bundleFilter});
} else {
bundlesTableViewer.setFilters(NO_FILTER);
}
}
@Focus
public void setFocus() {
bundlesTableViewer.getControl().setFocus();
}
private ImageRegistry initializeImageRegistry() {
Bundle b = FrameworkUtil.getBundle(this.getClass());
ImageRegistry imgReg = new ImageRegistry();
imgReg.put(ICON_REFRESH,
ImageDescriptor.createFromURL(b.getEntry(ICON_REFRESH)));
imgReg.put(ICON_STATE_ACTIVE,
ImageDescriptor.createFromURL(b.getEntry(ICON_STATE_ACTIVE)));
imgReg.put(ICON_STATE_RESOLVED,
ImageDescriptor.createFromURL(b.getEntry(ICON_STATE_RESOLVED)));
imgReg.put(ICON_STATE_STARTING,
ImageDescriptor.createFromURL(b.getEntry(ICON_STATE_STARTING)));
imgReg.put(ICON_STATE_STOPPING,
ImageDescriptor.createFromURL(b.getEntry(ICON_STATE_STOPPING)));
imgReg.put(ICON_STATE_INSTALLED,
ImageDescriptor.createFromURL(b.getEntry(ICON_STATE_INSTALLED)));
imgReg.put(ICON_STATE_UNINSTALLED, ImageDescriptor.createFromURL(b
.getEntry(ICON_STATE_UNINSTALLED)));
imgReg.put(ICON_START,
ImageDescriptor.createFromURL(b.getEntry(ICON_START)));
imgReg.put(ICON_STOP,
ImageDescriptor.createFromURL(b.getEntry(ICON_STOP)));
ctx.set(ImageRegistry.class, imgReg);
return imgReg;
}
}