/******************************************************************************* * Copyright (c) 2012 Pivotal Software, Inc. * 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: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.operations.AbstractOperation; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ICheckStateProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.StyledString.Styler; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.mylyn.commons.workbench.SubstringPatternFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.TextStyle; 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.Display; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.wst.server.ui.editor.ServerEditorPart; import org.eclipse.wst.server.ui.editor.ServerEditorSection; import com.vmware.vfabric.ide.eclipse.tcserver.internal.core.TcServer; /** * A section for enabling Insight plug-ins. * @author Steffen Pingel * @author Christian Dupuis */ public class InsightPluginsSection extends ServerEditorSection implements IInsightPageParticipant { public class EnablePluginsOperation extends AbstractOperation { private final List<InsightPlugin> plugins; private final boolean state; public EnablePluginsOperation(List<InsightPlugin> plugins, boolean state) { super("Select Insight plugins"); this.plugins = plugins; this.state = state; } @Override public IStatus execute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { enable(state); return Status.OK_STATUS; } @Override public IStatus redo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { return execute(monitor, info); } @Override public IStatus undo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { enable(!state); return Status.OK_STATUS; } private void enable(boolean state) { for (InsightPlugin plugin : plugins) { plugin.setEnabled(state); } if (pluginViewer.getControl() != null && !pluginViewer.getControl().isDisposed()) { pluginViewer.refresh(); } } } private class PluginLabelProvider extends LabelProvider implements IStyledLabelProvider { final Styler NO_STYLE = new Styler() { @Override public void applyStyles(TextStyle textStyle) { } }; public StyledString getStyledText(Object element) { String text = getText(element); if (text != null) { StyledString styledString = new StyledString(text); if (element instanceof InsightPlugin) { InsightPlugin plugin = (InsightPlugin) element; styledString.append(" " + plugin.getDetails(), StyledString.DECORATIONS_STYLER); } return styledString; } return new StyledString(); } @Override public String getText(Object element) { return ((InsightPlugin) element).getName(); } } private TcServer serverInstance; private PropertyChangeListener listener; private Button enableButton; private CheckboxTreeViewer pluginViewer; private InsightPluginModel model; private InsightEditorPage editor; private class CheckboxFilteredTree extends FilteredTree { public CheckboxFilteredTree(Composite parent, int treeStyle, PatternFilter filter) { super(parent, treeStyle, filter, true); } @Override protected TreeViewer doCreateTreeViewer(Composite parent, int style) { return new CheckboxTreeViewer(parent, style); } public CheckboxTreeViewer getCheckboxTreeViewer() { return getViewer(); } @Override public CheckboxTreeViewer getViewer() { return (CheckboxTreeViewer) super.getViewer(); } } public InsightPluginsSection() { } @Override public void createSection(Composite parent) { super.createSection(parent); FormToolkit toolkit = getFormToolkit(parent.getDisplay()); Section section = toolkit.createSection(parent, ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR | Section.DESCRIPTION | ExpandableComposite.FOCUS_TITLE | ExpandableComposite.EXPANDED); section.setText("Plugins"); section.setDescription("Enable plug-ins to gather specific metrics."); section.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL)); Composite composite = toolkit.createComposite(section, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginHeight = 8; layout.marginWidth = 8; composite.setLayout(layout); toolkit.paintBordersFor(composite); section.setClient(composite); CheckboxFilteredTree filteredTree = new CheckboxFilteredTree(composite, SWT.FULL_SELECTION | SWT.BORDER, new SubstringPatternFilter()); GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 200).applyTo(filteredTree); pluginViewer = filteredTree.getCheckboxTreeViewer(); // required to make filtering work pluginViewer.setLabelProvider(new PluginLabelProvider()); pluginViewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { InsightPlugin plugin = (InsightPlugin) event.getElement(); execute(new EnablePluginsOperation(Collections.singletonList(plugin), event.getChecked())); } }); pluginViewer.setCheckStateProvider(new ICheckStateProvider() { public boolean isChecked(Object element) { return ((InsightPlugin) element).isEnabled(); } public boolean isGrayed(Object element) { return false; } }); TreeViewerColumn nameColumn = new TreeViewerColumn(pluginViewer, SWT.NONE); nameColumn.getColumn().setText("Name"); nameColumn.getColumn().setWidth(400); nameColumn.setLabelProvider(new DelegatingStyledCellLabelProvider(new PluginLabelProvider())); pluginViewer.setContentProvider(new ITreeContentProvider() { private InsightPluginModel input; private final Object[] EMPTY_ARRAY = new Object[0]; public void dispose() { // ignore } public Object[] getChildren(Object parentElement) { return EMPTY_ARRAY; } public Object[] getElements(Object parent) { if (input != null) { return input.getPlugins().toArray(); } return EMPTY_ARRAY; } public Object getParent(Object element) { return null; } public boolean hasChildren(Object element) { return false; } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { input = (InsightPluginModel) newInput; } }); pluginViewer.setSorter(new ViewerSorter() { @Override public int compare(Viewer viewer, Object e1, Object e2) { InsightPlugin p1 = (InsightPlugin) e1; InsightPlugin p2 = (InsightPlugin) e2; return p1.getName().compareTo(p2.getName()); } }); Composite buttonComposite = new Composite(composite, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.TOP).applyTo(buttonComposite); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).extendedMargins(0, 0, 0, 0) .applyTo(buttonComposite); createButtons(buttonComposite); initialize(); } @Override public void setServerEditorPart(ServerEditorPart editor) { super.setServerEditorPart(editor); this.editor = (InsightEditorPage) editor; this.editor.addPageParticipant(this); } public void createButtons(Composite composite) { FormToolkit toolkit = getFormToolkit(getShell().getDisplay()); Button selectAllButton = toolkit.createButton(composite, "", SWT.PUSH); GridDataFactory.fillDefaults().grab(true, false).applyTo(selectAllButton); selectAllButton.setText("&Select All"); selectAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { List<InsightPlugin> plugins = new ArrayList<InsightPlugin>(); TreeItem[] items = pluginViewer.getTree().getItems(); for (TreeItem item : items) { if (item.getData() instanceof InsightPlugin) { if (!((InsightPlugin) item.getData()).isEnabled()) { plugins.add((InsightPlugin) item.getData()); } } } if (plugins.size() > 0) { execute(new EnablePluginsOperation(plugins, true)); } } }); Button deselectAllButton = toolkit.createButton(composite, "", SWT.PUSH); GridDataFactory.fillDefaults().grab(true, false).applyTo(deselectAllButton); deselectAllButton.setText("&Deselect All"); deselectAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { List<InsightPlugin> plugins = new ArrayList<InsightPlugin>(); TreeItem[] items = pluginViewer.getTree().getItems(); for (TreeItem item : items) { if (item.getData() instanceof InsightPlugin) { if (((InsightPlugin) item.getData()).isEnabled()) { plugins.add((InsightPlugin) item.getData()); } } } if (plugins.size() > 0) { execute(new EnablePluginsOperation(plugins, false)); } } }); } @Override public void dispose() { if (server != null) { server.removePropertyChangeListener(listener); } } @Override public void init(IEditorSite site, IEditorInput input) { super.init(site, input); serverInstance = (TcServer) server.loadAdapter(TcServer.class, null); addChangeListener(); initialize(); } private void update() { if (enableButton != null && !enableButton.isDisposed()) { Display.getDefault().asyncExec(new Runnable() { public void run() { enableButton.setSelection(!serverInstance.getAddExtraVmArgs().containsAll( Arrays.asList(TcServerInsightUtil.DISABLED_INSIGHT))); } }); } if (pluginViewer != null) { model = new InsightPluginModel(); IPath insightPath = TcServerInsightUtil.getInsightPath(serverInstance.getServer()); if (insightPath != null) { model.load(insightPath.append("collection-plugins")); } pluginViewer.setInput(model); } } protected void addChangeListener() { listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if (TcServer.PROPERTY_ADD_EXTRA_VMARGS.equals(event.getPropertyName())) { update(); } } }; server.addPropertyChangeListener(listener); } /** * Initialize the fields in this editor. */ protected void initialize() { update(); } public void doSave(IProgressMonitor monitor) { model.commit(); } }