aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Ashford2012-02-01 21:16:48 (EST)
committerOtavio Pontes2012-06-01 14:58:45 (EDT)
commit8ed47c6da14a8ba3f6f996b11b7137e7c66c1b1a (patch)
tree215380a807dfc12c27dcc49356c49d630e9a2075
parent2c328b65154d937beec84464de782a8661a208cb (diff)
downloadorg.eclipse.linuxtools-8ed47c6da14a8ba3f6f996b11b7137e7c66c1b1a.zip
org.eclipse.linuxtools-8ed47c6da14a8ba3f6f996b11b7137e7c66c1b1a.tar.gz
org.eclipse.linuxtools-8ed47c6da14a8ba3f6f996b11b7137e7c66c1b1a.tar.bz2
Reimplement the RemoteConnection class in terms of the RemoteProxy
This version of RemoteConnection is a re-write and re-envision of the RemoteConnection package that's in org.eclipse.linuxtools.profiling.launch.remote plugin. I intend for this class to be the only mechanism used for connecting with the target machine (whether it's local or remote), so there is no longer a need for a separate .remote plugin. The RemoteConnection class and related classes have been moved from the .remote plugin to org.eclipse.linuxtools.profiling.launch, and are now based upon IRemoteProxyManager, IRemoteCommandLauncher, and IRemoteFileProxy. The RemoteConnection class is basically now just a convenience class on top of the above facilities, and is intended to make the job of writing launchers a little easier. We can add more methods over time as we find the need. Signed-off-by: Corey Ashford <cjashfor@linux.vnet.ibm.com>
-rw-r--r--profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/ProfileLaunchPlugin.java50
-rw-r--r--profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnection.java308
-rw-r--r--profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnectionException.java26
-rw-r--r--profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteMessages.java26
-rw-r--r--profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/remoteMessages.properties12
5 files changed, 422 insertions, 0 deletions
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/ProfileLaunchPlugin.java b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/ProfileLaunchPlugin.java
index 6f09a80..b4d745e 100644
--- a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/ProfileLaunchPlugin.java
+++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/internal/profiling/launch/ProfileLaunchPlugin.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.linuxtools.internal.profiling.launch;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@@ -21,6 +23,8 @@ public class ProfileLaunchPlugin extends AbstractUIPlugin {
// The shared instance
private static ProfileLaunchPlugin plugin;
+ private static Shell debugDialogShell;
+
/**
* The constructor
@@ -28,6 +32,19 @@ public class ProfileLaunchPlugin extends AbstractUIPlugin {
public ProfileLaunchPlugin() {
}
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() == null) {
+ // If the default instance is not yet initialized,
+ // return a static identifier. This identifier must
+ // match the plugin id defined in plugin.xml
+ return PLUGIN_ID;
+ }
+ return getDefault().getBundle().getSymbolicName();
+ }
+
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
@@ -46,6 +63,10 @@ public class ProfileLaunchPlugin extends AbstractUIPlugin {
super.stop(context);
}
+ public static void setDialogShell(Shell shell) {
+ debugDialogShell = shell;
+ }
+
/**
* Returns the shared instance
*
@@ -59,4 +80,33 @@ public class ProfileLaunchPlugin extends AbstractUIPlugin {
return getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
}
+ /**
+ * Logs the specified status with this plug-in's log.
+ *
+ * @param status
+ * status to log
+ */
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+ /**
+ * Logs an internal error with the specified message.
+ *
+ * @param message
+ * the error message to log
+ */
+ public static void logErrorMessage(String message) {
+ log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
+ }
+
+ /**
+ * Logs an internal error with the specified throwable
+ *
+ * @param e
+ * the exception to be logged
+ */
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e));
+ }
+
}
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnection.java b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnection.java
new file mode 100644
index 0000000..b0540d7
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnection.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM corporation
+ * 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:
+ * IBM Corp. - Initial implementation.
+ *******************************************************************************/
+package org.eclipse.linuxtools.profiling.launch;
+
+import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.IFileSystem;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
+
+/**
+ * This package layers on top of the IRemoteProxyManager and its related classes.
+ * It provides some convenient methods that can be used for writing launcher tabs and
+ * launch delegates.
+ *
+ * @author Corey Ashford
+ *
+ */
+public class RemoteConnection {
+
+ private IRemoteProxyManager rmtProxyMgr;
+ private IRemoteCommandLauncher rmtCmdLauncher;
+ private IRemoteFileProxy rmtFileProxy;
+
+ public RemoteConnection(URI uri)
+ throws RemoteConnectionException {
+ try {
+ rmtProxyMgr = RemoteProxyManager.getInstance();
+ rmtCmdLauncher = rmtProxyMgr.getLauncher(uri);
+ rmtFileProxy = rmtProxyMgr.getFileProxy(uri);
+ } catch (CoreException e) {
+ throw new RemoteConnectionException(
+ RemoteMessages.RemoteConnection_failed, e);
+ }
+ }
+
+ /**
+ * Copy a data from a path (can be a file or directory) from the remote host
+ * to the local host.
+ *
+ * @param remotePath
+ * @param localPath
+ * @throws CoreException
+ */
+ private void copyFileFromRemoteHost(String remotePath, String localPath,
+ IProgressMonitor monitor)
+ throws CoreException {
+ SubMonitor progress = SubMonitor.convert(monitor, 15);
+ try {
+ IFileSystem localFS = EFS.getLocalFileSystem();
+ IFileStore localFile = localFS.getStore(Path.fromOSString(localPath));
+ IFileStore rmtFile = rmtFileProxy.getResource(remotePath);
+ rmtFile.copy(localFile, EFS.OVERWRITE, progress);
+ } finally {
+ if (monitor != null) {
+ monitor.done();
+ }
+ }
+ }
+
+ /***
+ * Upload files to remote target directory. This method is recursive. If a
+ * local directory is specified as the input, then all folders and files are
+ * uploaded to the remote target directory. The remote target directory must
+ * exist prior to calling this method or else failure will occur.
+ *
+ * A RemoteConnectionException is thrown on any failure condition.
+ *
+ * @param localPath
+ * - the local path to file
+ * @param remotePath
+ * - the remote path
+ * @param monitor
+ * - progress monitor
+ * @throws RemoteConnectionException
+ */
+ public void upload(IPath localPath, IPath remotePath,
+ IProgressMonitor monitor) throws RemoteConnectionException {
+ try {
+ copyFileToRemoteHost(localPath.toOSString(),
+ remotePath.toOSString(), monitor);
+ } catch (CoreException e) {
+ throw new RemoteConnectionException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * Create a folder on the remote system. A RemoteConnectionException is
+ * thrown if any failure occurs.
+ *
+ * @param remoteFolderPath
+ * - path of the remote folder to create
+ * @param monitor
+ * - progress monitor
+ * @throws RemoteConnectionException
+ */
+ public void createFolder(IPath remoteFolderPath, IProgressMonitor monitor)
+ throws RemoteConnectionException {
+ IFileStore remoteFolder = rmtFileProxy.getResource(remoteFolderPath.toString());
+ try {
+ remoteFolder.mkdir(0, new NullProgressMonitor());
+ } catch (CoreException e) {
+ throw new RemoteConnectionException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * Break up a buffer from ConsoleOutputStream and return it as an array
+ * of lines
+ * @param buffer typically from ConsoleOutputStream object's readBuffer() method
+ * @return array of lines as Strings with no line terminators
+ */
+ public static String[] getLines(String buffer) /* throws RemoteConnectionException */ {
+ // Count the number of newlines in the buffer.
+ int numLines = 0;
+
+ for (char c : buffer.toCharArray()) {
+ if (c == '\n') {
+ numLines++;
+ }
+ }
+ String lines[] = new String[numLines];
+
+ int line = 0;
+ int startOfString = 0;
+ for (int endOfString = 0; endOfString < buffer.length(); endOfString++) {
+ if (buffer.charAt(endOfString) == '\n') {
+ lines[line++] = new String(buffer.toCharArray(), startOfString, endOfString
+ - startOfString);
+ startOfString = endOfString + 1;
+ }
+ }
+ return lines;
+ }
+
+ /**
+ * Remote delete function. This method is recursive. If a remote directory
+ * is specified, the remote directory and all its contents are removed. A
+ * RemoteConnectionException is thrown if failure occurs for any reason.
+ *
+ * @param remotePath
+ * - the remote path of the file or folder to be deleted
+ * @param monitor
+ * - progress monitor
+ * @throws RemoteConnectionException
+ */
+ public void delete(IPath remotePath, IProgressMonitor monitor)
+ throws RemoteConnectionException {
+ try {
+ IFileStore remoteFile = rmtFileProxy.getResource(
+ remotePath.toString());
+ remoteFile.delete(0, monitor);
+ } catch (CoreException e) {
+ throw new RemoteConnectionException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * Download a file or folder from a remote system. The method is recursive.
+ * If a remote folder is specified, all the contents of the folder are
+ * downloaded, including folders, and placed under the directory specified
+ * by the localPath variable. It is assumed that any remote non-binary file
+ * is UTF-8. A RemoteConnectionException is thrown if any failure occurs.
+ *
+ * @param remotePath
+ * - path to remote file or folder
+ * @param localPath
+ * - local directory target
+ * @param monitor
+ * - progress monitor
+ * @throws RemoteConnectionExcseption
+ */
+ public void download(IPath remotePath, IPath localPath,
+ IProgressMonitor monitor) throws RemoteConnectionException {
+ try {
+ copyFileFromRemoteHost(remotePath.toString(), localPath.toString(),
+ monitor);
+ } catch (CoreException e) {
+ throw new RemoteConnectionException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ private void copyFileToRemoteHost(String localPath, String remotePath,
+ IProgressMonitor monitor) throws CoreException {
+ SubMonitor progress = SubMonitor.convert(monitor, 15);
+ try {
+ IFileSystem localFS = EFS.getLocalFileSystem();
+ IFileStore localFile = localFS.getStore(Path.fromOSString(localPath));
+ IFileStore rmtFile = rmtFileProxy.getResource(remotePath);
+ localFile.copy(rmtFile, EFS.OVERWRITE, progress);
+ } finally {
+ if (monitor != null) {
+ monitor.done();
+ }
+ }
+ }
+
+ private static final String ENV_CMD = "/bin/env"; //$NON-NLS-1$
+ private static final String WHICH_CMD = "which"; //$NON-NLS-1$
+ private static final String PATH_ENV_VAR = "PATH"; //$NON-NLS-1$
+ private static final String SEPARATOR = ":"; //$NON-NLS-1$
+
+ /**
+ * Returns the current environment from the remote host. This method returns
+ * the environment variables as a map to make lookups and replacements simpler.
+ * @return Map&lt;String,String&gt; with the environment variable names as keys.
+ * @throws CoreException
+ */
+ public Map<String,String> getEnv() throws CoreException {
+ IPath envPath = Path.fromOSString(ENV_CMD);
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+ String empty[] = new String[0];
+
+ rmtCmdLauncher.execute(envPath, empty, empty, null, new NullProgressMonitor());
+ rmtCmdLauncher.waitAndRead(stdout, stderr, new NullProgressMonitor());
+ Map<String,String> env = new HashMap<String, String>();
+ String envLines[] = getLines(stdout.toString());
+ // Skip the first line, which is just env command being issued
+ for (int idx = 1; idx < envLines.length; idx++) {
+ String keyAndVal[] = envLines[idx].split("=", 2);
+ // If there's a full "<env_var>=<value>|<null>" expression, add this var to the map
+ // Note: <value> may be an empty string.
+ if (keyAndVal.length == 2)
+ env.put(keyAndVal[0], keyAndVal[1]);
+ else if (keyAndVal.length == 1)
+ env.put(keyAndVal[0], null);
+ }
+ return env;
+ }
+
+ /**
+ * Translates an environment variable map back into an array usable by
+ * IRemoteCommandLauncher.execute().
+ * @param envMap environment variable map
+ * @return array of Strings usable in IRemoteCommandLauncher.execute()
+ */
+ public static String[] envMapToEnvArray(Map<String, String> envMap) {
+ String envArray[] = new String[envMap.size()];
+ int idx = 0;
+ for (String key : envMap.keySet()) {
+ envArray[idx++] = key + "=" + envMap.get(key);
+ }
+ return envArray;
+ }
+
+ /**
+ * Run 'which <b>command</b>' on the remote machine to find where the executable resides.
+ * Prepend the $PATH variable with the value of <b>toolsPath</b> so that <i>which</i> may find a
+ * particular version of the command, if it exists.
+ * @param command the command or tool to locate on the remote system
+ * @param toolsPath contains one or more colon-separated paths in which to search for
+ * for the command, in addition to the default locations in $PATH.
+ * @return location of command, if found.
+ * @throws CoreException
+ */
+ public IPath whichCommand(String command, String toolsPath) throws CoreException {
+ String args[] = new String[1];
+ Map<String,String> envMap = getEnv();
+
+ IPath whichPath = Path.fromOSString(WHICH_CMD);
+ args[0] = command;
+
+ if (envMap.containsKey(PATH_ENV_VAR)) {
+ String pathVal = envMap.get(PATH_ENV_VAR);
+ envMap.put(PATH_ENV_VAR, toolsPath + SEPARATOR + pathVal);
+ } else {
+ envMap.put(PATH_ENV_VAR, toolsPath);
+ }
+ String envArray[] = envMapToEnvArray(envMap);
+
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+
+ rmtCmdLauncher.execute(whichPath, args, envArray, null, new NullProgressMonitor());
+ rmtCmdLauncher.waitAndRead(stdout, stderr, new NullProgressMonitor());
+ String outputLines[] = getLines(stdout.toString());
+ // The first line of the read buffer is the command that was executed, in this case
+ // "which <command>", so use the second line, index=1
+ return Path.fromOSString(outputLines[1]);
+ }
+
+ public IRemoteCommandLauncher getRmtCmdLauncher() {
+ return rmtCmdLauncher;
+ }
+
+ public IRemoteFileProxy getRmtFileProxy() {
+ return rmtFileProxy;
+ }
+
+}
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnectionException.java b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnectionException.java
new file mode 100644
index 0000000..c51fb9f
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteConnectionException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat Inc.
+ * 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:
+ * Red Hat Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.profiling.launch;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Status;
+
+import org.eclipse.linuxtools.internal.profiling.launch.ProfileLaunchPlugin;
+
+public class RemoteConnectionException extends CoreException {
+
+ private static final long serialVersionUID = 1L;
+
+ public RemoteConnectionException(String message, Throwable t) {
+ super(new Status(Status.ERROR, ProfileLaunchPlugin.PLUGIN_ID, message, t));
+ }
+
+}
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteMessages.java b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteMessages.java
new file mode 100644
index 0000000..53d9f76
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/RemoteMessages.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Elliott Baron
+ * 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:
+ * Elliott Baron <ebaron@fedoraproject.org> - initial API and implementation
+ * Red Hat Inc. - modified to be shared by remote tools
+ *******************************************************************************/
+package org.eclipse.linuxtools.profiling.launch;
+
+import org.eclipse.osgi.util.NLS;
+
+public class RemoteMessages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.profiling.launch.remoteMessages"; //$NON-NLS-1$
+ public static String RemoteConnection_failed;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, RemoteMessages.class);
+ }
+
+ private RemoteMessages() {
+ }
+}
diff --git a/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/remoteMessages.properties b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/remoteMessages.properties
new file mode 100644
index 0000000..f5be144
--- /dev/null
+++ b/profiling/org.eclipse.linuxtools.profiling.launch/src/org/eclipse/linuxtools/profiling/launch/remoteMessages.properties
@@ -0,0 +1,12 @@
+#*******************************************************************************
+# * Copyright (c) 2011 Red Hat Inc.
+# * 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:
+# * Red Hat Inc. - Initial implementation
+# * IBM Corp. - reduced the messages needed by using the PTP code.
+# *******************************************************************************/
+RemoteConnection_failed=Failed to connect to remote system.