Java tutorial
/******************************************************************************* * Copyright (c) 2010, 2012 SAP AG 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: * SAP AG - initial API and implementation * IBM Corporation - refactor for new/import wizard as WizardPage, * rename from ProviderConfigurationDialog *******************************************************************************/ package org.eclipse.mat.ui.internal.acquire; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.mat.SnapshotException; import org.eclipse.mat.internal.acquire.HeapDumpProviderDescriptor; import org.eclipse.mat.internal.acquire.HeapDumpProviderRegistry; import org.eclipse.mat.query.registry.AnnotatedObjectArgumentsSet; import org.eclipse.mat.query.registry.ArgumentDescriptor; import org.eclipse.mat.query.registry.ArgumentFactory; import org.eclipse.mat.snapshot.acquire.IHeapDumpProvider; import org.eclipse.mat.ui.Messages; import org.eclipse.mat.ui.accessibility.AccessibleCompositeAdapter; import org.eclipse.mat.ui.internal.acquire.ProviderArgumentsTable.ITableListener; import org.eclipse.mat.ui.internal.browser.QueryContextHelp; import org.eclipse.mat.util.IProgressListener; import org.eclipse.mat.util.MessageUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.PlatformUI; public class ProviderConfigurationWizardPage extends WizardPage implements ITableListener { private ProviderArgumentsTable table; private Table availableProvidersTable; private AcquireDialog acquireDialog; private QueryContextHelp helpPopup; private boolean changed; public ProviderConfigurationWizardPage(AcquireDialog acquireDialog) { super(Messages.ProviderConfigurationDialog_ConfigureProvidersDialogTitle, Messages.ProviderConfigurationDialog_ConfigureProvidersDialogTitle, null); this.acquireDialog = acquireDialog; } //@Override public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.RESIZE); composite.setLayout(new GridLayout(1, false)); GridDataFactory.fillDefaults().grab(true, true).span(1, 1).applyTo(composite); Label providersLabel = new Label(composite, SWT.NONE); providersLabel.setText(Messages.ProviderConfigurationDialog_AvailableProvidersLabel); GridDataFactory.swtDefaults().span(1, 1).applyTo(providersLabel); createProvidersTable(composite); GridDataFactory.fillDefaults().grab(true, true).span(1, 1).applyTo(availableProvidersTable); Label argumentsLabel = new Label(composite, SWT.NONE); argumentsLabel.setText(Messages.ProviderConfigurationDialog_ConfigurableParameteresLabel); GridDataFactory.swtDefaults().span(1, 1).applyTo(argumentsLabel); createArgumentsTable(composite); availableProvidersTable.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (e.item instanceof TableItem) { AnnotatedObjectArgumentsSet argumentsSet = (AnnotatedObjectArgumentsSet) ((TableItem) e.item) .getData(); table.providerSelected(argumentsSet); onFocus(null); relocateHelp(true); } } }); PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.mat.ui.help.query_arguments"); //$NON-NLS-1$ Listener listener = new Listener() { public void handleEvent(Event event) { relocateHelp(false); } }; getShell().addListener(SWT.Resize, listener); getShell().addListener(SWT.Move, listener); setControl(composite); } public IWizardPage getNextPage() { try { if (changed) { applyChanges(); onError(null); } } catch (SnapshotException e) { onError(e.getLocalizedMessage()); return null; } return super.getNextPage(); } private void applyChanges() throws SnapshotException { AnnotatedObjectArgumentsSet currentSet = table.getArgumentSet(); if (currentSet != null) { // Throw exception if current selection fails applyProviderChanges(currentSet); } for (TableItem item : availableProvidersTable.getItems()) { AnnotatedObjectArgumentsSet argumentSet = (AnnotatedObjectArgumentsSet) item.getData(); if (argumentSet != currentSet) { try { applyProviderChanges(argumentSet); } catch (SnapshotException e) { // Ignore errors from non-selected providers } } } } private void applyProviderChanges(AnnotatedObjectArgumentsSet argumentSet) throws SnapshotException { try { HeapDumpProviderDescriptor providerDescriptor = (HeapDumpProviderDescriptor) argumentSet .getDescriptor(); IHeapDumpProvider impl = providerDescriptor.getHeapDumpProvider(); for (ArgumentDescriptor parameter : providerDescriptor.getArguments()) { Object value = argumentSet.getArgumentValue(parameter); if (value == null && parameter.isMandatory()) { value = parameter.getDefaultValue(); if (value == null) throw new SnapshotException(MessageUtil.format( Messages.ProviderConfigurationDialog_MissingParameterErrorMessage, parameter.getName())); } if (value == null) { if (argumentSet.getValues().containsKey(parameter)) { Logger.getLogger(getClass().getName()).log(Level.INFO, MessageUtil.format("Setting null value for: {0}", parameter.getName())); //$NON-NLS-1$ parameter.getField().set(impl, null); } continue; } try { if (value instanceof ArgumentFactory) { parameter.getField().set(impl, ((ArgumentFactory) value).build(parameter)); } else if (parameter.isArray()) { List<?> list = (List<?>) value; Object array = Array.newInstance(parameter.getType(), list.size()); int ii = 0; for (Object v : list) Array.set(array, ii++, v); parameter.getField().set(impl, array); } else if (parameter.isList()) { // handle ArgumentFactory inside list List<?> source = (List<?>) value; List<Object> target = new ArrayList<Object>(source.size()); for (int ii = 0; ii < source.size(); ii++) { Object v = source.get(ii); if (v instanceof ArgumentFactory) v = ((ArgumentFactory) v).build(parameter); target.add(v); } parameter.getField().set(impl, target); } else { parameter.getField().set(impl, value); } } catch (IllegalArgumentException e) { throw new SnapshotException(MessageUtil.format( Messages.ProviderConfigurationDialog_IllegalArgumentErrorMessage, value, value.getClass().getName(), parameter.getName(), parameter.getType().getName()), e); } catch (IllegalAccessException e) { // should not happen as we check accessibility when // registering queries throw new SnapshotException( MessageUtil.format("Unable to access field {0} of type {1}", parameter //$NON-NLS-1$ .getName(), parameter.getType().getName()), e); } } } catch (IProgressListener.OperationCanceledException e) { throw e; // no nesting! } catch (SnapshotException e) { throw e; // no nesting! } catch (Exception e) { throw SnapshotException.rethrow(e); } } private void createProvidersTable(Composite parent) { availableProvidersTable = new Table(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION); TableColumn column1 = new TableColumn(availableProvidersTable, SWT.NONE); column1.setText(Messages.ProviderConfigurationDialog_NameColumnHeader); column1.setWidth(200); TableColumn column2 = new TableColumn(availableProvidersTable, SWT.NONE); column2.setText(Messages.ProviderConfigurationDialog_DescriptionColumnHeader); column2.setWidth(300); availableProvidersTable.setHeaderVisible(true); availableProvidersTable.setLinesVisible(true); AccessibleCompositeAdapter.access(availableProvidersTable); Collection<HeapDumpProviderDescriptor> providers = HeapDumpProviderRegistry.instance() .getHeapDumpProviders(); for (HeapDumpProviderDescriptor heapDumpProviderDescriptor : providers) { TableItem item = new TableItem(availableProvidersTable, SWT.NONE, 0); item.setData(new AnnotatedObjectArgumentsSet(heapDumpProviderDescriptor)); item.setText(0, heapDumpProviderDescriptor.getName()); if (heapDumpProviderDescriptor.getHelp() != null) item.setText(1, heapDumpProviderDescriptor.getHelp()); } availableProvidersTable.layout(); availableProvidersTable.pack(); } private void createArgumentsTable(Composite parent) { ScrolledComposite composite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); composite.setLayout(new GridLayout()); composite.setExpandHorizontal(true); composite.setExpandVertical(true); GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); Composite tableComposite = new Composite(composite, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).indent(0, 0).applyTo(tableComposite); Dialog.applyDialogFont(composite); table = new ProviderArgumentsTable(tableComposite, SWT.FULL_SELECTION | SWT.SINGLE); table.addListener(this); tableComposite.layout(); tableComposite.pack(); composite.setContent(tableComposite); GridDataFactory.fillDefaults().hint(300, 100).grab(true, true).span(1, 2).applyTo(composite); } public void relocateHelp(final boolean create) { final AnnotatedObjectArgumentsSet argumentSet = table.getArgumentSet(); if (argumentSet == null) return; if (argumentSet.getDescriptor().isHelpAvailable() && // (create || (helpPopup != null && helpPopup.getShell() != null))) { if (getShell() == null) { helpPopup.close(); return; } getShell().getDisplay().timerExec(100, new Runnable() { public void run() { if (getShell() != null && !getShell().isDisposed()) { Rectangle myBounds = getShell().getBounds(); Rectangle helpBounds = new Rectangle(myBounds.x, myBounds.y + myBounds.height, myBounds.width, SWT.DEFAULT); if (helpPopup != null) { if (!create) { helpPopup.resize(helpBounds); return; } else { // Get ready to create a new pop-up with new help text helpPopup.close(); } } helpPopup = new QueryContextHelp(getShell(), argumentSet.getDescriptor(), helpBounds); helpPopup.open(); } } }); } } public void setVisible(boolean f) { if (!f) { if (changed) { changed = false; acquireDialog.refresh(); } if (helpPopup != null) helpPopup.close(); } else { relocateHelp(true); } super.setVisible(f); } public void onInputChanged() { // A new dump provider configuration has been selected. // Update next button e.g. if new provider isn't executable. onError(null); getContainer().updateButtons(); } public void onValueChanged() { if (!changed) { // We do care if the user changes a parameter for finding VMs // The list of VMs will be refreshed when we leave this page, but clear the // selection now so the finish button doesn't work. acquireDialog.clearSelection(); // set the changed flag afterwards so updating the buttons doesn't // force an applychanges immediately changed = true; } getContainer().updateButtons(); } public void onError(String message) { setErrorMessage(message); // a work around: calling onFocus ensures a correct update of the error // message. Without this call it doesn't update the message correct. onFocus(null); } public void onFocus(String message) { if (getErrorMessage() != null) setMessage(getErrorMessage(), IMessageProvider.ERROR); else if (message != null) setMessage(message, IMessageProvider.INFORMATION); else setMessage(table.getProviderDescriptor().getName()); // Causes recursion from getNextPage(); //getContainer().updateButtons(); } @Override public boolean isPageComplete() { boolean exec = false; AnnotatedObjectArgumentsSet argumentSet = table.getArgumentSet(); if (argumentSet != null) { // If a provider is selected it should be executable exec |= argumentSet.isExecutable(); } else { // So long as one provider is executable then we can attempt to get a dump for (TableItem item : availableProvidersTable.getItems()) { argumentSet = (AnnotatedObjectArgumentsSet) item.getData(); exec |= argumentSet.isExecutable(); } } // If an error message is displayed then don't allow next return exec && getErrorMessage() == null; } }