diff --git a/org.eclipse.tm.terminal.serial/src/org/eclipse/tm/internal/terminal/serial/SerialConnector.java b/org.eclipse.tm.terminal.serial/src/org/eclipse/tm/internal/terminal/serial/SerialConnector.java index 6cc5df9a497..905c05b80e3 100644 --- a/org.eclipse.tm.terminal.serial/src/org/eclipse/tm/internal/terminal/serial/SerialConnector.java +++ b/org.eclipse.tm.terminal.serial/src/org/eclipse/tm/internal/terminal/serial/SerialConnector.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; @@ -40,34 +41,20 @@ public class SerialConnector implements ITerminalConnector { private CommPortIdentifier fSerialPortIdentifier; private SerialPortHandler fTerminalSerialPortHandler; private boolean fIsPortInUse; - private final SerialSettings fSettings; + private SerialSettings fSettings; public SerialConnector() { - SerialSettings settins=null; - try { - settins=new SerialSettings(); - } catch (NoClassDefFoundError e) { - // tell the user how to install the library - Activator.getDefault().getLog().log(new Status(IStatus.WARNING,Activator.PLUGIN_ID,0, SerialMessages.ERROR_LIBRARY_NOT_INSTALLED,e)); - } - fSettings=settins; - } - public String getId() { - return null; - } - public String getName() { - return null; - } - public boolean isInstalled() { - // check if serial is installed - try { - return SerialPort.class!=null; - } catch (Throwable e) { - return false; - } } public SerialConnector(SerialSettings settings) { fSettings=settings; } + public void initialize() throws Exception { + try { + fSettings=new SerialSettings(); + } catch (NoClassDefFoundError e) { + // tell the user how to install the library + throw new CoreException(new Status(IStatus.WARNING,Activator.PLUGIN_ID,0, SerialMessages.ERROR_LIBRARY_NOT_INSTALLED,e)); + } + } public void connect(ITerminalControl control) { Logger.log("entered."); //$NON-NLS-1$ fControl=control; @@ -203,5 +190,4 @@ public class SerialConnector implements ITerminalConnector { public void save(ISettingsStore store) { fSettings.save(store); } - } \ No newline at end of file diff --git a/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnector.java b/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnector.java index ad348e8b5a0..6d45e3864c6 100644 --- a/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnector.java +++ b/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnector.java @@ -36,24 +36,12 @@ public class SshConnector implements ITerminalConnector { private int fHeight; public SshConnector() { this(new SshSettings()); - try { - fJsch=new JSch(); - } catch(NoClassDefFoundError e) { - // ignore - e.printStackTrace(); - } } public SshConnector(SshSettings settings) { fSettings=settings; } - public String getId() { - return null; - } - public String getName() { - return null; - } - public boolean isInstalled() { - return fJsch!=null; + public void initialize() throws Exception { + fJsch=new JSch(); } public void connect(ITerminalControl control) { Logger.log("entered."); //$NON-NLS-1$ diff --git a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalSettingsDlg.java b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalSettingsDlg.java index cf897b697b9..48a34a2b4c8 100644 --- a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalSettingsDlg.java +++ b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalSettingsDlg.java @@ -16,9 +16,16 @@ *******************************************************************************/ package org.eclipse.tm.internal.terminal.view; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; @@ -33,11 +40,11 @@ import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; -import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; class TerminalSettingsDlg extends Dialog { private Combo fCtlConnTypeCombo; - private final ITerminalConnector[] fConnectors; + private final ITerminalConnectorInfo[] fConnectors; private final ISettingsPage[] fPages; /** * Maps the fConnectors index to the fPages index @@ -48,9 +55,9 @@ class TerminalSettingsDlg extends Dialog { private PageBook fPageBook; private IDialogSettings fDialogSettings; - public TerminalSettingsDlg(Shell shell, ITerminalConnector[] connectors, ITerminalConnector connector) { + public TerminalSettingsDlg(Shell shell, ITerminalConnectorInfo[] connectors, ITerminalConnectorInfo connector) { super(shell); - fConnectors=connectors; + fConnectors=getValidConnectors(connectors); fPages=new ISettingsPage[fConnectors.length]; fPageIndex=new int[fConnectors.length]; fSelectedConnector=-1; @@ -59,28 +66,47 @@ class TerminalSettingsDlg extends Dialog { fSelectedConnector=i; } } + /** + * @param connectors + * @return connectors excluding connectors with errors + */ + private ITerminalConnectorInfo[] getValidConnectors(ITerminalConnectorInfo[] connectors) { + List list=new ArrayList(Arrays.asList(connectors)); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + ITerminalConnectorInfo info = (ITerminalConnectorInfo) iterator.next(); + if(info.isInitialized() && info.getInitializationErrorMessage()!=null) + iterator.remove(); + } + connectors=(ITerminalConnectorInfo[]) list.toArray(new ITerminalConnectorInfo[list.size()]); + return connectors; + } ISettingsPage getPage(int i) { if(fPages[i]==null) { - try { - fPages[i]=fConnectors[i].makeSettingsPage(); - // TODO: what happens if an error occurs while - // the control is partly created? - fPages[i].createControl(fPageBook); - } catch (final Exception e) { + if(fConnectors[i].getInitializationErrorMessage()!=null) { // create a error message + final ITerminalConnectorInfo conn=fConnectors[i]; fPages[i]=new ISettingsPage(){ public void createControl(Composite parent) { Label l=new Label(parent,SWT.WRAP); - l.setText("Error"); //$NON-NLS-1$ + String error=NLS.bind(ViewMessages.CONNECTOR_NOT_AVAILABLE,conn.getName()); + l.setText(error); l.setForeground(l.getDisplay().getSystemColor(SWT.COLOR_RED)); - MessageDialog.openError(getShell(), "Initialization Problems!", e.getLocalizedMessage()); //$NON-NLS-1$ + MessageDialog.openError(getShell(), + error, + NLS.bind(ViewMessages.CANNOT_INITIALIZE, + conn.getName(), + conn.getInitializationErrorMessage())); } public void loadSettings() {} public void saveSettings() {} public boolean validateSettings() {return false;} }; - fPages[i].createControl(fPageBook); + } else { + fPages[i]=fConnectors[i].getConnector().makeSettingsPage(); } + // TODO: what happens if an error occurs while + // the control is partly created? + fPages[i].createControl(fPageBook); fPageIndex[i]=fNPages++; resize(); } @@ -136,6 +162,11 @@ class TerminalSettingsDlg extends Dialog { return ctlComposite; } + public void create() { + super.create(); + // initialize the OK button after creating the all dialog elements + updateOKButton(); + } private void initFields() { // Load controls for (int i = 0; i < fConnectors.length; i++) { @@ -189,7 +220,7 @@ class TerminalSettingsDlg extends Dialog { } }); } - public ITerminalConnector getConnector() { + public ITerminalConnectorInfo getConnector() { if(fSelectedConnector>=0) return fConnectors[fSelectedConnector]; return null; @@ -199,6 +230,21 @@ class TerminalSettingsDlg extends Dialog { getPage(index); Control[] pages=fPageBook.getChildren(); fPageBook.showPage(pages[fPageIndex[fSelectedConnector]]); + updateOKButton(); + + } + /** + * enables the OK button if the user can create a connection + */ + private void updateOKButton() { + // TODO: allow contributions to enable the OK button + // enable the OK button if we have a valid connection selected + if(getButton(IDialogConstants.OK_ID)!=null) { + boolean enable=false; + if(getConnector()!=null) + enable=getConnector().getInitializationErrorMessage()==null; + getButton(IDialogConstants.OK_ID).setEnabled(enable); + } } protected IDialogSettings getDialogBoundsSettings() { IDialogSettings ds=TerminalViewPlugin.getDefault().getDialogSettings(); diff --git a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalView.java b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalView.java index fa051afe1db..0c16d92d46c 100644 --- a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalView.java +++ b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/TerminalView.java @@ -50,7 +50,7 @@ import org.eclipse.tm.internal.terminal.control.ITerminalListener; import org.eclipse.tm.internal.terminal.control.ITerminalViewControl; import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsStore; -import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; import org.eclipse.tm.internal.terminal.provisional.api.Logger; import org.eclipse.tm.internal.terminal.provisional.api.TerminalConnectorExtension; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; @@ -162,7 +162,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi public void onTerminalConnect() { if (isConnected()) return; - if(fCtlTerminal.getTerminalConnection()==null) + if(fCtlTerminal.getTerminalConnectorInfo()==null) setConnector(showSettingsDialog()); fCtlTerminal.connectTerminal(); } @@ -195,7 +195,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi } public void onTerminalSettings() { - ITerminalConnector c=showSettingsDialog(); + ITerminalConnectorInfo c=showSettingsDialog(); if(c!=null) { setConnector(c); @@ -203,11 +203,11 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi } } - private ITerminalConnector showSettingsDialog() { + private ITerminalConnectorInfo showSettingsDialog() { // When the settings dialog is opened, load the Terminal settings from the // persistent settings. - TerminalSettingsDlg dlgTerminalSettings = new TerminalSettingsDlg(getViewSite().getShell(),fCtlTerminal.getConnectors(),fCtlTerminal.getTerminalConnection()); + TerminalSettingsDlg dlgTerminalSettings = new TerminalSettingsDlg(getViewSite().getShell(),fCtlTerminal.getConnectors(),fCtlTerminal.getTerminalConnectorInfo()); Logger.log("opening Settings dialog."); //$NON-NLS-1$ @@ -224,7 +224,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi return dlgTerminalSettings.getConnector(); } - private void setConnector(ITerminalConnector connector) { + private void setConnector(ITerminalConnectorInfo connector) { fCtlTerminal.setConnector(connector); } @@ -246,7 +246,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi // display in the view's content description line. This is used by class // TerminalText when it processes an ANSI OSC escape sequence that commands // the terminal to display text in its title bar. - } else if(fCtlTerminal.getTerminalConnection()==null){ + } else if(fCtlTerminal.getTerminalConnectorInfo()==null){ strTitle=ViewMessages.NO_CONNECTION_SELECTED; } else { // When parameter 'data' is null, we construct a descriptive string to @@ -257,7 +257,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi //In order to make the logic of assembling, and the separators, better adapt to foreign languages if(summary.length()>0) summary=summary+" - "; //$NON-NLS-1$ - String name=fCtlTerminal.getTerminalConnection().getName(); + String name=fCtlTerminal.getTerminalConnectorInfo().getName(); if(name.length()>0) { name+=": "; //$NON-NLS-1$ } @@ -276,7 +276,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi // TODO: use another mechanism than "?" for the magic non initialized state // see TerminalConnectorProxy.getSettingsSummary String summary="?"; //$NON-NLS-1$ - if(fCtlTerminal.getTerminalConnection()!=null) + if(fCtlTerminal.getTerminalConnectorInfo()!=null) summary=fCtlTerminal.getSettingsSummary(); if("?".equals(summary)) { //$NON-NLS-1$ summary=fStore.get(STORE_SETTING_SUMMARY, ""); //$NON-NLS-1$ @@ -411,21 +411,21 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi * This method creates the top-level control for the Terminal view. */ protected void setupControls(Composite wndParent) { - ITerminalConnector[] connectors=TerminalConnectorExtension.getTerminalConnectors(); + ITerminalConnectorInfo[] connectors=TerminalConnectorExtension.getTerminalConnectors(); fCtlTerminal = TerminalViewControlFactory.makeControl(this, wndParent, connectors); String connectionType=fStore.get(STORE_CONNECTION_TYPE); for (int i = 0; i < connectors.length; i++) { - connectors[i].load(getStore(connectors[i])); + connectors[i].getConnector().load(getStore(connectors[i])); if(connectors[i].getId().equals(connectionType)) fCtlTerminal.setConnector(connectors[i]); } setCommandInputField("true".equals(fStore.get(STORE_HAS_COMMAND_INPUT_FIELD))); //$NON-NLS-1$ } - private void saveSettings(ITerminalConnector connector) { - ITerminalConnector[] connectors=fCtlTerminal.getConnectors(); + private void saveSettings(ITerminalConnectorInfo connector) { + ITerminalConnectorInfo[] connectors=fCtlTerminal.getConnectors(); for (int i = 0; i < connectors.length; i++) { - connectors[i].save(getStore(connectors[i])); + connectors[i].getConnector().save(getStore(connectors[i])); } if(connector!=null) { fStore.put(STORE_CONNECTION_TYPE,connector.getId()); @@ -445,7 +445,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi fStore.put(STORE_SETTING_SUMMARY, getSettingsSummary()); fStore.saveState(memento); } - private ISettingsStore getStore(ITerminalConnector connector) { + private ISettingsStore getStore(ITerminalConnectorInfo connector) { return new SettingStorePrefixDecorator(fStore,connector.getId()+"."); //$NON-NLS-1$ } diff --git a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.java b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.java index a6ae47f360e..81633071a23 100644 --- a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.java +++ b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.java @@ -38,5 +38,8 @@ public class ViewMessages extends NLS { public static String STATE_CONNECTING; public static String STATE_OPENED; public static String STATE_CLOSED; + + public static String CANNOT_INITIALIZE; + public static String CONNECTOR_NOT_AVAILABLE; } diff --git a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.properties b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.properties index af72f181ce1..34c08082937 100644 --- a/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.properties +++ b/org.eclipse.tm.terminal.view/src/org/eclipse/tm/internal/terminal/view/ViewMessages.properties @@ -30,3 +30,6 @@ STATE_CONNECTED = CONNECTED STATE_CONNECTING = CONNECTING... STATE_OPENED = OPENED STATE_CLOSED = CLOSED + +CANNOT_INITIALIZE = Cannot initialize {0}:\n{1} +CONNECTOR_NOT_AVAILABLE = Connector {0} not available! \ No newline at end of file diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/ITerminalViewControl.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/ITerminalViewControl.java index df951caf813..d9c59a80838 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/ITerminalViewControl.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/ITerminalViewControl.java @@ -14,7 +14,7 @@ package org.eclipse.tm.internal.terminal.control; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.graphics.Font; -import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; /** @@ -36,10 +36,10 @@ public interface ITerminalViewControl { void disconnectTerminal(); void disposeTerminal(); String getSettingsSummary(); - ITerminalConnector[] getConnectors(); + ITerminalConnectorInfo[] getConnectors(); void setFocus(); - ITerminalConnector getTerminalConnection(); - void setConnector(ITerminalConnector connector); + ITerminalConnectorInfo getTerminalConnectorInfo(); + void setConnector(ITerminalConnectorInfo connector); void connectTerminal(); /** * @param write a single character to terminal diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/TerminalViewControlFactory.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/TerminalViewControlFactory.java index 97dd54d44e5..a5453057aac 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/TerminalViewControlFactory.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/TerminalViewControlFactory.java @@ -13,10 +13,10 @@ package org.eclipse.tm.internal.terminal.control; import org.eclipse.swt.widgets.Composite; import org.eclipse.tm.internal.terminal.control.impl.TerminalControl; -import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; public class TerminalViewControlFactory { - public static ITerminalViewControl makeControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) { + public static ITerminalViewControl makeControl(ITerminalListener target, Composite wndParent, ITerminalConnectorInfo[] connectors) { return new TerminalControl(target, wndParent, connectors); } } diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/ITerminalControlForText.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/ITerminalControlForText.java index a74893dc922..0e99bf61b57 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/ITerminalControlForText.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/ITerminalControlForText.java @@ -13,7 +13,7 @@ package org.eclipse.tm.internal.terminal.control.impl; import java.io.OutputStream; -import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; /** @@ -27,7 +27,7 @@ public interface ITerminalControlForText { void setState(TerminalState state); void setTerminalTitle(String title); - ITerminalConnector getTerminalConnection(); + ITerminalConnectorInfo getTerminalConnectorInfo(); void disconnectTerminal(); diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalControl.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalControl.java index 663f2c26ec9..86bd2ea0353 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalControl.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalControl.java @@ -49,6 +49,7 @@ import org.eclipse.tm.internal.terminal.control.ICommandInputField; import org.eclipse.tm.internal.terminal.control.ITerminalListener; import org.eclipse.tm.internal.terminal.control.ITerminalViewControl; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector; +import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnectorInfo; import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl; import org.eclipse.tm.internal.terminal.provisional.api.Logger; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; @@ -88,14 +89,14 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro private String fMsg = ""; //$NON-NLS-1$ private VerifyKeyListener fVerifyKeyListener; private FocusListener fFocusListener; - private ITerminalConnector fConnector; - private final ITerminalConnector[] fConnectors; + private ITerminalConnectorInfo fConnectorInfo; + private final ITerminalConnectorInfo[] fConnectors; private ICommandInputField fCommandInputField; private volatile TerminalState fState; - public TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) { + public TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnectorInfo[] connectors) { fConnectors=connectors; fTerminalListener=target; setTerminalText(new TerminalText(this)); @@ -103,7 +104,7 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro setupTerminal(wndParent); } - public ITerminalConnector[] getConnectors() { + public ITerminalConnectorInfo[] getConnectors() { return fConnectors; } @@ -237,19 +238,28 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro public void connectTerminal() { Logger.log("entered."); //$NON-NLS-1$ - if(fConnector==null) + if(getTerminalConnector()==null) return; fTerminalText.resetState(); - try { - fConnector.connect(this); - } catch(RuntimeException e) { - showErrorMessage(NLS.bind(TerminalMessages.CannotConnectTo,new Object[]{fConnector.getName(),e.getMessage()})); + if(fConnectorInfo.getInitializationErrorMessage()!=null) { + showErrorMessage(NLS.bind( + TerminalMessages.CannotConnectTo, + fConnectorInfo.getName(), + fConnectorInfo.getInitializationErrorMessage())); + // we cannot connect because the connector was not initialized return; } + getTerminalConnector().connect(this); // clean the error message setMsg(""); //$NON-NLS-1$ waitForConnect(); } + + private ITerminalConnector getTerminalConnector() { + if(fConnectorInfo==null) + return null; + return fConnectorInfo.getConnector(); + } /* (non-Javadoc) * @see org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl#disconnectTerminal() */ @@ -259,9 +269,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro if (getState()==TerminalState.CLOSED) { return; } - if(fConnector!=null) { - fConnector.disconnect(); -// fConnector=null; + if(getTerminalConnector()!=null) { + getTerminalConnector().disconnect(); } } @@ -482,8 +491,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro public OutputStream getOutputStream() { - if(fConnector!=null) - return fConnector.getOutputStream(); + if(getTerminalConnector()!=null) + return getTerminalConnector().getOutputStream(); return null; } @@ -523,10 +532,9 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro /** */ - public ITerminalConnector getTerminalConnection() { - return fConnector; + public ITerminalConnectorInfo getTerminalConnectorInfo() { + return fConnectorInfo; } - protected class TerminalModifyListener implements ModifyListener { public void modifyText(ModifyEvent e) { if (e.getSource() instanceof StyledText) { @@ -752,9 +760,9 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro // locally, send a LF after sending a CR. // ISSUE: Is this absolutely required? - if (character == '\r' && getTerminalConnection() != null + if (character == '\r' && getTerminalConnectorInfo() != null && isConnected() - && getTerminalConnection().isLocalEcho()) { + && getTerminalConnectorInfo().getConnector().isLocalEcho()) { sendChar('\n', false); } @@ -773,8 +781,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro // // o The character is the DELETE character. - if (getTerminalConnection() == null - || getTerminalConnection().isLocalEcho() == false || altKeyPressed + if (getTerminalConnectorInfo() == null + || getTerminalConnectorInfo().getConnector().isLocalEcho() == false || altKeyPressed || (character >= '\u0001' && character < '\t') || (character > '\t' && character < '\r') || (character > '\r' && character <= '\u001f') @@ -815,13 +823,13 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro } public String getSettingsSummary() { - if(fConnector!=null) - return fConnector.getSettingsSummary(); + if(getTerminalConnector()!=null) + return getTerminalConnector().getSettingsSummary(); return ""; //$NON-NLS-1$ } - public void setConnector(ITerminalConnector connector) { - fConnector=connector; + public void setConnector(ITerminalConnectorInfo connector) { + fConnectorInfo=connector; } public ICommandInputField getCommandInputField() { diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties index 2c49b042ca5..ee82aa2f003 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalMessages.properties @@ -17,4 +17,4 @@ TerminalError = Terminal Error SocketError = Socket Error IOError = IO Error -CannotConnectTo = Cannot connect to {1}:\n{2} \ No newline at end of file +CannotConnectTo = Cannot initialize {0}:\n{1} \ No newline at end of file diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalText.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalText.java index 2443d091cb0..b2d966c738b 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalText.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/control/impl/TerminalText.java @@ -1744,13 +1744,19 @@ public class TerminalText implements ControlListener { // there is nothing we can do to tell the remote host about the size of the // terminal. - ITerminalConnector telnetConnection = terminal.getTerminalConnection(); + ITerminalConnector telnetConnection = getConnector(); // TODO MSA: send only if dimensions have really changed! if (telnetConnection != null && widthInColumns != 0 && heightInLines != 0) { telnetConnection.setTerminalSize(widthInColumns, heightInLines); } } + private ITerminalConnector getConnector() { + if(terminal.getTerminalConnectorInfo()!=null) + return terminal.getTerminalConnectorInfo().getConnector(); + return null; + } + /** * This method computes the the pixel width of a character in the current * font. The Font object representing the font in the Terminal view doesn't diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnector.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnector.java index 4c455c7c174..eea187f98d9 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnector.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnector.java @@ -28,27 +28,12 @@ import java.io.OutputStream; */ public interface ITerminalConnector { /** - * @return an ID of this connector. The id from the plugin.xml. - *

Note: return null because the framework takes - * care to get the value from the plugin.xml + * Initializes the Connector. Some connector depend on external libraries that + * might not be installed. + * @throws Exception The exception should have a useful + * {@link Exception#getLocalizedMessage()} that explains the problem to the user. */ - // TODO: eliminate the need of implementing this NOOP method for extensions - String getId(); - - /** - * @return null the name (as specified in the plugin.xml) - *

Note: return null because the framework takes - * care to get the value from the plugin.xml - */ - // TODO: eliminate the need of implementing this NOOP method for extensions - String getName(); - - /** - * @return true if the contribution is functioning (e.g. all external libraries are - * installed). This was added for the serial support, because it requires the java comm - * library, which is installed in the lib/ext directory of the - */ - boolean isInstalled(); + void initialize() throws Exception; /** * Connect using the current state of the settings. diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnectorInfo.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnectorInfo.java new file mode 100644 index 00000000000..4f83eea026e --- /dev/null +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/ITerminalConnectorInfo.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 Wind River Systems, Inc. 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: + * Michael Scharf (Wind River) - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.internal.terminal.provisional.api; + +/** + * This class is a handle to a {@link ITerminalConnector connector} that comes from an + * extension. It maintains a proxy to the connector to allow lazy initialization of the + * real {@link ITerminalConnector connector} that comes from an extension. + * + */ +public interface ITerminalConnectorInfo { + /** + * @return an ID of this connector. The id from the plugin.xml. + *

Note: return null because the framework takes + * care to get the value from the plugin.xml + */ + String getId(); + + /** + * @return null the name (as specified in the plugin.xml) + *

Note: return null because the framework takes + * care to get the value from the plugin.xml + */ + String getName(); + + /** + * @return true if the ITerminalConnector has been initialized. + * If there was an initialization error, {@link #getInitializationErrorMessage()} + * returns the error message. + */ + boolean isInitialized(); + + /** + * This method initializes the connector if it is not initialized! + * If the connector was initialized successfully, null is + * returned. Otherwise an error message describing the problem is returned. + * @return null or a localized error message. + */ + String getInitializationErrorMessage(); + + /** + * Returns a proxy to the connector that is lazily initialized. + * The following methods can be called without initializing + * the contributed class: + * {@link ITerminalConnector#getSettingsSummary()}, {@link ITerminalConnector#load(ISettingsStore)}, + * {@link ITerminalConnector#save(ISettingsStore)}, {@link ITerminalConnector#setTerminalSize(int, int)} + * @return a proxy of the real connector. Some calls initialize the the connection. + */ + ITerminalConnector getConnector(); +} diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/TerminalConnectorExtension.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/TerminalConnectorExtension.java index 05e59a42c11..ca3d6bfde42 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/TerminalConnectorExtension.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/provisional/api/TerminalConnectorExtension.java @@ -16,10 +16,7 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.RegistryFactory; -import org.eclipse.core.runtime.Status; -import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin; /** * A factory to get {@link ITerminalConnector} instances. @@ -34,6 +31,28 @@ import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin; *

*/ public class TerminalConnectorExtension { + static private class TerminalConnectorInfo implements ITerminalConnectorInfo { + TerminalConnectorProxy fProxy; + TerminalConnectorInfo(TerminalConnectorProxy proxy) { + fProxy=proxy; + } + public ITerminalConnector getConnector() { + return fProxy; + } + public String getId() { + return fProxy.getId(); + } + public String getName() { + return fProxy.getName(); + } + public String getInitializationErrorMessage() { + return fProxy.getLocalizedErrorMessage(); + } + public boolean isInitialized() { + return fProxy.isInitialized(); + } + + } /** * A placeholder for the ITerminalConnector. It gets initialized when * the real connector is needed. @@ -67,6 +86,12 @@ public class TerminalConnectorExtension { TerminalConnectorProxy(IConfigurationElement config) { fConfig=config; } + public String getLocalizedErrorMessage() { + getConnector(); + if(fException!=null) + return fException.getLocalizedMessage(); + return null; + } public String getId() { String id = fConfig.getAttribute("id"); //$NON-NLS-1$ if(id==null || id.length()==0) @@ -84,17 +109,15 @@ public class TerminalConnectorExtension { if(!isInitialized()) { try { fConnector=createConnector(fConfig); - if(fConnector==null || !fConnector.isInstalled()) - // TODO MSA externalize - throw new RuntimeException(getName()+ " is not properly installed!"); //$NON-NLS-1$ + fConnector.initialize(); } catch (Exception e) { fException=e; + // that's the place where we log the exception + Logger.logException(e); } if(fConnector!=null && fStore!=null) fConnector.load(fStore); } - if(fException!=null) - throw new RuntimeException(fException); return fConnector; } private boolean isInitialized() { @@ -116,11 +139,6 @@ public class TerminalConnectorExtension { // TODO: see TerminalView.getSettingsSummary return "?"; //$NON-NLS-1$ } - public boolean isInstalled() { - if(isInitialized() && fConnector==null) - return false; - return getConnector().isInstalled(); - } public boolean isLocalEcho() { return getConnector().isLocalEcho(); } @@ -137,7 +155,7 @@ public class TerminalConnectorExtension { public void save(ISettingsStore store) { // no need to save the settings: it cannot have changed // because we are not initialized.... - if(!isInstalled()) + if(fConnector!=null) getConnector().save(store); } public void setTerminalSize(int newWidth, int newHeight) { @@ -148,37 +166,26 @@ public class TerminalConnectorExtension { fConnector.setTerminalSize(newWidth, newHeight); } } + public void initialize() throws Exception { + throw new IllegalStateException("Connector already initialized!"); //$NON-NLS-1$ + } } /** * @return null or a new connector created from the extension */ static private ITerminalConnector createConnector(IConfigurationElement config) throws Exception { - try { - Object obj=config.createExecutableExtension("class"); //$NON-NLS-1$ - if(obj instanceof ITerminalConnector) { - ITerminalConnector conn=(ITerminalConnector) obj; - if(conn.isInstalled()) - return conn; - } - } catch (Exception e) { - log(e); - throw e; - } - return null; + return (ITerminalConnector)config.createExecutableExtension("class"); //$NON-NLS-1$ } /** - * @return a new list of ITerminalConnectors. + * @return a new list of ITerminalConnectorInfo. */ - public static ITerminalConnector[] getTerminalConnectors() { + public static ITerminalConnectorInfo[] getTerminalConnectors() { IConfigurationElement[] config=RegistryFactory.getRegistry().getConfigurationElementsFor("org.eclipse.tm.terminal.terminalConnector"); //$NON-NLS-1$ List result=new ArrayList(); for (int i = 0; i < config.length; i++) { - result.add(new TerminalConnectorProxy(config[i])); + result.add(new TerminalConnectorInfo(new TerminalConnectorProxy(config[i]))); } - return (ITerminalConnector[]) result.toArray(new ITerminalConnector[result.size()]); + return (ITerminalConnectorInfo[]) result.toArray(new ITerminalConnectorInfo[result.size()]); } - private static void log(Throwable e) { - TerminalPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, TerminalPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e)); - } } diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/telnet/TelnetConnector.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/telnet/TelnetConnector.java index 6a629fdac33..73097e4e442 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/telnet/TelnetConnector.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/telnet/TelnetConnector.java @@ -41,15 +41,11 @@ public class TelnetConnector implements ITerminalConnector { public TelnetConnector() { this(new TelnetSettings()); } - public String getId() { - return null; - } - public String getName() { - return null; - } public TelnetConnector(TelnetSettings settings) { fSettings=settings; } + public void initialize() throws Exception { + } public void connect(ITerminalControl control) { Logger.log("entered."); //$NON-NLS-1$ fControl=control; @@ -165,7 +161,4 @@ public class TelnetConnector implements ITerminalConnector { public void save(ISettingsStore store) { fSettings.save(store); } - public boolean isInstalled() { - return true; - } }