1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

[188939] All terminal connections fail if RXTX is not available

I did quite some refactoring:
- I added ITerminalConnectorInfo
- ITerminalConnectorInfo still returns a proxy to ITerminalConnector to deal with lazy initialization.
- ITerminalConnector.isInstalled, getName and getId have been removed
- ITerminalConnector now has a new initialize() method that can throw an Exception. This exception should have a localized massage that can be (and is) displayed in a dialog when something goes wrong.
- If a ITerminalConnector has initialization problems, it is not shown in the terminal  settings dialog for that connection
This commit is contained in:
Michael Scharf 2007-05-26 04:15:43 +00:00
parent 13c7592a7d
commit 9057a25e36
16 changed files with 247 additions and 164 deletions

View file

@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
@ -40,34 +41,20 @@ public class SerialConnector implements ITerminalConnector {
private CommPortIdentifier fSerialPortIdentifier; private CommPortIdentifier fSerialPortIdentifier;
private SerialPortHandler fTerminalSerialPortHandler; private SerialPortHandler fTerminalSerialPortHandler;
private boolean fIsPortInUse; private boolean fIsPortInUse;
private final SerialSettings fSettings; private SerialSettings fSettings;
public SerialConnector() { 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) { public SerialConnector(SerialSettings settings) {
fSettings=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) { public void connect(ITerminalControl control) {
Logger.log("entered."); //$NON-NLS-1$ Logger.log("entered."); //$NON-NLS-1$
fControl=control; fControl=control;
@ -203,5 +190,4 @@ public class SerialConnector implements ITerminalConnector {
public void save(ISettingsStore store) { public void save(ISettingsStore store) {
fSettings.save(store); fSettings.save(store);
} }
} }

View file

@ -36,24 +36,12 @@ public class SshConnector implements ITerminalConnector {
private int fHeight; private int fHeight;
public SshConnector() { public SshConnector() {
this(new SshSettings()); this(new SshSettings());
try {
fJsch=new JSch();
} catch(NoClassDefFoundError e) {
// ignore
e.printStackTrace();
}
} }
public SshConnector(SshSettings settings) { public SshConnector(SshSettings settings) {
fSettings=settings; fSettings=settings;
} }
public String getId() { public void initialize() throws Exception {
return null; fJsch=new JSch();
}
public String getName() {
return null;
}
public boolean isInstalled() {
return fJsch!=null;
} }
public void connect(ITerminalControl control) { public void connect(ITerminalControl control) {
Logger.log("entered."); //$NON-NLS-1$ Logger.log("entered."); //$NON-NLS-1$

View file

@ -16,9 +16,16 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.tm.internal.terminal.view; 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.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent; 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.Label;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; 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 { class TerminalSettingsDlg extends Dialog {
private Combo fCtlConnTypeCombo; private Combo fCtlConnTypeCombo;
private final ITerminalConnector[] fConnectors; private final ITerminalConnectorInfo[] fConnectors;
private final ISettingsPage[] fPages; private final ISettingsPage[] fPages;
/** /**
* Maps the fConnectors index to the fPages index * Maps the fConnectors index to the fPages index
@ -48,9 +55,9 @@ class TerminalSettingsDlg extends Dialog {
private PageBook fPageBook; private PageBook fPageBook;
private IDialogSettings fDialogSettings; private IDialogSettings fDialogSettings;
public TerminalSettingsDlg(Shell shell, ITerminalConnector[] connectors, ITerminalConnector connector) { public TerminalSettingsDlg(Shell shell, ITerminalConnectorInfo[] connectors, ITerminalConnectorInfo connector) {
super(shell); super(shell);
fConnectors=connectors; fConnectors=getValidConnectors(connectors);
fPages=new ISettingsPage[fConnectors.length]; fPages=new ISettingsPage[fConnectors.length];
fPageIndex=new int[fConnectors.length]; fPageIndex=new int[fConnectors.length];
fSelectedConnector=-1; fSelectedConnector=-1;
@ -59,28 +66,47 @@ class TerminalSettingsDlg extends Dialog {
fSelectedConnector=i; 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) { ISettingsPage getPage(int i) {
if(fPages[i]==null) { if(fPages[i]==null) {
try { if(fConnectors[i].getInitializationErrorMessage()!=null) {
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) {
// create a error message // create a error message
final ITerminalConnectorInfo conn=fConnectors[i];
fPages[i]=new ISettingsPage(){ fPages[i]=new ISettingsPage(){
public void createControl(Composite parent) { public void createControl(Composite parent) {
Label l=new Label(parent,SWT.WRAP); 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)); 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 loadSettings() {}
public void saveSettings() {} public void saveSettings() {}
public boolean validateSettings() {return false;} 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++; fPageIndex[i]=fNPages++;
resize(); resize();
} }
@ -136,6 +162,11 @@ class TerminalSettingsDlg extends Dialog {
return ctlComposite; return ctlComposite;
} }
public void create() {
super.create();
// initialize the OK button after creating the all dialog elements
updateOKButton();
}
private void initFields() { private void initFields() {
// Load controls // Load controls
for (int i = 0; i < fConnectors.length; i++) { 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) if(fSelectedConnector>=0)
return fConnectors[fSelectedConnector]; return fConnectors[fSelectedConnector];
return null; return null;
@ -199,6 +230,21 @@ class TerminalSettingsDlg extends Dialog {
getPage(index); getPage(index);
Control[] pages=fPageBook.getChildren(); Control[] pages=fPageBook.getChildren();
fPageBook.showPage(pages[fPageIndex[fSelectedConnector]]); 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() { protected IDialogSettings getDialogBoundsSettings() {
IDialogSettings ds=TerminalViewPlugin.getDefault().getDialogSettings(); IDialogSettings ds=TerminalViewPlugin.getDefault().getDialogSettings();

View file

@ -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.ITerminalViewControl;
import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory; 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.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.Logger;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalConnectorExtension; import org.eclipse.tm.internal.terminal.provisional.api.TerminalConnectorExtension;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
@ -162,7 +162,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi
public void onTerminalConnect() { public void onTerminalConnect() {
if (isConnected()) if (isConnected())
return; return;
if(fCtlTerminal.getTerminalConnection()==null) if(fCtlTerminal.getTerminalConnectorInfo()==null)
setConnector(showSettingsDialog()); setConnector(showSettingsDialog());
fCtlTerminal.connectTerminal(); fCtlTerminal.connectTerminal();
} }
@ -195,7 +195,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi
} }
public void onTerminalSettings() { public void onTerminalSettings() {
ITerminalConnector c=showSettingsDialog(); ITerminalConnectorInfo c=showSettingsDialog();
if(c!=null) { if(c!=null) {
setConnector(c); 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 // When the settings dialog is opened, load the Terminal settings from the
// persistent settings. // 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$ Logger.log("opening Settings dialog."); //$NON-NLS-1$
@ -224,7 +224,7 @@ public class TerminalView extends ViewPart implements ITerminalView, ITerminalLi
return dlgTerminalSettings.getConnector(); return dlgTerminalSettings.getConnector();
} }
private void setConnector(ITerminalConnector connector) { private void setConnector(ITerminalConnectorInfo connector) {
fCtlTerminal.setConnector(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 // display in the view's content description line. This is used by class
// TerminalText when it processes an ANSI OSC escape sequence that commands // TerminalText when it processes an ANSI OSC escape sequence that commands
// the terminal to display text in its title bar. // the terminal to display text in its title bar.
} else if(fCtlTerminal.getTerminalConnection()==null){ } else if(fCtlTerminal.getTerminalConnectorInfo()==null){
strTitle=ViewMessages.NO_CONNECTION_SELECTED; strTitle=ViewMessages.NO_CONNECTION_SELECTED;
} else { } else {
// When parameter 'data' is null, we construct a descriptive string to // 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 //In order to make the logic of assembling, and the separators, better adapt to foreign languages
if(summary.length()>0) if(summary.length()>0)
summary=summary+" - "; //$NON-NLS-1$ summary=summary+" - "; //$NON-NLS-1$
String name=fCtlTerminal.getTerminalConnection().getName(); String name=fCtlTerminal.getTerminalConnectorInfo().getName();
if(name.length()>0) { if(name.length()>0) {
name+=": "; //$NON-NLS-1$ 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 // TODO: use another mechanism than "?" for the magic non initialized state
// see TerminalConnectorProxy.getSettingsSummary // see TerminalConnectorProxy.getSettingsSummary
String summary="?"; //$NON-NLS-1$ String summary="?"; //$NON-NLS-1$
if(fCtlTerminal.getTerminalConnection()!=null) if(fCtlTerminal.getTerminalConnectorInfo()!=null)
summary=fCtlTerminal.getSettingsSummary(); summary=fCtlTerminal.getSettingsSummary();
if("?".equals(summary)) { //$NON-NLS-1$ if("?".equals(summary)) { //$NON-NLS-1$
summary=fStore.get(STORE_SETTING_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. * This method creates the top-level control for the Terminal view.
*/ */
protected void setupControls(Composite wndParent) { protected void setupControls(Composite wndParent) {
ITerminalConnector[] connectors=TerminalConnectorExtension.getTerminalConnectors(); ITerminalConnectorInfo[] connectors=TerminalConnectorExtension.getTerminalConnectors();
fCtlTerminal = TerminalViewControlFactory.makeControl(this, wndParent, connectors); fCtlTerminal = TerminalViewControlFactory.makeControl(this, wndParent, connectors);
String connectionType=fStore.get(STORE_CONNECTION_TYPE); String connectionType=fStore.get(STORE_CONNECTION_TYPE);
for (int i = 0; i < connectors.length; i++) { 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)) if(connectors[i].getId().equals(connectionType))
fCtlTerminal.setConnector(connectors[i]); fCtlTerminal.setConnector(connectors[i]);
} }
setCommandInputField("true".equals(fStore.get(STORE_HAS_COMMAND_INPUT_FIELD))); //$NON-NLS-1$ setCommandInputField("true".equals(fStore.get(STORE_HAS_COMMAND_INPUT_FIELD))); //$NON-NLS-1$
} }
private void saveSettings(ITerminalConnector connector) { private void saveSettings(ITerminalConnectorInfo connector) {
ITerminalConnector[] connectors=fCtlTerminal.getConnectors(); ITerminalConnectorInfo[] connectors=fCtlTerminal.getConnectors();
for (int i = 0; i < connectors.length; i++) { for (int i = 0; i < connectors.length; i++) {
connectors[i].save(getStore(connectors[i])); connectors[i].getConnector().save(getStore(connectors[i]));
} }
if(connector!=null) { if(connector!=null) {
fStore.put(STORE_CONNECTION_TYPE,connector.getId()); 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.put(STORE_SETTING_SUMMARY, getSettingsSummary());
fStore.saveState(memento); fStore.saveState(memento);
} }
private ISettingsStore getStore(ITerminalConnector connector) { private ISettingsStore getStore(ITerminalConnectorInfo connector) {
return new SettingStorePrefixDecorator(fStore,connector.getId()+"."); //$NON-NLS-1$ return new SettingStorePrefixDecorator(fStore,connector.getId()+"."); //$NON-NLS-1$
} }

View file

@ -39,4 +39,7 @@ public class ViewMessages extends NLS {
public static String STATE_OPENED; public static String STATE_OPENED;
public static String STATE_CLOSED; public static String STATE_CLOSED;
public static String CANNOT_INITIALIZE;
public static String CONNECTOR_NOT_AVAILABLE;
} }

View file

@ -30,3 +30,6 @@ STATE_CONNECTED = CONNECTED
STATE_CONNECTING = CONNECTING... STATE_CONNECTING = CONNECTING...
STATE_OPENED = OPENED STATE_OPENED = OPENED
STATE_CLOSED = CLOSED STATE_CLOSED = CLOSED
CANNOT_INITIALIZE = Cannot initialize {0}:\n{1}
CONNECTOR_NOT_AVAILABLE = Connector {0} not available!

View file

@ -14,7 +14,7 @@ package org.eclipse.tm.internal.terminal.control;
import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.graphics.Font; 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; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
/** /**
@ -36,10 +36,10 @@ public interface ITerminalViewControl {
void disconnectTerminal(); void disconnectTerminal();
void disposeTerminal(); void disposeTerminal();
String getSettingsSummary(); String getSettingsSummary();
ITerminalConnector[] getConnectors(); ITerminalConnectorInfo[] getConnectors();
void setFocus(); void setFocus();
ITerminalConnector getTerminalConnection(); ITerminalConnectorInfo getTerminalConnectorInfo();
void setConnector(ITerminalConnector connector); void setConnector(ITerminalConnectorInfo connector);
void connectTerminal(); void connectTerminal();
/** /**
* @param write a single character to terminal * @param write a single character to terminal

View file

@ -13,10 +13,10 @@ package org.eclipse.tm.internal.terminal.control;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.tm.internal.terminal.control.impl.TerminalControl; 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 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); return new TerminalControl(target, wndParent, connectors);
} }
} }

View file

@ -13,7 +13,7 @@ package org.eclipse.tm.internal.terminal.control.impl;
import java.io.OutputStream; 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; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
/** /**
@ -27,7 +27,7 @@ public interface ITerminalControlForText {
void setState(TerminalState state); void setState(TerminalState state);
void setTerminalTitle(String title); void setTerminalTitle(String title);
ITerminalConnector getTerminalConnection(); ITerminalConnectorInfo getTerminalConnectorInfo();
void disconnectTerminal(); void disconnectTerminal();

View file

@ -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.ITerminalListener;
import org.eclipse.tm.internal.terminal.control.ITerminalViewControl; 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.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.ITerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.Logger; import org.eclipse.tm.internal.terminal.provisional.api.Logger;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; 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 String fMsg = ""; //$NON-NLS-1$
private VerifyKeyListener fVerifyKeyListener; private VerifyKeyListener fVerifyKeyListener;
private FocusListener fFocusListener; private FocusListener fFocusListener;
private ITerminalConnector fConnector; private ITerminalConnectorInfo fConnectorInfo;
private final ITerminalConnector[] fConnectors; private final ITerminalConnectorInfo[] fConnectors;
private ICommandInputField fCommandInputField; private ICommandInputField fCommandInputField;
private volatile TerminalState fState; private volatile TerminalState fState;
public TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) { public TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnectorInfo[] connectors) {
fConnectors=connectors; fConnectors=connectors;
fTerminalListener=target; fTerminalListener=target;
setTerminalText(new TerminalText(this)); setTerminalText(new TerminalText(this));
@ -103,7 +104,7 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
setupTerminal(wndParent); setupTerminal(wndParent);
} }
public ITerminalConnector[] getConnectors() { public ITerminalConnectorInfo[] getConnectors() {
return fConnectors; return fConnectors;
} }
@ -237,19 +238,28 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
public void connectTerminal() { public void connectTerminal() {
Logger.log("entered."); //$NON-NLS-1$ Logger.log("entered."); //$NON-NLS-1$
if(fConnector==null) if(getTerminalConnector()==null)
return; return;
fTerminalText.resetState(); fTerminalText.resetState();
try { if(fConnectorInfo.getInitializationErrorMessage()!=null) {
fConnector.connect(this); showErrorMessage(NLS.bind(
} catch(RuntimeException e) { TerminalMessages.CannotConnectTo,
showErrorMessage(NLS.bind(TerminalMessages.CannotConnectTo,new Object[]{fConnector.getName(),e.getMessage()})); fConnectorInfo.getName(),
fConnectorInfo.getInitializationErrorMessage()));
// we cannot connect because the connector was not initialized
return; return;
} }
getTerminalConnector().connect(this);
// clean the error message // clean the error message
setMsg(""); //$NON-NLS-1$ setMsg(""); //$NON-NLS-1$
waitForConnect(); waitForConnect();
} }
private ITerminalConnector getTerminalConnector() {
if(fConnectorInfo==null)
return null;
return fConnectorInfo.getConnector();
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl#disconnectTerminal() * @see org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl#disconnectTerminal()
*/ */
@ -259,9 +269,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
if (getState()==TerminalState.CLOSED) { if (getState()==TerminalState.CLOSED) {
return; return;
} }
if(fConnector!=null) { if(getTerminalConnector()!=null) {
fConnector.disconnect(); getTerminalConnector().disconnect();
// fConnector=null;
} }
} }
@ -482,8 +491,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
public OutputStream getOutputStream() { public OutputStream getOutputStream() {
if(fConnector!=null) if(getTerminalConnector()!=null)
return fConnector.getOutputStream(); return getTerminalConnector().getOutputStream();
return null; return null;
} }
@ -523,10 +532,9 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
/** /**
*/ */
public ITerminalConnector getTerminalConnection() { public ITerminalConnectorInfo getTerminalConnectorInfo() {
return fConnector; return fConnectorInfo;
} }
protected class TerminalModifyListener implements ModifyListener { protected class TerminalModifyListener implements ModifyListener {
public void modifyText(ModifyEvent e) { public void modifyText(ModifyEvent e) {
if (e.getSource() instanceof StyledText) { if (e.getSource() instanceof StyledText) {
@ -752,9 +760,9 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
// locally, send a LF after sending a CR. // locally, send a LF after sending a CR.
// ISSUE: Is this absolutely required? // ISSUE: Is this absolutely required?
if (character == '\r' && getTerminalConnection() != null if (character == '\r' && getTerminalConnectorInfo() != null
&& isConnected() && isConnected()
&& getTerminalConnection().isLocalEcho()) { && getTerminalConnectorInfo().getConnector().isLocalEcho()) {
sendChar('\n', false); sendChar('\n', false);
} }
@ -773,8 +781,8 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
// //
// o The character is the DELETE character. // o The character is the DELETE character.
if (getTerminalConnection() == null if (getTerminalConnectorInfo() == null
|| getTerminalConnection().isLocalEcho() == false || altKeyPressed || getTerminalConnectorInfo().getConnector().isLocalEcho() == false || altKeyPressed
|| (character >= '\u0001' && character < '\t') || (character >= '\u0001' && character < '\t')
|| (character > '\t' && character < '\r') || (character > '\t' && character < '\r')
|| (character > '\r' && character <= '\u001f') || (character > '\r' && character <= '\u001f')
@ -815,13 +823,13 @@ public class TerminalControl implements ITerminalControlForText, ITerminalContro
} }
public String getSettingsSummary() { public String getSettingsSummary() {
if(fConnector!=null) if(getTerminalConnector()!=null)
return fConnector.getSettingsSummary(); return getTerminalConnector().getSettingsSummary();
return ""; //$NON-NLS-1$ return ""; //$NON-NLS-1$
} }
public void setConnector(ITerminalConnector connector) { public void setConnector(ITerminalConnectorInfo connector) {
fConnector=connector; fConnectorInfo=connector;
} }
public ICommandInputField getCommandInputField() { public ICommandInputField getCommandInputField() {

View file

@ -17,4 +17,4 @@
TerminalError = Terminal Error TerminalError = Terminal Error
SocketError = Socket Error SocketError = Socket Error
IOError = IO Error IOError = IO Error
CannotConnectTo = Cannot connect to {1}:\n{2} CannotConnectTo = Cannot initialize {0}:\n{1}

View file

@ -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 // there is nothing we can do to tell the remote host about the size of the
// terminal. // terminal.
ITerminalConnector telnetConnection = terminal.getTerminalConnection(); ITerminalConnector telnetConnection = getConnector();
// TODO MSA: send only if dimensions have really changed! // TODO MSA: send only if dimensions have really changed!
if (telnetConnection != null && widthInColumns != 0 && heightInLines != 0) { if (telnetConnection != null && widthInColumns != 0 && heightInLines != 0) {
telnetConnection.setTerminalSize(widthInColumns, heightInLines); 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 * 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 * font. The Font object representing the font in the Terminal view doesn't

View file

@ -28,27 +28,12 @@ import java.io.OutputStream;
*/ */
public interface ITerminalConnector { public interface ITerminalConnector {
/** /**
* @return an ID of this connector. The id from the plugin.xml. * Initializes the Connector. Some connector depend on external libraries that
* <p>Note: return <code>null</code> because the framework takes * might not be installed.
* care to get the value from the plugin.xml * @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 void initialize() throws Exception;
String getId();
/**
* @return <code>null</code> the name (as specified in the plugin.xml)
* <p>Note: return <code>null</code> 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();
/** /**
* Connect using the current state of the settings. * Connect using the current state of the settings.

View file

@ -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.
* <p>Note: return <code>null</code> because the framework takes
* care to get the value from the plugin.xml
*/
String getId();
/**
* @return <code>null</code> the name (as specified in the plugin.xml)
* <p>Note: return <code>null</code> 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, <code>null</code> is
* returned. Otherwise an error message describing the problem is returned.
* @return <code>null</code> 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();
}

View file

@ -16,10 +16,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.RegistryFactory; 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. * A factory to get {@link ITerminalConnector} instances.
@ -34,6 +31,28 @@ import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin;
* </p> * </p>
*/ */
public class TerminalConnectorExtension { 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 * A placeholder for the ITerminalConnector. It gets initialized when
* the real connector is needed. * the real connector is needed.
@ -67,6 +86,12 @@ public class TerminalConnectorExtension {
TerminalConnectorProxy(IConfigurationElement config) { TerminalConnectorProxy(IConfigurationElement config) {
fConfig=config; fConfig=config;
} }
public String getLocalizedErrorMessage() {
getConnector();
if(fException!=null)
return fException.getLocalizedMessage();
return null;
}
public String getId() { public String getId() {
String id = fConfig.getAttribute("id"); //$NON-NLS-1$ String id = fConfig.getAttribute("id"); //$NON-NLS-1$
if(id==null || id.length()==0) if(id==null || id.length()==0)
@ -84,17 +109,15 @@ public class TerminalConnectorExtension {
if(!isInitialized()) { if(!isInitialized()) {
try { try {
fConnector=createConnector(fConfig); fConnector=createConnector(fConfig);
if(fConnector==null || !fConnector.isInstalled()) fConnector.initialize();
// TODO MSA externalize
throw new RuntimeException(getName()+ " is not properly installed!"); //$NON-NLS-1$
} catch (Exception e) { } catch (Exception e) {
fException=e; fException=e;
// that's the place where we log the exception
Logger.logException(e);
} }
if(fConnector!=null && fStore!=null) if(fConnector!=null && fStore!=null)
fConnector.load(fStore); fConnector.load(fStore);
} }
if(fException!=null)
throw new RuntimeException(fException);
return fConnector; return fConnector;
} }
private boolean isInitialized() { private boolean isInitialized() {
@ -116,11 +139,6 @@ public class TerminalConnectorExtension {
// TODO: see TerminalView.getSettingsSummary // TODO: see TerminalView.getSettingsSummary
return "?"; //$NON-NLS-1$ return "?"; //$NON-NLS-1$
} }
public boolean isInstalled() {
if(isInitialized() && fConnector==null)
return false;
return getConnector().isInstalled();
}
public boolean isLocalEcho() { public boolean isLocalEcho() {
return getConnector().isLocalEcho(); return getConnector().isLocalEcho();
} }
@ -137,7 +155,7 @@ public class TerminalConnectorExtension {
public void save(ISettingsStore store) { public void save(ISettingsStore store) {
// no need to save the settings: it cannot have changed // no need to save the settings: it cannot have changed
// because we are not initialized.... // because we are not initialized....
if(!isInstalled()) if(fConnector!=null)
getConnector().save(store); getConnector().save(store);
} }
public void setTerminalSize(int newWidth, int newHeight) { public void setTerminalSize(int newWidth, int newHeight) {
@ -148,37 +166,26 @@ public class TerminalConnectorExtension {
fConnector.setTerminalSize(newWidth, newHeight); 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 * @return null or a new connector created from the extension
*/ */
static private ITerminalConnector createConnector(IConfigurationElement config) throws Exception { static private ITerminalConnector createConnector(IConfigurationElement config) throws Exception {
try { return (ITerminalConnector)config.createExecutableExtension("class"); //$NON-NLS-1$
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 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$ IConfigurationElement[] config=RegistryFactory.getRegistry().getConfigurationElementsFor("org.eclipse.tm.terminal.terminalConnector"); //$NON-NLS-1$
List result=new ArrayList(); List result=new ArrayList();
for (int i = 0; i < config.length; i++) { 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));
}
} }

View file

@ -41,15 +41,11 @@ public class TelnetConnector implements ITerminalConnector {
public TelnetConnector() { public TelnetConnector() {
this(new TelnetSettings()); this(new TelnetSettings());
} }
public String getId() {
return null;
}
public String getName() {
return null;
}
public TelnetConnector(TelnetSettings settings) { public TelnetConnector(TelnetSettings settings) {
fSettings=settings; fSettings=settings;
} }
public void initialize() throws Exception {
}
public void connect(ITerminalControl control) { public void connect(ITerminalControl control) {
Logger.log("entered."); //$NON-NLS-1$ Logger.log("entered."); //$NON-NLS-1$
fControl=control; fControl=control;
@ -165,7 +161,4 @@ public class TelnetConnector implements ITerminalConnector {
public void save(ISettingsStore store) { public void save(ISettingsStore store) {
fSettings.save(store); fSettings.save(store);
} }
public boolean isInstalled() {
return true;
}
} }