Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'terminals/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/services/TerminalService.java')
-rw-r--r--terminals/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/services/TerminalService.java359
1 files changed, 359 insertions, 0 deletions
diff --git a/terminals/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/services/TerminalService.java b/terminals/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/services/TerminalService.java
new file mode 100644
index 000000000..08398fcf4
--- /dev/null
+++ b/terminals/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/services/TerminalService.java
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ * 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.ui.terminals.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.widgets.Display;
+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.interfaces.ITerminalTabListener;
+import org.eclipse.tcf.te.core.terminals.interfaces.constants.ITerminalsConnectorConstants;
+import org.eclipse.tcf.te.ui.terminals.interfaces.ILauncherDelegate;
+import org.eclipse.tcf.te.ui.terminals.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.terminals.launcher.LauncherDelegateManager;
+import org.eclipse.tcf.te.ui.terminals.manager.ConsoleManager;
+import org.eclipse.tcf.te.ui.terminals.nls.Messages;
+import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Terminal service implementation.
+ */
+@SuppressWarnings("restriction")
+public class TerminalService implements ITerminalService {
+ /**
+ * The registered terminal tab dispose listeners.
+ */
+ private final ListenerList terminalTabListeners = new ListenerList();
+
+ // Flag to remember if the terminal view has been restored or not.
+ private boolean fRestoringView;
+
+ // Terminal tab events
+
+ /**
+ * A terminal tab got disposed.
+ */
+ public static final int TAB_DISPOSED = 1;
+
+ /**
+ * Common terminal service runnable implementation.
+ */
+ protected static abstract class TerminalServiceRunnable {
+
+ /**
+ * Invoked to execute the terminal service runnable.
+ *
+ * @param id The terminals view id or <code>null</code>.
+ * @param secondaryId The terminals view secondary id or <code>null</code>.
+ * @param title The terminal tab title. Must not be <code>null</code>.
+ * @param connector The terminal connector. Must not be <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ * @param done The callback to invoke if the operation finished or <code>null</code>.
+ */
+ public abstract void run(String id, String secondaryId, String title, ITerminalConnector connector, Object data, Done done);
+
+ /**
+ * Returns if or if not to execute the runnable asynchronously.
+ * <p>
+ * The method returns per default <code>true</code>. Overwrite to
+ * modify the behavior.
+ *
+ * @return <code>True</code> to execute the runnable asynchronously, <code>false</code> otherwise.
+ */
+ public boolean isExecuteAsync() { return true; }
+ }
+
+ /**
+ * Constructor
+ */
+ public TerminalService() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService#addTerminalTabListener(org.eclipse.tcf.te.core.terminals.interfaces.ITerminalTabListener)
+ */
+ @Override
+ public final void addTerminalTabListener(ITerminalTabListener listener) {
+ Assert.isNotNull(listener);
+ terminalTabListeners.add(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService#removeTerminalTabListener(org.eclipse.tcf.te.core.terminals.interfaces.ITerminalTabListener)
+ */
+ @Override
+ public final void removeTerminalTabListener(ITerminalTabListener listener) {
+ Assert.isNotNull(listener);
+ terminalTabListeners.remove(listener);
+ }
+
+ /**
+ * Convenience method for notifying the registered terminal tab listeners.
+ *
+ * @param event The terminal tab event.
+ * @param source The disposed tab item. Must not be <code>null</code>.
+ * @param data The custom data object associated with the disposed tab item or <code>null</code>.
+ */
+ public final void fireTerminalTabEvent(final int event, final Object source, final Object data) {
+ Assert.isNotNull(source);
+
+ // If no listener is registered, we are done here
+ if (terminalTabListeners.isEmpty()) return;
+
+ // Get the list or currently registered listeners
+ Object[] l = terminalTabListeners.getListeners();
+ // Loop the registered terminal tab listeners and invoke the proper method
+ for (int i = 0; i < l.length; i++) {
+ final ITerminalTabListener listener = (ITerminalTabListener) l[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ @Override
+ public void run() throws Exception {
+ switch (event) {
+ case TAB_DISPOSED:
+ listener.terminalTabDisposed(source, data);
+ break;
+ default:
+ }
+ }
+ };
+ SafeRunner.run(job);
+ }
+ }
+
+ /**
+ * Executes the given runnable operation and invokes the given callback, if any,
+ * after the operation finished.
+ *
+ * @param properties The terminal properties. Must not be <code>null</code>.
+ * @param runnable The terminal service runnable. Must not be <code>null</code>.
+ * @param done The callback to invoke if the operation has been finished or <code>null</code>.
+ */
+ protected final void executeServiceOperation(final Map<String, Object> properties, final TerminalServiceRunnable runnable, final Done done) {
+ Assert.isNotNull(properties);
+ Assert.isNotNull(runnable);
+
+ // Extract the properties
+ String id = (String)properties.get(ITerminalsConnectorConstants.PROP_ID);
+ String secondaryId = (String)properties.get(ITerminalsConnectorConstants.PROP_SECONDARY_ID);
+ String title = (String)properties.get(ITerminalsConnectorConstants.PROP_TITLE);
+ Object data = properties.get(ITerminalsConnectorConstants.PROP_DATA);
+
+ // Normalize the terminals console view id
+ id = normalizeId(id, data);
+ // Normalize the terminal console tab title
+ title = normalizeTitle(title, data);
+
+ // Create the terminal connector instance
+ final ITerminalConnector connector = createTerminalConnector(properties);
+ if (connector == null) {
+ // Properties contain invalid connector arguments
+ if (done != null) {
+ Exception e = new IllegalArgumentException(Messages.TerminalService_error_cannotCreateConnector);
+ done.done(new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), e.getLocalizedMessage(), e));
+ }
+ return;
+ }
+
+ // Finalize the used variables
+ final String finId = id;
+ final String finSecondaryId = secondaryId;
+ final String finTitle = title;
+ final Object finData = data;
+
+ // Execute the operation
+ if (!runnable.isExecuteAsync()) {
+ runnable.run(finId, finSecondaryId, finTitle, connector, finData, done);
+ }
+ else {
+ try {
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ runnable.run(finId, finSecondaryId, finTitle, connector, finData, done);
+ }
+ });
+ }
+ catch (Exception e) {
+ // if display is disposed, silently ignore.
+ }
+ }
+ }
+
+ /**
+ * Normalize the terminals view id.
+ *
+ * @param id The terminals view id or <code>null</code>.
+ * @param data The custom data object or <code>null</code>.
+ *
+ * @return The normalized terminals console view id.
+ */
+ protected String normalizeId(String id, Object data) {
+ return id != null ? id : IUIConstants.ID;
+ }
+
+ /**
+ * Normalize the terminal tab title.
+ *
+ * @param title The terminal tab title or <code>null</code>.
+ * @param data The custom data object or <code>null</code>.
+ *
+ * @return The normalized terminal tab title.
+ */
+ protected String normalizeTitle(String title, Object data) {
+ // If the title is explicitly specified, return as is
+ if (title != null) return title;
+
+ // Return the default console title in all other cases
+ return Messages.TerminalService_defaultTitle;
+ }
+
+ /**
+ * Creates the terminal connector configured within the given properties.
+ *
+ * @param properties The terminal console properties. Must not be <code>null</code>.
+ * @return The terminal connector or <code>null</code>.
+ */
+ protected ITerminalConnector createTerminalConnector(Map<String, Object> properties) {
+ Assert.isNotNull(properties);
+
+ // The terminal connector result object
+ ITerminalConnector connector = null;
+
+ // Get the launcher delegate id from the properties
+ String delegateId = (String)properties.get(ITerminalsConnectorConstants.PROP_DELEGATE_ID);
+ if (delegateId != null) {
+ // Get the launcher delegate
+ ILauncherDelegate delegate = LauncherDelegateManager.getInstance().getLauncherDelegate(delegateId, false);
+ if (delegate != null) {
+ // Create the terminal connector
+ connector = delegate.createTerminalConnector(properties);
+ }
+ }
+
+ return connector;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService#openConsole(java.util.Map, org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService.Done)
+ */
+ @Override
+ public void openConsole(final Map<String, Object> properties, final Done done) {
+ Assert.isNotNull(properties);
+ final boolean restoringView = fRestoringView;
+
+ executeServiceOperation(properties, new TerminalServiceRunnable() {
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run(final String id, final String secondaryId, final String title,
+ final ITerminalConnector connector, final Object data, final Done done) {
+ if (restoringView) {
+ doRun(id, secondaryId, title, connector, data, done);
+ } else {
+ // First, restore the view. This opens consoles from the memento
+ fRestoringView = true;
+ ConsoleManager.getInstance().showConsoleView(id, secondaryId);
+ fRestoringView = false;
+
+ // After that schedule opening the requested console
+ try {
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ doRun(id, secondaryId, title, connector, data, done);
+ }
+ });
+ }
+ catch (Exception e) {
+ // if display is disposed, silently ignore.
+ }
+ }
+ }
+
+ public void doRun(String id, String secondaryId, String title, ITerminalConnector connector, Object data, Done done) {
+ // Determine the terminal encoding
+ String encoding = (String)properties.get(ITerminalsConnectorConstants.PROP_ENCODING);
+ // Create the flags to pass on to openConsole
+ Map<String, Boolean> flags = new HashMap<String, Boolean>();
+ flags.put("activate", Boolean.TRUE); //$NON-NLS-1$
+ if (properties.get(ITerminalsConnectorConstants.PROP_FORCE_NEW) instanceof Boolean) {
+ flags.put(ITerminalsConnectorConstants.PROP_FORCE_NEW, (Boolean)properties.get(ITerminalsConnectorConstants.PROP_FORCE_NEW));
+ }
+ if (properties.get(ITerminalsConnectorConstants.PROP_HAS_DISCONNECT_BUTTON) instanceof Boolean) {
+ flags.put(ITerminalsConnectorConstants.PROP_HAS_DISCONNECT_BUTTON, (Boolean)properties.get(ITerminalsConnectorConstants.PROP_HAS_DISCONNECT_BUTTON));
+ }
+ // Open the new console
+ CTabItem item;
+ if (secondaryId != null)
+ item = ConsoleManager.getInstance().openConsole(id, secondaryId, title, encoding, connector, data, flags);
+ else
+ item = ConsoleManager.getInstance().openConsole(id, title, encoding, connector, data, flags);
+ // Associate the original terminal properties with the tab item.
+ // This makes it easier to persist the connection data within the memento handler
+ if (item != null && !item.isDisposed()) item.setData("properties", properties); //$NON-NLS-1$
+
+ // Invoke the callback
+ if (done != null) done.done(Status.OK_STATUS);
+ }
+ }, done);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService#closeConsole(java.util.Map, org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService.Done)
+ */
+ @Override
+ public void closeConsole(final Map<String, Object> properties, final Done done) {
+ Assert.isNotNull(properties);
+
+ executeServiceOperation(properties, new TerminalServiceRunnable() {
+ @Override
+ public void run(String id, String secondaryId, String title, ITerminalConnector connector, Object data, Done done) {
+ // Close the console
+ ConsoleManager.getInstance().closeConsole(id, title, connector, data);
+ // Invoke the callback
+ if (done != null) done.done(Status.OK_STATUS);
+ }
+ }, done);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService#terminateConsole(java.util.Map, org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService.Done)
+ */
+ @Override
+ public void terminateConsole(Map<String, Object> properties, Done done) {
+ Assert.isNotNull(properties);
+
+ executeServiceOperation(properties, new TerminalServiceRunnable() {
+ @Override
+ public void run(String id, String secondaryId, String title, ITerminalConnector connector, Object data, Done done) {
+ // Close the console
+ ConsoleManager.getInstance().terminateConsole(id, title, connector, data);
+ // Invoke the callback
+ if (done != null) done.done(Status.OK_STATUS);
+ }
+ }, done);
+ }
+}

Back to the top