From 3feceeebed629568a597abc1a2526fa3b0b8ecff Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Wed, 14 Dec 2011 10:11:03 +0100 Subject: Target Explorer: Added scripting core plugin and updated features --- .../core/scripting/launcher/ScriptLauncher.java | 245 +++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/launcher/ScriptLauncher.java (limited to 'target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/launcher') diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/launcher/ScriptLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/launcher/ScriptLauncher.java new file mode 100644 index 000000000..24b4cb2d1 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core.scripting/src/org/eclipse/tcf/te/tcf/core/scripting/launcher/ScriptLauncher.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (c) 2011 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.tcf.core.scripting.launcher; + +import java.io.IOException; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.protocol.IChannel.IChannelListener; +import org.eclipse.tcf.protocol.IPeer; +import org.eclipse.tcf.te.runtime.callback.Callback; +import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; +import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; +import org.eclipse.tcf.te.tcf.core.Tcf; +import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; +import org.eclipse.tcf.te.tcf.core.scripting.activator.CoreBundleActivator; +import org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncher; +import org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncherProperties; +import org.eclipse.tcf.te.tcf.core.scripting.nls.Messages; +import org.eclipse.tcf.te.tcf.core.scripting.parser.Parser; +import org.eclipse.tcf.te.tcf.core.scripting.parser.Token; + +/** + * Script launcher implementation. + */ +public class ScriptLauncher extends PlatformObject implements IScriptLauncher { + // The channel instance + /* default */ IChannel channel; + // The process properties instance + private IPropertiesContainer properties; + + // The callback instance + private ICallback callback; + + /** + * Constructor. + */ + public ScriptLauncher() { + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncher#dispose() + */ + @Override + public void dispose() { + // Store a final reference to the channel instance + final IChannel finChannel = channel; + + // Close the channel as all disposal is done + if (finChannel != null) Tcf.getChannelManager().closeChannel(finChannel); + + // Dissociate the channel + channel = null; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncher#launch(org.eclipse.tcf.protocol.IPeer, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback) + */ + @Override + public void launch(final IPeer peer, final IPropertiesContainer properties, final ICallback callback) { + Assert.isNotNull(peer); + Assert.isNotNull(properties); + + // Normalize the callback + if (callback == null) { + this.callback = new Callback() { + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.callback.Callback#internalDone(java.lang.Object, org.eclipse.core.runtime.IStatus) + */ + @Override + public void internalDone(Object caller, IStatus status) { + } + }; + } + else { + this.callback = callback; + } + + // Remember the process properties + this.properties = properties; + + // Open a dedicated channel to the given peer + Tcf.getChannelManager().openChannel(peer, true, new IChannelManager.DoneOpenChannel() { + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel#doneOpenChannel(java.lang.Throwable, org.eclipse.tcf.protocol.IChannel) + */ + @Override + public void doneOpenChannel(Throwable error, IChannel channel) { + if (error == null) { + ScriptLauncher.this.channel = channel; + + // Attach a channel listener so we can dispose ourself if the channel + // is closed from the remote side. + channel.addChannelListener(new IChannelListener() { + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelOpened() + */ + @Override + public void onChannelOpened() { + } + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable) + */ + @Override + public void onChannelClosed(Throwable error) { + if (error != null) { + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.ScriptLauncher_error_channelConnectFailed, peer.getID(), error.getLocalizedMessage()), + error); + invokeCallback(status, null); + } + } + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#congestionLevel(int) + */ + @Override + public void congestionLevel(int level) { + } + }); + + // Check if the channel is in connected state + if (channel.getState() != IChannel.STATE_OPEN) { + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + Messages.ScriptLauncher_error_channelNotConnected, + new IllegalStateException()); + invokeCallback(status, null); + return; + } + + // Do some very basic sanity checking on the script properties + if (properties.getStringProperty(IScriptLauncherProperties.PROP_SCRIPT) == null) { + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + Messages.ScriptLauncher_error_missingScript, + new IllegalArgumentException(IScriptLauncherProperties.PROP_SCRIPT)); + invokeCallback(status, null); + return; + } + + // Execute the launch now + executeLaunch(); + } else { + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.ScriptLauncher_error_channelConnectFailed, peer.getID(), error.getLocalizedMessage()), + error); + invokeCallback(status, null); + } + } + }); + } + + /** + * Executes the script launch. + */ + protected void executeLaunch() { + // Get the script properties container + final IPropertiesContainer properties = getProperties(); + if (properties == null) { + // This is an illegal argument. Properties must be set + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.ScriptLauncher_error_illegalNullArgument, "properties"), //$NON-NLS-1$ + new IllegalArgumentException()); + invokeCallback(status, null); + return; + } + + // Get the script to execute + String script = properties.getStringProperty(IScriptLauncherProperties.PROP_SCRIPT); + if (script == null || "".equals(script.trim())) { //$NON-NLS-1$ + IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), + Messages.ScriptLauncher_error_missingScript, + new IllegalArgumentException(IScriptLauncherProperties.PROP_SCRIPT)); + invokeCallback(status, null); + return; + } + + // Create the script parser instance + Parser parser = new Parser(script); + try { + Token[] tokens = parser.parse(); + } catch (IOException e) { + + } + } + + /** + * Invoke the callback with the given parameters. If the given status severity + * is {@link IStatus#ERROR}, the process launcher object is disposed automatically. + * + * @param status The status. Must not be null. + * @param result The result object or null. + */ + protected void invokeCallback(IStatus status, Object result) { + // Dispose the process launcher if we report an error + if (status.getSeverity() == IStatus.ERROR) { + dispose(); + } + + // Invoke the callback + ICallback callback = getCallback(); + if (callback != null) { + callback.setResult(result); + callback.done(this, status); + } + } + + /** + * Returns the channel instance. + * + * @return The channel instance or null if none. + */ + public final IChannel getChannel() { + return channel; + } + + /** + * Returns the process properties container. + * + * @return The process properties container or null if none. + */ + public final IPropertiesContainer getProperties() { + return properties; + } + + /** + * Returns the callback instance. + * + * @return The callback instance or null if none. + */ + protected final ICallback getCallback() { + return callback; + } + +} -- cgit v1.2.3