summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Aubry2012-09-28 08:18:10 (EDT)
committersbernard2012-09-28 08:18:10 (EDT)
commit3d0b93879ecdafe0087d429f40812337f3912507 (patch)
tree0689de3edd3f408e124b43ec6fd4d0716cc101f8
parent443b80ba8d881bc8b145546ab381ebbcf28fca3a (diff)
downloadorg.eclipse.koneki.ldt-3d0b93879ecdafe0087d429f40812337f3912507.zip
org.eclipse.koneki.ldt-3d0b93879ecdafe0087d429f40812337f3912507.tar.gz
org.eclipse.koneki.ldt-3d0b93879ecdafe0087d429f40812337f3912507.tar.bz2
bug 390674: [remote] Remote launch configuration
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/META-INF/MANIFEST.MF19
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/OSGI-INF/l10n/bundle.properties3
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/build.properties3
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/plugin.xml16
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/InputStreamMonitor.java178
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRSEUtil.java77
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteDebugConstant.java20
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationDelegate.java225
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationUtil.java123
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/Messages.java39
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/OutputStreamMonitor.java274
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/RSEUtil.java135
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/SshProcess.java359
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/StreamsProxy.java143
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/messages.properties13
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/META-INF/MANIFEST.MF14
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/build.properties3
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/lua_launcher.gifbin0 -> 551 bytes
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/main_tab.gifbin0 -> 360 bytes
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/plugin.xml28
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/Activator.java14
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/ImageConstants.java15
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationMainTab.java292
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationTabGroup.java23
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/Messages.java31
-rw-r--r--plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/messages.properties5
26 files changed, 2041 insertions, 11 deletions
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.koneki.ldt.remote.debug.core/META-INF/MANIFEST.MF
index 14f7a04..be26fa0 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/META-INF/MANIFEST.MF
@@ -1,11 +1,24 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
-Bundle-SymbolicName: org.eclipse.koneki.ldt.remote.debug.core
+Bundle-SymbolicName: org.eclipse.koneki.ldt.remote.debug.core;singleton:=true
Bundle-Version: 0.9.0.qualifier
Bundle-Activator: org.eclipse.koneki.ldt.remote.debug.core.internal.Activator
-Require-Bundle: org.eclipse.core.runtime
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.debug.core,
+ org.eclipse.rse.core;bundle-version="3.3.0",
+ org.eclipse.rse;bundle-version="3.4.0",
+ org.eclipse.rse.services;bundle-version="3.2.200",
+ org.eclipse.rse.subsystems.files.core;bundle-version="3.3.0",
+ com.jcraft.jsch;bundle-version="0.1.46",
+ org.eclipse.rse.ui;bundle-version="3.3.0",
+ org.eclipse.rse.connectorservice.ssh;bundle-version="2.1.300",
+ org.eclipse.rse.services.ssh;bundle-version="3.2.0",
+ org.eclipse.koneki.ldt;bundle-version="0.9.0",
+ org.eclipse.dltk.core;bundle-version="3.0.0",
+ org.eclipse.dltk.launching;bundle-version="4.0.0",
+ org.eclipse.dltk.debug;bundle-version="4.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.koneki.ldt.remote.debug.core.internal;x-internal:=true
+Export-Package: org.eclipse.koneki.ldt.remote.debug.core.internal;x-friends:="org.eclipse.koneki.ldt.remote.debug.ui"
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/OSGI-INF/l10n/bundle.properties b/plugins/org.eclipse.koneki.ldt.remote.debug.core/OSGI-INF/l10n/bundle.properties
index 703d5a5..4bea453 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.core/OSGI-INF/l10n/bundle.properties
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/OSGI-INF/l10n/bundle.properties
@@ -1,3 +1,4 @@
#Properties file for org.eclipse.koneki.ldt.remote.debug.core
Bundle-Name = LDT Remote Development Support Debug Core (Incubation)
-Bundle-Vendor = Eclipse Koneki \ No newline at end of file
+Bundle-Vendor = Eclipse Koneki
+launchConfigurationType.name = Lua Remote Application \ No newline at end of file
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/build.properties b/plugins/org.eclipse.koneki.ldt.remote.debug.core/build.properties
index 2096750..e2c8cb9 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.core/build.properties
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/build.properties
@@ -13,7 +13,8 @@ output.. = bin/
bin.includes = META-INF/,\
.,\
OSGI-INF/,\
- about.html
+ about.html,\
+ plugin.xml
# The java version of the source code
javacSource=1.6
# The java version of the byte code targeted
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/plugin.xml b/plugins/org.eclipse.koneki.ldt.remote.debug.core/plugin.xml
new file mode 100644
index 0000000..8a48cb3
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.debug.core.launchConfigurationTypes">
+ <launchConfigurationType
+ id="org.eclipse.koneki.ldt.remote.debug.core.luaremotedebug"
+ modes="run, debug"
+ name="%launchConfigurationType.name"
+ delegate="org.eclipse.koneki.ldt.remote.debug.core.internal.LuaRemoteLaunchConfigurationDelegate"
+ sourceLocatorId="org.eclipse.koneki.ldt.debug.core.SourceLookup"
+ sourcePathComputerId="org.eclipse.koneki.ldt.debug.core.SourcePathComputer">
+ </launchConfigurationType>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/InputStreamMonitor.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/InputStreamMonitor.java
new file mode 100644
index 0000000..aa8296c
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/InputStreamMonitor.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+//FIXME This class is a copy from eclipse.debug.core plugin
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import org.eclipse.debug.core.DebugPlugin;
+
+/**
+ * Writes to the input stream of a system process, queueing output if the stream is blocked.
+ *
+ * The input stream monitor writes to system in via an output stream.
+ */
+public class InputStreamMonitor {
+
+ /**
+ * The stream which is being written to (connected to system in).
+ */
+ private OutputStream fStream;
+ /**
+ * The queue of output.
+ */
+ private Vector<String> fQueue;
+
+ /**
+ * The thread which writes to the stream.
+ */
+ private Thread fThread;
+ /**
+ * A lock for ensuring that writes to the queue are contiguous
+ */
+ private Object fLock;
+
+ /**
+ * Whether the underlying output stream has been closed
+ */
+ private boolean fClosed = false;
+
+ /**
+ * The encoding of the input stream.
+ */
+ private String fEncoding;
+
+ /**
+ * Creates an input stream monitor which writes to system in via the given output stream.
+ *
+ * @param stream
+ * output stream
+ */
+ public InputStreamMonitor(OutputStream stream) {
+ this(stream, null);
+ }
+
+ /**
+ * Creates an input stream monitor which writes to system in via the given output stream.
+ *
+ * @param stream
+ * output stream
+ * @param encoding
+ * stream encoding or <code>null</code> for system default
+ */
+ public InputStreamMonitor(OutputStream stream, String encoding) {
+ fStream = stream;
+ fQueue = new Vector<String>();
+ fLock = new Object();
+ fEncoding = encoding;
+ }
+
+ /**
+ * Appends the given text to the stream, or queues the text to be written at a later time if the stream is blocked.
+ *
+ * @param text
+ * text to append
+ */
+ public void write(String text) {
+ synchronized (fLock) {
+ fQueue.add(text);
+ fLock.notifyAll();
+ }
+ }
+
+ /**
+ * Starts a thread which writes the stream.
+ */
+ public void startMonitoring() {
+ if (fThread == null) {
+ fThread = new Thread(new Runnable() {
+ public void run() {
+ write();
+ }
+ }, "Input Stream Monitor"); //$NON-NLS-1$
+ fThread.setDaemon(true);
+ fThread.start();
+ }
+ }
+
+ /**
+ * Close all communications between this monitor and the underlying stream.
+ */
+ public void close() {
+ if (fThread != null) {
+ Thread thread = fThread;
+ fThread = null;
+ thread.interrupt();
+ }
+ }
+
+ /**
+ * Continuously writes to the stream.
+ */
+ protected void write() {
+ while (fThread != null) {
+ writeNext();
+ }
+ if (!fClosed) {
+ try {
+ fStream.close();
+ } catch (IOException e) {
+ DebugPlugin.log(e);
+ }
+ }
+ }
+
+ /**
+ * Write the text in the queue to the stream.
+ */
+ protected void writeNext() {
+ while (!fQueue.isEmpty() && !fClosed) {
+ String text = (String) fQueue.firstElement();
+ fQueue.removeElementAt(0);
+ try {
+ if (fEncoding != null)
+ fStream.write(text.getBytes(fEncoding));
+ else
+ fStream.write(text.getBytes());
+ fStream.flush();
+ } catch (IOException e) {
+ DebugPlugin.log(e);
+ }
+ }
+ try {
+ synchronized (fLock) {
+ fLock.wait();
+ }
+ // CHECKSTYLE:OFF
+ } catch (InterruptedException e) {
+ // CHECKSTYLE:ON
+ }
+
+ }
+
+ /**
+ * Closes the output stream attached to the standard input stream of this monitor's process.
+ *
+ * @exception IOException
+ * if an exception occurs closing the input stream
+ */
+ public void closeInputStream() throws IOException {
+ if (!fClosed) {
+ fClosed = true;
+ fStream.close();
+ } else {
+ throw new IOException();
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRSEUtil.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRSEUtil.java
new file mode 100644
index 0000000..4d5fc49
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRSEUtil.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.util.EnumSet;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.koneki.ldt.core.IProjectSourceVisitor;
+import org.eclipse.koneki.ldt.core.LuaUtils;
+import org.eclipse.koneki.ldt.core.LuaUtils.ProjectFragmentFilter;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+
+/**
+ * Utility class, contains some helpers to use RSE
+ */
+public final class LuaRSEUtil {
+ private LuaRSEUtil() {
+ }
+
+ /**
+ * upload of the given script project and all dependencies (define in buildpath) except for archive
+ *
+ * @throws CoreException
+ */
+ public static void uploadFiles(final IRemoteFileSubSystem subsystem, final IScriptProject project, final String destinationFolderPath,
+ final IProgressMonitor monitor) throws CoreException {
+ final IProjectSourceVisitor visitor = new IProjectSourceVisitor() {
+
+ @Override
+ public void processFile(IPath absolutePath, IPath relativePath, String charset, IProgressMonitor monitor) throws CoreException {
+ final String destinationPath = destinationFolderPath + subsystem.getSeparator() + relativePath.toPortableString();
+ final String destinationEncoding = subsystem.getRemoteEncoding();
+ final SubMonitor subMonitor = SubMonitor.convert(monitor, 1);
+ try {
+ // Create file directory
+ subsystem.upload(absolutePath.toOSString(), charset, destinationPath, destinationEncoding, subMonitor.newChild(1));
+ } catch (final SystemMessageException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to upload files", e)); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public void processDirectory(IPath absolutePath, IPath relativePath, IProgressMonitor monitor) throws CoreException {
+ final String innerDestinationFolderPath = destinationFolderPath + subsystem.getSeparator() + relativePath.toPortableString();
+ final SubMonitor subMonitor = SubMonitor.convert(monitor, 1);
+ try {
+ // Create remote directory
+ final IRemoteFile remoteFolder = subsystem.getRemoteFileObject(innerDestinationFolderPath, subMonitor);
+ subsystem.createFolder(remoteFolder, subMonitor.newChild(1));
+ } catch (final SystemMessageException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to upload files", e)); //$NON-NLS-1$
+ }
+
+ }
+
+ };
+
+ LuaUtils.visitSourceFiles(project,
+ EnumSet.complementOf(EnumSet.of(ProjectFragmentFilter.ARCHIVE, ProjectFragmentFilter.EXECUTION_ENVIRONMENT)), visitor, monitor);
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteDebugConstant.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteDebugConstant.java
new file mode 100644
index 0000000..92858a6
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteDebugConstant.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+public interface LuaRemoteDebugConstant {
+
+ String HOST_ID = Activator.PLUGIN_ID + ".debug.hostid"; //$NON-NLS-1$
+ String PROJECT_NAME = null;
+ String ENV_VAR_KEY_DBGP_IDE_KEY = null;
+ String ENV_VAR_KEY_DBGP_IDE_PORT = null;
+
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationDelegate.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..6503b9b
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationDelegate.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.dbgp.DbgpSessionIdGenerator;
+import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+import org.osgi.framework.Bundle;
+
+import com.jcraft.jsch.Session;
+
+public class LuaRemoteLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
+ private static final String[] DEBUG_FILES = { "/script/debugintrospection.lua", "script/debugger.lua" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+ //private static final String DEBGUGGER_MODULE = "debugger"; //$NON-NLS-1$
+
+ /**
+ * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String,
+ * org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ SubMonitor submonitor = SubMonitor.convert(monitor, 11);
+ try {
+ // wait RSE is initialized
+ // TODO not sure this is the good way to wait for init everywhere in the code
+ RSEUtil.waitForRSEInitialization();
+
+ // get configuration information
+ String projectName = configuration.getAttribute(LuaRemoteDebugConstant.PROJECT_NAME, "");//$NON-NLS-1$
+ IHost host = LuaRemoteLaunchConfigurationUtil.getHost(configuration);
+
+ @SuppressWarnings("rawtypes")
+ Map env = configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, Collections.EMPTY_MAP);
+
+ // valid configuration information
+ String validateLuaEmbeddedConfiguration = LuaRemoteLaunchConfigurationUtil.validateLuaEmbeddedConfiguration(projectName, host);
+ if (validateLuaEmbeddedConfiguration != null)
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, validateLuaEmbeddedConfiguration));
+ submonitor.worked(1);
+
+ // get Project
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+
+ // get the first found remote file SubSystem
+ IRemoteFileSubSystem remoteFileSubSystem = RSEUtil.getRemoteFileSubsystem(host);
+ if (remoteFileSubSystem == null)
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_noremotefilesystem));
+
+ // try to connect to the target
+ try {
+ if (submonitor.isCanceled())
+ return;
+ remoteFileSubSystem.connect(submonitor.newChild(1), false);
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_connectionfailed, e));
+ }
+
+ // compute the remote project workingdir
+ if (submonitor.isCanceled())
+ return;
+ String remoteApplicationFolderPath = "/tmp/"; //$NON-NLS-1$
+ String remoteapplicationpath = "/tmp/"; //$NON-NLS-1$
+
+ // kill Process if already running
+ // could happen if connection is closed and last process launch is not terminate
+ Session session = RSEUtil.getCurrentSshSession(host.getConnectorServices());
+ SshProcess.killProcess(session, remoteApplicationFolderPath);
+
+ // check an prepare remote folder
+ try {
+ if (submonitor.isCanceled())
+ return;
+ IRemoteFile remoteApplicationPath = remoteFileSubSystem.getRemoteFileObject(remoteapplicationpath, submonitor.newChild(1));
+ if (remoteApplicationPath.exists()) {
+ if (remoteApplicationPath.isFile()) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_filealreadyexist + remoteapplicationpath));
+ }
+ } else {
+ remoteFileSubSystem.createFolder(remoteApplicationPath, submonitor.newChild(1));
+ }
+ submonitor.setWorkRemaining(8);
+
+ // remoteFile is a folder
+ // create(or delete and recreate) the working directory
+ if (submonitor.isCanceled())
+ return;
+ IRemoteFile remoteWorkingFolder = remoteFileSubSystem.getRemoteFileObject(remoteApplicationFolderPath, submonitor.newChild(1));
+ if (remoteWorkingFolder.exists()) {
+ if (remoteWorkingFolder.isFile()) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_filealreadyexist, remoteApplicationFolderPath)));
+ } else {
+ remoteFileSubSystem.delete(remoteWorkingFolder, submonitor.newChild(1));
+ }
+ }
+ submonitor.setWorkRemaining(6);
+ remoteFileSubSystem.createFolder(remoteWorkingFolder, submonitor.newChild(1));
+
+ // create project application
+ if (submonitor.isCanceled())
+ return;
+
+ // upload sourcecode
+ IScriptProject scriptProject = DLTKCore.create(project);
+ LuaRSEUtil.uploadFiles(remoteFileSubSystem, scriptProject, remoteApplicationFolderPath, submonitor.newChild(3));
+
+ // upload Debug module
+ SubMonitor introspectionMonitor = submonitor.newChild(1);
+ introspectionMonitor.setWorkRemaining(DEBUG_FILES.length);
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ String localEncoding = Charset.defaultCharset().name();
+ String remoteEncoding = remoteFileSubSystem.getRemoteEncoding();
+ for (String luaFile : DEBUG_FILES) {
+ try {
+ Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
+ URL resource = bundle.getResource(luaFile);
+ File result = new File(FileLocator.toFileURL(resource).getPath());
+ String remotePath = remoteApplicationFolderPath + remoteFileSubSystem.getSeparator() + result.getName();
+ remoteFileSubSystem.upload(result.getAbsolutePath(), localEncoding, remotePath, remoteEncoding, submonitor.newChild(1));
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_unabletoloadintrospectionlib, e));
+ }
+ }
+ }
+ } catch (SystemMessageException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.LuaRemoteLaunchConfigurationDelegate_error_unabletoaccestoremoteapplicationdir + remoteapplicationpath, e));
+ }
+
+ // set environment var
+ String sessionID = DbgpSessionIdGenerator.generate();
+ Map<String, String> envVars = new HashMap<String, String>();
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ // dbgp env vars
+ envVars.put(LuaRemoteDebugConstant.ENV_VAR_KEY_DBGP_IDE_KEY, sessionID);
+ envVars.put(LuaRemoteDebugConstant.ENV_VAR_KEY_DBGP_IDE_PORT, String.valueOf(DLTKDebugPlugin.getDefault().getDbgpService().getPort()));
+ }
+ for (Object oEntry : env.entrySet()) {
+ @SuppressWarnings("rawtypes")
+ Map.Entry entry = (Entry) oEntry;
+ envVars.put(entry.getKey().toString(), entry.getValue().toString());
+ }
+
+ // create lua execution command
+ // String mainRelativePath = LuaConstants.DEFAULT_MAIN_FILE;
+ // List<String> cmd = new ArrayList<String>(6);
+ // // FIXME is there a cleaner way to control buffering ?
+ // // see: http://lua-users.org/lists/lua-l/2011-05/msg00549.html
+ // String bootstrapCode = "io.stdout:setvbuf(\"line\");"; //$NON-NLS-1$
+
+ // TODO Retreive properties from target to create the ssh process
+ // cmd.add("lua");
+ // if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ // // load debugging libraries. The -l parameter cannot be used here because the debugger MUST be the first module to be loaded
+ // bootstrapCode += " require(\"" + DEBGUGGER_MODULE + "\")();"; //$NON-NLS-1$//$NON-NLS-2$
+ // }
+ // cmd.add("-e"); //$NON-NLS-1$
+ // cmd.add(bootstrapCode);
+ // cmd.add(mainRelativePath);
+ //
+ // // Create Process
+ // if (submonitor.isCanceled())
+ // return;
+ //
+ // SshProcess process = new SshProcess(session, launch, remoteApplicationFolderPath, cmd.toArray(new String[cmd.size()]), envVars);
+ //
+ // if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ // // Desactivate DBGP Stream redirection
+ // // TODO manage DBGP Stream redirection (so desactivate process redirection in debug mode)
+ // launch.setAttribute(DLTKDebugLaunchConstants.ATTR_DEBUG_CONSOLE, "false"); //$NON-NLS-1$
+ // LuaRemoteDebuggingEngineRunner debugingEngine = new LuaRemoteDebuggingEngineRunner(process, sessionID, remoteApplicationFolderPath);
+ // debugingEngine.run(new InterpreterConfig(), launch, new NullProgressMonitor());
+ // launch.addProcess(process);
+ // } else {
+ // process.start();
+ // launch.addProcess(process);
+ // }
+ } finally {
+ submonitor.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationUtil.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationUtil.java
new file mode 100644
index 0000000..77a4443
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/LuaRemoteLaunchConfigurationUtil.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.koneki.ldt.core.LuaNature;
+import org.eclipse.rse.core.RSECorePlugin;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.core.model.ISystemProfile;
+
+/**
+ * Utility class to handle ILaunchConfiguration for LuaEmbeddedLaunchConfiguration
+ */
+public final class LuaRemoteLaunchConfigurationUtil {
+
+ private LuaRemoteLaunchConfigurationUtil() {
+ }
+
+ /**
+ * set the HOST_ID attributes in the given launch configuration
+ *
+ * @param conf
+ * to edit
+ * @param host
+ * to save in the HOST_ID attribute
+ */
+ public static final void setConnectionId(ILaunchConfigurationWorkingCopy conf, IHost host) {
+ List<String> hostData = new ArrayList<String>();
+ hostData.add(host.getSystemProfileName());
+ hostData.add(host.getName());
+ conf.setAttribute(LuaRemoteDebugConstant.HOST_ID, hostData);
+ }
+
+ /**
+ * get the host identify by the given ILaunchConfiguration.
+ *
+ * @return the host defined for this ILaunchConfiguration or null if no host is found
+ */
+ public static final IHost getHost(ILaunchConfiguration conf) {
+ try {
+ List<?> hostData = conf.getAttribute(LuaRemoteDebugConstant.HOST_ID, Collections.EMPTY_LIST);
+
+ // list must contained 2 elements (profileName and host name)
+ if (hostData.size() != 2)
+ return null;
+
+ // get profile name
+ Object oProfileName = hostData.get(0);
+ if (!(oProfileName instanceof String))
+ return null;
+ String profileName = (String) oProfileName;
+
+ // get host name
+ Object oHost = hostData.get(1);
+ if (!(oHost instanceof String))
+ return null;
+ String hostID = (String) oHost;
+
+ // get profile
+ ISystemProfile systemProfile = RSECorePlugin.getTheSystemRegistry().getSystemProfile(profileName);
+ if (systemProfile == null)
+ return null;
+
+ // get host
+ IHost host = RSECorePlugin.getTheSystemRegistry().getHost(systemProfile, hostID);
+ return host;
+ } catch (CoreException e) {
+ return null;
+ }
+ }
+
+ /**
+ * internal method to validate the value of the current tab
+ *
+ * @param luaInspectorPort
+ *
+ * @return true if value is valid
+ */
+ public static String validateLuaEmbeddedConfiguration(String projectName, IHost host) {
+ // projectName validation
+ if (projectName == null || projectName.isEmpty()) {
+ return "A project must be selected.";
+ }
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ if (project == null || !project.exists()) {
+ return "This project doesn't exist.";
+ }
+ if (!project.isOpen()) {
+ return "This project is not open.";
+ }
+ try {
+ if (!project.hasNature(LuaNature.ID)) {
+ return "This project is not a lua project.";
+ }
+ } catch (CoreException e) {
+ // must not append (at this line project is open and exist)
+ return null;
+ }
+
+ // target validation
+ if (host == null) {
+ return "An host must be selected.";
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/Messages.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/Messages.java
new file mode 100644
index 0000000..24c2a99
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/Messages.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+// CHECKSTYLE NLS: OFF
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.koneki.ldt.remote.debug.core.internal.messages"; //$NON-NLS-1$
+ public static String LuaRemoteLaunchConfigurationDelegate_error_connectionfailed;
+ public static String LuaRemoteLaunchConfigurationDelegate_error_filealreadyexist;
+ public static String LuaRemoteLaunchConfigurationDelegate_error_noremotefilesystem;
+ public static String LuaRemoteLaunchConfigurationDelegate_error_unabletoaccestoremoteapplicationdir;
+ public static String LuaRemoteLaunchConfigurationDelegate_error_unabletoloadintrospectionlib;
+ public static String LuaRemoteLaunchConfigurationUtil_error_closed_project;
+ public static String LuaRemoteLaunchConfigurationUtil_error_command_path_empty;
+ public static String LuaRemoteLaunchConfigurationUtil_error_no_host_selected;
+ public static String LuaRemoteLaunchConfigurationUtil_error_no_project;
+ public static String LuaRemoteLaunchConfigurationUtil_error_not_lua_project;
+ public static String LuaRemoteLaunchConfigurationUtil_error_remote_application_path_empty;
+ public static String LuaRemoteLaunchConfigurationUtil_error_unexisted_project;
+ public static String SshProcess_exception_kill_process_failed;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
+// CHECKSTYLE NLS: ON
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/OutputStreamMonitor.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/OutputStreamMonitor.java
new file mode 100644
index 0000000..b90a0e7
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/OutputStreamMonitor.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+//FIXME This class is a copy from eclipse.debug.core plugin
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IStreamListener;
+import org.eclipse.debug.core.model.IFlushableStreamMonitor;
+
+/**
+ * Monitors the output stream of a system process and notifies listeners of additions to the stream.
+ *
+ * The output stream monitor reads system out (or err) via and input stream.
+ */
+public class OutputStreamMonitor implements IFlushableStreamMonitor {
+
+ /**
+ * The size of the read buffer
+ */
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * The stream being monitored (connected system out or err).
+ */
+ private InputStream fStream;
+
+ /**
+ * A collection of listeners
+ */
+ private ListenerList fListeners = new ListenerList();
+
+ /**
+ * Whether content is being buffered
+ */
+ private boolean fBuffered = true;
+
+ /**
+ * The local copy of the stream contents
+ */
+ private StringBuffer fContents;
+
+ /**
+ * The thread which reads from the stream
+ */
+ private Thread fThread;
+
+ /**
+ * Whether or not this monitor has been killed. When the monitor is killed, it stops reading from the stream immediately.
+ */
+ private boolean fKilled = false;
+
+ private long lastSleep;
+
+ private String fEncoding;
+
+ /**
+ * Creates an output stream monitor on the given stream (connected to system out or err).
+ *
+ * @param stream
+ * input stream to read from
+ * @param encoding
+ * stream encoding or <code>null</code> for system default
+ */
+ public OutputStreamMonitor(InputStream stream, String encoding) {
+ fStream = new BufferedInputStream(stream, 8192);
+ fEncoding = encoding;
+ fContents = new StringBuffer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IStreamMonitor#addListener(org.eclipse.debug.core.IStreamListener)
+ */
+ public synchronized void addListener(IStreamListener listener) {
+ fListeners.add(listener);
+ }
+
+ /**
+ * Causes the monitor to close all communications between it and the underlying stream by waiting for the thread to terminate.
+ */
+ protected void close() {
+ if (fThread != null) {
+ Thread thread = fThread;
+ fThread = null;
+ try {
+ thread.join();
+ } catch (InterruptedException ie) {
+ Activator.logWarning("Output Stream Monitor thread interrupted on close."); //$NON-NLS-1$
+ }
+ fListeners = new ListenerList();
+ }
+ }
+
+ /**
+ * Notifies the listeners that text has been appended to the stream.
+ */
+ private void fireStreamAppended(String text) {
+ getNotifier().notifyAppend(text);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IStreamMonitor#getContents()
+ */
+ public synchronized String getContents() {
+ return fContents.toString();
+ }
+
+ /**
+ * Continually reads from the stream.
+ * <p>
+ * This method, along with the <code>startReading</code> method is used to allow <code>OutputStreamMonitor</code> to implement
+ * <code>Runnable</code> without publicly exposing a <code>run</code> method.
+ */
+ private void read() {
+ lastSleep = System.currentTimeMillis();
+ long currentTime = lastSleep;
+ byte[] bytes = new byte[BUFFER_SIZE];
+ int read = 0;
+ while (read >= 0) {
+ try {
+ if (fKilled) {
+ break;
+ }
+ read = fStream.read(bytes);
+ if (read > 0) {
+ String text;
+ if (fEncoding != null) {
+ text = new String(bytes, 0, read, fEncoding);
+ } else {
+ text = new String(bytes, 0, read);
+ }
+ synchronized (this) {
+ if (isBuffered()) {
+ fContents.append(text);
+ }
+ fireStreamAppended(text);
+ }
+ }
+ } catch (IOException ioe) {
+ if (!fKilled) {
+ DebugPlugin.log(ioe);
+ }
+ return;
+ } catch (NullPointerException e) {
+ // killing the stream monitor while reading can cause an NPE
+ // when reading from the stream
+ if (!fKilled && fThread != null) {
+ DebugPlugin.log(e);
+ }
+ return;
+ }
+
+ currentTime = System.currentTimeMillis();
+ if (currentTime - lastSleep > 1000) {
+ lastSleep = currentTime;
+ try {
+ Thread.sleep(1); // just give up CPU to maintain UI responsiveness.
+ } catch (InterruptedException e) {
+ Activator.logWarning("Output Stream Monitor thread interrupted on read"); //$NON-NLS-1$
+ }
+ }
+ }
+ try {
+ fStream.close();
+ } catch (IOException e) {
+ DebugPlugin.log(e);
+ }
+ }
+
+ protected void kill() {
+ fKilled = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IStreamMonitor#removeListener(org.eclipse.debug.core.IStreamListener)
+ */
+ public synchronized void removeListener(IStreamListener listener) {
+ fListeners.remove(listener);
+ }
+
+ /**
+ * Starts a thread which reads from the stream
+ */
+ protected void startMonitoring() {
+ if (fThread == null) {
+ fThread = new Thread(new Runnable() {
+ public void run() {
+ read();
+ }
+ }, "Output Stream Monitor"); //$NON-NLS-1$
+ fThread.setDaemon(true);
+ fThread.setPriority(Thread.MIN_PRIORITY);
+ fThread.start();
+ }
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IFlushableStreamMonitor#setBuffered(boolean)
+ */
+ public synchronized void setBuffered(boolean buffer) {
+ fBuffered = buffer;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IFlushableStreamMonitor#flushContents()
+ */
+ public synchronized void flushContents() {
+ fContents.setLength(0);
+ }
+
+ /**
+ * @see IFlushableStreamMonitor#isBuffered()
+ */
+ public synchronized boolean isBuffered() {
+ return fBuffered;
+ }
+
+ private ContentNotifier getNotifier() {
+ return new ContentNotifier();
+ }
+
+ class ContentNotifier implements ISafeRunnable {
+
+ private IStreamListener fListener;
+ private String fText;
+
+ /**
+ * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
+ */
+ public void handleException(Throwable exception) {
+ DebugPlugin.log(exception);
+ }
+
+ /**
+ * @see org.eclipse.core.runtime.ISafeRunnable#run()
+ */
+ public void run() throws Exception {
+ fListener.streamAppended(fText, OutputStreamMonitor.this);
+ }
+
+ public void notifyAppend(String text) {
+ if (text == null)
+ return;
+ fText = text;
+ Object[] copiedListeners = fListeners.getListeners();
+ for (int i = 0; i < copiedListeners.length; i++) {
+ fListener = (IStreamListener) copiedListeners[i];
+ SafeRunner.run(this);
+ }
+ fListener = null;
+ fText = null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/RSEUtil.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/RSEUtil.java
new file mode 100644
index 0000000..65f0e03
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/RSEUtil.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.rse.core.RSECorePlugin;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.internal.connectorservice.ssh.SshConnectorService;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.files.IFileService;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+
+import com.jcraft.jsch.Session;
+
+/**
+ * Utility class, contains some helpers to use RSE
+ */
+@SuppressWarnings("restriction")
+public final class RSEUtil {
+ private RSEUtil() {
+ }
+
+ /**
+ * Return the ssh connection session in this connector services
+ */
+ public static Session getCurrentSshSession(IConnectorService[] connectors) {
+ // TODO find a way to not use internal class (and so remove the rse.ui dependency)
+ for (IConnectorService connectorService : connectors) {
+ if (connectorService instanceof SshConnectorService) {
+ SshConnectorService iConnectorService = (SshConnectorService) connectorService;
+ return iConnectorService.getSession();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * stop the current thread until RSE is initialized or the thread is interrupted
+ */
+ public static void waitForRSEInitialization() {
+ try {
+ RSECorePlugin.waitForInitCompletion();
+ // CHECKSTYLE:OFF
+ } catch (InterruptedException e) {
+ // nothing to do ..
+ // CHECKSTYLE:ON
+ }
+ }
+
+ /**
+ * Gets the first found remote file SubSystem in the given host
+ *
+ * @param host
+ * @return a remote file subsystem or null if none is found
+ */
+ public static IRemoteFileSubSystem getRemoteFileSubsystem(IHost host) {
+ ISubSystem[] subSystems = host.getSubSystems();
+ for (ISubSystem subsystem : subSystems) {
+ if (subsystem instanceof IRemoteFileSubSystem) {
+ return ((IRemoteFileSubSystem) subsystem);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * workaround of BUG ECLIPSE TOOLSLINUX-86 349947, no more needed since tm 3.4
+ *
+ * @return true if the file exist
+ */
+ @Deprecated
+ public static boolean fileExist(IRemoteFileSubSystem subsystem, IRemoteFile file) {
+ try {
+ IRemoteFile[] list = subsystem.list(file.getParentRemoteFile(), file.getName(), IFileService.FILE_TYPE_FILES_AND_FOLDERS,
+ new NullProgressMonitor());
+ return list.length == 1;
+ } catch (SystemMessageException e) {
+ return false;
+ }
+ }
+
+ /**
+ * upload the content of the given folder at the given destination
+ *
+ * @throws CoreException
+ */
+ public static void uploadFiles(IRemoteFileSubSystem subsystem, IFolder sourceFolder, String destinationFolderPath, IProgressMonitor monitor)
+ throws CoreException {
+ IResource[] members = sourceFolder.members();
+ SubMonitor subMonitor = SubMonitor.convert(monitor, members.length);
+ if (members.length > 0) {
+ for (int i = 0; i < members.length && !subMonitor.isCanceled(); i++) {
+ try {
+ IResource sourceMember = members[i];
+ if (sourceMember instanceof IFile) {
+ IFile sourceFile = ((IFile) sourceMember);
+ String sourcePath = sourceFile.getLocation().toOSString();
+ String sourceEncoding = sourceFile.getCharset();
+ String destinationPath = destinationFolderPath + subsystem.getSeparator() + sourceFile.getName();
+ String destinationEncoding = subsystem.getRemoteEncoding();
+ subsystem.upload(sourcePath, sourceEncoding, destinationPath, destinationEncoding, subMonitor.newChild(3));
+ } else if (sourceMember instanceof IFolder) {
+ IFolder innerSourceFolder = (IFolder) sourceMember;
+ String innerDestinationFolderPath = destinationFolderPath + subsystem.getSeparator() + innerSourceFolder.getName();
+ IRemoteFile remoteFolder = subsystem.getRemoteFileObject(innerDestinationFolderPath, subMonitor.newChild(1));
+ subsystem.createFolder(remoteFolder, subMonitor.newChild(1));
+ uploadFiles(subsystem, innerSourceFolder, innerDestinationFolderPath, subMonitor.newChild(1));
+ }
+ } catch (SystemMessageException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to upload files", e)); //$NON-NLS-1$
+ }
+ }
+
+ }
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/SshProcess.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/SshProcess.java
new file mode 100644
index 0000000..24cdb16
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/SshProcess.java
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStreamsProxy;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Implementation of {@link org.eclipse.debug.core.model.IProcess} based on ssh connection
+ */
+public class SshProcess implements IProcess {
+
+ private ILaunch launch;
+ private ChannelExec channelExec;
+ private StreamsProxy sshStreamProxy;
+ private String label;
+ private Session currentSession;
+ private String workingDir;
+
+ /**
+ * Create and launch a process corresponding to the given command throw an ssh connection<br>
+ * <b>/!\ Session must be connected !</b>
+ *
+ * A .PID file will be create in the working directory for this process.(which contains the PID of this process)<br>
+ * This file is used to be able to stop (kill) the process when needed.<br>
+ * So, User must have the write to create file in the working directory and so 2 process must not be run at the same time in the same working
+ * directory
+ *
+ * @throws CoreException
+ * if exec channel can not be created, or session is down
+ */
+ public SshProcess(Session session, ILaunch launch, String workingDirectoryPath, String[] command, Map<String, String> envVars)
+ throws CoreException {
+ this.launch = launch;
+ this.currentSession = session;
+ this.workingDir = workingDirectoryPath;
+
+ // open exec channel
+ Channel channel;
+ try {
+ channel = session.openChannel("exec"); //$NON-NLS-1$
+ } catch (JSchException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to create SShProcess", e)); //$NON-NLS-1$
+ }
+ if (!(channel instanceof ChannelExec))
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to create SShProcess")); //$NON-NLS-1$
+ channelExec = (ChannelExec) channel;
+
+ // Create command label (unescaped form)
+ StringBuilder labelCmd = new StringBuilder();
+ for (String part : command) {
+ labelCmd.append(part).append(" "); //$NON-NLS-1$
+ }
+ this.label = labelCmd.toString();
+
+ // create composed command
+ String composedCommand = createLaunchCommand(workingDirectoryPath, command, envVars);
+ channelExec.setCommand(composedCommand);
+ }
+
+ /**
+ * Escapes a string so it became a valid Shell token.
+ *
+ * @param s
+ * @return
+ */
+ public static String escapeShell(String s) {
+ // TODO: there is still some sequences to escape
+ return "\"" + s.replaceAll("\"", Matcher.quoteReplacement("\\\"")) + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ /**
+ * start the process <br>
+ * don't forget to call Terminate if an error is raised.
+ *
+ * @throws CoreException
+ * if an error occured (session is down, channel is not open,IO Problem on channel's stream)
+ */
+ public void start() throws CoreException {
+ // start stream monitoring
+ try {
+ sshStreamProxy = new StreamsProxy(channelExec.getInputStream(), channelExec.getErrStream(), channelExec.getOutputStream(), null, null);
+ } catch (IOException e) {
+ this.terminate();
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to start SShProcess", e)); //$NON-NLS-1$
+ }
+
+ // start connection
+ try {
+ channelExec.connect();
+ } catch (JSchException e) {
+ this.terminate();
+ throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to start SShProcess", e)); //$NON-NLS-1$
+ }
+ fireCreationEvent();
+
+ // monitor channel state
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ boolean connected;
+ do {
+ connected = channelExec.isConnected();
+ try {
+ Thread.sleep(100);
+ // CHECKSTYLE:OFF
+ } catch (InterruptedException e) {
+ // nothing to do
+ // CHECKSTYLE:ON
+ }
+ } while (connected);
+ sshStreamProxy.kill();
+ fireTerminateEvent();
+ }
+ }).start();
+ }
+
+ /**
+ * create one command from workingdir, envpath and command
+ */
+ private String createLaunchCommand(String workingDirectoryPath, String[] command, Map<String, String> envVars) {
+ // TODO : should works only on linux...
+
+ StringBuilder composedCommand = new StringBuilder();
+ // add : move to the working directory
+ composedCommand.append("cd "); //$NON-NLS-1$
+ composedCommand.append(escapeShell(workingDirectoryPath));
+ composedCommand.append(" && "); //$NON-NLS-1$
+
+ // add : set env path
+ for (Entry<String, String> entrySet : envVars.entrySet()) {
+ composedCommand.append("export "); //$NON-NLS-1$
+ composedCommand.append(entrySet.getKey());
+ composedCommand.append("="); //$NON-NLS-1$
+ composedCommand.append(escapeShell(entrySet.getValue()));
+ composedCommand.append(" && "); //$NON-NLS-1$
+ }
+
+ // if a .PID file already exist, we try to kill the corresponding process
+ // and remove the old .PID file
+ // run this command in silent mode (redirect all the output stream in /dev/null)
+ composedCommand.append("("); //$NON-NLS-1$
+ composedCommand.append("cat .PID > /dev/null 2>&1"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+ composedCommand.append("kill `cat .PID` > /dev/null 2>&1"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+ composedCommand.append("rm .PID > /dev/null 2>&1"); //$NON-NLS-1$
+ composedCommand.append(")"); //$NON-NLS-1$
+ composedCommand.append("; "); //$NON-NLS-1$
+
+ // launch command in background
+ composedCommand.append("{ "); //$NON-NLS-1$
+ for (String part : command) {
+ composedCommand.append(escapeShell(part)).append(" "); //$NON-NLS-1$
+ }
+ composedCommand.append(" & }"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+
+ // store the PID of the last background task (so the command below)
+ composedCommand.append("echo $! > .PID"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+
+ // wait the end of the command execution
+ composedCommand.append("wait $!"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+
+ // remove the PID file
+ composedCommand.append("rm .PID"); //$NON-NLS-1$
+
+ return composedCommand.toString();
+ }
+
+ /**
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
+ */
+ @Override
+ public boolean canTerminate() {
+ return !isTerminated();
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+ */
+ @Override
+ public boolean isTerminated() {
+ return channelExec.isClosed();
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.ITerminate#terminate()
+ */
+ @Override
+ public void terminate() throws DebugException {
+ if (!isTerminated()) {
+ SshProcess.killProcess(currentSession, workingDir);
+ } else {
+ sshStreamProxy.kill();
+ fireTerminateEvent();
+ }
+ }
+
+ /**
+ * create the kill command for the current process
+ */
+ private static String createKillCommand(String pidContainerFolder) {
+ // TODO : should works only on linux...
+
+ StringBuilder composedCommand = new StringBuilder();
+ // add : move to the working directory
+ composedCommand.append("cd "); //$NON-NLS-1$
+ composedCommand.append(escapeShell(pidContainerFolder));
+ composedCommand.append(" && "); //$NON-NLS-1$
+
+ // kill process
+ composedCommand.append("kill `cat .PID`"); //$NON-NLS-1$
+ composedCommand.append(" && "); //$NON-NLS-1$
+ composedCommand.append(" rm .PID"); //$NON-NLS-1$
+ return composedCommand.toString();
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#getLabel()
+ */
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#getLaunch()
+ */
+ @Override
+ public ILaunch getLaunch() {
+ return launch;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#getStreamsProxy()
+ */
+ @Override
+ public IStreamsProxy getStreamsProxy() {
+ return sshStreamProxy;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#setAttribute(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void setAttribute(String key, String value) {
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#getAttribute(java.lang.String)
+ */
+ @Override
+ public String getAttribute(String key) {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.debug.core.model.IProcess#getExitValue()
+ */
+ @Override
+ public int getExitValue() throws DebugException {
+ return channelExec.getExitStatus();
+ }
+
+ /**
+ * Fires a creation event.
+ */
+ protected void fireCreationEvent() {
+ fireEvent(new DebugEvent(this, DebugEvent.CREATE));
+ }
+
+ /**
+ * Fires the given debug event.
+ *
+ * @param event
+ * debug event to fire
+ */
+ protected void fireEvent(DebugEvent event) {
+ DebugPlugin manager = DebugPlugin.getDefault();
+ if (manager != null) {
+ manager.fireDebugEventSet(new DebugEvent[] { event });
+ }
+ }
+
+ /**
+ * Fires a terminate event.
+ */
+ protected void fireTerminateEvent() {
+ fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
+ }
+
+ /**
+ * Fires a change event.
+ */
+ protected void fireChangeEvent() {
+ fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
+ }
+
+ /**
+ * try to kill the process with the PID equal to the value of the .PID file contained in pidContainerFolder
+ */
+ public static void killProcess(Session session, String pidContainerFolder) throws DebugException {
+ try {
+ // create a new channel
+ Channel channel = session.openChannel("exec"); //$NON-NLS-1$
+ if (!(channel instanceof ChannelExec))
+ throw new JSchException("Unable to create exec channel"); //$NON-NLS-1$
+ ChannelExec killChannel = (ChannelExec) channel;
+
+ // create kill command
+ String killCommand = createKillCommand(pidContainerFolder);
+ killChannel.setCommand(killCommand);
+
+ // execute command
+ killChannel.connect();
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ throw new DebugException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SshProcess_exception_kill_process_failed, e));
+ }
+ }
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/StreamsProxy.java b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/StreamsProxy.java
new file mode 100644
index 0000000..eb528a3
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/StreamsProxy.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.core.internal;
+
+//FIXME This class is partial copy from eclipse.debug.core plugin
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.debug.core.model.IStreamsProxy;
+import org.eclipse.debug.core.model.IStreamsProxy2;
+
+/**
+ * Standard implementation of a streams proxy for IStreamsProxy.
+ */
+
+public class StreamsProxy implements IStreamsProxy, IStreamsProxy2 {
+ /**
+ * The monitor for the output stream (connected to standard out of the process)
+ */
+ private OutputStreamMonitor fOutputMonitor;
+ /**
+ * The monitor for the error stream (connected to standard error of the process)
+ */
+ private OutputStreamMonitor fErrorMonitor;
+ /**
+ * The monitor for the input stream (connected to standard in of the process)
+ */
+ private InputStreamMonitor fInputMonitor;
+ /**
+ * Records the open/closed state of communications with the underlying streams. Note: fClosed is initialized to <code>false</code> by default.
+ */
+ private boolean fClosed;
+
+ /**
+ * Creates a <code>StreamsProxy</code> on the streams of the given system process.
+ *
+ * @param process
+ * system process to create a streams proxy on
+ * @param encoding
+ * the process's encoding or <code>null</code> if default
+ */
+ public StreamsProxy(InputStream inputStream, InputStream errorStream, OutputStream outputStream, String inputEncoding, String outputEncoding) {
+ fOutputMonitor = new OutputStreamMonitor(inputStream, inputEncoding);
+ fErrorMonitor = new OutputStreamMonitor(errorStream, inputEncoding);
+ fInputMonitor = new InputStreamMonitor(outputStream, outputEncoding);
+ fOutputMonitor.startMonitoring();
+ fErrorMonitor.startMonitoring();
+ fInputMonitor.startMonitoring();
+ }
+
+ /**
+ * Causes the proxy to close all communications between it and the underlying streams after all remaining data in the streams is read.
+ */
+ public void close() {
+ if (!isClosed(true)) {
+ fOutputMonitor.close();
+ fErrorMonitor.close();
+ fInputMonitor.close();
+ }
+ }
+
+ /**
+ * Returns whether the proxy is currently closed. This method synchronizes access to the <code>fClosed</code> flag.
+ *
+ * @param setClosed
+ * If <code>true</code> this method will also set the <code>fClosed</code> flag to true. Otherwise, the <code>fClosed</code> flag is
+ * not modified.
+ * @return Returns whether the stream proxy was already closed.
+ */
+ private boolean isClosed(boolean setClosed) {
+ boolean closed;
+ synchronized (this) {
+ closed = fClosed;
+ if (setClosed) {
+ fClosed = true;
+ }
+ }
+ return closed;
+ }
+
+ /**
+ * Causes the proxy to close all communications between it and the underlying streams immediately. Data remaining in the streams is lost.
+ */
+ public void kill() {
+ synchronized (this) {
+ fClosed = true;
+ }
+ fOutputMonitor.kill();
+ fErrorMonitor.kill();
+ fInputMonitor.close();
+ }
+
+ /**
+ * @see IStreamsProxy#getErrorStreamMonitor()
+ */
+ public IStreamMonitor getErrorStreamMonitor() {
+ return fErrorMonitor;
+ }
+
+ /**
+ * @see IStreamsProxy#getOutputStreamMonitor()
+ */
+ public IStreamMonitor getOutputStreamMonitor() {
+ return fOutputMonitor;
+ }
+
+ /**
+ * @see IStreamsProxy#write(String)
+ */
+ public void write(String input) throws IOException {
+ if (!isClosed(false)) {
+ fInputMonitor.write(input);
+ } else {
+ throw new IOException();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.debug.core.model.IStreamsProxy2#closeInputStream()
+ */
+ public void closeInputStream() throws IOException {
+ if (!isClosed(false)) {
+ fInputMonitor.closeInputStream();
+ } else {
+ throw new IOException();
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/messages.properties b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/messages.properties
new file mode 100644
index 0000000..68d19a7
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.core/src/org/eclipse/koneki/ldt/remote/debug/core/internal/messages.properties
@@ -0,0 +1,13 @@
+LuaRemoteLaunchConfigurationDelegate_error_connectionfailed=Connection to host failed. Unable to copy file on the host
+LuaRemoteLaunchConfigurationDelegate_error_filealreadyexist=A file already exist with the path :{0}
+LuaRemoteLaunchConfigurationDelegate_error_noremotefilesystem=The host for this launch configuration has no remote file system. Unable to copy file on the host.
+LuaRemoteLaunchConfigurationDelegate_error_unabletoaccestoremoteapplicationdir=Error when trying to access to remote application path :{0}
+LuaRemoteLaunchConfigurationDelegate_error_unabletoloadintrospectionlib=Error while loading introspection library
+LuaRemoteLaunchConfigurationUtil_error_closed_project=This project is not open.
+LuaRemoteLaunchConfigurationUtil_error_command_path_empty=Lua Command path must not be empty.
+LuaRemoteLaunchConfigurationUtil_error_no_host_selected=An host must be selected.
+LuaRemoteLaunchConfigurationUtil_error_no_project=A project must be selected.
+LuaRemoteLaunchConfigurationUtil_error_not_lua_project=This project is not a lua project.
+LuaRemoteLaunchConfigurationUtil_error_remote_application_path_empty=Remote Application path must not be empty.
+LuaRemoteLaunchConfigurationUtil_error_unexisted_project=This project doesn't exist.
+SshProcess_exception_kill_process_failed=An exception occurred when trying to stop the application.
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/META-INF/MANIFEST.MF
index a1539e7..a2796d3 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/META-INF/MANIFEST.MF
@@ -1,11 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
-Bundle-SymbolicName: org.eclipse.koneki.ldt.remote.debug.ui
+Bundle-SymbolicName: org.eclipse.koneki.ldt.remote.debug.ui;singleton:=true
Bundle-Version: 0.9.0.qualifier
Bundle-Activator: org.eclipse.koneki.ldt.remote.debug.ui.internal.Activator
-Require-Bundle: org.eclipse.core.runtime
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.debug.ui,
+ org.eclipse.koneki.ldt.ui;bundle-version="0.9.0",
+ org.eclipse.ui;bundle-version="3.103.0",
+ org.eclipse.koneki.ldt.remote.debug.core;bundle-version="0.9.0",
+ org.eclipse.dltk.launching;bundle-version="4.0.0",
+ org.eclipse.rse.ui;bundle-version="3.3.0",
+ org.eclipse.rse.core;bundle-version="3.3.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.koneki.ldt.remote.debug.ui.internal;x-internal:=true
+Export-Package: org.eclipse.koneki.ldt.remote.debug.ui.internal;x-internal:=true,
+ org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab;x-internal:=true
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/build.properties b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/build.properties
index 2096750..e2c8cb9 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/build.properties
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/build.properties
@@ -13,7 +13,8 @@ output.. = bin/
bin.includes = META-INF/,\
.,\
OSGI-INF/,\
- about.html
+ about.html,\
+ plugin.xml
# The java version of the source code
javacSource=1.6
# The java version of the byte code targeted
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/lua_launcher.gif b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/lua_launcher.gif
new file mode 100644
index 0000000..0fe4de9
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/lua_launcher.gif
Binary files differ
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/main_tab.gif b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/main_tab.gif
new file mode 100644
index 0000000..0193dbe
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/icons/obj16/main_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/plugin.xml b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/plugin.xml
new file mode 100644
index 0000000..8f715b1
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/plugin.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ class="org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab.LuaRemoteLaunchConfigurationTabGroup"
+ id="org.eclipse.koneki.ldt.remote.debug.ui.luaRemoteApplicationLaunchTabGroup"
+ type="org.eclipse.koneki.ldt.remote.debug.core.luaremotedebug">
+ <launchMode
+ mode="debug"
+ perspective="org.eclipse.debug.ui.DebugPerspective">
+ </launchMode>
+ <launchMode
+ mode="run"
+ perspective="org.eclipse.debug.ui.DebugPerspective">
+ </launchMode>
+ </launchConfigurationTabGroup>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+ <launchConfigurationTypeImage
+ configTypeID="org.eclipse.koneki.ldt.remote.debug.core.luaremotedebug"
+ icon="icons/obj16/lua_launcher.gif"
+ id="org.eclipse.koneki.ldt.remote.debug.core.luaremotedebug.image">
+ </launchConfigurationTypeImage>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/Activator.java b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/Activator.java
index 824fd8c..e78b645 100644
--- a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/Activator.java
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/Activator.java
@@ -11,14 +11,15 @@
package org.eclipse.koneki.ldt.remote.debug.ui.internal;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle.
*/
-public class Activator extends Plugin {
+public class Activator extends AbstractUIPlugin {
/** The plug-in ID */
public static final String PLUGIN_ID = "org.eclipse.koneki.ldt.remote.debug.ui"; //$NON-NLS-1$
@@ -62,6 +63,15 @@ public class Activator extends Plugin {
}
/**
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry reg) {
+ reg.put(ImageConstants.LUA_REMOTE_APP_LAUNCH_MAIN_TAB_ICON,
+ AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ImageConstants.LUA_REMOTE_APP_LAUNCH_MAIN_TAB_ICON));
+ }
+
+ /**
* Log a error message caused by the given exception
*
* @param message
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/ImageConstants.java b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/ImageConstants.java
new file mode 100644
index 0000000..6bcf9bd
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/ImageConstants.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.ui.internal;
+
+public interface ImageConstants {
+ String LUA_REMOTE_APP_LAUNCH_MAIN_TAB_ICON = "icons/obj16/main_tab.gif"; //$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationMainTab.java b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationMainTab.java
new file mode 100644
index 0000000..d8b2488
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationMainTab.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.koneki.ldt.remote.debug.core.internal.LuaRemoteDebugConstant;
+import org.eclipse.koneki.ldt.remote.debug.core.internal.LuaRemoteLaunchConfigurationUtil;
+import org.eclipse.koneki.ldt.remote.debug.ui.internal.Activator;
+import org.eclipse.koneki.ldt.remote.debug.ui.internal.ImageConstants;
+import org.eclipse.koneki.ldt.ui.LuaDialogUtil;
+import org.eclipse.koneki.ldt.ui.SWTUtil;
+import org.eclipse.rse.core.RSECorePlugin;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.ui.widgets.SystemHostCombo;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class LuaRemoteLaunchConfigurationMainTab extends AbstractLaunchConfigurationTab {
+
+ /**
+ * Commons listener for Textfield (used to update dialog buttons)
+ */
+ private final class TextModifyListener implements ModifyListener {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ // private Text luacpathText;
+ // private Text luapathText;
+ private SystemHostCombo hostCombo;
+ private TextModifyListener textModifyListener = new TextModifyListener();
+ private Text projectNameText;
+ private Button projectSelectionButton;
+
+ /**
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+ GridLayoutFactory.swtDefaults().applyTo(comp);
+ comp.setFont(parent.getFont());
+
+ // TODO not sure this is the good way to wait for init everywhere in the code
+ try {
+ RSECorePlugin.waitForInitCompletion();
+ // CHECKSTYLE:OFF
+ } catch (InterruptedException e) {
+ // nothing to do ..
+ // CHECKSTYLE:ON
+ }
+
+ createProjectConfigComponent(comp);
+ createTargetConfigComponent(comp);
+ }
+
+ /**
+ * create the composite used to configure the target information
+ *
+ * @param comp
+ */
+ private void createProjectConfigComponent(Composite comp) {
+ // create group
+ Group group = new Group(comp, SWT.None);
+ group.setText(Messages.LuaRemoteMainTab_projectgroup_title);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.swtDefaults().numColumns(2).applyTo(group);
+
+ // create project choice :
+ projectNameText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(projectNameText);
+ projectSelectionButton = new Button(group, SWT.PUSH);
+ projectSelectionButton.setText(Messages.LuaRemoteMainTab_projectgroup_browseprojectbutton);
+ final int browseButtonHorizontalHint = SWTUtil.getButtonWidthHint(projectSelectionButton);
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.BEGINNING).hint(browseButtonHorizontalHint, SWT.DEFAULT).applyTo(projectSelectionButton);
+ }
+
+ /**
+ * create the composite used to configure the target information
+ */
+ private void createTargetConfigComponent(Composite comp) {
+ // create group
+ Group group = new Group(comp, SWT.None);
+ group.setText(Messages.LuaRemoteMainTab_targetgroup_title);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.swtDefaults().numColumns(2).applyTo(group);
+
+ // create target combo
+ Label hostLabel = new Label(group, SWT.None);
+ hostLabel.setText(Messages.LuaRemoteMainTab_targetgroup_hostlabel);
+ IHost selectfirstHost = null;
+ hostCombo = new SystemHostCombo(group, SWT.None, selectfirstHost, true, "files", false); //$NON-NLS-1$
+ final int newSystemHint = SWTUtil.getButtonWidthHint(hostCombo.getNewButton());
+ hostCombo.setButtonWidthHint(newSystemHint);
+
+ GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(hostCombo);
+
+ // create interpreter command :
+ // Label luacommandLabel = new Label(group, SWT.None);
+ // luacommandLabel.setText(Messages.LuaEmbeddedMainTab_targetgroup_luacommandlabel);
+ // luaCommandPathText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ // GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(luaCommandPathText);
+
+ // // create luapath
+ // Label luapathLabel = new Label(group, SWT.None);
+ // luapathLabel.setText(Messages.LuaEmbeddedMainTab_targetgroup_luapathlabel);
+ // luapathText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ // GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(luapathText);
+ //
+ // // create luacpath
+ // Label luacpathLabel = new Label(group, SWT.None);
+ // luacpathLabel.setText(Messages.LuaEmbeddedMainTab_targetgroup_luacpathlabel);
+ // luacpathText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ // GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(luacpathText);
+
+ // create remote path
+ // Label ramoteApplicationPathLabel = new Label(group, SWT.None);
+ // ramoteApplicationPathLabel.setText(Messages.LuaEmbeddedMainTab_targetgroup_remoteapppathlabel);
+ // remoteApplicationPathText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ // GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(remoteApplicationPathText);
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+ */
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ // TODO : get project of selected resource
+ configuration.setAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
+
+ // get first available target
+ // IHost[] hosts = RSECorePlugin.getTheSystemRegistry().getHosts();
+ // if (hosts.length > 0) {
+ // LuaRemoteLaunchConfigurationUtil.setConnectionId(configuration, hosts[0]);
+ // }
+
+ // TODO integrate UI, see org.eclipse.dltk.debug.ui.launchConfigurations.ScriptLaunchConfigurationTab
+ configuration.setAttribute(ScriptLaunchConfigurationConstants.ENABLE_DBGP_LOGGING, false);
+ }
+
+ /**
+ * add listeners to be aware of tab modification (to update dialog buttons)
+ */
+ private void addListeners() {
+ if (!projectNameText.isListening(SWT.Modify))
+ projectNameText.addModifyListener(textModifyListener);
+ if (!projectSelectionButton.isListening(SWT.Selection))
+ projectSelectionButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectLuaEmbeddedProject();
+ }
+ });
+ // if (!luapathText.isListening(SWT.Modify))
+ // luapathText.addModifyListener(textModifyListener);
+ // if (!luacpathText.isListening(SWT.Modify))
+ // luacpathText.addModifyListener(textModifyListener);
+ if (!hostCombo.isListening(SWT.Selection))
+ hostCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ String projectName = configuration.getAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
+ if (!projectName.equals(projectNameText.getText()))
+ projectNameText.setText(projectName);
+ IHost host = LuaRemoteLaunchConfigurationUtil.getHost(configuration);
+ if (hostCombo.getHost() != host)
+ hostCombo.select(host);
+ addListeners();
+ } catch (CoreException e) {
+ Activator.logError("Launch Configuration main tab for lua embedded failed at initialization", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+ */
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ // Save attributes
+ configuration.setAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectNameText.getText());
+ IHost host = hostCombo.getHost();
+ if (host != null)
+ LuaRemoteLaunchConfigurationUtil.setConnectionId(configuration, hostCombo.getHost());
+ else
+ configuration.removeAttribute(LuaRemoteDebugConstant.HOST_ID);
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+ */
+ @Override
+ public String getName() {
+ return Messages.LuaRemoteMainTab_tabname;
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage()
+ */
+ @Override
+ public Image getImage() {
+ return Activator.getDefault().getImageRegistry().get(ImageConstants.LUA_REMOTE_APP_LAUNCH_MAIN_TAB_ICON);
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ @Override
+ public boolean isValid(ILaunchConfiguration configuration) {
+ // try {
+ // String projectName = configuration.getAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, "");//$NON-NLS-1$
+ // IHost host = LuaRemoteLaunchConfigurationUtil.getHost(configuration);
+ // return innerIsValuesValid(projectName, host, luacommandpath, remoteapplicationpath);
+ // return false;
+ // } catch (CoreException e) {
+ // Activator.logError("Launch Configuration main tab for lua embedded failed at validation", e); //$NON-NLS-1$
+ // return false;
+ // }
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#canSave()
+ */
+ @Override
+ public boolean canSave() {
+ String projectName = projectNameText.getText();
+ IHost host = hostCombo.getHost();
+ return innerIsValuesValid(projectName, host);
+ }
+
+ /**
+ * internal method to validate the value of the current tab
+ *
+ * @param luaInspectorPort
+ *
+ * @return true if value is valid
+ */
+ private boolean innerIsValuesValid(String projectName, IHost host) {
+ String error = LuaRemoteLaunchConfigurationUtil.validateLuaEmbeddedConfiguration(projectName, host);
+ setErrorMessage(error);
+ return error == null;
+ }
+
+ /**
+ * Open project selection dialog
+ */
+ private void selectLuaEmbeddedProject() {
+ String currentProjectName = projectNameText.getText();
+ IProject selectedProject = LuaDialogUtil.openSelectLuaProjectDialog(getShell(), projectNameText.getText());
+ if (selectedProject != null && !selectedProject.getName().equals(currentProjectName))
+ projectNameText.setText(selectedProject.getName());
+ }
+
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationTabGroup.java b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationTabGroup.java
new file mode 100644
index 0000000..d187caa
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/LuaRemoteLaunchConfigurationTabGroup.java
@@ -0,0 +1,23 @@
+package org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+
+public class LuaRemoteLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
+
+ public LuaRemoteLaunchConfigurationTabGroup() {
+ }
+
+ @Override
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[3];
+ tabs[0] = new LuaRemoteLaunchConfigurationMainTab();
+ tabs[1] = new EnvironmentTab();
+ tabs[2] = new CommonTab();
+ setTabs(tabs);
+ }
+
+}
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/Messages.java b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/Messages.java
new file mode 100644
index 0000000..e64c410
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/Messages.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab;
+
+import org.eclipse.osgi.util.NLS;
+
+//CHECKSTYLE NLS: OFF
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.koneki.ldt.remote.debug.ui.internal.launch.tab.messages"; //$NON-NLS-1$
+ public static String LuaRemoteMainTab_projectgroup_browseprojectbutton;
+ public static String LuaRemoteMainTab_projectgroup_title;
+ public static String LuaRemoteMainTab_tabname;
+ public static String LuaRemoteMainTab_targetgroup_hostlabel;
+ public static String LuaRemoteMainTab_targetgroup_title;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
+// CHECKSTYLE NLS: ON
diff --git a/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/messages.properties b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/messages.properties
new file mode 100644
index 0000000..bfe51b4
--- /dev/null
+++ b/plugins/org.eclipse.koneki.ldt.remote.debug.ui/src/org/eclipse/koneki/ldt/remote/debug/ui/internal/launch/tab/messages.properties
@@ -0,0 +1,5 @@
+LuaRemoteMainTab_projectgroup_browseprojectbutton=Bro&wse...
+LuaRemoteMainTab_projectgroup_title=Project :
+LuaRemoteMainTab_tabname=Main
+LuaRemoteMainTab_targetgroup_hostlabel=Host :
+LuaRemoteMainTab_targetgroup_title=Target Settings :