diff --git a/plugins/org.eclipse.tcf.te.core.terminals/.classpath b/plugins/org.eclipse.tcf.te.core.terminals/.classpath
new file mode 100644
index 00000000000..ad32c83a788
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/.classpath
@@ -0,0 +1,7 @@
+
+
May 24, 2012
+The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.
+ +If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.
+ + + \ No newline at end of file diff --git a/plugins/org.eclipse.tcf.te.core.terminals/build.properties b/plugins/org.eclipse.tcf.te.core.terminals/build.properties new file mode 100644 index 00000000000..20b8ec4298b --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/build.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2012, 2015 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: +# Wind River Systems - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html,\ + plugin.xml diff --git a/plugins/org.eclipse.tcf.te.core.terminals/plugin.properties b/plugins/org.eclipse.tcf.te.core.terminals/plugin.properties new file mode 100644 index 00000000000..8bb225013de --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/plugin.properties @@ -0,0 +1,14 @@ +################################################################################## +# Copyright (c) 2015 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: +# Wind River Systems - initial API and implementation +################################################################################## + +pluginName = Target Explorer, Terminals Core +providerName = Eclipse.org - Target Explorer + +ExtensionPoint.contextPropertiesProviders = Terminal Context Properties Providers diff --git a/plugins/org.eclipse.tcf.te.core.terminals/plugin.xml b/plugins/org.eclipse.tcf.te.core.terminals/plugin.xml new file mode 100644 index 00000000000..4d281a2f19d --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/plugin.xml @@ -0,0 +1,6 @@ + + +null
.
+ * @return True
if the context properties provider contribution is enabled
+ * for the given terminal context, false
otherwise.
+ */
+ protected boolean isEnabled(Object context) {
+ if (context == null) {
+ return getEnablement() == null;
+ }
+
+ Expression enablement = getEnablement();
+
+ // The service contribution is enabled by default if no expression is specified.
+ boolean enabled = enablement == null;
+
+ if (enablement != null) {
+ // Set the default variable to the service context.
+ EvaluationContext evalContext = new EvaluationContext(null, context);
+ // Allow plug-in activation
+ evalContext.setAllowPluginActivation(true);
+ // Evaluate the expression
+ try {
+ enabled = enablement.evaluate(evalContext).equals(EvaluationResult.TRUE);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), e.getLocalizedMessage(), e);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+
+ return enabled;
+ }
+
+ /**
+ * Returns the enablement expression.
+ *
+ * @return The enablement expression or null
.
+ */
+ protected Expression getEnablement() {
+ return expression;
+ }
+ }
+
+
+ /**
+ * Creates a new terminal context properties provider proxy instance and initialize it.
+ *
+ * @param config The configuration element. Must not be null
.
+ * @return The new terminal context properties provider proxy instance.
+ */
+ private static Proxy getProxy(IConfigurationElement config) {
+ Assert.isNotNull(config);
+ Proxy proxy = new Proxy();
+ try {
+ proxy.setInitializationData(config, null, null);
+ } catch (CoreException e) {
+ if (Platform.inDebugMode()) {
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(e.getStatus());
+ }
+ }
+ return proxy;
+ }
+
+ /**
+ * Load the terminal context properties provider contributions.
+ */
+ private static void loadContributions() {
+ IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.tcf.te.core.terminals.contextPropertiesProviders"); //$NON-NLS-1$
+ if (ep != null) {
+ IExtension[] extensions = ep.getExtensions();
+ if (extensions != null) {
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] configElements = extension.getConfigurationElements();
+ if (configElements != null) {
+ for (IConfigurationElement configElement : configElements) {
+ if ("contextPropertiesProvider".equals(configElement.getName())) { //$NON-NLS-1$
+ Proxy proxy = getProxy(configElement);
+ contributions.add(proxy);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the terminal context properties provider for the given context. The first terminal
+ * context properties provider which is enabled is returned.
+ *
+ * @param context The terminal context. Must not be null
.
+ *
+ * @return The service or null
.
+ */
+ public static ITerminalContextPropertiesProvider getProvider(Object context) {
+ Assert.isNotNull(context);
+
+ // Load the contributions if not yet loaded
+ synchronized (contributions) {
+ if (!contributionsLoaded) {
+ loadContributions();
+ contributionsLoaded = true;
+ }
+ }
+
+ for (Proxy proxy : contributions) {
+ if (proxy.isEnabled(context)) {
+ return proxy.getProvider();
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/TerminalServiceFactory.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/TerminalServiceFactory.java
new file mode 100644
index 00000000000..4b5eba9c958
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/TerminalServiceFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tcf.te.core.terminals.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService;
+import org.eclipse.tcf.te.core.terminals.nls.Messages;
+import org.osgi.framework.Bundle;
+
+/**
+ * Terminal service factory implementation.
+ * + * Provides access to the terminal service instance. + */ +public final class TerminalServiceFactory { + private static ITerminalService instance = null; + + static { + // Tries to instantiate the terminal service implementation + // from the o.e.tcf.te.ui.terminals bundle + Bundle bundle = Platform.getBundle("org.eclipse.tcf.te.ui.terminals"); //$NON-NLS-1$ + if (bundle != null && bundle.getState() != Bundle.UNINSTALLED && bundle.getState() != Bundle.STOPPING) { + try { + Class> clazz = bundle.loadClass("org.eclipse.tcf.te.ui.terminals.services.TerminalService"); //$NON-NLS-1$ + instance = (ITerminalService) clazz.newInstance(); + } + catch (Exception e) { + if (Platform.inDebugMode()) { + Platform.getLog(bundle).log(new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), Messages.TerminalServiceFactory_error_serviceImplLoadFailed, e)); + } + } + } + } + + /** + * Returns the terminal service instance. + */ + public static ITerminalService getService() { + return instance; + } +} diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/activator/CoreBundleActivator.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/activator/CoreBundleActivator.java new file mode 100644 index 00000000000..054468888df --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/activator/CoreBundleActivator.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2015 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.core.terminals.activator; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class CoreBundleActivator implements BundleActivator { + // The bundle context + private static BundleContext context; + + /** + * Returns the bundle context + * + * @return the bundle context + */ + public static BundleContext getContext() { + return context; + } + + /** + * Convenience method which returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + if (getContext() != null && getContext().getBundle() != null) { + return getContext().getBundle().getSymbolicName(); + } + return "org.eclipse.tcf.te.core.terminals"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext bundleContext) throws Exception { + CoreBundleActivator.context = bundleContext; + } + + /* (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext bundleContext) throws Exception { + CoreBundleActivator.context = null; + } +} diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalContextPropertiesProvider.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalContextPropertiesProvider.java new file mode 100644 index 00000000000..41f2cd3e79f --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalContextPropertiesProvider.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2015 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.core.terminals.interfaces; + +import java.util.Map; + +/** + * Terminal context properties provider. + *
+ * The context properties provider allows querying desired properties + * for a given context. The context is typically an element from a selection + * and the inner structure of the element is unknown to the terminal. + */ +public interface ITerminalContextPropertiesProvider { + + /** + * Returns a unmodifiable map containing the target address and port for the given context, + * if it can be determined. + *
+ * A context may return multiple target addresses and ports if the context can be reached using + * different connection methods. + *
+ * Note: + *
null
.null
.
+ * @return The unmodifiable map containing the target addresses and ports, or null
.
+ */
+ public Mapnull
is returned.
+ *
+ * @param context The context to get the property from. Must not be null
.
+ * @param key The property key. Must not be null
.
+ *
+ * @return The stored property value or null
.
+ */
+ public Object getProperty(Object context, String key);
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalService.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalService.java
new file mode 100644
index 00000000000..e4c90c5878c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalService.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2011 - 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.interfaces;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Terminals service.
+ */
+public interface ITerminalService {
+
+ /**
+ * Client call back interface.
+ */
+ public interface Done {
+ /**
+ * Called when the terminal service operation is done.
+ *
+ * @param status The status of the terminal service operation.
+ */
+ public void done(IStatus status);
+ }
+
+ /**
+ * Opens a terminal asynchronously and invokes the given callback if done.
+ *
+ * @param properties The terminal properties. Must not be null
.
+ * @param done The callback to invoke if finished or null
.
+ */
+ public void openConsole(Mapnull
.
+ * @param done The callback to invoke if finished or null
.
+ */
+ public void closeConsole(Mapnull
.
+ * @param done The callback to invoke if finished or null
.
+ */
+ public void terminateConsole(Mapnull
.
+ */
+ public void addTerminalTabListener(ITerminalTabListener listener);
+
+ /**
+ * Unregister the given listener from receiving notifications about terminal
+ * events. Calling this method multiple times with the same listener
+ * has no effect.
+ *
+ * @param listener The terminal tab listener. Must not be null
.
+ */
+ public void removeTerminalTabListener(ITerminalTabListener listener);
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalServiceOutputStreamMonitorListener.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalServiceOutputStreamMonitorListener.java
new file mode 100644
index 00000000000..dda3704b018
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalServiceOutputStreamMonitorListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.interfaces;
+
+/**
+ * An interface to be implemented by listeners who want to listen
+ * to the streams data without interfering with the original data receiver.
+ *
+ * Listeners are invoked within the monitor processing thread.
+ */
+public interface ITerminalServiceOutputStreamMonitorListener {
+
+ /**
+ * Signals that some content has been read from the monitored stream.
+ *
+ * @param byteBuffer The byte stream. Must not be null
.
+ * @param bytesRead The number of bytes that were read into the read buffer.
+ */
+ public void onContentReadFromStream(byte[] byteBuffer, int bytesRead);
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalTabListener.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalTabListener.java
new file mode 100644
index 00000000000..77e3e04eb13
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/ITerminalTabListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.interfaces;
+
+/**
+ * Listener to implement and to register to get notified about
+ * terminal tabs events, like the disposal of a terminal tab.
+ */
+public interface ITerminalTabListener {
+
+ /**
+ * Invoked once a terminal tab got disposed. The source object is
+ * the disposed tab item and data is the custom data object associated
+ * with the disposed tab item.
+ *
+ * @param source The disposed tab item. Must not be null
.
+ * @param data The custom data object associated with the disposed tab item or null
.
+ */
+ public void terminalTabDisposed(Object source, Object data);
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/IContextPropertiesConstants.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/IContextPropertiesConstants.java
new file mode 100644
index 00000000000..b2e98aacd39
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/IContextPropertiesConstants.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.interfaces.constants;
+
+/**
+ * Defines the terminal context properties constants.
+ */
+public interface IContextPropertiesConstants {
+
+ /**
+ * Target name.
+ *
+ * The target name is not meant to be identical with the targets network name. It can + * be the targets network name, but it can be any other string identifying the target + * to the user as well. The name is for display only, it is not meant to be used for + * communicating with the target. + */ + public static String PROP_NAME = "name"; //$NON-NLS-1$ + + /** + * Target agent address. + *
+ * The value is typically the address an agent running at the target. + */ + public static String PROP_ADDRESS = "address"; //$NON-NLS-1$ + + /** + * Target agent port. + *
+ * The value is typically the port an agent running at the target. + */ + public static String PROP_PORT = "port"; //$NON-NLS-1$ + + /** + * The default user name to use to log into the target. + */ + public static String PROP_DEFAULT_USER = "defaultUser"; //$NON-NLS-1$ + + /** + * The default encoding to use. + */ + public static String PROP_DEFAULT_ENCODING = "defaultEncoding"; //$NON-NLS-1$ +} diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ILineSeparatorConstants.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ILineSeparatorConstants.java new file mode 100644 index 00000000000..8fea4b82df7 --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ILineSeparatorConstants.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2011 - 2015 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.core.terminals.interfaces.constants; + +/** + * Line separator constants. + *
+ * Copied from org.eclipse.tcf.internal.terminal.local.ILocalTerminalSettings
.
+ */
+public interface ILineSeparatorConstants {
+
+ /**
+ * The line separator setting CR (carriage return only; for example, used by Mac OS 9).
+ */
+ public final static String LINE_SEPARATOR_CR = "\\r"; //$NON-NLS-1$
+
+ /**
+ * The line separator setting CRLF (carriage return and line feed; for example, used by
+ * Windows).
+ */
+ public final static String LINE_SEPARATOR_CRLF = "\\r\\n"; //$NON-NLS-1$
+
+ /**
+ * The line separator setting LF (line feed only; used by all UNIX-based systems).
+ */
+ public final static String LINE_SEPARATOR_LF = "\\n"; //$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ITerminalsConnectorConstants.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ITerminalsConnectorConstants.java
new file mode 100644
index 00000000000..0624d36224f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/interfaces/constants/ITerminalsConnectorConstants.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2011 - 2015 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:
+ * Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361352] [TERMINALS][SSH] Add SSH terminal support
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.interfaces.constants;
+
+import org.eclipse.tcf.te.core.terminals.interfaces.ITerminalServiceOutputStreamMonitorListener;
+
+
+/**
+ * Defines the terminals connector constants.
+ */
+public interface ITerminalsConnectorConstants {
+
+ /**
+ * Property: The unique id of the terminals view to open.
+ *
+ * Property Type: {@link String} + */ + public static final String PROP_ID = "id"; //$NON-NLS-1$ + + /** + * Property: The unique secondary id of the terminals view to open. + *
+ * Property Type: {@link String} + */ + public static final String PROP_SECONDARY_ID = "secondaryId"; //$NON-NLS-1$ + + /** + * Property: The title of the terminal tab to open. + *
+ * Property Type: {@link String} + */ + public static final String PROP_TITLE = "title"; //$NON-NLS-1$ + + /** + * Property: The encoding of the terminal tab to open. + *
+ * Property Type: {@link String} + */ + public static final String PROP_ENCODING = "encoding"; //$NON-NLS-1$ + + /** + * Property: Custom data object to associate with the terminal tab. + *
+ * Property Type: {@link Object} + */ + public static final String PROP_DATA = "data"; //$NON-NLS-1$ + + /** + * Property: External selection to associate with the terminal tab. + *
+ * Property Type: {@link org.eclipse.jface.viewers.ISelection} + */ + public static final String PROP_SELECTION = "selection"; //$NON-NLS-1$ + + /** + * Property: Flag to force a new terminal tab. + *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_FORCE_NEW = "terminal.forceNew"; //$NON-NLS-1$ + + /** + * Property: Flag to signal if the terminal tab shall have a disconnect button or not. + *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_HAS_DISCONNECT_BUTTON = "hasDisconnectButton"; //$NON-NLS-1$ + + /** + * Property: Terminals launcher delegate id. + *
+ * Property Type: {@link String} + */ + public static final String PROP_DELEGATE_ID = "delegateId"; //$NON-NLS-1$ + + /** + * Property: Specific terminal connector type id. Allows clients to + * override the specifically used terminal connector + * implementation for a given type. + *
+ * Property Type: {@link String} + */ + public static final String PROP_TERMINAL_CONNECTOR_ID = "tm.terminal.connector.id"; //$NON-NLS-1$ + + // ***** Generic terminals connector properties ***** + + /** + * Property: Timeout to be passed to the terminal connector. The specific terminal + * connector implementation may interpret this value differently. If not + * set, the terminal connector may use a default value. + *
+ * Property Type: {@link Integer} + */ + public static final String PROP_TIMEOUT = "timeout"; //$NON-NLS-1$ + + /** + * Property: Flag to control if a local echo is needed from the terminal widget. + *
Typical for process and streams terminals. + *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_LOCAL_ECHO = "localEcho"; //$NON-NLS-1$ + + /** + * Property: Data flag to tell the terminal to not reconnect when hitting enter + * in a disconnected terminal. + * The flag can be set by adding an IPropertiesContainer with the set + * flag as PROP_DATA. + *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_DATA_NO_RECONNECT = "data.noReconnect"; //$NON-NLS-1$ + + /** + * Property: The line separator expected by the remote terminal on input streams and + * send by the remote terminal on output streams. + *
Typical for process and streams terminals. + *
+ * Property Type: {@link String} + */ + public static final String PROP_LINE_SEPARATOR = "lineSeparator"; //$NON-NLS-1$ + + /** + * Property: The list of stdout listeners to attach to the corresponding stream monitor. + *
Typical for process and streams terminals. + *
+ * Property Type: {@link ITerminalServiceOutputStreamMonitorListener} array + */ + public static final String PROP_STDOUT_LISTENERS = "stdoutListeners"; //$NON-NLS-1$ + + /** + * Property: The list of stderr listeners to attach to the corresponding stream monitor. + *
Typical for process and streams terminals. + *
+ * Property Type: {@link ITerminalServiceOutputStreamMonitorListener} array
+ */
+ public static final String PROP_STDERR_LISTENERS = "stderrListeners"; //$NON-NLS-1$
+
+ /**
+ * Property: If set to true
, backslashes are translated to
+ * slashes before pasting the text to the terminal widget.
+ *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_TRANSLATE_BACKSLASHES_ON_PASTE = "translateBackslashesOnPaste"; //$NON-NLS-1$ + + // ***** IP based terminals connector properties ***** + + /** + * Property: Host name or IP address the terminal server is running. + *
Typical for telnet or ssh terminals. + *
+ * Property Type: {@link String} + */ + public static final String PROP_IP_HOST = "ip.host"; //$NON-NLS-1$ + + /** + * Property: Port at which the terminal server is providing the console input and output. + *
Typical for telnet or ssh terminals. + *
+ * Property Type: {@link Integer} + */ + public static final String PROP_IP_PORT = "ip.port"; //$NON-NLS-1$ + + /** + * Property: An offset to add to the specified port number. + *
Typical for telnet or ssh terminals. + *
+ * Property Type: {@link Integer} + */ + public static final String PROP_IP_PORT_OFFSET = "ip.port.offset"; //$NON-NLS-1$ + + // ***** Process based terminals connector properties ***** + + /** + * Property: Process image path. + *
Typical for process terminals. + *
+ * Property Type: {@link String} + */ + public static final String PROP_PROCESS_PATH = "process.path"; //$NON-NLS-1$ + + /** + * Property: Process arguments. + *
Typical for process terminals. + *
+ * Property Type: {@link String} + */ + public static final String PROP_PROCESS_ARGS = "process.args"; //$NON-NLS-1$ + + /** + * Property: Process arguments. + *
Typical for process terminals. + *
+ * Property Type: {@link String} + */ + public static final String PROP_PROCESS_WORKING_DIR = "process.working_dir"; //$NON-NLS-1$ + + /** + * Property: Process environment. + *
Typical for process terminals. + *
+ * Property Type: {@link String} array + */ + public static final String PROP_PROCESS_ENVIRONMENT = "process.environment"; //$NON-NLS-1$ + + /** + * Property: Flag to merge process environment with native environment. + *
Typical for process terminals. + *
+ * Property Type: {@link Boolean} + */ + public static final String PROP_PROCESS_MERGE_ENVIRONMENT = "process.environment.merge"; //$NON-NLS-1$ + + /** + * Property: Runtime process instance. + *
Typical for process terminals. + *
+ * Property Type: {@link Process} + */ + public static final String PROP_PROCESS_OBJ = "process"; //$NON-NLS-1$ + + /** + * Property: Runtime process PTY instance. + *
Typical for process terminals. + *
+ * Property Type: {@link org.eclipse.cdt.utils.pty.PTY} + */ + public static final String PROP_PTY_OBJ = "pty"; //$NON-NLS-1$ + + // ***** Streams based terminals connector properties ***** + + /** + * Property: Stdin streams instance. + *
Typical for streams terminals. + *
+ * Property Type: {@link OutputStream} + */ + public static final String PROP_STREAMS_STDIN = "streams.stdin"; //$NON-NLS-1$ + + /** + * Property: Stdout streams instance. + *
Typical for streams terminals. + *
+ * Property Type: {@link InputStream} + */ + public static final String PROP_STREAMS_STDOUT = "streams.stdout"; //$NON-NLS-1$ + + /** + * Property: Stderr streams instance. + *
Typical for streams terminals. + *
+ * Property Type: {@link InputStream} + */ + public static final String PROP_STREAMS_STDERR = "streams.stderr"; //$NON-NLS-1$ + + // ***** Ssh specific properties ***** + + /** + * Property: ssh keep alive value. + *
+ * Property Type: {@link Integer} + */ + public static final String PROP_SSH_KEEP_ALIVE = "ssh.keep_alive"; //$NON-NLS-1$ + + /** + * Property: Ssh password. + *
+ * Property Type: {@link String} + */ + public static final String PROP_SSH_PASSWORD = "ssh.password"; //$NON-NLS-1$ + + /** + * Property: Ssh user. + *
+ * Property Type: {@link String} + */ + public static final String PROP_SSH_USER = "ssh.user"; //$NON-NLS-1$ + + // ***** Serial specific properties ***** + + /** + * The serial device name. + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_DEVICE = "serial.device"; //$NON-NLS-1$ + + /** + * The baud rate. + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_BAUD_RATE = "serial.baudrate"; //$NON-NLS-1$ + + /** + * The data bits + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_DATA_BITS = "serial.databits"; //$NON-NLS-1$ + + /** + * The parity + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_PARITY = "serial.parity"; //$NON-NLS-1$ + + /** + * The stop bits + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_STOP_BITS = "serial.stopbits"; //$NON-NLS-1$ + + /** + * The flow control + *
+ * Property Type: {@link String} + */ + public static final String PROP_SERIAL_FLOW_CONTROL = "serial.flowcontrol"; //$NON-NLS-1$ +} diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.java new file mode 100644 index 00000000000..23cc87c4636 --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2015 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.core.terminals.nls; + +import org.eclipse.osgi.util.NLS; + +/** + * Externalized strings management. + */ +public class Messages extends NLS { + + // The plug-in resource bundle name + private static final String BUNDLE_NAME = "org.eclipse.tcf.te.core.terminals.nls.Messages"; //$NON-NLS-1$ + + /** + * Static constructor. + */ + static { + // Load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + // **** Declare externalized string id's down here ***** + + public static String TerminalServiceFactory_error_serviceImplLoadFailed; + + public static String Extension_error_missingRequiredAttribute; +} diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.properties b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.properties new file mode 100644 index 00000000000..212cd1893c1 --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/nls/Messages.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2015 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: +# Wind River Systems - initial API and implementation +############################################################################### + +TerminalServiceFactory_error_serviceImplLoadFailed=Failed to load terminal service implementation. + +Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"! + diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/preferences/ScopedEclipsePreferences.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/preferences/ScopedEclipsePreferences.java new file mode 100644 index 00000000000..33d505f2ce6 --- /dev/null +++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/preferences/ScopedEclipsePreferences.java @@ -0,0 +1,459 @@ +/******************************************************************************* + * Copyright (c) 2011, 2015 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.core.terminals.preferences; + +import java.io.OutputStream; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.core.runtime.preferences.IPreferenceFilter; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; + +/** + * Helper class to handle scoped Eclipse preferences for plug-in's. Scoped + * preferences means a given preference context plus the default preferences + * scope. + *
+ * On changes a {@link PreferenceChangeEvent} is sent to inform all listeners of the change. + * + * @see IEclipsePreferences + * @see IEclipsePreferences.PreferenceChangeEvent + * @see IEclipsePreferences.IPreferenceChangeListener + */ +public class ScopedEclipsePreferences { + /** + * The preferences scope qualifier. + */ + private final String qualifier; + + /** + * The default scope preference node. + */ + protected final IEclipsePreferences defaultPrefs; + + /** + * The context scope preference node. + */ + protected final IEclipsePreferences contextScopePrefs; + + /** + * The registered preference change listeners. + */ + private final ListenerList listeners = new ListenerList(); + + /** + * Constructor. + *
+ * Initialize the scoped preferences with a new instance scope for the given qualifier. The default
+ * scope is determined by calling DefaultScope().getNode(qualifier)
.
+ *
+ * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be null
.
+ */
+ public ScopedEclipsePreferences(String qualifier) {
+ this(InstanceScope.INSTANCE, qualifier);
+ }
+
+ /**
+ * Constructor.
+ *
+ * Initialize the scoped preferences with the given scope. The default scope
+ * is determined by calling DefaultScope().getNode(qualifier)
.
+ *
+ * @param context The preference scope context. Must not be null
.
+ * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be null
.
+ */
+ public ScopedEclipsePreferences(IScopeContext context, String qualifier) {
+ Assert.isNotNull(context);
+ Assert.isNotNull(qualifier);
+ this.qualifier = qualifier;
+ defaultPrefs = DefaultScope.INSTANCE.getNode(getQualifier());
+ contextScopePrefs = context.getNode(getQualifier());
+ }
+
+ /**
+ * Returns the qualifier that is used to get the preferences.
+ * For plugin preferences, this is the unique identifier of the plugin.
+ */
+ protected final String getQualifier() {
+ return qualifier;
+ }
+
+ /**
+ * Exports the preferences to the stream.
+ *
+ * Note: The stream will be closed after the export.
+ *
+ * @param stream The stream to where preferences and defaults should be exported.
+ */
+ public void exportPreferences(OutputStream stream) {
+ Assert.isNotNull(stream);
+ try {
+ IPreferenceFilter filter = new IPreferenceFilter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getScopes()
+ */
+ @Override
+ public String[] getScopes() {
+ return new String[] { InstanceScope.SCOPE };
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getMapping(java.lang.String)
+ */
+ @Override
+ public Map getMapping(String scope) {
+ return null;
+ }
+ };
+
+ Platform.getPreferencesService().exportPreferences(contextScopePrefs, new IPreferenceFilter[] { filter }, stream);
+ stream.close();
+ }
+ catch (Exception e) {
+ }
+ }
+
+ /**
+ * Check whether a key is set or not.
+ *
+ * @param key The key to check.
+ * @return null
if the key does not exist.
+ */
+ public boolean containsKey(String key) {
+ return Platform.getPreferencesService().getString(getQualifier(), key, null, null) != null;
+ }
+
+ /**
+ * Get a String preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final String getString(String key) {
+ return Platform.getPreferencesService().getString(getQualifier(), key, null, null);
+ }
+
+ /**
+ * Get a boolean preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final boolean getBoolean(String key) {
+ return Platform.getPreferencesService().getBoolean(getQualifier(), key, false, null);
+ }
+
+ /**
+ * Get an int preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final int getInt(String key) {
+ return Platform.getPreferencesService().getInt(getQualifier(), key, 0, null);
+ }
+
+ /**
+ * Get a long preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final long getLong(String key) {
+ return Platform.getPreferencesService().getLong(getQualifier(), key, 0, null);
+ }
+
+ /**
+ * Get a default String preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or null
.
+ */
+ public final String getDefaultString(String key) {
+ return defaultPrefs.get(key, null);
+ }
+
+ /**
+ * Get a default boolean preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or null
.
+ */
+ public final boolean getDefaultBoolean(String key) {
+ return defaultPrefs.getBoolean(key, false);
+ }
+
+ /**
+ * Get a default int preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or null
.
+ */
+ public final int getDefaultInt(String key) {
+ return defaultPrefs.getInt(key, 0);
+ }
+
+ /**
+ * Get a default long preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or null
.
+ */
+ public final long getDefaultLong(String key) {
+ return defaultPrefs.getLong(key, 0);
+ }
+
+ /**
+ * Set a String preference value. If the value is null
or is equal to
+ * the default value, the entry will be removed.
+ *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. + * + * @param key The preference key. + * @return The value of the preference key. + */ + public void putString(String key, String value) { + String defValue = defaultPrefs.get(key, null); + String instValue = getString(key); + if (value == null || value.equals(defValue)) { + contextScopePrefs.remove(key); + flushAndNotify(contextScopePrefs, key, instValue, defValue); + } + else if (!value.equals(instValue)) { + contextScopePrefs.put(key, value); + flushAndNotify(contextScopePrefs, key, instValue, value); + } + } + + /** + * Set a boolean preference value. If the value is equal the default value, + * the entry will be removed. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. + * + * @param key The preference key. + * @return The value of the preference key. + */ + public void putBoolean(String key, boolean value) { + boolean defValue = defaultPrefs.getBoolean(key, false); + boolean instValue = getBoolean(key); + if (value == defValue) { + contextScopePrefs.remove(key); + flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(defValue)); + } + else if (value != instValue) { + contextScopePrefs.putBoolean(key, value); + flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(value)); + } + } + + /** + * Set an int preference value. If the value is equal to the default value, + * the entry will be removed. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old + * and new values are string representation in base 10. + * + * @param key The preference key. + * @return The value of the preference key. + */ + public void putInt(String key, int value) { + int defValue = defaultPrefs.getInt(key, 0); + int instValue = getInt(key); + if (value == defValue) { + contextScopePrefs.remove(key); + flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(defValue)); + } + else if (value != instValue) { + contextScopePrefs.putInt(key, value); + flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(value)); + } + } + + /** + * Set a long preference value. If the given value is equal to the default + * value, the entry will be removed. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key.
+ */
+ public void putLong(String key, long value) {
+ long defValue = defaultPrefs.getLong(key, 0);
+ long instValue = getLong(key);
+ if (value == defValue) {
+ contextScopePrefs.remove(key);
+ flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(defValue));
+ }
+ else if (value != instValue) {
+ contextScopePrefs.putLong(key, value);
+ flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(value));
+ }
+ }
+
+ /**
+ * Set a default String preference value. If the given value is null
,
+ * the entry will be removed.
+ *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. + * + * @param key The preference key. + * @return The default value of the preference key. + */ + public void putDefaultString(String key, String value) { + String defValue = defaultPrefs.get(key, null); + if (value == null) { + defaultPrefs.remove(key); + flushAndNotify(defaultPrefs, key, defValue, null); + } + else if (!value.equals(defValue)) { + defaultPrefs.put(key, value); + flushAndNotify(defaultPrefs, key, defValue, value); + } + } + + /** + * Set a default boolean preference value. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. + * + * @param key The preference key. + * @return The default value of the preference key. + */ + public void putDefaultBoolean(String key, boolean value) { + boolean defValue = defaultPrefs.getBoolean(key, false); + if (value != defValue) { + defaultPrefs.putBoolean(key, value); + flushAndNotify(defaultPrefs, key, Boolean.toString(defValue), Boolean.toString(value)); + } + } + + /** + * Set a default int preference value. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old + * and new values are string representation in base 10. + * + * @param key The preference key. + * @return The default value of the preference key. + */ + public void putDefaultInt(String key, int value) { + int defValue = defaultPrefs.getInt(key, 0); + if (value != defValue) { + defaultPrefs.putInt(key, value); + flushAndNotify(defaultPrefs, key, Integer.toString(defValue), Integer.toString(value)); + } + } + + /** + * Set a default long preference value. + *
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key.
+ */
+ public void putDefaultLong(String key, long value) {
+ long defValue = defaultPrefs.getLong(key, 0);
+ if (value != defValue) {
+ defaultPrefs.putLong(key, value);
+ flushAndNotify(defaultPrefs, key, Long.toString(defValue), Long.toString(value));
+ }
+ }
+
+ /**
+ * Write back the changes to the store and notify all listeners about the changed key.
+ *
+ * @param node The preference node which has changed. Must not be null
.
+ * @param key The key of the changed preference. Must not be null
.
+ * @param oldValue The old value as a {@link String}, or null
.
+ * @param newValue The new value as a {@link String}, or null
.
+ */
+ protected final void flushAndNotify(IEclipsePreferences node, String key, String oldValue, String newValue) {
+ // Flush the preferences to the persistence store
+ try { node.flush(); } catch (BackingStoreException e) { /* Ignored on purpose */ }
+
+ // Notify the listeners
+ firePreferenceEvent(node, key, oldValue, newValue);
+ }
+
+ /**
+ * Register the given listener to receive notifications of preference changes to this node.
+ * Calling this method multiple times with the same listener has no effect. The given listener
+ * argument must not be null
.
+ *
+ * @param listener The preference change listener. Must not be null
.
+ */
+ public void addPreferenceChangeListener(IPreferenceChangeListener listener) {
+ Assert.isNotNull(listener);
+ listeners.add(listener);
+ }
+
+ /**
+ * De-register the given listener from receiving notifications of preference changes
+ * to this node. Calling this method multiple times with the same listener has no
+ * effect. The given listener argument must not be null
.
+ *
+ * @param listener The preference change listener. Must not be null
.
+ */
+ public void removePreferenceChangeListener(IPreferenceChangeListener listener) {
+ Assert.isNotNull(listener);
+ listeners.remove(listener);
+ }
+
+ /**
+ * Convenience method for notifying the registered preference change listeners.
+ *
+ * @param node The preference node which has changed. Must not be null
.
+ * @param key The key of the changed preference. Must not be null
.
+ * @param oldValue The old value as a {@link String}, or null
.
+ * @param newValue The new value as a {@link String}, or null
.
+ */
+ protected void firePreferenceEvent(IEclipsePreferences node, String key, String oldValue, String newValue) {
+ Assert.isNotNull(node);
+ Assert.isNotNull(key);
+
+ // If no listener is registered, we are done here
+ if (listeners.isEmpty()) return;
+
+ // Get the list or currently registered listeners
+ Object[] l = listeners.getListeners();
+ // Create the preference change event
+ final PreferenceChangeEvent event = new PreferenceChangeEvent(node, key, oldValue, newValue);
+ for (int i = 0; i < l.length; i++) {
+ final IPreferenceChangeListener listener = (IPreferenceChangeListener) l[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ @Override
+ public void run() throws Exception {
+ listener.preferenceChange(event);
+ }
+ };
+ SafeRunner.run(job);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/tracing/TraceHandler.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/tracing/TraceHandler.java
new file mode 100644
index 00000000000..fcce8ab071d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/tracing/TraceHandler.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.tracing;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tcf.te.core.terminals.activator.CoreBundleActivator;
+
+/**
+ * Helper class to handle tracing using the platforms debug capabilities.
+ */
+public class TraceHandler {
+ /**
+ * The bundle identifier.
+ */
+ private final String identifier;
+
+ /**
+ * The tracer instance.
+ */
+ private Tracer tracer = null;
+
+ /**
+ * The tracer is responsible for writing the trace message to the desired
+ * output media.
+ */
+ protected static class Tracer {
+
+ /**
+ * The bundle identifier.
+ */
+ private final String fIdentifier;
+
+ /**
+ * The qualifier for the default "<bundle identifier>/debugmode"
+ * tracing slot.
+ */
+ private final String fDebugModeQualifier;
+
+ /**
+ * Constructor.
+ *
+ * @param identifier The bundle identifier. Must not be null
.
+ */
+ public Tracer(String identifier) {
+ Assert.isNotNull(identifier);
+ fIdentifier = identifier;
+
+ // Initialize the debug mode qualifier
+ fDebugModeQualifier = fIdentifier + "/debugmode"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the value of the debug mode tracing slot.
+ *
+ * If not set, or the value is not an {@link Integer}, the method returns 0
.
+ *
+ * @return The debug mode value.
+ */
+ protected int getDebugMode() {
+ try {
+ String mode = Platform.getDebugOption(fDebugModeQualifier);
+ if (mode != null && Integer.decode(mode).intValue() > 0) {
+ return Integer.decode(mode).intValue();
+ }
+ } catch (NumberFormatException e) { /* ignored on purpose */ }
+
+ return 0;
+ }
+
+ /**
+ * Check if the specified trace slot is enabled.
+ *
+ * @param slotId The name of the slot.
+ * @return true
if the slot is defined and enabled, false
otherwise.
+ */
+ protected boolean isSlotEnabled(String slotId) {
+ return fIdentifier != null ? Boolean.parseBoolean(Platform.getDebugOption(fIdentifier + "/" + slotId)) : false; //$NON-NLS-1$
+ }
+
+ /**
+ * Check if tracing is enabled for given mode and slot.
+ *
+ * @param debugMode The debug mode for the current debug.
+ * @param slotId The name of the slot.
+ *
+ * @return true
if the debug should be written, false
otherwise.
+ */
+ protected final boolean isEnabled(int debugMode, String slotId) {
+ return getDebugMode() < 0 ||
+ (debugMode <= getDebugMode() &&
+ (slotId == null || slotId.trim().length() == 0 || isSlotEnabled(slotId)));
+ }
+
+ /**
+ * Format the trace message.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ protected String getFormattedDebugMessage(String message, int debugMode, String slotId, int severity, Object clazz) {
+ StringBuffer debug = new StringBuffer();
+ if (slotId != null || clazz != null) {
+ if (clazz != null) {
+ String name = clazz instanceof Class> ? ((Class>)clazz).getSimpleName() : clazz.getClass().getSimpleName();
+ debug.append(name.trim().length() > 0 ? name.trim() : clazz instanceof Class> ? ((Class>)clazz).getName() : clazz.getClass().getName());
+ }
+ if (slotId != null) {
+ debug.append(" at "); //$NON-NLS-1$
+ debug.append(slotId);
+ }
+ if (debugMode >= 0) {
+ debug.append(" (Mode "); //$NON-NLS-1$
+ debug.append(debugMode);
+ debug.append(')');
+ }
+ debug.append('\n');
+ debug.append('\t');
+ }
+ debug.append(message);
+
+ return debug.toString();
+ }
+
+ /**
+ * Write the trace message.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ protected void write(String message, int debugMode, String slotId, int severity, Object clazz) {
+ String formattedMessage = getFormattedDebugMessage(message, debugMode, slotId, severity, clazz);
+ if (severity == IStatus.ERROR || severity == IStatus.WARNING) {
+ System.err.println(formattedMessage);
+ }
+ else {
+ System.out.println(formattedMessage);
+ }
+ }
+
+ /**
+ * Trace the given message with the given debug mode and slot.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ public final void trace(String message, int debugMode, String slotId, int severity, Object clazz) {
+ if (isEnabled(debugMode, slotId)) {
+ write(message, debugMode, slotId, severity, clazz);
+ }
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * Initializes the tracing handler with the given bundle identifier.
+ *
+ * @param identifier The bundle identifier or null
.
+ */
+ public TraceHandler(String identifier) {
+ this.identifier = identifier != null ? identifier : CoreBundleActivator.getUniqueIdentifier();
+ Assert.isNotNull(this.identifier);
+ }
+
+ /**
+ * Returns the identifier.
+ */
+ protected final String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Returns the tracer instance. Create a new tracer instance
+ * on first invocation.
+ *
+ * @return The tracer instance.
+ */
+ protected Tracer getTracer() {
+ if (tracer == null) {
+ tracer = new Tracer(identifier);
+ }
+ return tracer;
+ }
+
+ /**
+ * Return the current debug mode.
+ */
+ public final int getDebugMode() {
+ return getTracer().getDebugMode();
+ }
+
+ /**
+ * Check whether a trace slot is enabled. The debug mode defaults
+ * to 0.
+ *
+ * @param slotId The name of the slot.
+ *
+ * @return true
if the slot is enabled, false
otherwise.
+ */
+ public final boolean isSlotEnabled(String slotId) {
+ return isSlotEnabled(0, slotId);
+ }
+
+ /**
+ * Check whether a trace slot is enabled with the given debug mode.
+ *
+ * @param debugMode The debug mode
+ * @param slotId The name of the slot.
+ *
+ * @return true
if the slot is enabled, false
otherwise.
+ */
+ public final boolean isSlotEnabled(int debugMode, String slotId) {
+ return getTracer().isEnabled(debugMode, slotId);
+ }
+
+ /**
+ * Trace the given message.
+ *
+ * The message severity will be {@link IStatus#INFO} and the message will be
+ * traced unconditionally.
+ *
+ * @param message The message.
+ * @param clazz The class that calls this tracer or null
.
+ */
+ public final void trace(String message, Object clazz) {
+ getTracer().trace(message, 0, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ *
+ * The message severity will be {@link IStatus#INFO}.
+ *
+ * @param message The message.
+ * @param debugMode The minimum debug mode that has to be set to write out the message.
+ * @param clazz The class that calls this tracer or null
.
+ */
+ public final void trace(String message, int debugMode, Object clazz) {
+ getTracer().trace(message, debugMode, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ *
+ * The message severity will be {@link IStatus#INFO} and the debug mode
+ * will default to
+ * For use with terminals, the parameter 0
.
+ *
+ * @param message The message.
+ * @param slotId The slot that has to be enabled to write out the message.
+ * @param clazz The class that calls this tracer or null
.
+ */
+ public final void trace(String message, String slotId, Object clazz) {
+ getTracer().trace(message, 0, slotId, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ *
+ * @param message The message.
+ * @param debugMode The minimum debug mode that has to be set to write out the message.
+ * @param slotId The slot that has to be enabled to write out the message.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer or null
.
+ *
+ * @see IStatus
+ */
+ public final void trace(String message, int debugMode, String slotId, int severity, Object clazz) {
+ getTracer().trace(message, debugMode, slotId, severity, clazz);
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/utils/Env.java b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/utils/Env.java
new file mode 100644
index 00000000000..2605d765812
--- /dev/null
+++ b/plugins/org.eclipse.tcf.te.core.terminals/src/org/eclipse/tcf/te/core/terminals/utils/Env.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.terminals.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.service.environment.Constants;
+
+/**
+ * Environment handling utility methods.
+ */
+public class Env {
+
+ // Reference to the monitor to lock if determining the native environment
+ private final static Object ENV_GET_MONITOR = new Object();
+
+ // Reference to the native environment with the case of the variable names preserved
+ private static Mapterminal
should be set to
+ * true
. In this case, the method will assure that the TERM
+ * environment variable is always set to ANSI
and is not overwritten
+ * by the passed in environment.
+ *
+ * @param envp The environment to set on top of the native environment or null
.
+ * @param terminal True
if used with an terminal, false
otherwise.
+ *
+ * @return The merged environment.
+ */
+ public static String[] getEnvironment(String[] envp, boolean terminal) {
+ // Get the cached native environment
+ Mapnull
.
+ */
+ private static void cacheNativeEnvironment(Map