/******************************************************************************* * Copyright (c) 2008 Remy Chi Jian Suen 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: * Remy Chi Jian Suen <remy.suen@gmail.com> - initial API and implementation ******************************************************************************/ package org.eclipse.ecf.remoteservices.ui; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.ecf.internal.remoteservices.ui.Messages; import org.eclipse.ecf.remoteservices.ui.RemoteMethod.Parameter; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.window.IShellProvider; import org.eclipse.jface.window.SameShellProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; /** * The MethodInvocationDialog allows a user to select a method given a * <code>java.lang.Class</code> to invoke and communicate with a remote service. * * @since 2.0 */ @Deprecated public final class MethodInvocationDialog extends Dialog { /** * An integer constant that corresponds to the "Async Listener" selection. * * @see #getInvocationType() */ public static final int ASYNC_LISTENER = 0; /** * An integer constant that corresponds to the "Async Future Result" * selection. * * @see #getInvocationType() */ public static final int ASYNC_FUTURE_RESULT = ASYNC_LISTENER + 1; /** * An integer constant that corresponds to the "Async Fire-and-Go" * selection. * * @see #getInvocationType() */ public static final int ASYNC_FIRE_AND_GO = ASYNC_FUTURE_RESULT + 1; /** * An integer constant that corresponds to the "OSGi Service Proxy" * selection. * * @see #getInvocationType() */ public static final int OSGI_SERVICE_PROXY = ASYNC_FIRE_AND_GO + 1; /** * An integer constant that corresponds to the "Remote Service Proxy" * selection. * * @see #getInvocationType() */ public static final int REMOTE_SERVICE_PROXY = OSGI_SERVICE_PROXY + 1; /** * An integer constant that corresponds to the "Synchronous" selection. * * @see #getInvocationType() */ public static final int SYNCHRONOUS = REMOTE_SERVICE_PROXY + 1; private static final String[] COLUMN_PROPERTIES = { "Parameter", "Argument" }; //$NON-NLS-1$ //$NON-NLS-2$ /** * Provide a default timeout value of 30,000 milliseconds. */ private static final String DEFAULT_TIMEOUT_VALUE = "30000"; //$NON-NLS-1$ private TableViewer methodsViewer; private TableViewer parametersViewer; private Text timeoutText; private Combo invocationCombo; private final RemoteMethod[] methods; private Method method; private Object[] methodArguments; private int timeout; private int invocationType; /** * Creates a new MethodInvocationDialog on top of the specified shell * provider. * * @param parentShell * the provider to return the parent shell of this dialog * @param cls * the class to select the methods from */ public MethodInvocationDialog(IShellProvider parentShell, Class cls) { super(parentShell); Assert.isNotNull(cls); Method[] methods = cls.getMethods(); final List validMethods = new ArrayList(); for (int i = 0; i < methods.length; i++) { final Class[] parameters = methods[i].getParameterTypes(); final String[] types = new String[parameters.length]; if (types.length == 0) { validMethods.add(methods[i]); continue; } boolean match = true; for (int j = 0; j < types.length; j++) { final String name = parameters[j].getName(); if (!name.equals("char") && !name.equals("boolean") //$NON-NLS-1$ //$NON-NLS-2$ && !name.equals("int") && !name.equals("double") //$NON-NLS-1$ //$NON-NLS-2$ && !name.equals("float") && !name.equals("long") //$NON-NLS-1$ //$NON-NLS-2$ && !name.equals("short") && !name.equals("byte") //$NON-NLS-1$ //$NON-NLS-2$ && !name.equals("java.lang.String")) { //$NON-NLS-1$ match = false; break; } } if (match) { validMethods.add(methods[i]); } } methods = (Method[]) validMethods.toArray(new Method[validMethods.size()]); this.methods = new RemoteMethod[methods.length]; for (int i = 0; i < methods.length; i++) { this.methods[i] = new RemoteMethod(methods[i]); } } /** * Creates a new MethodInvocationDialog over the provided shell. * * @param parentShell * the parent shell * @param cls * the class to select the methods from */ public MethodInvocationDialog(Shell parentShell, Class cls) { this(new SameShellProvider(parentShell), cls); } protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(Messages.MethodInvocationDialog_ShellTitle); } protected Control createDialogArea(Composite parent) { parent = (Composite) super.createDialogArea(parent); final Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); composite.setLayout(new GridLayout(2, true)); Label label = new Label(composite, SWT.LEAD); label.setText(Messages.MethodInvocationDialog_AvailableMethodsLabel); label = new Label(composite, SWT.LEAD); label.setText(Messages.MethodInvocationDialog_ArgumentsLabel); methodsViewer = new TableViewer(composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); methodsViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); methodsViewer.setContentProvider(new ArrayContentProvider()); methodsViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent e) { final IStructuredSelection iss = (IStructuredSelection) e.getSelection(); final Object element = iss.getFirstElement(); if (element != null) { getButton(IDialogConstants.OK_ID).setEnabled(!timeoutText.getText().equals("")); //$NON-NLS-1$ final RemoteMethod method = (RemoteMethod) element; parametersViewer.setInput(method.getParameters()); } } }); methodsViewer.setLabelProvider(new LabelProvider() { public String getText(Object element) { final RemoteMethod method = (RemoteMethod) element; return method.getReturnType() + ' ' + method.getSignature(); } }); parametersViewer = new TableViewer(composite, SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.BORDER); parametersViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); parametersViewer.setContentProvider(new ArrayContentProvider()); parametersViewer.setLabelProvider(new ITableLabelProvider() { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { final Parameter p = (Parameter) element; if (columnIndex == 0) { final String name = p.getParameter().getName(); if (name.charAt(0) == 'j') { // this is java.lang.String return "String"; //$NON-NLS-1$ } else { return name; } } else { return p.getArgument(); } } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return true; } public void removeListener(ILabelProviderListener listener) { } }); parametersViewer.setCellEditors(new CellEditor[] { null, new TextCellEditor(parametersViewer.getTable()) }); parametersViewer.setCellModifier(new ICellModifier() { public boolean canModify(Object element, String property) { return property.equals(COLUMN_PROPERTIES[1]); } public Object getValue(Object element, String property) { return ((Parameter) element).getArgument(); } public void modify(Object element, String property, Object value) { if (property.equals(COLUMN_PROPERTIES[1])) { if (element instanceof TableItem) { final TableItem item = ((TableItem) element); final Parameter p = (Parameter) item.getData(); final String argument = (String) value; p.setArgument(argument); item.setText(1, argument); } } } }); parametersViewer.setColumnProperties(COLUMN_PROPERTIES); final Table table = parametersViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); TableColumn column = new TableColumn(table, SWT.LEAD); column.setWidth(150); column.setText(Messages.MethodInvocationDialog_ParameterColumn); column = new TableColumn(table, SWT.LEAD); column.setWidth(150); column.setText(Messages.MethodInvocationDialog_ValueColumn); methodsViewer.setInput(methods); final Composite bottomComposite = new Composite(composite, SWT.NONE); bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); final GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; bottomComposite.setLayout(layout); label = new Label(bottomComposite, SWT.LEAD); label.setText(Messages.MethodInvocationDialog_TimeoutLabel); label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); timeoutText = new Text(bottomComposite, SWT.BORDER); timeoutText.setText(DEFAULT_TIMEOUT_VALUE); timeoutText.addVerifyListener(new VerifyListener() { public void verifyText(VerifyEvent e) { switch (e.text.length()) { case 0: e.doit = true; break; case 1: e.doit = Character.isDigit(e.text.charAt(0)); break; default: e.doit = false; break; } } }); timeoutText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { getButton(IDialogConstants.OK_ID).setEnabled(!timeoutText.getText().equals("") //$NON-NLS-1$ && !methodsViewer.getSelection().isEmpty()); } }); timeoutText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); label = new Label(bottomComposite, SWT.LEAD); label.setText(Messages.MethodInvocationDialog_InvocationTypeLabel); label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); invocationCombo = new Combo(bottomComposite, SWT.READ_ONLY); invocationCombo.setItems(new String[] { Messages.MethodInvocationDialog_InvocationTypeAsyncListener, Messages.MethodInvocationDialog_InvocationTypeAsyncFutureResult, Messages.MethodInvocationDialog_InvocationTypeAsyncFireAndGo, Messages.MethodInvocationDialog_InvocationTypeOSGiServiceProxy, Messages.MethodInvocationDialog_InvocationTypeRemoteServiceProxy, Messages.MethodInvocationDialog_InvocationTypeSynchronous }); invocationCombo.select(0); bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); return parent; } public void create() { super.create(); final Button okButton = getButton(IDialogConstants.OK_ID); okButton.setEnabled(false); okButton.setText(Messages.MethodInvocationDialog_BUTTON_INVOKE_TEXT); } protected void okPressed() { final IStructuredSelection selection = (IStructuredSelection) methodsViewer.getSelection(); final RemoteMethod remoteMethod = (RemoteMethod) selection.getFirstElement(); method = remoteMethod.getMethod(); final Parameter[] p = remoteMethod.getParameters(); methodArguments = new Object[p.length]; for (int i = 0; i < p.length; i++) { final String name = p[i].getParameter().getName(); final String arg = p[i].getArgument(); if (name.equals("char")) { //$NON-NLS-1$ methodArguments[i] = new Character(arg.charAt(0)); } else if (name.equals("boolean")) { //$NON-NLS-1$ methodArguments[i] = Boolean.valueOf(arg); } else if (name.equals("int")) { //$NON-NLS-1$ methodArguments[i] = Integer.valueOf(arg); } else if (name.equals("double")) { //$NON-NLS-1$ methodArguments[i] = Double.valueOf(arg); } else if (name.equals("float")) { //$NON-NLS-1$ methodArguments[i] = Float.valueOf(arg); } else if (name.equals("long")) { //$NON-NLS-1$ methodArguments[i] = Long.valueOf(arg); } else if (name.equals("short")) { //$NON-NLS-1$ methodArguments[i] = Short.valueOf(arg); } else if (name.equals("byte")) { //$NON-NLS-1$ methodArguments[i] = Byte.valueOf(arg); } else { methodArguments[i] = arg; } } timeout = Integer.parseInt(timeoutText.getText()); invocationType = invocationCombo.getSelectionIndex(); super.okPressed(); } /** * Returns the method that has been selected by the user. * * @return the selected method */ public Method getMethod() { return method; } /** * Returns the arguments that has been specified by the user to pass to the * method. * * @return the list of arguments to pass into the method */ public Object[] getMethodArguments() { return methodArguments; } /** * Retrieves the timeout value that has been specified by the user. This * value is in milliseconds. * * @return the timeout valued specified by the user in milliseconds */ public int getTimeout() { return timeout; } /** * Returns the type of invocation that should be used to call the selected * method to communicate with a remote service. * * @return the invocation type selected by the user * @see #ASYNC_LISTENER * @see #ASYNC_FUTURE_RESULT * @see #ASYNC_FIRE_AND_GO * @see #OSGI_SERVICE_PROXY * @see #REMOTE_SERVICE_PROXY * @see #SYNCHRONOUS */ public int getInvocationType() { return invocationType; } }