November 30, 2017
++ 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 2.0 ("EPL"). A copy of the EPL is + available at https://www.eclipse.org/legal/epl-2.0. + 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 https://www.eclipse.org. +
+ + + + \ No newline at end of file diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/build.properties b/terminal/plugins/org.eclipse.tm.terminal.view.core/build.properties new file mode 100644 index 00000000000..a7b382de0be --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/build.properties @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2012, 2018 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 2.0 which accompanies this distribution, and is +# available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Wind River Systems - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html,\ + plugin.xml +src.includes = about.html,\ + schema/ diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.properties b/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.properties new file mode 100644 index 00000000000..06a1f6cae28 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.properties @@ -0,0 +1,16 @@ +################################################################################## +# Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is +# available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Wind River Systems - initial API and implementation +################################################################################## + +pluginName = Terminal View Core +providerName = Eclipse.org + +ExtensionPoint.contextPropertiesProviders = Terminal Context Properties Providers diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.xml b/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.xml new file mode 100644 index 00000000000..b60ca296396 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/plugin.xml @@ -0,0 +1,27 @@ + + + + +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.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/TerminalServiceFactory.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/TerminalServiceFactory.java
new file mode 100644
index 00000000000..595046ffdb8
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/TerminalServiceFactory.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.terminal.view.core.activator.CoreBundleActivator;
+import org.eclipse.tm.terminal.view.core.interfaces.ITerminalService;
+import org.eclipse.tm.terminal.view.core.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.tm.terminal.view.ui bundle + Bundle bundle = Platform.getBundle("org.eclipse.tm.terminal.view.ui"); //$NON-NLS-1$ + if (bundle != null && bundle.getState() != Bundle.UNINSTALLED && bundle.getState() != Bundle.STOPPING) { + try { + Class> clazz = bundle.loadClass("org.eclipse.tm.terminal.view.ui.services.TerminalService"); //$NON-NLS-1$ + instance = (ITerminalService) clazz.getDeclaredConstructor().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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/activator/CoreBundleActivator.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/activator/CoreBundleActivator.java new file mode 100644 index 00000000000..4184e1b9438 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/activator/CoreBundleActivator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.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 plug-in. + */ + public static String getUniqueIdentifier() { + if (getContext() != null && getContext().getBundle() != null) { + return getContext().getBundle().getSymbolicName(); + } + return "org.eclipse.tm.terminal.view.core"; //$NON-NLS-1$ + } + + @Override + public void start(BundleContext bundleContext) throws Exception { + CoreBundleActivator.context = bundleContext; + } + + @Override + public void stop(BundleContext bundleContext) throws Exception { + CoreBundleActivator.context = null; + } +} diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalContextPropertiesProvider.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalContextPropertiesProvider.java new file mode 100644 index 00000000000..eefca07d8fd --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalContextPropertiesProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalService.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalService.java
new file mode 100644
index 00000000000..e28f1b42298
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalService.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2011 - 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.interfaces;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Terminal 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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalServiceOutputStreamMonitorListener.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalServiceOutputStreamMonitorListener.java
new file mode 100644
index 00000000000..b48a1113adf
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalServiceOutputStreamMonitorListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalTabListener.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalTabListener.java
new file mode 100644
index 00000000000..bd3a034680b
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/ITerminalTabListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/IContextPropertiesConstants.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/IContextPropertiesConstants.java
new file mode 100644
index 00000000000..55daaeecbc7
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/IContextPropertiesConstants.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ILineSeparatorConstants.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ILineSeparatorConstants.java new file mode 100644 index 00000000000..f6888a22629 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ILineSeparatorConstants.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2011 - 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.interfaces.constants; + +/** + * Line separator constants. + */ +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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ITerminalsConnectorConstants.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ITerminalsConnectorConstants.java new file mode 100644 index 00000000000..4d60d49c31b --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/interfaces/constants/ITerminalsConnectorConstants.java @@ -0,0 +1,373 @@ +/******************************************************************************* + * Copyright (c) 2011, 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + * Max Weninger (Wind River) - [361352] [TERMINALS][SSH] Add SSH terminal support + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.interfaces.constants; + +import java.io.InputStream; +import java.io.OutputStream; + +import org.eclipse.tm.terminal.view.core.interfaces.ITerminalServiceOutputStreamMonitorListener; + +/** + * Defines the terminals connector constants. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +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. + *
+ * Special values: + *
null means open on the first primary terminal (the one with no secondary id)
+ * + * Property Type: {@link String} + */ + public static final String PROP_SECONDARY_ID = "secondaryId"; //$NON-NLS-1$ + + /** + * Special value for {@link #PROP_SECONDARY_ID} to indicate reuse of the most recent terminal view + * @since 4.8 + */ + public static final String LAST_ACTIVE_SECONDARY_ID = "last"; //$NON-NLS-1$ + + /** + * Special value for {@link #PROP_SECONDARY_ID} to indicate reuse of any terminal view + * @since 4.8 + */ + public static final String ANY_ACTIVE_SECONDARY_ID = "*"; //$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: Flag to disable updating the terminal title from ANSI escape sequences. + *
+ * Property Type: {@link Boolean} + * @since 4.10 + */ + public static final String PROP_TITLE_DISABLE_ANSI_TITLE = "titleDisableAnsiTitle"; //$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: Terminal 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. + *
+ * 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$ + + // ***** Telnet specific properties ***** + + /** + * The end-of-line sequence to be sent to the server on "Enter". + *
+ * Property Type: {@link String} + * @since 4.2 + */ + public static final String PROP_TELNET_EOL = "telnet.eol"; //$NON-NLS-1$ + +} diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/internal/PropertyTester.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/internal/PropertyTester.java new file mode 100644 index 00000000000..7e0f46ce6db --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/internal/PropertyTester.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2011 - 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.internal; + +import org.eclipse.tm.terminal.view.core.TerminalContextPropertiesProviderFactory; + +/** + * Property tester implementation. + */ +public class PropertyTester extends org.eclipse.core.expressions.PropertyTester { + + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + + // "hasContextPropertiesProvider": Checks if a context properties provider is available for the given receiver. + if ("hasContextPropertiesProvider".equals(property)) { //$NON-NLS-1$ + boolean hasProvider = TerminalContextPropertiesProviderFactory.getProvider(receiver) != null; + return expectedValue instanceof Boolean ? ((Boolean) expectedValue).equals(Boolean.valueOf(hasProvider)) + : hasProvider; + } + + return false; + } + +} diff --git a/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.java new file mode 100644 index 00000000000..2d778f3b126 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.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.tm.terminal.view.core.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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.properties b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.properties new file mode 100644 index 00000000000..647a26ff699 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/nls/Messages.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2015, 2018 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 2.0 which accompanies this distribution, and is +# available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# 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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/preferences/ScopedEclipsePreferences.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/preferences/ScopedEclipsePreferences.java new file mode 100644 index 00000000000..34a730e77d9 --- /dev/null +++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/preferences/ScopedEclipsePreferences.java @@ -0,0 +1,453 @@ +/******************************************************************************* + * Copyright (c) 2011, 2018 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 2.0 which accompanies this distribution, and is + * available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.terminal.view.core.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.eclipse.core.runtime.preferences.PreferenceFilterEntry; +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
+ * Initialize the scoped preferences with a new instance scope for the given qualifier. The default
+ * scope is determined by calling
+ * Initialize the scoped preferences with the given scope. The default scope
+ * is determined by calling
+ * 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() {
+ @Override
+ public String[] getScopes() {
+ return new String[] { InstanceScope.SCOPE };
+ }
+
+ @Override
+ public Map
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @param value 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.
+ * @param value 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.
+ * @param value 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.
+ * @param value 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
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @param value 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.
+ * @param value 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.
+ * @param value 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.
+ * @param value 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
+ * If not set, or the value is not an {@link Integer}, the method returns
+ * Initializes the tracing handler with the given bundle identifier.
+ *
+ * @param identifier The bundle identifier or
+ * 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
+ * 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
+ * The message severity will be {@link IStatus#INFO} and the debug mode
+ * will default to
+ * For use with terminals, the parameter 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.
+ * 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.
+ * 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.
+ * null,
+ * the entry will be removed.
+ * 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;
+
+ // Create the preference change event
+ final PreferenceChangeEvent event = new PreferenceChangeEvent(node, key, oldValue, newValue);
+ for (IPreferenceChangeListener listener : listeners) {
+ 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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/tracing/TraceHandler.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/tracing/TraceHandler.java
new file mode 100644
index 00000000000..98945b613c2
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/tracing/TraceHandler.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.tracing;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tm.terminal.view.core.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.
+ * 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)) //$NON-NLS-1$
+ : false;
+ }
+
+ /**
+ * 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.
+ * 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.
+ * null.
+ */
+ public final void trace(String message, Object clazz) {
+ getTracer().trace(message, 0, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ * null.
+ */
+ public final void trace(String message, int debugMode, Object clazz) {
+ getTracer().trace(message, debugMode, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ * 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/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/utils/Env.java b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/utils/Env.java
new file mode 100644
index 00000000000..4b081c81e8a
--- /dev/null
+++ b/terminal/plugins/org.eclipse.tm.terminal.view.core/src/org/eclipse/tm/terminal/view/core/utils/Env.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2018 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 2.0 which accompanies this distribution, and is
+ * available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.terminal.view.core.utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Environment handling utility methods.
+ */
+public class Env {
+
+ /**
+ * Returns the merged environment of the native environment and the passed
+ * in environment. Passed in variables will overwrite the native environment
+ * if the same variables are set there.
+ * terminal 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 a copy of the native environment variables
+ Properties environmentVariables = getEnvVars();
+
+ // If a "local" environment is provided, merge it with the native
+ // environment.
+ if (envp != null) {
+ for (String keyValue : envp) {
+ // keyValue is the full provided variable in form "name=value"
+ String[] parts = keyValue.split("=", 2); //$NON-NLS-1$
+ if (parts.length == 2) {
+ String name = parts[0];
+ String value = parts[1];
+
+ if ("