Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.tcf.rse/src')
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Activator.java67
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFService.java25
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSessionProvider.java29
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSubSystem.java21
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.java149
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.properties137
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorService.java390
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorServiceManager.java45
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFRSETask.java69
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileAdapter.java37
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileResource.java147
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileService.java805
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileSubSystemConfiguration.java135
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFRemoteFile.java67
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessAdapter.java43
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessResource.java378
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessService.java258
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessSubSystemConfiguration.java60
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFRemoteProcess.java35
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewProcessAdapterFactory.java50
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewRemoteProcessAdapter.java502
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFServiceCommandShell.java206
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFShellSubSystemConfiguration.java79
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalInputStream.java140
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalOutputStream.java105
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalShell.java444
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalService.java58
-rw-r--r--plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalServiceSubSystemConfiguration.java67
28 files changed, 4548 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Activator.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Activator.java
new file mode 100644
index 000000000..794836daa
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Activator.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.tm.tcf.rse"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ public ImageDescriptor getImageDescriptorFromPath(String path) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFService.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFService.java
new file mode 100644
index 000000000..79f1e4624
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFService.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Adapted from org.eclipse.rse.internal.services.ssh.ISshService
+ * Copyright (c) 2006, 2010 Wind River Systems, 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:
+ * Martin Oberhuber (Wind River) - initial API and implementation
+ * Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH
+ * Intel Corporation - [329654] Make all sub services operate against TCF connector service
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+/**
+ * Markup Interface for services using the TCFConnectorService.
+ *
+ * By implementing this interface, services can be recognized
+ * as operating against an TCFConnectorService. The interface
+ * is used as the key in a table for looking up the connector
+ * service when needed.
+ */
+public interface ITCFService {
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSessionProvider.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSessionProvider.java
new file mode 100644
index 000000000..a39e892c2
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSessionProvider.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Intel Corporation. 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:
+ * Intel Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.tm.internal.tcf.rse;
+
+import org.eclipse.rse.services.files.RemoteFileException;
+import org.eclipse.tm.tcf.protocol.IChannel;
+
+public interface ITCFSessionProvider {
+ public static final int ERROR_CODE = 100; // filed error code
+ public static final int SUCCESS_CODE = 150; // login pass code
+ public static final int CONNECT_CLOSED = 200; // code for end of login attempts
+ public static final int TCP_CONNECT_TIMEOUT = 10; //seconds - TODO: Make configurable
+
+ public IChannel getChannel();
+ public String getSessionUserId();
+ public String getSessionPassword();
+ public String getSessionHostName();
+ public boolean isSubscribed();
+ public void subscribe() throws RemoteFileException;
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSubSystem.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSubSystem.java
new file mode 100644
index 000000000..30bc23f90
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/ITCFSubSystem.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import org.eclipse.rse.core.subsystems.ISubSystem;
+
+/**
+ * Subsystem can implement this interface to indicate that it can share TCF connection with
+ * other subsystems on same host.
+ */
+public interface ITCFSubSystem extends ISubSystem {
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.java
new file mode 100644
index 000000000..2ea0c0645
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Intel Corp. - Add TCF Connection Descriptions and File System Style
+ * Liping Ke(Intel Corp.) - Add TCF Terminal/Shell Services Descriptions
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ public static String SysMonitor_AllProcesses;
+ public static String SysMonitor_Process;
+
+ // PROCESS PROPERTIES
+ public static String PROCESS_ID_LABEL;
+ public static String PROCESS_PID_LABEL;
+ public static String PROCESS_NAME_LABEL;
+ public static String PROCESS_CWD_LABEL;
+ public static String PROCESS_ROOT_LABEL;
+ public static String PROCESS_UID_LABEL;
+ public static String PROCESS_USERNAME_LABEL;
+ public static String PROCESS_GID_LABEL;
+ public static String PROCESS_GROUPNAME_LABEL;
+ public static String PROCESS_PPID_LABEL;
+ public static String PROCESS_PGRP_LABEL;
+ public static String PROCESS_STATE_LABEL;
+ public static String PROCESS_TRACERPID_LABEL;
+ public static String PROCESS_VMSIZE_LABEL;
+ public static String PROCESS_VMRSS_LABEL;
+ public static String PROCESS_SESSION_LABEL;
+ public static String PROCESS_TTY_LABEL;
+ public static String PROCESS_TGID_LABEL;
+ public static String PROCESS_FLAGS_LABEL;
+ public static String PROCESS_MINFLT_LABEL;
+ public static String PROCESS_CMINFLT_LABEL;
+ public static String PROCESS_MAJFLT_LABEL;
+ public static String PROCESS_CMAJFLT_LABEL;
+ public static String PROCESS_UTIME_LABEL;
+ public static String PROCESS_STIME_LABEL;
+ public static String PROCESS_CUTIME_LABEL;
+ public static String PROCESS_CSTIME_LABEL;
+ public static String PROCESS_PC_UTIME_LABEL;
+ public static String PROCESS_PC_STIME_LABEL;
+ public static String PROCESS_PRIORITY_LABEL;
+ public static String PROCESS_NICE_LABEL;
+ public static String PROCESS_ITREALVALUE_LABEL;
+ public static String PROCESS_STARTTIME_LABEL;
+ public static String PROCESS_RLIMIT_LABEL;
+ public static String PROCESS_CODESTART_LABEL;
+ public static String PROCESS_CODEEND_LABEL;
+ public static String PROCESS_STACKSTART_LABEL;
+ public static String PROCESS_SIGNALS_LABEL;
+ public static String PROCESS_SIGBLOCK_LABEL;
+ public static String PROCESS_SIGIGNORE_LABEL;
+ public static String PROCESS_SIGCATCH_LABEL;
+ public static String PROCESS_WCHAN_LABEL;
+ public static String PROCESS_NSWAP_LABEL;
+ public static String PROCESS_CNSWAP_LABEL;
+ public static String PROCESS_EXITSIGNAL_LABEL;
+ public static String PROCESS_PROCESSOR_LABEL;
+ public static String PROCESS_RTPRIORITY_LABEL;
+ public static String PROCESS_POLICY_LABEL;
+
+ public static String PROCESS_ID_TOOLTIP;
+ public static String PROCESS_PID_TOOLTIP;
+ public static String PROCESS_NAME_TOOLTIP;
+ public static String PROCESS_CWD_TOOLTIP;
+ public static String PROCESS_ROOT_TOOLTIP;
+ public static String PROCESS_UID_TOOLTIP;
+ public static String PROCESS_USERNAME_TOOLTIP;
+ public static String PROCESS_GID_TOOLTIP;
+ public static String PROCESS_GROUPNAME_TOOLTIP;
+ public static String PROCESS_PPID_TOOLTIP;
+ public static String PROCESS_PGRP_TOOLTIP;
+ public static String PROCESS_STATE_TOOLTIP;
+ public static String PROCESS_TRACERPID_TOOLTIP;
+ public static String PROCESS_VMSIZE_TOOLTIP;
+ public static String PROCESS_VMRSS_TOOLTIP;
+ public static String PROCESS_SESSION_TOOLTIP;
+ public static String PROCESS_TTY_TOOLTIP;
+ public static String PROCESS_TGID_TOOLTIP;
+ public static String PROCESS_FLAGS_TOOLTIP;
+ public static String PROCESS_MINFLT_TOOLTIP;
+ public static String PROCESS_CMINFLT_TOOLTIP;
+ public static String PROCESS_MAJFLT_TOOLTIP;
+ public static String PROCESS_CMAJFLT_TOOLTIP;
+ public static String PROCESS_UTIME_TOOLTIP;
+ public static String PROCESS_STIME_TOOLTIP;
+ public static String PROCESS_PC_UTIME_TOOLTIP;
+ public static String PROCESS_PC_STIME_TOOLTIP;
+ public static String PROCESS_CUTIME_TOOLTIP;
+ public static String PROCESS_CSTIME_TOOLTIP;
+ public static String PROCESS_PRIORITY_TOOLTIP;
+ public static String PROCESS_NICE_TOOLTIP;
+ public static String PROCESS_ITREALVALUE_TOOLTIP;
+ public static String PROCESS_STARTTIME_TOOLTIP;
+ public static String PROCESS_RLIMIT_TOOLTIP;
+ public static String PROCESS_CODESTART_TOOLTIP;
+ public static String PROCESS_CODEEND_TOOLTIP;
+ public static String PROCESS_STACKSTART_TOOLTIP;
+ public static String PROCESS_SIGNALS_TOOLTIP;
+ public static String PROCESS_SIGBLOCK_TOOLTIP;
+ public static String PROCESS_SIGIGNORE_TOOLTIP;
+ public static String PROCESS_SIGCATCH_TOOLTIP;
+ public static String PROCESS_WCHAN_TOOLTIP;
+ public static String PROCESS_NSWAP_TOOLTIP;
+ public static String PROCESS_CNSWAP_TOOLTIP;
+ public static String PROCESS_EXITSIGNAL_TOOLTIP;
+ public static String PROCESS_PROCESSOR_TOOLTIP;
+ public static String PROCESS_RTPRIORITY_TOOLTIP;
+ public static String PROCESS_POLICY_TOOLTIP;
+
+ public static String PROCESS_VMSIZE_VALUE;
+ public static String PROCESS_VMRSS_VALUE;
+ public static String IS_UNIX_STYLE;
+
+ public static String TCFConnectorService_Name;
+ public static String TCFConnectorService_Description;
+ public static String TCFFileService_CopyingFiles;
+ public static String TCFFileService_DeletingFiles;
+ public static String TCFFileService_FileNotFoundMessage;
+ public static String TCFFileService_UserCancellation;
+ public static String TCFFileService_UserCancellation1;
+ public static String TCFFileService_UserDeleteCancellation;
+ public static String TCFFileService_UserDeleteCancellation1;
+ public static String PropertySet_Description;
+
+ public static String TCFPlugin_Unexpected_Exception;
+ public static String TCFTerminalService_Description;
+ public static String TCFTerminalService_Name;
+ public static String TCFShellService_Description;
+ public static String TCFShellService_Name;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(Messages.class.getName(), Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.properties b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.properties
new file mode 100644
index 000000000..fee3cc5f4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/Messages.properties
@@ -0,0 +1,137 @@
+################################################################################
+# Copyright (c) 2007, 2010 Wind River Systems, 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:
+# Wind River Systems - initial API and implementation
+# Intel Corp. - Add TCF Connection Descriptions and File System Style
+# Liping Ke(Intel Corp.) - Add TCF Terminal/shell service Descriptions
+################################################################################
+
+# NLS_MESSAGEFORMAT_VAR
+# NLS_ENCODING=UTF-8
+
+SysMonitor_AllProcesses=All Processes
+SysMonitor_Process=Process
+
+PROCESS_ID_LABEL=Context ID
+PROCESS_PID_LABEL=Process ID
+PROCESS_NAME_LABEL=Executable Name
+PROCESS_CWD_LABEL=CWD
+PROCESS_ROOT_LABEL=FS Root
+PROCESS_UID_LABEL=User ID
+PROCESS_USERNAME_LABEL=Username
+PROCESS_GID_LABEL=Group ID
+PROCESS_GROUPNAME_LABEL=Groupname
+PROCESS_PPID_LABEL=Parent PID
+PROCESS_PGRP_LABEL=Proucess Group
+PROCESS_STATE_LABEL=State
+PROCESS_TRACERPID_LABEL=Tracer PID
+PROCESS_VMSIZE_LABEL=VM Size
+PROCESS_VMRSS_LABEL=VM RSS
+PROCESS_SESSION_LABEL=Session
+PROCESS_TTY_LABEL=TTY
+PROCESS_TGID_LABEL=Task Group ID
+PROCESS_FLAGS_LABEL=Flags
+PROCESS_MINFLT_LABEL=Minor Faults
+PROCESS_CMINFLT_LABEL=Children Minor Faults
+PROCESS_MAJFLT_LABEL=Major Faults
+PROCESS_CMAJFLT_LABEL=Children Major Faults
+PROCESS_UTIME_LABEL=User Time
+PROCESS_STIME_LABEL=System Time
+PROCESS_CUTIME_LABEL=Children User Time
+PROCESS_CSTIME_LABEL=Children System Time
+PROCESS_PC_UTIME_LABEL=% User Time
+PROCESS_PC_STIME_LABEL=% System Time
+PROCESS_PRIORITY_LABEL=Priority
+PROCESS_NICE_LABEL=Nice
+PROCESS_ITREALVALUE_LABEL=Interval Timer
+PROCESS_STARTTIME_LABEL=Start Time
+PROCESS_RLIMIT_LABEL=RSS Limit
+PROCESS_CODESTART_LABEL=Code Start
+PROCESS_CODEEND_LABEL=Code End
+PROCESS_STACKSTART_LABEL=Stack Start
+PROCESS_SIGNALS_LABEL=Pending Signals
+PROCESS_SIGBLOCK_LABEL=Blocked Signals
+PROCESS_SIGIGNORE_LABEL=Ignored Signals
+PROCESS_SIGCATCH_LABEL=Caught Signals
+PROCESS_WCHAN_LABEL=Wait Channel
+PROCESS_NSWAP_LABEL=Swaped Pages
+PROCESS_CNSWAP_LABEL=Children Swapped Pages
+PROCESS_EXITSIGNAL_LABEL=Exit Signal
+PROCESS_PROCESSOR_LABEL=Processor
+PROCESS_RTPRIORITY_LABEL=Real Time Priority
+PROCESS_POLICY_LABEL=Scheduling Policy
+
+PROCESS_ID_TOOLTIP=TCF context ID of the process
+PROCESS_PID_TOOLTIP=The system ID number of the process
+PROCESS_NAME_TOOLTIP=The executable associated with the process
+PROCESS_CWD_TOOLTIP=Current working directory of the process
+PROCESS_ROOT_TOOLTIP=Current file system root of the process
+PROCESS_UID_TOOLTIP=The user ID of the owner of the process
+PROCESS_USERNAME_TOOLTIP=The username of the owner of the process
+PROCESS_GID_TOOLTIP=The group ID of the owner of the process
+PROCESS_GROUPNAME_TOOLTIP=The groupname of the owner of the process
+PROCESS_PPID_TOOLTIP=The process ID of the parent of the process
+PROCESS_PGRP_TOOLTIP=The process group ID
+PROCESS_STATE_TOOLTIP=The state in which the process currently is
+PROCESS_TRACERPID_TOOLTIP=The tracer process ID of the process
+PROCESS_VMSIZE_TOOLTIP=The amount of virtual memory taken up by this process
+PROCESS_VMRSS_TOOLTIP=The amount of virtual memory resident set size of this process (actual RAM taken up by the process)
+PROCESS_SESSION_TOOLTIP=The session ID of the process
+PROCESS_TTY_TOOLTIP=The TTY the process uses
+PROCESS_TGID_TOOLTIP=The task group to which process belongs
+PROCESS_FLAGS_TOOLTIP=The kernel flags word of the process.
+PROCESS_MINFLT_TOOLTIP=The number of minor faults the process has made which have not required loading a memory page from disk.
+PROCESS_CMINFLT_TOOLTIP=The number of minor faults that the process's waited-for children have made.
+PROCESS_MAJFLT_TOOLTIP=The number of major faults the process has made which have required loading a memory page from disk.
+PROCESS_CMAJFLT_TOOLTIP=Children Major Faults
+PROCESS_UTIME_TOOLTIP=User Time
+PROCESS_STIME_TOOLTIP=System Time
+PROCESS_CUTIME_TOOLTIP=Children User Time
+PROCESS_CSTIME_TOOLTIP=Children System Time
+PROCESS_PC_UTIME_TOOLTIP=% User Time
+PROCESS_PC_STIME_TOOLTIP=% System Time
+PROCESS_PRIORITY_TOOLTIP=Priority
+PROCESS_NICE_TOOLTIP=Nice
+PROCESS_ITREALVALUE_TOOLTIP=Interval Timer
+PROCESS_STARTTIME_TOOLTIP=Start Time
+PROCESS_RLIMIT_TOOLTIP=RSS Limit
+PROCESS_CODESTART_TOOLTIP=Code Start
+PROCESS_CODEEND_TOOLTIP=Code End
+PROCESS_STACKSTART_TOOLTIP=Stack Start
+PROCESS_SIGNALS_TOOLTIP=Pending Signals
+PROCESS_SIGBLOCK_TOOLTIP=Blocked Signals
+PROCESS_SIGIGNORE_TOOLTIP=Ignored Signals
+PROCESS_SIGCATCH_TOOLTIP=Caught Signals
+PROCESS_WCHAN_TOOLTIP=Wait Channel
+PROCESS_NSWAP_TOOLTIP=Swaped Pages
+PROCESS_CNSWAP_TOOLTIP=Children Swapped Pages
+PROCESS_EXITSIGNAL_TOOLTIP=Exit Signal
+PROCESS_PROCESSOR_TOOLTIP=Processor
+PROCESS_RTPRIORITY_TOOLTIP=Real Time Priority
+PROCESS_POLICY_TOOLTIP=Scheduling Policy
+
+TCFConnectorService_Name=TCF Connector Service
+TCFConnectorService_Description=Target Communication Framework
+TCFFileService_CopyingFiles=Copying remote files\!
+TCFFileService_DeletingFiles=Deleting selected folders or files\!
+TCFFileService_FileNotFoundMessage=Failed to find the file to be copied file or directory\!
+TCFFileService_UserCancellation=User cancelled the copy operation\!
+TCFFileService_UserCancellation1=User cancelled the copy operation\!
+TCFFileService_UserDeleteCancellation=User cancelled the delete operation\!
+TCFFileService_UserDeleteCancellation1=User cancelled the delete operation\!
+PropertySet_Description=TCF login properties. Set these according to your remote system's login prompts.
+
+TCFPlugin_Unexpected_Exception=Unexpected {0}: {1}
+TCFTerminalService_Name=TCF Terminal Service
+TCFTerminalService_Description=TCF Terminal Service Description
+TCFShellService_Name=TCF Shell Service
+TCFShellService_Description=TCF Shell Service Description
+
+PROCESS_VMSIZE_VALUE={0} KB
+PROCESS_VMRSS_VALUE={0} KB
+IS_UNIX_STYLE=true \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorService.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorService.java
new file mode 100644
index 000000000..905ca1563
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorService.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Martin Oberhuber (Wind River) - [269682] Get port from RSE Property
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Anna Dushistova (MontaVista) - [285373] TCFConnectorService should send CommunicationsEvent.BEFORE_CONNECT and CommunicationsEvent.BEFORE_DISCONNECT
+ * Liping Ke (Intel Corp.)- [326490] Add authentication to the TCF Connector Service and attach stream subs/unsubs method
+ * Jeff Johnston (RedHat) - [350752] TCFConnectorService doesn't recognize connections with SSL transport
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.core.model.IPropertySet;
+import org.eclipse.rse.core.model.PropertyType;
+import org.eclipse.rse.core.model.SystemSignonInformation;
+import org.eclipse.rse.core.subsystems.CommunicationsEvent;
+import org.eclipse.rse.services.files.RemoteFileException;
+import org.eclipse.rse.ui.subsystems.StandardConnectorService;
+import org.eclipse.tm.tcf.core.AbstractPeer;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IService;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IFileSystem;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.tcf.services.IStreams;
+import org.eclipse.tm.tcf.services.ISysMonitor;
+import org.eclipse.tm.tcf.services.ITerminals;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+
+public class TCFConnectorService extends StandardConnectorService implements ITCFSessionProvider{
+
+ public static final String PROPERTY_SET_NAME = "TCF Connection Settings"; //$NON-NLS-1$
+ public static final String PROPERTY_LOGIN_REQUIRED = "Login.Required"; //$NON-NLS-1$
+ public static final String PROPERTY_PWD_REQUIRED="Pwd.Required"; //$NON-NLS-1$
+ public static final String PROPERTY_LOGIN_PROMPT = "Login.Prompt"; //$NON-NLS-1$
+ public static final String PROPERTY_PASSWORD_PROMPT = "Password.Prompt"; //$NON-NLS-1$
+ public static final String PROPERTY_COMMAND_PROMPT = "Command.Prompt"; //$NON-NLS-1$
+
+ private IChannel channel;
+ private Throwable channel_error;
+ private final List<Runnable> wait_list = new ArrayList<Runnable>();
+
+ private boolean poll_timer_started;
+
+ private boolean bSubscribed = false;
+
+ /* subscribe the stream service on this TCP connection */
+ private IStreams.StreamsListener streamListener = new IStreams.StreamsListener() {
+ public void created(String stream_type, String stream_id,
+ String context_id) {
+ }
+ /**
+ * Called when a stream is disposed.
+ *
+ * @param stream_type
+ * - source type of the stream.
+ * @param stream_id
+ * - ID of the stream.
+ */
+ public void disposed(String stream_type, String stream_id) {
+ }
+ };
+
+
+ public TCFConnectorService(IHost host, int port) {
+ super(Messages.TCFConnectorService_Name,
+ Messages.TCFConnectorService_Description, host,
+ port);
+ getTCFPropertySet();
+ }
+
+ public IPropertySet getTCFPropertySet() {
+ IPropertySet tcfSet = getPropertySet(PROPERTY_SET_NAME);
+ if (tcfSet == null) {
+ tcfSet = createPropertySet(PROPERTY_SET_NAME, Messages.PropertySet_Description);
+ //add default values if not set
+ tcfSet.addProperty(PROPERTY_LOGIN_REQUIRED, "false", PropertyType.getEnumPropertyType(new String[] {"true", "false"})); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ tcfSet.addProperty(PROPERTY_PWD_REQUIRED, "false", PropertyType.getEnumPropertyType(new String[] {"true", "false"})); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ tcfSet.addProperty(PROPERTY_LOGIN_PROMPT, "ogin: ", PropertyType.getStringPropertyType()); //$NON-NLS-1$
+ tcfSet.addProperty(PROPERTY_PASSWORD_PROMPT, "assword: ", PropertyType.getStringPropertyType()); //$NON-NLS-1$
+ tcfSet.addProperty(PROPERTY_COMMAND_PROMPT, "#", PropertyType.getStringPropertyType()); //$NON-NLS-1$
+ }
+ return tcfSet;
+ }
+
+ /**
+ * @return true if the associated connector service requires a password.
+ */
+
+ public final boolean requiresPassword() {
+ return false;
+ }
+
+ @Override
+ protected void internalConnect(final IProgressMonitor monitor) throws Exception {
+ assert !Protocol.isDispatchThread();
+ final Exception[] res = new Exception[1];
+ // Fire comm event to signal state about to change
+ fireCommunicationsEvent(CommunicationsEvent.BEFORE_CONNECT);
+ monitor.beginTask("Connecting " + getHostName(), 1); //$NON-NLS-1$
+ synchronized (res) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (!connectTCFChannel(res, monitor))
+ add_to_wait_list(this);
+ }
+ });
+ res.wait();
+ }
+ if (res[0] != null) throw res[0];
+ monitor.done();
+ }
+
+ @Override
+ protected void internalDisconnect(final IProgressMonitor monitor)
+ throws Exception {
+ assert !Protocol.isDispatchThread();
+ final Exception[] res = new Exception[1];
+ // Fire comm event to signal state about to change
+ fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT);
+ monitor.beginTask("Disconnecting " + getHostName(), 1); //$NON-NLS-1$
+ try {
+ /* First UnSubscribe TCP channel */
+ unsubscribe();
+ /* Disconnecting TCP channel */
+ synchronized (res) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (!disconnectTCFChannel(res, monitor))
+ add_to_wait_list(this);
+ }
+ });
+ res.wait();
+ }
+ if (res[0] != null) throw res[0];
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new RemoteFileException("Error creating Terminal", e); //$NON-NLS-1$
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ public boolean isConnected() {
+ final boolean res[] = new boolean[1];
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ res[0] = channel != null && channel.getState() == IChannel.STATE_OPEN;
+ }
+ });
+ return res[0];
+ }
+
+ private void add_to_wait_list(Runnable cb) {
+ wait_list.add(cb);
+ if (poll_timer_started) return;
+ Protocol.invokeLater(1000, new Runnable() {
+ public void run() {
+ poll_timer_started = false;
+ run_wait_list();
+ }
+ });
+ poll_timer_started = true;
+ }
+
+ private void run_wait_list() {
+ if (wait_list.isEmpty()) return;
+ Runnable[] r = wait_list.toArray(new Runnable[wait_list.size()]);
+ wait_list.clear();
+ for (int i = 0; i < r.length; i++) r[i].run();
+ }
+
+ private boolean connectTCFChannel(Exception[] res, IProgressMonitor monitor) {
+ if (channel != null) {
+ switch (channel.getState()) {
+ case IChannel.STATE_OPEN:
+ case IChannel.STATE_CLOSED:
+ synchronized (res) {
+ if (channel_error instanceof Exception) res[0] = (Exception)channel_error;
+ else if (channel_error != null) res[0] = new Exception(channel_error);
+ else res[0] = null;
+ res.notify();
+ return true;
+ }
+ }
+ }
+ if (monitor.isCanceled()) {
+ synchronized (res) {
+ res[0] = new Exception("Canceled"); //$NON-NLS-1$
+ if (channel != null) channel.terminate(res[0]);
+ res.notify();
+ return true;
+ }
+ }
+ if (channel == null) {
+ String host = getHostName().toLowerCase();
+ int port = getConnectPort();
+ if (port <= 0) {
+ //Default fallback
+ port = TCFConnectorServiceManager.TCF_PORT;
+ }
+ IPeer peer = null;
+ String port_str = Integer.toString(port);
+ ILocator locator = Protocol.getLocator();
+ for (IPeer p : locator.getPeers().values()) {
+ Map<String, String> attrs = p.getAttributes();
+ if (("TCP".equals(attrs.get(IPeer.ATTR_TRANSPORT_NAME)) || //$NON-NLS-1$
+ "SSL".equals(attrs.get(IPeer.ATTR_TRANSPORT_NAME)))&& //$NON-NLS-1$
+ host.equalsIgnoreCase(attrs.get(IPeer.ATTR_IP_HOST)) &&
+ port_str.equals(attrs.get(IPeer.ATTR_IP_PORT))) {
+ peer = p;
+ break;
+ }
+ }
+ if (peer == null) {
+ Map<String, String> attrs = new HashMap<String, String>();
+ attrs.put(IPeer.ATTR_ID, "RSE:" + host + ":" + port_str); //$NON-NLS-1$ //$NON-NLS-2$
+ attrs.put(IPeer.ATTR_NAME, getName());
+ attrs.put(IPeer.ATTR_TRANSPORT_NAME, "TCP"); //$NON-NLS-1$
+ attrs.put(IPeer.ATTR_IP_HOST, host);
+ attrs.put(IPeer.ATTR_IP_PORT, port_str);
+ peer = new AbstractPeer(attrs);
+ }
+ channel = peer.openChannel();
+ channel.addChannelListener(new IChannel.IChannelListener() {
+
+ public void onChannelOpened() {
+ assert channel != null;
+ run_wait_list();
+ }
+
+ public void congestionLevel(int level) {
+ }
+
+ public void onChannelClosed(Throwable error) {
+ assert channel != null;
+ channel.removeChannelListener(this);
+ channel_error = error;
+ if (wait_list.isEmpty()) {
+ fireCommunicationsEvent(CommunicationsEvent.CONNECTION_ERROR);
+ }
+ else {
+ run_wait_list();
+ }
+ bSubscribed = false;
+ channel = null;
+ channel_error = null;
+ }
+
+ });
+ assert channel.getState() == IChannel.STATE_OPENING;
+ }
+ return false;
+ }
+
+ private boolean disconnectTCFChannel(Exception[] res, IProgressMonitor monitor) {
+ if (channel == null || channel.getState() == IChannel.STATE_CLOSED) {
+ synchronized (res) {
+ res[0] = null;
+ res.notify();
+ return true;
+ }
+ }
+ if (monitor.isCanceled()) {
+ synchronized (res) {
+ res[0] = new Exception("Canceled"); //$NON-NLS-1$
+ res.notify();
+ return true;
+ }
+ }
+ if (channel.getState() == IChannel.STATE_OPEN) channel.close();
+ return false;
+ }
+
+ public <V extends IService> V getService(Class<V> service_interface) {
+ if (channel == null || channel.getState() != IChannel.STATE_OPEN) throw new Error("Not connected"); //$NON-NLS-1$
+ V m = channel.getRemoteService(service_interface);
+ if (m == null) throw new Error("Remote peer does not support " + service_interface.getName() + " service"); //$NON-NLS-1$ //$NON-NLS-2$
+ return m;
+ }
+
+ public ISysMonitor getSysMonitorService() {
+ return getService(ISysMonitor.class);
+ }
+
+ public IFileSystem getFileSystemService() {
+ return getService(IFileSystem.class);
+ }
+
+ public IChannel getChannel() {
+ return channel;
+ }
+
+ public String getSessionHostName() {
+ String hostName = "";
+ IHost host = getHost();
+ if (host != null) hostName = host.getHostName();
+ return hostName;
+ }
+
+ public String getSessionUserId() {
+ return getUserId();
+ }
+
+ public String getSessionPassword() {
+ String password = "";
+ SystemSignonInformation ssi = getSignonInformation();
+ if (ssi != null) {
+ password = ssi.getPassword();
+ }
+ return password;
+ }
+
+ public boolean isSubscribed() {
+ return bSubscribed;
+ }
+
+ public void unsubscribe() throws IOException {
+ if (bSubscribed) {
+ new TCFTask<Object>() {
+ public void run() {
+ IStreams streams = getService(IStreams.class);
+ streams.unsubscribe(ITerminals.NAME, streamListener,
+ new IStreams.DoneUnsubscribe() {
+ public void doneUnsubscribe(IToken token,
+ Exception error) {
+ done(this);
+ }
+ });
+ }
+ }.getIO();
+ bSubscribed = false;
+ }
+
+ }
+
+ public void subscribe() throws RemoteFileException {
+ try {
+ new TCFTask<Object>() {
+ public void run() {
+ if (bSubscribed) {
+ done(this);
+ }
+ else {
+ bSubscribed = true;
+ IStreams streams = getService(IStreams.class);
+ streams.subscribe(ITerminals.NAME, streamListener,
+ new IStreams.DoneSubscribe() {
+ public void doneSubscribe(IToken token,
+ Exception error) {
+ if (error != null) {
+ bSubscribed = false;
+ error(error);
+ }
+ else
+ done(this);
+ }
+
+ });
+ }}
+ }.getIO();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();//$NON-NLS-1$
+ throw new RemoteFileException(
+ "Error When Subscribe Terminal streams!", e); //$NON-NLS-1$
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorServiceManager.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorServiceManager.java
new file mode 100644
index 000000000..25b423710
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFConnectorServiceManager.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.core.subsystems.AbstractConnectorServiceManager;
+import org.eclipse.rse.core.subsystems.IConnectorService;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+
+public class TCFConnectorServiceManager extends AbstractConnectorServiceManager {
+
+ public static int TCF_PORT = 1534;
+
+ private static final TCFConnectorServiceManager manager =
+ new TCFConnectorServiceManager();
+
+ @Override
+ public IConnectorService createConnectorService(IHost host) {
+ return new TCFConnectorService(host, TCF_PORT);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Class getSubSystemCommonInterface(ISubSystem subsystem) {
+ return ITCFSubSystem.class;
+ }
+
+ @Override
+ public boolean sharesSystem(ISubSystem otherSubSystem) {
+ return otherSubSystem instanceof ITCFSubSystem;
+ }
+
+ public static TCFConnectorServiceManager getInstance() {
+ return manager;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFRSETask.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFRSETask.java
new file mode 100644
index 000000000..4d5e5e154
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/TCFRSETask.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Martin Oberhuber (Wind River) - [238564] Adopt TM 3.0 APIs
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Uwe Stieber (Wind River) - [273572] SystemMessage contains exception class name instead of error message
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.ExecutionException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+public abstract class TCFRSETask<V> extends TCFTask<V> {
+
+ public V get(IProgressMonitor monitor, String task_name)
+ throws InterruptedException, ExecutionException {
+ monitor.beginTask(task_name, 1);
+ try {
+ return get();
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ public V getS(IProgressMonitor monitor, String task_name) throws SystemMessageException {
+ if (monitor != null) monitor.beginTask(task_name, 1);
+ try {
+ return get();
+ }
+ catch (Throwable e) {
+ if (e instanceof SystemMessageException) throw (SystemMessageException)e;
+ SystemMessage m = new SystemMessage("TCF", "C", "0001", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ SystemMessage.ERROR,
+ "TCF task aborted".equals(e.getMessage()) && e.getCause() != null ? e.getCause().getMessage() : e.getMessage(), //$NON-NLS-1$
+ ""); //$NON-NLS-1$
+ throw new SystemMessageException(m);
+ }
+ finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+
+ public V getI(IProgressMonitor monitor, String task_name) throws InvocationTargetException, InterruptedException {
+ if (monitor != null) monitor.beginTask(task_name, 1);
+ try {
+ return get();
+ }
+ catch (Throwable e) {
+ if (e instanceof InvocationTargetException) throw (InvocationTargetException)e;
+ if (e instanceof InterruptedException) throw (InterruptedException)e;
+ throw new InvocationTargetException(e);
+ }
+ finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileAdapter.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileAdapter.java
new file mode 100644
index 000000000..7e35849b1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileAdapter.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Martin Oberhuber (Wind River) - [238564] Adopt TM 3.0 APIs
+ ******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.files;
+
+import org.eclipse.rse.services.files.IHostFile;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.AbstractRemoteFile;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
+import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
+
+public class TCFFileAdapter implements IHostFileToRemoteFileAdapter {
+
+ public AbstractRemoteFile convertToRemoteFile(FileServiceSubSystem ss,
+ IRemoteFileContext ctx, IRemoteFile parent, IHostFile node) {
+ return new TCFRemoteFile(ss, ctx, parent, node);
+ }
+
+ public AbstractRemoteFile[] convertToRemoteFiles(FileServiceSubSystem ss,
+ IRemoteFileContext ctx, IRemoteFile parent, IHostFile[] nodes) {
+ if (nodes == null) return null;
+ TCFRemoteFile[] res = new TCFRemoteFile[nodes.length];
+ for (int i = 0; i < res.length; i++) {
+ res[i] = new TCFRemoteFile(ss, ctx, parent, nodes[i]);
+ }
+ return res;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileResource.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileResource.java
new file mode 100644
index 000000000..81a536172
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileResource.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Anna Dushistova (MontaVista) - [247164][tcf] a lot of file/directory properties are not supported
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.files;
+
+import org.eclipse.rse.core.subsystems.AbstractResource;
+import org.eclipse.rse.services.files.HostFilePermissions;
+import org.eclipse.rse.services.files.IHostFile;
+import org.eclipse.rse.services.files.IHostFilePermissions;
+import org.eclipse.rse.services.files.IHostFilePermissionsContainer;
+import org.eclipse.tm.tcf.services.IFileSystem;
+
+
+public class TCFFileResource extends AbstractResource implements IHostFile, IHostFilePermissionsContainer{
+
+ private final TCFFileService service;
+ private String parent;
+ private String name;
+ private final IFileSystem.FileAttrs attrs;
+ private final boolean root;
+ private IHostFilePermissions permissions;
+
+ public TCFFileResource(TCFFileService service, String parent, String name,
+ IFileSystem.FileAttrs attrs, boolean root) {
+ if (name == null) {
+ int i = parent.lastIndexOf('/');
+ if (i > 0) {
+ name = parent.substring(i + 1);
+ parent = parent.substring(0, i);
+ }
+ else if (i == 0) {
+ name = parent.substring(i + 1);
+ parent = "/"; //$NON-NLS-1$
+ }
+ else {
+ name = parent;
+ parent = null;
+ }
+ }
+ this.service = service;
+ this.parent = parent;
+ this.name = name;
+ this.attrs = attrs;
+ this.root = root;
+ if (attrs != null) this.permissions = new HostFilePermissions(
+ attrs.permissions, "" + attrs.uid, "" + attrs.gid); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private String toLocalPath(String path) {
+ if (path.length() > 1 && path.charAt(1) == ':') {
+ return path.replace('/', '\\');
+ }
+ else {
+ return path.replace('\\', '/');
+ }
+ }
+
+ public boolean canRead() {
+ return attrs != null && service.canRead(attrs);
+ }
+
+ public boolean canWrite() {
+ return attrs != null && service.canWrite(attrs);
+ }
+
+ public boolean exists() {
+ return attrs != null;
+ }
+
+ public synchronized String getAbsolutePath() {
+ if (root) return toLocalPath(name);
+ if (parent.endsWith("/")) return toLocalPath(parent + name); //$NON-NLS-1$
+ return toLocalPath(parent + '/' + name);
+ }
+
+ public long getModifiedDate() {
+ if (attrs == null) return 0;
+ if ((attrs.flags & IFileSystem.ATTR_ACMODTIME) == 0) return 0;
+ return attrs.mtime;
+ }
+
+ public synchronized String getName() {
+ return toLocalPath(name);
+ }
+
+ public synchronized String getParentPath() {
+ if (root) return null;
+ return toLocalPath(parent);
+ }
+
+ public long getSize() {
+ if (attrs == null) return 0;
+ if ((attrs.flags & IFileSystem.ATTR_SIZE) == 0) return 0;
+ return attrs.size;
+ }
+
+ public boolean isArchive() {
+ return false;
+ }
+
+ public boolean isDirectory() {
+ if (attrs == null) return false;
+ return attrs.isDirectory();
+ }
+
+ public boolean isFile() {
+ if (attrs == null) return false;
+ return attrs.isFile();
+ }
+
+ public synchronized boolean isHidden() {
+ return name.startsWith("."); //$NON-NLS-1$
+ }
+
+ public synchronized boolean isRoot() {
+ return root;
+ }
+
+ public synchronized void renameTo(String path) {
+ path = path.replace('\\', '/');
+ if (path.equals("/")) { //$NON-NLS-1$
+ parent = name = "/"; //$NON-NLS-1$
+ return;
+ }
+ assert !path.endsWith("/"); //$NON-NLS-1$
+ int i = path.lastIndexOf('/');
+ parent = path.substring(0, i);
+ name = path.substring(i + 1);
+ }
+
+ public IHostFilePermissions getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(IHostFilePermissions permissions) {
+ this.permissions = permissions;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileService.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileService.java
new file mode 100644
index 000000000..afaab224b
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileService.java
@@ -0,0 +1,805 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Martin Oberhuber (Wind River) - [238564] Adopt TM 3.0 APIs
+ * Uwe Stieber (Wind River) - [271224] NPE in TCFFileService#download
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Uwe Stieber (Wind River) - [274277] The TCF file service subsystem implementation is not updating the progress monitor
+ * Intel Corporation - [326489] Make recursive copy/delete available (delete/copy a folder contains files)
+ * Intel Corporation - [329654] Make all sub services operate against TCF connector service
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.files;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.services.clientserver.FileTypeMatcher;
+import org.eclipse.rse.services.clientserver.IMatcher;
+import org.eclipse.rse.services.clientserver.NamePatternMatcher;
+import org.eclipse.rse.services.clientserver.messages.SimpleSystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.clientserver.messages.SystemOperationFailedException;
+import org.eclipse.rse.services.files.AbstractFileService;
+import org.eclipse.rse.services.files.IHostFile;
+import org.eclipse.tm.internal.tcf.rse.Activator;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.Messages;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorServiceManager;
+import org.eclipse.tm.internal.tcf.rse.TCFRSETask;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IFileSystem;
+import org.eclipse.tm.tcf.services.IFileSystem.DirEntry;
+import org.eclipse.tm.tcf.services.IFileSystem.FileAttrs;
+import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tm.tcf.services.IFileSystem.IFileHandle;
+import org.eclipse.tm.tcf.util.TCFFileInputStream;
+import org.eclipse.tm.tcf.util.TCFFileOutputStream;
+
+
+public class TCFFileService extends AbstractFileService {
+
+ private final TCFConnectorService connector;
+
+ private UserInfo user_info;
+
+ private static final class UserInfo {
+ final int r_uid;
+ final int e_uid;
+ final int r_gid;
+ final int e_gid;
+ final String home;
+
+ final Throwable error;
+
+ UserInfo(int r_uid, int e_uid, int r_gid, int e_gid, String home) {
+ this.r_uid = r_uid;
+ this.e_uid = e_uid;
+ this.r_gid = r_gid;
+ this.e_gid = e_gid;
+ this.home = home;
+ error = null;
+ }
+
+ UserInfo(Throwable error) {
+ this.error = error;
+ r_uid = -1;
+ e_uid = -1;
+ r_gid = -1;
+ e_gid = -1;
+ home = null;
+ }
+ }
+
+ public TCFFileService(IHost host) {
+ connector = (TCFConnectorService)TCFConnectorServiceManager
+ .getInstance().getConnectorService(host, ITCFService.class);
+ }
+
+ @Override
+ public String getDescription() {
+ return "The TCF File Service uses the Target Communication Framework to provide service" + //$NON-NLS-1$
+ "for the Files subsystem. It requires a TCF agent to be running on the remote machine."; //$NON-NLS-1$
+ }
+
+ public SystemMessage getMessage(Throwable x) {
+ return new SimpleSystemMessage(Activator.PLUGIN_ID,
+ SystemMessage.ERROR, x.getMessage(), x);
+ }
+
+ @Override
+ public String getName() {
+ return "TCF File Service"; //$NON-NLS-1$
+ }
+
+ private String toRemotePath(String parent, String name) throws SystemMessageException {
+ assert !Protocol.isDispatchThread();
+ String s = null;
+ if (parent != null) parent = parent.replace('\\', '/');
+ if (name != null) name = name.replace('\\', '/');
+ if (parent == null || parent.length() == 0) s = name;
+ else if (name == null || name.equals(".")) s = parent; //$NON-NLS-1$
+ else if (name.equals("/")) s = parent; //$NON-NLS-1$
+ else if (parent.endsWith("/")) s = parent + name; //$NON-NLS-1$
+ else s = parent + '/' + name;
+ if (s.startsWith("./") || s.equals(".")) { //$NON-NLS-1$ //$NON-NLS-2$
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) throw new SystemMessageException(getMessage(ui.error));
+ s = ui.home.replace('\\', '/') + s.substring(1);
+ }
+ while (s.endsWith("/.")) s = s.substring(0, s.length() - 2); //$NON-NLS-1$
+ return s;
+ }
+
+ /* Delete from UI action will call deleteBatch interface, yet
+ * for copy from UI action, it will call copy! It's totally
+ * inconsistency! For solving the problem, we have to modify
+ * the copy itself and made it recursive. We can't modify it
+ * in the same way as delete does!
+ *
+ */
+
+ public void internalCopy(String srcParent,
+ String srcName, String tgtParent, String tgtName, IProgressMonitor monitor)
+ throws SystemMessageException, InterruptedException {
+ //Note the dest directory or file exist surely since UI operations have
+ //done something, rename it to copy of XXX
+ if (monitor != null)
+ {
+ if (monitor.isCanceled())
+ {
+ throw new InterruptedException(Messages.TCFFileService_UserCancellation);
+ }
+ }
+
+ try
+ {
+ //firstly create the target directory!
+ this.createFolder(tgtParent, tgtName, monitor);
+ //then copy the next level directory!
+ final String new_srcpath = toRemotePath(srcParent, srcName);
+ final String new_tgtpath = toRemotePath(tgtParent, tgtName);
+ IHostFile[] arrFiles = internalFetch(new_srcpath, null,
+ FILE_TYPE_FILES_AND_FOLDERS, monitor);
+ if (arrFiles == null || arrFiles.length <=0 )
+ return;
+ else
+ {
+ for (int i = 0; i < arrFiles.length; i++)
+ {
+ String srcFile = toRemotePath(new_srcpath, arrFiles[i].getName());
+ String tgtFile = toRemotePath(new_tgtpath, arrFiles[i].getName());
+ if (arrFiles[i].isFile())
+ {
+ copy(srcFile, tgtFile, monitor);
+ }
+ else
+ {
+ //do recursive directory copy!
+ internalCopy(new_srcpath, arrFiles[i].getName(), new_tgtpath,
+ arrFiles[i].getName(), monitor);
+ }
+ }
+ }
+ }
+ catch (SystemMessageException e)
+ {
+ e.printStackTrace();
+ throw new SystemMessageException(e.getSystemMessage());
+ }
+ catch (InterruptedException e)
+ {
+ throw new InterruptedException(Messages.TCFFileService_UserCancellation1);
+ }
+ }
+
+ public void copy(String srcParent,
+ String srcName, String tgtParent, String tgtName, IProgressMonitor monitor)
+ throws SystemMessageException {
+
+ if (monitor != null)
+ monitor.beginTask(Messages.TCFFileService_CopyingFiles, 1);
+
+ try {
+
+ IHostFile curFile = getFile(srcParent, srcName, monitor);
+ final String srcFile = toRemotePath(srcParent, srcName);
+ final String tgtFile = toRemotePath(tgtParent, tgtName);
+
+ if (curFile.isFile())
+ copy(srcFile, tgtFile, monitor);
+ else if (curFile.isDirectory())
+ {
+ internalCopy(srcParent, srcName, tgtParent, tgtName, monitor);
+ }
+ else
+ {
+ FileNotFoundException e =
+ new FileNotFoundException(Messages.TCFFileService_FileNotFoundMessage);
+ throw new SystemMessageException(getMessage(e));
+ }
+ }
+ catch (Exception e) {
+ // TODO Auto-generated catch block
+ if (e instanceof SystemMessageException)
+ throw (SystemMessageException)e;
+ throw new SystemOperationFailedException(Activator.PLUGIN_ID, e);
+
+ }
+ finally {
+ if (monitor != null)
+ monitor.done();
+ }
+ }
+
+ public void copy(final String srcFile, final String tgtFile, IProgressMonitor monitor)
+ throws SystemMessageException {
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.copy(srcFile, tgtFile, false, false, new IFileSystem.DoneCopy() {
+ public void doneCopy(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(Boolean.TRUE);
+ }
+ });
+ }
+ }.getS(monitor, "Copy: " + srcFile); //$NON-NLS-1$
+ }
+
+ public void copyBatch(String[] srcParents,
+ String[] srcNames, String tgtParent, IProgressMonitor monitor) throws SystemMessageException {
+ for (int i = 0; i < srcParents.length; i++) {
+ copy(srcParents[i], srcNames[i], tgtParent, srcNames[i], monitor);
+ }
+ }
+
+ public IHostFile createFile(String parent,
+ String name, IProgressMonitor monitor) throws SystemMessageException {
+ try {
+ getOutputStream(parent, name, true, monitor).close();
+ return getFile(parent, name, monitor);
+ }
+ catch (IOException e) {
+ throw new SystemMessageException(getMessage(e));
+ }
+ }
+
+ public IHostFile createFolder(final String parent, final String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<IHostFile>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.mkdir(path, null, new IFileSystem.DoneMkDir() {
+ public void doneMkDir(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) error(error);
+ else done(new TCFFileResource(TCFFileService.this,
+ path, null, attrs, false));
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Create folder"); //$NON-NLS-1$
+ }
+
+ public void delete(String parent,
+ String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ IFileSystem.DoneRemove done = new IFileSystem.DoneRemove() {
+ public void doneRemove(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ done(Boolean.TRUE);
+ }
+ };
+ if (attrs.isDirectory()) {
+ fs.rmdir(path, done);
+ }
+ else {
+ fs.remove(path, done);
+ }
+ }
+ });
+ }
+ }.getS(monitor, "Delete"); //$NON-NLS-1$
+ }
+
+ private void internalDelete(String parent, String name,
+ IProgressMonitor monitor)
+ throws SystemMessageException, InterruptedException
+ {
+ if (monitor != null)
+ {
+ if (monitor.isCanceled())
+ {
+ throw new InterruptedException(Messages.TCFFileService_UserDeleteCancellation);
+ }
+ }
+
+ try
+ {
+ final String new_path = toRemotePath(parent, name);
+ IHostFile[] arrFiles = internalFetch(new_path, null,
+ FILE_TYPE_FILES_AND_FOLDERS, monitor);
+ if (arrFiles == null || arrFiles.length <= 0)
+ {
+ //This is an empty directory, directly delete!
+ delete(parent, name, monitor);
+ }
+ else
+ {
+ for (int i = 0; i < arrFiles.length; i++)
+ {
+
+ if (arrFiles[i].isFile())
+ {
+ delete(new_path, arrFiles[i].getName(), monitor);
+ }
+ else
+ internalDelete(new_path, arrFiles[i].getName(), monitor);
+ }
+ //now the folder becomes empty, let us delete it!
+ delete(parent, name, monitor);
+ }
+ }
+ catch (SystemMessageException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ throw new SystemMessageException(e.getSystemMessage());
+ }
+ catch (InterruptedException e) {
+ throw new InterruptedException(Messages.TCFFileService_UserDeleteCancellation1);
+ }
+ }
+
+ @Override
+ public void deleteBatch(String[] remoteParents, String[] fileNames,
+ IProgressMonitor monitor)
+ throws SystemMessageException {
+ if (monitor != null)
+ monitor.beginTask(Messages.TCFFileService_DeletingFiles, remoteParents.length);
+ try
+ {
+ for (int i = 0; i < remoteParents.length; i++) {
+ IHostFile curFile = getFile(remoteParents[i], fileNames[i], monitor);
+ if (curFile.isFile())
+ delete(remoteParents[i], fileNames[i], monitor);
+ else if (curFile.isDirectory())
+ internalDelete(remoteParents[i], fileNames[i], monitor);
+ }
+ }
+ catch (Exception x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemOperationFailedException(Activator.PLUGIN_ID, x);
+ }
+ finally {
+ if (monitor != null)
+ monitor.done();
+ }
+ }
+
+ public void download(final String parent,
+ final String name, final File file, final boolean is_binary,
+ final String host_encoding, IProgressMonitor monitor) throws SystemMessageException {
+ IHostFile hostFile = getFile(parent, name, new NullProgressMonitor());
+ monitor.beginTask("Downloading " + toRemotePath(parent, name) + " ...", Long.valueOf(hostFile.getSize() / 1024).intValue()); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ file.getParentFile().mkdirs();
+ InputStream inp = getInputStream(parent, name, is_binary, new NullProgressMonitor());
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+ copyStream(inp, out, is_binary, "UTF8", host_encoding, monitor); //$NON-NLS-1$
+ }
+ catch (Exception x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemOperationFailedException(Activator.PLUGIN_ID, x);
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public String getEncoding(IProgressMonitor monitor) throws SystemMessageException {
+ return "UTF8"; //$NON-NLS-1$
+ }
+
+ public IHostFile getFile(final String parent,
+ final String name, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ return new TCFRSETask<IHostFile>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token,
+ FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ if (error.getStatus() == IFileSystem.STATUS_NO_SUCH_FILE) {
+ done(new TCFFileResource(TCFFileService.this, path, null, null, false));
+ return;
+ }
+ error(error);
+ return;
+ }
+ done(new TCFFileResource(TCFFileService.this, path, null, attrs, false));
+ }
+ });
+ }
+ }.getS(monitor, "Stat"); //$NON-NLS-1$
+ }
+
+ @Override
+ protected IHostFile[] internalFetch(final String parent, final String filter, final int fileType, final IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, null);
+ final boolean wantFiles = (fileType==FILE_TYPE_FILES_AND_FOLDERS || (fileType&FILE_TYPE_FILES)!=0);
+ final boolean wantFolders = (fileType==FILE_TYPE_FILES_AND_FOLDERS || (fileType%FILE_TYPE_FOLDERS)!=0);
+ return new TCFRSETask<IHostFile[]>() {
+ private IMatcher matcher = null;
+ public void run() {
+ if (filter == null) {
+ matcher = null;
+ }
+ else if (filter.endsWith(",")) { //$NON-NLS-1$
+ String[] types = filter.split(","); //$NON-NLS-1$
+ matcher = new FileTypeMatcher(types, true);
+ }
+ else {
+ matcher = new NamePatternMatcher(filter, true, true);
+ }
+ final List<TCFFileResource> results = new ArrayList<TCFFileResource>();
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.opendir(path, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, final IFileHandle handle) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ fs.readdir(handle, new IFileSystem.DoneReadDir() {
+ public void doneReadDir(IToken token,
+ FileSystemException error, DirEntry[] entries, boolean eof) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ for (DirEntry e : entries) {
+ if (e.attrs == null) {
+ // Attrs are not available if, for example,
+ // the entry is a broken symbolic link
+ }
+ else if (e.attrs.isDirectory()) {
+ // dont filter folder names if getting both folders and files
+ if (wantFolders && (matcher==null || fileType==FILE_TYPE_FILES_AND_FOLDERS || matcher.matches(e.filename))) {
+ results.add(new TCFFileResource(TCFFileService.this,
+ path, e.filename, e.attrs, false));
+ }
+ }
+ else if (e.attrs.isFile()) {
+ if (wantFiles && (matcher == null || matcher.matches(e.filename))) {
+ results.add(new TCFFileResource(TCFFileService.this,
+ path, e.filename, e.attrs, false));
+ }
+ }
+ }
+ if (eof) {
+ fs.close(handle, new IFileSystem.DoneClose() {
+ public void doneClose(IToken token, FileSystemException error) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ done(results.toArray(new TCFFileResource[results.size()]));
+ }
+ });
+ }
+ else {
+ fs.readdir(handle, this);
+ }
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Get files and folders"); //$NON-NLS-1$
+ }
+
+ @Override
+ public InputStream getInputStream(final String parent, final String name, boolean isBinary, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ final IFileHandle handle = new TCFRSETask<IFileHandle>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.open(path, IFileSystem.TCF_O_READ, null, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ if (error != null) error(error);
+ else done(handle);
+ }
+ });
+ }
+ }.getS(monitor, "Get input stream"); //$NON-NLS-1$
+ return new TCFFileInputStream(handle);
+ }
+
+ @Override
+ public OutputStream getOutputStream(final String parent, final String name, boolean isBinary, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ final IFileHandle handle = new TCFRSETask<IFileHandle>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ int flags = IFileSystem.TCF_O_WRITE | IFileSystem.TCF_O_CREAT | IFileSystem.TCF_O_TRUNC;
+ fs.open(path, flags, null, new IFileSystem.DoneOpen() {
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ if (error != null) error(error);
+ else done(handle);
+ }
+ });
+ }
+ }.getS(monitor, "Get output stream"); //$NON-NLS-1$
+ return new TCFFileOutputStream(handle);
+ }
+
+ public IHostFile[] getRoots(IProgressMonitor monitor) throws SystemMessageException {
+ return new TCFRSETask<IHostFile[]>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.roots(new IFileSystem.DoneRoots() {
+ public void doneRoots(IToken token, FileSystemException error, DirEntry[] entries) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ List<TCFFileResource> l = new ArrayList<TCFFileResource>();
+ for (DirEntry e : entries) {
+ if (e.attrs == null) continue;
+ l.add(new TCFFileResource(TCFFileService.this, null, e.filename, e.attrs, true));
+ }
+ done(l.toArray(new IHostFile[l.size()]));
+ }
+ });
+ }
+ }.getS(monitor, "Get roots"); //$NON-NLS-1$
+ }
+
+ public IHostFile getUserHome() {
+ UserInfo ui = getUserInfo();
+ try {
+ return getFile(ui.home, ".", new NullProgressMonitor()); //$NON-NLS-1$
+ }
+ catch (SystemMessageException e) {
+ throw new Error(e);
+ }
+ }
+
+ public boolean isCaseSensitive() {
+ return true;
+ }
+
+ public void move(final String srcParent,
+ final String srcName, final String tgtParent, final String tgtName, IProgressMonitor monitor)
+ throws SystemMessageException {
+ final String src_path = toRemotePath(srcParent, srcName);
+ final String tgt_path = toRemotePath(tgtParent, tgtName);
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.rename(src_path, tgt_path, new IFileSystem.DoneRename() {
+ public void doneRename(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(Boolean.TRUE);
+ }
+ });
+ }
+ }.getS(monitor, "Move"); //$NON-NLS-1$
+ }
+
+ public void rename(String remoteParent,
+ String oldName, String newName, IProgressMonitor monitor) throws SystemMessageException {
+ move(remoteParent, oldName, remoteParent, newName, monitor);
+ }
+
+ public void rename(String remoteParent,
+ String oldName, String newName, IHostFile oldFile, IProgressMonitor monitor)
+ throws SystemMessageException {
+ move(remoteParent, oldName, remoteParent, newName, monitor);
+ oldFile.renameTo(toRemotePath(remoteParent, newName));
+ }
+
+ public void setLastModified(final String parent,
+ final String name, final long timestamp, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ FileAttrs attrs = new FileAttrs(IFileSystem.ATTR_ACMODTIME,
+ 0, 0, 0, 0, timestamp, timestamp, null);
+ fs.setstat(path, attrs, new IFileSystem.DoneSetStat() {
+ public void doneSetStat(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(Boolean.TRUE);
+ }
+ });
+ }
+ }.getS(monitor, "Set modification time"); //$NON-NLS-1$
+ }
+
+ public void setReadOnly(final String parent,
+ final String name, final boolean readOnly, IProgressMonitor monitor) throws SystemMessageException {
+ final String path = toRemotePath(parent, name);
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ final IFileSystem fs = connector.getFileSystemService();
+ fs.stat(path, new IFileSystem.DoneStat() {
+ public void doneStat(IToken token, FileSystemException error, FileAttrs attrs) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ int p = attrs.permissions;
+ if (readOnly) {
+ p &= ~IFileSystem.S_IWUSR;
+ p &= ~IFileSystem.S_IWGRP;
+ p &= ~IFileSystem.S_IWOTH;
+ }
+ else {
+ p |= IFileSystem.S_IWUSR;
+ p |= IFileSystem.S_IWGRP;
+ p |= IFileSystem.S_IWOTH;
+ }
+ FileAttrs new_attrs = new FileAttrs(IFileSystem.ATTR_PERMISSIONS,
+ 0, 0, 0, p, 0, 0, null);
+ fs.setstat(path, new_attrs, new IFileSystem.DoneSetStat() {
+ public void doneSetStat(IToken token, FileSystemException error) {
+ if (error != null) error(error);
+ else done(Boolean.TRUE);
+ }
+ });
+ }
+ });
+ }
+ }.getS(monitor, "Set permissions"); //$NON-NLS-1$
+ }
+
+ public void upload(InputStream inp,
+ String parent, String name, boolean isBinary,
+ String hostEncoding, IProgressMonitor monitor) throws SystemMessageException {
+ monitor.beginTask("Upload", 1); //$NON-NLS-1$
+ try {
+ OutputStream out = getOutputStream(parent, name, isBinary, new NullProgressMonitor());
+ // As we cannot determine the local file size, redirect the worked ticks to a NullProgressMonitor.
+ copyStream(inp, out, isBinary, hostEncoding, "UTF8", new NullProgressMonitor()); //$NON-NLS-1$
+ }
+ catch (Throwable x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemMessageException(getMessage(x));
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ public void upload(File localFile,
+ String parent, String name, boolean isBinary,
+ String srcEncoding, String hostEncoding, IProgressMonitor monitor)
+ throws SystemMessageException {
+ monitor.beginTask("Uploading " + localFile.toString() + " ...", Long.valueOf(localFile.length() / 1024).intValue()); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ OutputStream out = getOutputStream(parent, name, isBinary, new NullProgressMonitor());
+ InputStream inp = new BufferedInputStream(new FileInputStream(localFile));
+ copyStream(inp, out, isBinary, hostEncoding, "UTF8", monitor); //$NON-NLS-1$
+ }
+ catch (Throwable x) {
+ if (x instanceof SystemMessageException) throw (SystemMessageException)x;
+ throw new SystemMessageException(getMessage(x));
+ }
+ finally {
+ monitor.done();
+ }
+ }
+
+ private void copyStream(InputStream inp, OutputStream out,
+ boolean is_binary, String inp_encoding, String out_encoding, IProgressMonitor monitor) throws IOException {
+ try {
+ if (!is_binary) {
+ if (inp_encoding == null || inp_encoding.equals("UTF-8")) inp_encoding = "UTF8"; //$NON-NLS-1$ //$NON-NLS-2$
+ if (out_encoding == null || out_encoding.equals("UTF-8")) out_encoding = "UTF8"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (is_binary || inp_encoding.equals(out_encoding)) {
+ byte[] buf = new byte[0x1000];
+ for (;;) {
+ int buf_len = inp.read(buf);
+ if (buf_len < 0) break;
+ out.write(buf, 0, buf_len);
+ if (monitor != null) monitor.worked(buf_len / 1024);
+ }
+ }
+ else {
+ Reader reader = new InputStreamReader(inp, inp_encoding);
+ Writer writer = new OutputStreamWriter(out, out_encoding);
+ char[] buf = new char[0x1000];
+ for (;;) {
+ int buf_len = reader.read(buf);
+ if (buf_len < 0) break;
+ writer.write(buf, 0, buf_len);
+ if (monitor != null) monitor.worked(buf_len / 1024);
+ }
+ writer.flush();
+ }
+ }
+ finally {
+ out.close();
+ inp.close();
+ }
+ }
+
+ private synchronized UserInfo getUserInfo() {
+ if (user_info == null || user_info.error != null) {
+ user_info = new TCFRSETask<UserInfo>() {
+ public void run() {
+ IFileSystem fs = connector.getFileSystemService();
+ fs.user(new IFileSystem.DoneUser() {
+ public void doneUser(IToken token, FileSystemException error, int real_uid,
+ int effective_uid, int real_gid, int effective_gid, String home) {
+ if (error != null) done(new UserInfo(error));
+ else done(new UserInfo(real_uid, effective_uid, real_gid, effective_gid, home));
+ }
+ });
+ }
+ }.getE();
+ }
+ return user_info;
+ }
+
+ public boolean canRead(FileAttrs attrs) {
+ if ((attrs.flags & IFileSystem.ATTR_PERMISSIONS) == 0) return false;
+ if ((attrs.flags & IFileSystem.ATTR_UIDGID) == 0) return false;
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) return false;
+ if (ui.e_uid == attrs.uid) {
+ return (attrs.permissions & IFileSystem.S_IRUSR) != 0;
+ }
+ if (ui.e_gid == attrs.gid) {
+ return (attrs.permissions & IFileSystem.S_IRGRP) != 0;
+ }
+ return (attrs.permissions & IFileSystem.S_IROTH) != 0;
+ }
+
+ public boolean canWrite(FileAttrs attrs) {
+ if ((attrs.flags & IFileSystem.ATTR_PERMISSIONS) == 0) return false;
+ if ((attrs.flags & IFileSystem.ATTR_UIDGID) == 0) return false;
+ UserInfo ui = getUserInfo();
+ if (ui.error != null) return false;
+ if (ui.e_uid == attrs.uid) {
+ return (attrs.permissions & IFileSystem.S_IWUSR) != 0;
+ }
+ if (ui.e_gid == attrs.gid) {
+ return (attrs.permissions & IFileSystem.S_IWGRP) != 0;
+ }
+ return (attrs.permissions & IFileSystem.S_IWOTH) != 0;
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileSubSystemConfiguration.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileSubSystemConfiguration.java
new file mode 100644
index 000000000..79e1dd48d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFFileSubSystemConfiguration.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Intel Corp. - Add Unix File System style detection, set TRUE by default
+ * Intel Corporation - [329654] Make all sub services operate against TCF connector service
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.files;
+
+import java.util.Vector;
+
+import org.eclipse.rse.core.filters.ISystemFilter;
+import org.eclipse.rse.core.filters.ISystemFilterPool;
+import org.eclipse.rse.core.filters.ISystemFilterPoolManager;
+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.services.clientserver.SystemSearchString;
+import org.eclipse.rse.services.files.IFileService;
+import org.eclipse.rse.services.search.IHostSearchResultConfiguration;
+import org.eclipse.rse.services.search.IHostSearchResultSet;
+import org.eclipse.rse.services.search.ISearchService;
+import org.eclipse.rse.subsystems.files.core.ILanguageUtilityFactory;
+import org.eclipse.rse.subsystems.files.core.model.RemoteFileFilterString;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystemConfiguration;
+import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+import org.eclipse.rse.ui.SystemBasePlugin;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.Messages;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorServiceManager;
+
+public class TCFFileSubSystemConfiguration extends FileServiceSubSystemConfiguration {
+
+ private final TCFFileAdapter file_adapter = new TCFFileAdapter();
+
+ public TCFFileSubSystemConfiguration()
+ {
+ super();
+ if (Messages.IS_UNIX_STYLE.equalsIgnoreCase("true"))
+ setIsUnixStyle(true);
+ else
+ setIsUnixStyle(false);
+ }
+
+ @Override
+ public ISubSystem createSubSystemInternal(IHost host) {
+ TCFConnectorService connectorService = (TCFConnectorService)getConnectorService(host);
+ return new FileServiceSubSystem(host, connectorService,
+ getFileService(host), getHostFileAdapter(), createSearchService(host));
+ }
+
+ public IFileService createFileService(IHost host) {
+ return new TCFFileService(host);
+ }
+
+ public IHostSearchResultConfiguration createSearchConfiguration(IHost host,
+ IHostSearchResultSet resultSet, Object searchTarget,
+ SystemSearchString searchString) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ISearchService createSearchService(IHost host) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IHostFileToRemoteFileAdapter getHostFileAdapter() {
+ return file_adapter;
+ }
+
+ public ILanguageUtilityFactory getLanguageUtilityFactory(IRemoteFileSubSystem ss) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean supportsArchiveManagement() {
+ return false;
+ }
+
+ @Override
+ public IConnectorService getConnectorService(IHost host) {
+ return TCFConnectorServiceManager.getInstance()
+ .getConnectorService(host, getServiceImplType());
+ }
+
+ @Override
+ public Class<ITCFService> getServiceImplType() {
+ return ITCFService.class;
+ }
+
+ @Override
+ public void setConnectorService(IHost host, IConnectorService connectorService) {
+ TCFConnectorServiceManager.getInstance().setConnectorService(host, getServiceImplType(), connectorService);
+ }
+
+ @Override
+ protected ISystemFilterPool createDefaultFilterPool(ISystemFilterPoolManager mgr) {
+ ISystemFilterPool pool = null;
+ try {
+ pool = mgr.createSystemFilterPool(getDefaultFilterPoolName(mgr.getName(), getId()), true);
+
+ Vector<String> filterStrings = new Vector<String>();
+ RemoteFileFilterString myHomeFilterString = new RemoteFileFilterString(this);
+ myHomeFilterString.setPath("."); //$NON-NLS-1$
+ myHomeFilterString.setFile("*"); //$NON-NLS-1$
+ filterStrings.add(myHomeFilterString.toString());
+ ISystemFilter filter = mgr.createSystemFilter(pool, "Home", filterStrings); //$NON-NLS-1$
+ filter.setNonChangable(true);
+ filter.setSingleFilterStringOnly(true);
+
+ filterStrings = new Vector<String>();
+ RemoteFileFilterString rootFilesFilterString = new RemoteFileFilterString(this);
+ rootFilesFilterString.setPath(""); //$NON-NLS-1$
+ rootFilesFilterString.setFile("*"); //$NON-NLS-1$
+ filterStrings.add(rootFilesFilterString.toString());
+ filter = mgr.createSystemFilter(pool, "Root", filterStrings); //$NON-NLS-1$
+ filter.setNonChangable(true);
+ filter.setSingleFilterStringOnly(true);
+ }
+ catch (Exception exc) {
+ SystemBasePlugin.logError("Error creating default filter pool", exc); //$NON-NLS-1$
+ }
+ return pool;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFRemoteFile.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFRemoteFile.java
new file mode 100644
index 000000000..1be7f12f1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/files/TCFRemoteFile.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Anna Dushistova (MontaVista) - [247164][tcf] a lot of file/directory properties are not supported
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.files;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.files.IHostFile;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.AbstractRemoteFile;
+import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+import org.eclipse.rse.ui.SystemBasePlugin;
+
+public class TCFRemoteFile extends AbstractRemoteFile {
+
+ public TCFRemoteFile(FileServiceSubSystem ss, IRemoteFileContext ctx, IRemoteFile parent, IHostFile file) {
+ super(ss, ctx, parent, file);
+ }
+
+ @Override
+ public IRemoteFile getParentRemoteFile() {
+ if (this._parentFile == null) {
+ if (isRoot()) return null;
+ IRemoteFile parentFile = null;
+ IRemoteFileSubSystem ss = _context.getParentRemoteFileSubSystem();
+ if (ss != null) {
+ IProgressMonitor monitor = new NullProgressMonitor();
+ try {
+ parentFile = ss.getRemoteFileObject(getParentPath(), monitor);
+ }
+ catch (SystemMessageException e) {
+ SystemBasePlugin.logError("TCFRemoteFile.getParentRemoteFile()", e); //$NON-NLS-1$
+ }
+ }
+ this._parentFile = parentFile;
+ }
+ return this._parentFile;
+ }
+
+ public String getCanonicalPath() {
+ return getAbsolutePath();
+ }
+
+ public String getClassification() {
+ String result;
+ if (isFile()) {
+ result = "file"; //$NON-NLS-1$
+ } else if (isDirectory()) {
+ result = "directory"; //$NON-NLS-1$
+ } else {
+ result = "unknown"; //default-fallback //$NON-NLS-1$
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessAdapter.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessAdapter.java
new file mode 100644
index 000000000..7f43ddfc6
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessAdapter.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.rse.services.clientserver.processes.IHostProcess;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcess;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessContext;
+
+public class TCFProcessAdapter implements IHostProcessToRemoteProcessAdapter {
+
+ public IRemoteProcess convertToRemoteProcess(IRemoteProcessContext context,
+ IRemoteProcess parent, IHostProcess node) {
+ IHostProcess[] nodes = new IHostProcess[]{ node };
+ IRemoteProcess[] processes = convertToRemoteProcesses(context, parent, nodes);
+ if (processes != null && processes.length > 0) return processes[0];
+ return null;
+ }
+
+ public IRemoteProcess[] convertToRemoteProcesses(
+ IRemoteProcessContext context, IRemoteProcess parent,
+ IHostProcess[] nodes) {
+
+ if (nodes == null)return null;
+ List<IRemoteProcess> list = new ArrayList<IRemoteProcess>(nodes.length);
+ for (int idx = 0; idx < nodes.length; idx++) {
+ TCFProcessResource node = (TCFProcessResource)nodes[idx];
+ if (node != null) list.add(new TCFRemoteProcess(context, node));
+ }
+ return list.toArray(new IRemoteProcess[list.size()]);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessResource.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessResource.java
new file mode 100644
index 000000000..4fad1b6cd
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessResource.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Anna Dushistova (MontaVista) - [246996] [tcf] NullPointerException when trying to copy the process
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.rse.core.subsystems.AbstractResource;
+import org.eclipse.rse.services.clientserver.IServiceConstants;
+import org.eclipse.rse.services.clientserver.processes.IHostProcess;
+import org.eclipse.rse.services.clientserver.processes.ISystemProcessRemoteConstants;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ISysMonitor;
+import org.eclipse.tm.tcf.services.ISysMonitor.SysMonitorContext;
+
+public class TCFProcessResource extends AbstractResource implements IHostProcess {
+
+ public static final String PROP_PC_UTIME = "PCUTime"; //$NON-NLS-1$
+ public static final String PROP_PC_STIME = "PCSTime"; //$NON-NLS-1$
+
+ private final TCFProcessService rse_service;
+ private final ISysMonitor tcf_service;
+ private final TCFProcessResource prev;
+ private final String id;
+
+ private Throwable error;
+ private ISysMonitor.SysMonitorContext context;
+
+ private final List<Runnable> children_wait_list = new ArrayList<Runnable>();
+ private final HashMap<String,TCFProcessResource> children = new HashMap<String,TCFProcessResource>();
+ private boolean children_loading;
+ private boolean children_loaded;
+ private Throwable children_error;
+ private boolean running_wait_list;
+
+ private long timestamp;
+
+ private final String[] propertyKeys = new String[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_COUNT];
+ {
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_EXENAME] = ISysMonitor.PROP_FILE;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_GID] = ISysMonitor.PROP_GROUPNAME;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_PID] = ISysMonitor.PROP_PID;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_PPID] = ISysMonitor.PROP_PPID;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_STATUS] = ISysMonitor.PROP_STATE;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_TGID] = ISysMonitor.PROP_TGID;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_TRACERPID] = ISysMonitor.PROP_TRACERPID;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_UID] = ISysMonitor.PROP_UID;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_USERNAME] = ISysMonitor.PROP_USERNAME;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_VMSIZE] = ISysMonitor.PROP_VSIZE;
+ propertyKeys[ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_INDEX_VMRSS] = ISysMonitor.PROP_RSS;
+ }
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ TCFProcessResource(TCFProcessService rse_service, ISysMonitor service,
+ TCFProcessResource prev, String id) {
+ this.rse_service = rse_service;
+ this.tcf_service = service;
+ this.prev = prev;
+ this.id = id;
+ }
+
+ public String getID() {
+ return id;
+ }
+
+ public String getParentID() {
+ return (String)properties.get(ISysMonitor.PROP_PARENTID);
+ }
+
+ public TCFProcessService getService() {
+ return rse_service;
+ }
+
+ public void invalidate() {
+ assert Protocol.isDispatchThread();
+ error = null;
+ context = null;
+ }
+
+ public boolean validate(final Runnable done) {
+ assert Protocol.isDispatchThread();
+ if (error != null) return true;
+ if (context != null) return true;
+ tcf_service.getContext(id, new ISysMonitor.DoneGetContext() {
+
+ public void doneGetContext(IToken token, Exception error, SysMonitorContext context) {
+ TCFProcessResource.this.error = error;
+ TCFProcessResource.this.context = context;
+ timestamp = System.currentTimeMillis();
+ if (error != null) {
+ properties = new HashMap<String,Object>();
+ }
+ else {
+ properties = new HashMap<String,Object>(context.getProperties());
+ if (prev != null && timestamp > prev.timestamp) {
+ setPCProperty(PROP_PC_UTIME, ISysMonitor.PROP_UTIME);
+ setPCProperty(PROP_PC_STIME, ISysMonitor.PROP_STIME);
+ }
+ // Conversions are necessary for sorting to work
+ toLong(ISysMonitor.PROP_PID);
+ toLong(ISysMonitor.PROP_PPID);
+ toLong(ISysMonitor.PROP_UTIME);
+ toLong(ISysMonitor.PROP_STIME);
+ toLong(ISysMonitor.PROP_CUTIME);
+ toLong(ISysMonitor.PROP_CSTIME);
+ toLong(ISysMonitor.PROP_STARTTIME);
+ toLong(ISysMonitor.PROP_ITREALVALUE);
+ toBigInteger(ISysMonitor.PROP_CODESTART);
+ toBigInteger(ISysMonitor.PROP_CODEEND);
+ toBigInteger(ISysMonitor.PROP_STACKSTART);
+ toBigInteger(ISysMonitor.PROP_WCHAN);
+ }
+ Protocol.invokeLater(done);
+ }
+
+ });
+ return false;
+ }
+
+ private void toLong(String name) {
+ Number n = (Number)properties.get(name);
+ if (n == null || n instanceof Long) return;
+ properties.put(name, Long.valueOf(n.longValue()));
+ }
+
+ private void toBigInteger(String name) {
+ Number n = (Number)properties.get(name);
+ if (n == null || n instanceof BigInteger) return;
+ properties.put(name, new BigInteger(n.toString()));
+ }
+
+ private void setPCProperty(String property, String name) {
+ Object x = prev.properties.get(name);
+ Object y = properties.get(name);
+ if (x instanceof Number && y instanceof Number) {
+ BigInteger nx = x instanceof BigInteger ? (BigInteger) x
+ : new BigInteger(x.toString());
+ BigInteger ny = y instanceof BigInteger ? (BigInteger) y
+ : new BigInteger(y.toString());
+ double d = ny.subtract(nx).doubleValue()
+ / (timestamp - prev.timestamp);
+ properties.put(property, d);
+ }
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public Throwable getError() {
+ assert Protocol.isDispatchThread();
+ return error;
+ }
+
+ public ISysMonitor.SysMonitorContext getContext() {
+ assert Protocol.isDispatchThread();
+ return context;
+ }
+
+ // IHostProcess methods
+
+ public String getAllProperties() {
+ String result = ""; //$NON-NLS-1$
+ for (int i = 0; i < ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_COUNT; i++) {
+ result = result + properties.get(propertyKeys[i]);
+ if (i != ISystemProcessRemoteConstants.PROCESS_ATTRIBUTES_COUNT - 1)
+ result = result + IServiceConstants.TOKEN_SEPARATOR;
+ }
+ return result;
+ }
+
+ public long getGid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_UGID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public String getLabel() {
+ return Long.toString(getPid()) + " " + notNull(getName()); //$NON-NLS-1$
+ }
+
+ public String getName() {
+ return (String)properties.get(ISysMonitor.PROP_FILE);
+ }
+
+ public long getPPid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_PPID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public long getPid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_PID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public String getState() {
+ return (String)properties.get(ISysMonitor.PROP_STATE);
+ }
+
+ public long getTgid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_TGID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public long getTracerPid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_TRACERPID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public long getUid() {
+ Number n = (Number)properties.get(ISysMonitor.PROP_UID);
+ if (n == null) return -1;
+ return n.longValue();
+ }
+
+ public String getUsername() {
+ return (String)properties.get(ISysMonitor.PROP_USERNAME);
+ }
+
+ public long getVmRSSInKB() {
+ Number rss = (Number)properties.get(ISysMonitor.PROP_RSS);
+ Number psz = (Number)properties.get(ISysMonitor.PROP_PSIZE);
+ if (rss == null || psz == null) return 0;
+ return (rss.longValue() * psz.longValue() + 1023) / 1024;
+ }
+
+ public long getVmSizeInKB() {
+ Number vsz = (Number)properties.get(ISysMonitor.PROP_VSIZE);
+ if (vsz == null) return 0;
+ return (vsz.longValue() + 1023) / 1024;
+ }
+
+ public boolean isRoot() {
+ return true;
+ }
+
+ private String notNull(String s) {
+ return s == null ? "" : s;
+ }
+
+ String getStatusLine() {
+ final String STATUS_DELIMITER = "|"; //$NON-NLS-1$
+ StringBuffer s = new StringBuffer();
+ s.append(getPid()).append(STATUS_DELIMITER);
+ s.append(notNull(getName())).append(STATUS_DELIMITER);
+ s.append(notNull(getState())).append(STATUS_DELIMITER);
+ s.append(getTgid()).append(STATUS_DELIMITER);
+ s.append(getPPid()).append(STATUS_DELIMITER);
+ s.append('0').append(STATUS_DELIMITER);
+ s.append(getUid()).append(STATUS_DELIMITER);
+ s.append(notNull(getUsername())).append(STATUS_DELIMITER);
+ s.append(getGid()).append(STATUS_DELIMITER);
+ s.append(getVmSizeInKB()).append(STATUS_DELIMITER);
+ s.append(getVmRSSInKB()).append(STATUS_DELIMITER);
+ return s.toString();
+ }
+
+ public Map<String,Object> getProperties() {
+ return properties;
+ }
+
+ private void runChildrenWaitList() {
+ assert !children_loading;
+ assert children_loaded;
+ try {
+ running_wait_list = true;
+ for (Runnable r : children_wait_list) r.run();
+ children_wait_list.clear();
+ }
+ finally {
+ running_wait_list = false;
+ }
+ }
+
+ public Throwable getChildrenError() {
+ return children_error;
+ }
+
+ public void flushChildrenCache() {
+ Map<Long,TCFProcessResource> pid2res = rse_service.getProcessCache();
+ for (TCFProcessResource r : children.values()) {
+ long pid = r.getPid();
+ if (pid > 0 && getPid() != pid) pid2res.remove(r.getPid());
+ }
+ children_loaded = false;
+ children_error = null;
+ }
+
+ public boolean loadChildren(Runnable run) {
+ if (children_loaded) return true;
+ assert !running_wait_list;
+ children_wait_list.add(run);
+ if (children_loading) return false;
+ children_loading = true;
+ try {
+ final ISysMonitor m = rse_service.getTCFConnectorService().getSysMonitorService();
+ m.getChildren(getID(), new ISysMonitor.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] ids) {
+ try {
+ if (error != null) {
+ loadProcessesDone(error, null);
+ }
+ else if (ids == null) {
+ loadProcessesDone(null, new TCFProcessResource[0]);
+ }
+ else {
+ final TCFProcessResource[] arr = new TCFProcessResource[ids.length];
+ final Set<IHostProcess> pending = new HashSet<IHostProcess>();
+ for (int i = 0; i < ids.length; i++) {
+ final TCFProcessResource r = new TCFProcessResource(
+ rse_service, m, children.get(ids[i]), ids[i]);
+ if (!r.validate(new Runnable() {
+ public void run() {
+ pending.remove(r);
+ if (pending.isEmpty()) loadProcessesDone(null, arr);
+ }
+ })) pending.add(r);
+ arr[i] = r;
+ }
+ if (pending.isEmpty()) loadProcessesDone(null, arr);
+ }
+ }
+ catch (Throwable x) {
+ loadProcessesDone(x, null);
+ }
+ }
+ });
+ return false;
+ }
+ catch (Throwable x) {
+ loadProcessesDone(x, null);
+ return true;
+ }
+ }
+
+ private void loadProcessesDone(Throwable error, TCFProcessResource[] arr) {
+ assert children_loading;
+ children_loading = false;
+ children_loaded = true;
+ children.clear();
+ if (arr != null && error == null) {
+ Map<Long,TCFProcessResource> pid2res = rse_service.getProcessCache();
+ for (TCFProcessResource r : arr) {
+ long pid = r.getPid();
+ if (pid > 0 && getPid() != pid) pid2res.put(pid, r);
+ if (r.getError() == null) children.put(r.getID(), r);
+ }
+ }
+ children_error = error;
+ runChildrenWaitList();
+ }
+
+ @Override
+ public String toString() {
+ return "[" + getStatusLine() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessService.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessService.java
new file mode 100644
index 000000000..82f1bc622
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessService.java
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Martin Oberhuber (Wind River) - [238564] Adopt TM 3.0 APIs
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Intel Corporation - [329654] Make all sub services operate against TCF connector service
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.rse.core.model.IHost;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.clientserver.processes.HostProcessFilterImpl;
+import org.eclipse.rse.services.clientserver.processes.IHostProcess;
+import org.eclipse.rse.services.clientserver.processes.IHostProcessFilter;
+import org.eclipse.rse.services.clientserver.processes.ISystemProcessRemoteConstants;
+import org.eclipse.rse.services.processes.AbstractProcessService;
+import org.eclipse.rse.services.processes.IProcessService;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorServiceManager;
+import org.eclipse.tm.internal.tcf.rse.TCFRSETask;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IProcesses;
+
+
+public class TCFProcessService extends AbstractProcessService implements IProcessService {
+
+ private final TCFConnectorService connector;
+ private final TCFProcessResource root;
+ private final Map<Long,TCFProcessResource> pid2res = new HashMap<Long,TCFProcessResource>();
+ private final Map<String,Long> signals = new HashMap<String,Long>();
+ private final List<Runnable> get_signals_wait_list = new ArrayList<Runnable>();
+
+ public TCFProcessService(IHost host) {
+ connector = (TCFConnectorService)TCFConnectorServiceManager
+ .getInstance().getConnectorService(host, ITCFService.class);
+ root = new TCFProcessResource(this, null, null, null);
+ }
+
+ public TCFConnectorService getTCFConnectorService() {
+ return connector;
+ }
+
+ @Override
+ public String getDescription() {
+ return "The TCF Process Service uses the Target Communication Framework to provide service for the Processes subsystem." + //$NON-NLS-1$
+ " It requires a TCF agent to be running on the remote machine."; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getName() {
+ return "TCF Process Service"; //$NON-NLS-1$
+ }
+
+ @Override
+ public IHostProcess getParentProcess(long PID, IProgressMonitor monitor) throws SystemMessageException {
+ return getProcess(getProcess(PID, monitor).getPPid(), monitor);
+ }
+
+ @Override
+ public IHostProcess getProcess(final long PID, IProgressMonitor monitor) throws SystemMessageException {
+ return new TCFRSETask<IHostProcess>() {
+ public void run() {
+ if (!root.loadChildren(this)) return;
+ if (root.getChildrenError() != null) {
+ error(root.getChildrenError());
+ return;
+ }
+ done(pid2res.get(PID));
+ }
+ }.getS(monitor, "Get process properties"); //$NON-NLS-1$
+ }
+
+ public String[] getSignalTypes() {
+ return new TCFRSETask<String[]>() {
+ public void run() {
+ if (signals.isEmpty()) {
+ if (get_signals_wait_list.contains(this)) {
+ done(signals.keySet().toArray(new String[signals.size()]));
+ }
+ else {
+ if (get_signals_wait_list.isEmpty()) {
+ connector.getService(IProcesses.class).getSignalList(null, new IProcesses.DoneGetSignalList() {
+ public void doneGetSignalList(IToken token, Exception error, Collection<Map<String,Object>> list) {
+ if (list != null) {
+ for (Map<String,Object> m : list) {
+ String name = (String)m.get(IProcesses.SIG_NAME);
+ Number code = (Number)m.get(IProcesses.SIG_CODE);
+ if (name != null && code != null) signals.put(name, code.longValue());
+ }
+ }
+ for (Runnable r : get_signals_wait_list) r.run();
+ get_signals_wait_list.clear();
+ }
+ });
+ }
+ get_signals_wait_list.add(this);
+ }
+ }
+ else {
+ done(signals.keySet().toArray(new String[signals.size()]));
+ }
+ }
+ }.getE();
+ }
+
+ public boolean kill(final long PID, final String signal, IProgressMonitor monitor) throws SystemMessageException {
+ return new TCFRSETask<Boolean>() {
+ public void run() {
+ if (!root.loadChildren(this)) return;
+ if (root.getChildrenError() != null) {
+ error(root.getChildrenError());
+ return;
+ }
+ TCFProcessResource prs = pid2res.get(PID);
+ if (prs == null) {
+ done(false);
+ return;
+ }
+ Long signo = signals.get(signal);
+ if (signal.equals(ISystemProcessRemoteConstants.PROCESS_SIGNAL_TYPE_DEFAULT)) {
+ if (signo == null) signo = signals.get("SIGTERM");
+ if (signo == null) signo = signals.get("SIGKILL");
+ }
+ if (signo == null) {
+ error(new Exception("Unknown signal: " + signal));
+ return;
+ }
+ connector.getService(IProcesses.class).signal(prs.getID(), signo.longValue(), new IProcesses.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) {
+ error(error);
+ }
+ else {
+ done(true);
+ }
+ }
+ });
+ }
+ }.getS(monitor, "Sending signal to a process"); //$NON-NLS-1$
+ }
+
+ private void sort(IHostProcess[] arr) {
+ Comparator<IHostProcess> c = new Comparator<IHostProcess>() {
+ public int compare(IHostProcess o1, IHostProcess o2) {
+ long p1 = o1.getPid();
+ long p2 = o2.getPid();
+ if (p1 < p2) return -1;
+ if (p1 > p2) return 1;
+ return 0;
+ }
+ };
+ Arrays.sort(arr, c);
+ }
+
+ @Override
+ public IHostProcess[] listAllProcesses(IProgressMonitor monitor) throws SystemMessageException {
+ HostProcessFilterImpl rpfs = new HostProcessFilterImpl();
+ return listAllProcesses(rpfs, monitor);
+ }
+
+ public IHostProcess[] listAllProcesses(final IHostProcessFilter filter, IProgressMonitor monitor) throws SystemMessageException {
+ return listAllProcesses(filter, root, monitor);
+ }
+
+ private boolean eqaulIDs(String x, String y) {
+ if (x == null) return y == null;
+ return x.equals(y);
+ }
+
+ public IHostProcess[] listAllProcesses(final IHostProcessFilter filter, final IHostProcess up, IProgressMonitor monitor) throws SystemMessageException {
+ new TCFRSETask<Boolean>() {
+ public void run() {
+ TCFProcessResource parent = (TCFProcessResource)up;
+ if (parent != null) {
+ if (filter.getPpid() == null || filter.getPpid().equals("*") || parent.getChildrenError() != null) { //$NON-NLS-1$
+ parent.flushChildrenCache();
+ }
+ }
+ done(true);
+ }
+ }.getE();
+ return new TCFRSETask<IHostProcess[]>() {
+ public void run() {
+ TCFProcessResource parent = (TCFProcessResource)up;
+ if (parent == null) {
+ error(new IOException("Invalid parent")); //$NON-NLS-1$
+ return;
+ }
+ if (!parent.loadChildren(this)) return;
+ if (parent.getChildrenError() != null) {
+ error(parent.getChildrenError());
+ return;
+ }
+ List<IHostProcess> l = new ArrayList<IHostProcess>();
+ for (TCFProcessResource p : pid2res.values()) {
+ if (eqaulIDs(parent.getID(), p.getParentID())) {
+ if (p.getError() == null && filter.allows(p.getStatusLine())) l.add(p);
+ }
+ }
+ IHostProcess[] arr = new IHostProcess[l.size()];
+ l.toArray(arr);
+ sort(arr);
+ done(arr);
+ }
+ }.getS(monitor, "List processes"); //$NON-NLS-1$
+ }
+
+ @Override
+ public IHostProcess[] listAllProcesses(String exeNameFilter, String userNameFilter, String stateFilter, IProgressMonitor monitor)
+ throws SystemMessageException {
+ HostProcessFilterImpl rpfs = new HostProcessFilterImpl();
+ rpfs.setName(exeNameFilter);
+ rpfs.setUsername(userNameFilter);
+ rpfs.setSpecificState(stateFilter);
+ return listAllProcesses(rpfs, monitor);
+ }
+
+ @Override
+ public IHostProcess[] listChildProcesses(long parentPID, IProgressMonitor monitor) throws SystemMessageException {
+ HostProcessFilterImpl rpfs = new HostProcessFilterImpl();
+ return listChildProcesses(parentPID, rpfs, monitor);
+ }
+
+ @Override
+ public IHostProcess[] listChildProcesses(long parentPID, IHostProcessFilter filter, IProgressMonitor monitor)
+ throws SystemMessageException {
+ filter.setPpid(Long.toString(parentPID));
+ return listAllProcesses(filter, monitor);
+ }
+
+ @Override
+ public IHostProcess[] listRootProcesses(IProgressMonitor monitor) throws SystemMessageException {
+ IHostProcess[] roots = new IHostProcess[1];
+ roots[0] = getProcess(1, monitor);
+ return roots;
+ }
+
+ Map<Long,TCFProcessResource> getProcessCache() {
+ return pid2res;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessSubSystemConfiguration.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessSubSystemConfiguration.java
new file mode 100644
index 000000000..cd8698c0f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFProcessSubSystemConfiguration.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ * Intel Corporation - [329654] Make all sub services operate against TCF connector service
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+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.services.processes.IProcessService;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter;
+import org.eclipse.rse.subsystems.processes.servicesubsystem.ProcessServiceSubSystem;
+import org.eclipse.rse.subsystems.processes.servicesubsystem.ProcessServiceSubSystemConfiguration;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorServiceManager;
+
+public class TCFProcessSubSystemConfiguration extends ProcessServiceSubSystemConfiguration {
+
+ private final TCFProcessAdapter process_adapter = new TCFProcessAdapter();
+
+ @Override
+ public Class<ITCFService> getServiceImplType() {
+ return ITCFService.class;
+ }
+
+ @Override
+ public ISubSystem createSubSystemInternal(IHost host) {
+ TCFConnectorService connectorService = (TCFConnectorService)getConnectorService(host);
+ return new ProcessServiceSubSystem(host, connectorService,
+ getProcessService(host), getHostProcessAdapter());
+ }
+
+ public IProcessService createProcessService(IHost host) {
+ return new TCFProcessService(host);
+ }
+
+ public IHostProcessToRemoteProcessAdapter getHostProcessAdapter() {
+ return process_adapter;
+ }
+
+ @Override
+ public IConnectorService getConnectorService(IHost host) {
+ return TCFConnectorServiceManager.getInstance()
+ .getConnectorService(host, getServiceImplType());
+ }
+
+ @Override
+ public void setConnectorService(IHost host, IConnectorService connectorService) {
+ TCFConnectorServiceManager.getInstance().setConnectorService(host, getServiceImplType(), connectorService);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFRemoteProcess.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFRemoteProcess.java
new file mode 100644
index 000000000..26b10dac0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFRemoteProcess.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import java.util.Map;
+
+import org.eclipse.rse.services.clientserver.processes.IHostProcess;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessContext;
+import org.eclipse.rse.subsystems.processes.core.subsystem.impl.RemoteProcessImpl;
+
+public class TCFRemoteProcess extends RemoteProcessImpl {
+
+ public TCFRemoteProcess(IRemoteProcessContext context, IHostProcess process) {
+ super(context, process);
+ assert process != null;
+ }
+
+ @Override
+ public Object getObject() {
+ return _underlyingProcess;
+ }
+
+ public Map<String,Object> getProperties() {
+ return ((TCFProcessResource)_underlyingProcess).getProperties();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewProcessAdapterFactory.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewProcessAdapterFactory.java
new file mode 100644
index 000000000..7a9b1771a
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewProcessAdapterFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.rse.core.subsystems.IRemoteObjectIdentifier;
+import org.eclipse.rse.core.subsystems.ISystemDragDropAdapter;
+import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter;
+import org.eclipse.rse.ui.view.ISystemViewElementAdapter;
+import org.eclipse.ui.IActionFilter;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+public class TCFSystemViewProcessAdapterFactory implements IAdapterFactory {
+
+ private final TCFSystemViewRemoteProcessAdapter adapter =
+ new TCFSystemViewRemoteProcessAdapter();
+
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ assert adaptableObject instanceof TCFRemoteProcess;
+ if (adapterType == IPropertySource.class) {
+ ((ISystemViewElementAdapter)adapter).setPropertySourceInput(adaptableObject);
+ }
+ return adapter;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Class[] getAdapterList() {
+ return new Class[] {
+ ISystemViewElementAdapter.class,
+ ISystemDragDropAdapter.class,
+ ISystemRemoteElementAdapter.class,
+ IPropertySource.class,
+ IWorkbenchAdapter.class,
+ IActionFilter.class,
+ IDeferredWorkbenchAdapter.class,
+ IRemoteObjectIdentifier.class,
+ };
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewRemoteProcessAdapter.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewRemoteProcessAdapter.java
new file mode 100644
index 000000000..cf14e0018
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/processes/TCFSystemViewRemoteProcessAdapter.java
@@ -0,0 +1,502 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ * Uwe Stieber (Wind River) - [271227] Fix compiler warnings in org.eclipse.tm.tcf.rse
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.processes;
+
+import java.math.BigInteger;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.rse.core.model.ISystemMessageObject;
+import org.eclipse.rse.core.model.ISystemResourceSet;
+import org.eclipse.rse.core.model.SystemMessageObject;
+import org.eclipse.rse.core.model.SystemRemoteResourceSet;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.internal.processes.ui.actions.SystemKillProcessAction;
+import org.eclipse.rse.services.clientserver.processes.HostProcessFilterImpl;
+import org.eclipse.rse.services.clientserver.processes.IHostProcess;
+import org.eclipse.rse.services.clientserver.processes.IHostProcessFilter;
+import org.eclipse.rse.services.clientserver.processes.ISystemProcessRemoteTypes;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcess;
+import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessSubSystem;
+import org.eclipse.rse.ui.ISystemContextMenuConstants;
+import org.eclipse.rse.ui.ISystemMessages;
+import org.eclipse.rse.ui.RSEUIPlugin;
+import org.eclipse.rse.ui.SystemBasePlugin;
+import org.eclipse.rse.ui.SystemMenuManager;
+import org.eclipse.rse.ui.actions.SystemCopyToClipboardAction;
+import org.eclipse.rse.ui.view.AbstractSystemViewAdapter;
+import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter;
+import org.eclipse.rse.ui.view.ISystemViewElementAdapter;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.rse.Activator;
+import org.eclipse.tm.internal.tcf.rse.Messages;
+import org.eclipse.tm.tcf.services.ISysMonitor;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+
+
+@SuppressWarnings("restriction")
+public class TCFSystemViewRemoteProcessAdapter extends AbstractSystemViewAdapter
+ implements ISystemViewElementAdapter, ISystemRemoteElementAdapter{
+
+ private SystemCopyToClipboardAction copyClipboardAction;
+ private static final Object[] EMPTY_LIST = new Object[0];
+ private static IPropertyDescriptor[] properties = null;
+ private SystemKillProcessAction killProcessAction;
+
+ private static final NumberFormat percent_format;
+
+ static {
+ percent_format = NumberFormat.getPercentInstance();
+ percent_format.setMaximumFractionDigits(3);
+ }
+
+ @Override
+ public boolean canDrag(Object element) {
+ return true;
+ }
+
+ @Override
+ public boolean canDrag(SystemRemoteResourceSet elements) {
+ return true;
+ }
+
+ @Override
+ public Object doDrag(Object element, boolean sameSystemType, IProgressMonitor monitor) {
+ return getText(element);
+ }
+
+ @Override
+ public ISystemResourceSet doDrag(SystemRemoteResourceSet set, IProgressMonitor monitor) {
+ return set;
+ }
+
+ @Override
+ public void addActions(SystemMenuManager menu,
+ IStructuredSelection selection, Shell parent, String menuGroup) {
+ if (killProcessAction == null) {
+ killProcessAction = new SystemKillProcessAction(getShell());
+ }
+ menu.add(ISystemContextMenuConstants.GROUP_CHANGE, killProcessAction);
+ if (copyClipboardAction == null) {
+ Clipboard clipboard = RSEUIPlugin.getTheSystemRegistryUI().getSystemClipboard();
+ copyClipboardAction = new SystemCopyToClipboardAction(getShell(), clipboard);
+ }
+ menu.add(menuGroup, copyClipboardAction);
+ }
+
+ @Override
+ public ISubSystem getSubSystem(Object element) {
+ if (element instanceof IRemoteProcess) {
+ IRemoteProcess process = (IRemoteProcess)element;
+ return process.getParentRemoteProcessSubSystem();
+ }
+ return super.getSubSystem(element);
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor(Object element) {
+ IRemoteProcess process = (IRemoteProcess)element;
+ TCFProcessResource r = (TCFProcessResource)process.getObject();
+ String state = r.getState();
+ if (r.getParentID() != null) {
+ if (state == null || state.indexOf('R') >= 0) {
+ return Activator.getDefault().getImageDescriptorFromPath("icons/thread-r.gif"); //$NON-NLS-1$
+ }
+ return Activator.getDefault().getImageDescriptorFromPath("icons/thread-s.gif"); //$NON-NLS-1$
+ }
+ else {
+ if (state == null || state.indexOf('R') >= 0) {
+ return Activator.getDefault().getImageDescriptorFromPath("icons/process-r.gif"); //$NON-NLS-1$
+ }
+ return Activator.getDefault().getImageDescriptorFromPath("icons/process-s.gif"); //$NON-NLS-1$
+ }
+ }
+
+ public String getText(Object element) {
+ String text = ((IRemoteProcess)element).getLabel();
+ return (text == null) ? "" : text; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getAlternateText(Object element) {
+ IRemoteProcess process = (IRemoteProcess)element;
+ String allProperties = process.getAllProperties();
+ return allProperties.replace('|', '\t');
+ }
+
+ public String getAbsoluteName(Object object) {
+ IRemoteProcess process = (IRemoteProcess) object;
+ return "" + process.getPid(); //$NON-NLS-1$
+ }
+
+ @Override
+ public String getType(Object element) {
+ return "Process"; //$NON-NLS-1$
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ IRemoteProcess process = (IRemoteProcess) element;
+ IRemoteProcess parent = process.getParentRemoteProcess();
+ if ((parent != null) && parent.getAbsolutePath().equals(process.getAbsolutePath()))
+ // should never happen but sometimes it does, leading to infinite loop.
+ parent = null;
+ return parent;
+ }
+
+ @Override
+ public boolean hasChildren(IAdaptable element) {
+ return getChildren(element, new NullProgressMonitor()).length > 0;
+ }
+
+ @Override
+ public Object[] getChildren(IAdaptable element, IProgressMonitor monitor) {
+ IRemoteProcess process = (IRemoteProcess)element;
+ IRemoteProcessSubSystem ss = process.getParentRemoteProcessSubSystem();
+ IHostProcessFilter orgRpfs = process.getFilterString();
+ IHostProcessFilter newRpfs = new HostProcessFilterImpl(orgRpfs.toString());
+
+ Object[] children1 = null;
+ Object[] children2 = null;
+ newRpfs.setPpid(Long.toString(process.getPid()));
+
+ try {
+ TCFProcessResource r = (TCFProcessResource)process.getObject();
+ IHostProcess[] nodes = r.getService().listAllProcesses(orgRpfs, r, monitor);
+ TCFProcessAdapter adapter = new TCFProcessAdapter();
+ children1 = adapter.convertToRemoteProcesses(process.getContext(), process, nodes);
+ if (children1 == null) children1 = EMPTY_LIST;
+
+ children2 = ss.listAllProcesses(newRpfs, process.getContext(), monitor);
+ if (children2 == null) children2 = EMPTY_LIST;
+ }
+ catch (Exception exc) {
+ children1 = new SystemMessageObject[1];
+ children1[0] = new SystemMessageObject(RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_EXPAND_FAILED), ISystemMessageObject.MSGTYPE_ERROR, element);
+ children2 = null;
+ SystemBasePlugin.logError("Exception resolving file filter strings", exc); //$NON-NLS-1$
+ }
+ if (children1 == null || children1.length == 0) return children2;
+ if (children2 == null || children2.length == 0) return children1;
+ Object[] children = new Object[children1.length + children2.length];
+ System.arraycopy(children1, 0, children, 0, children1.length);
+ System.arraycopy(children2, 0, children, children1.length, children2.length);
+ return children;
+ }
+
+ @Override
+ protected IPropertyDescriptor[] internalGetPropertyDescriptors() {
+ if (properties != null) return properties;
+ List<IPropertyDescriptor> l = new ArrayList<IPropertyDescriptor>();
+
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_ID, Messages.PROCESS_ID_LABEL, Messages.PROCESS_ID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_PID, Messages.PROCESS_PID_LABEL, Messages.PROCESS_PID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_FILE, Messages.PROCESS_NAME_LABEL, Messages.PROCESS_NAME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CWD, Messages.PROCESS_CWD_LABEL, Messages.PROCESS_CWD_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_ROOT, Messages.PROCESS_ROOT_LABEL, Messages.PROCESS_ROOT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_STATE, Messages.PROCESS_STATE_LABEL, Messages.PROCESS_STATE_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_UID, Messages.PROCESS_UID_LABEL, Messages.PROCESS_UID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_USERNAME, Messages.PROCESS_USERNAME_LABEL, Messages.PROCESS_USERNAME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_UGID, Messages.PROCESS_GID_LABEL, Messages.PROCESS_GID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_GROUPNAME, Messages.PROCESS_GROUPNAME_LABEL, Messages.PROCESS_GROUPNAME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_PPID, Messages.PROCESS_PPID_LABEL, Messages.PROCESS_PPID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_PGRP, Messages.PROCESS_PGRP_LABEL, Messages.PROCESS_PGRP_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_TGID, Messages.PROCESS_TGID_LABEL, Messages.PROCESS_TGID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_TRACERPID, Messages.PROCESS_TRACERPID_LABEL, Messages.PROCESS_TRACERPID_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_VSIZE, Messages.PROCESS_VMSIZE_LABEL, Messages.PROCESS_VMSIZE_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_RSS, Messages.PROCESS_VMRSS_LABEL, Messages.PROCESS_VMRSS_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_SESSION, Messages.PROCESS_SESSION_LABEL, Messages.PROCESS_SESSION_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_TTY, Messages.PROCESS_TTY_LABEL, Messages.PROCESS_TTY_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_FLAGS, Messages.PROCESS_FLAGS_LABEL, Messages.PROCESS_FLAGS_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_MINFLT, Messages.PROCESS_MINFLT_LABEL, Messages.PROCESS_MINFLT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CMINFLT, Messages.PROCESS_CMINFLT_LABEL, Messages.PROCESS_CMINFLT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_MAJFLT, Messages.PROCESS_MAJFLT_LABEL, Messages.PROCESS_MAJFLT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CMAJFLT, Messages.PROCESS_CMAJFLT_LABEL, Messages.PROCESS_CMAJFLT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_UTIME, Messages.PROCESS_UTIME_LABEL, Messages.PROCESS_UTIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_STIME, Messages.PROCESS_STIME_LABEL, Messages.PROCESS_STIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CUTIME, Messages.PROCESS_CUTIME_LABEL, Messages.PROCESS_CUTIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CSTIME, Messages.PROCESS_CSTIME_LABEL, Messages.PROCESS_CSTIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(TCFProcessResource.PROP_PC_UTIME, Messages.PROCESS_PC_UTIME_LABEL, Messages.PROCESS_PC_UTIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(TCFProcessResource.PROP_PC_STIME, Messages.PROCESS_PC_STIME_LABEL, Messages.PROCESS_PC_STIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_PRIORITY, Messages.PROCESS_PRIORITY_LABEL, Messages.PROCESS_PRIORITY_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_NICE, Messages.PROCESS_NICE_LABEL, Messages.PROCESS_NICE_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_ITREALVALUE, Messages.PROCESS_ITREALVALUE_LABEL, Messages.PROCESS_ITREALVALUE_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_STARTTIME, Messages.PROCESS_STARTTIME_LABEL, Messages.PROCESS_STARTTIME_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_RLIMIT, Messages.PROCESS_RLIMIT_LABEL, Messages.PROCESS_RLIMIT_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CODESTART, Messages.PROCESS_CODESTART_LABEL, Messages.PROCESS_CODESTART_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CODEEND, Messages.PROCESS_CODEEND_LABEL, Messages.PROCESS_CODEEND_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_STACKSTART, Messages.PROCESS_STACKSTART_LABEL, Messages.PROCESS_STACKSTART_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_SIGNALS, Messages.PROCESS_SIGNALS_LABEL, Messages.PROCESS_SIGNALS_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_SIGBLOCK, Messages.PROCESS_SIGBLOCK_LABEL, Messages.PROCESS_SIGBLOCK_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_SIGIGNORE, Messages.PROCESS_SIGIGNORE_LABEL, Messages.PROCESS_SIGIGNORE_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_SIGCATCH, Messages.PROCESS_SIGCATCH_LABEL, Messages.PROCESS_SIGCATCH_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_WCHAN, Messages.PROCESS_WCHAN_LABEL, Messages.PROCESS_WCHAN_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_NSWAP, Messages.PROCESS_NSWAP_LABEL, Messages.PROCESS_NSWAP_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_CNSWAP, Messages.PROCESS_CNSWAP_LABEL, Messages.PROCESS_CNSWAP_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_EXITSIGNAL, Messages.PROCESS_EXITSIGNAL_LABEL, Messages.PROCESS_EXITSIGNAL_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_PROCESSOR, Messages.PROCESS_PROCESSOR_LABEL, Messages.PROCESS_PROCESSOR_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_RTPRIORITY, Messages.PROCESS_RTPRIORITY_LABEL, Messages.PROCESS_RTPRIORITY_TOOLTIP));
+ l.add(createSimplePropertyDescriptor(ISysMonitor.PROP_POLICY, Messages.PROCESS_POLICY_LABEL, Messages.PROCESS_POLICY_TOOLTIP));
+
+ properties = l.toArray(new IPropertyDescriptor[l.size()]);
+ return properties;
+ }
+
+ /**
+ * Returns the current value for the named property.
+ * @return the current value of the given property
+ */
+ @Override
+ protected Object internalGetPropertyValue(Object property) {
+ Object v = internalGetPropertyValueOrNull(property);
+ if (v == null) v = "";
+ return v;
+ }
+
+ private Object internalGetPropertyValueOrNull(Object property) {
+ TCFRemoteProcess process = (TCFRemoteProcess)propertySourceInput;
+ Object p = process.getProperties().get(property);
+ if (property.equals(ISysMonitor.PROP_VSIZE)) {
+ return NLS.bind(Messages.PROCESS_VMSIZE_VALUE, Long.toString(process.getVmSizeInKB()));
+ }
+ if (property.equals(ISysMonitor.PROP_RSS)) {
+ return NLS.bind(Messages.PROCESS_VMRSS_VALUE, Long.toString(process.getVmRSSInKB()));
+ }
+ if (property.equals(ISysMonitor.PROP_SIGNALS)) return formatBitSet(p);
+ if (property.equals(ISysMonitor.PROP_SIGBLOCK)) return formatBitSet(p);
+ if (property.equals(ISysMonitor.PROP_SIGCATCH)) return formatBitSet(p);
+ if (property.equals(ISysMonitor.PROP_SIGIGNORE)) return formatBitSet(p);
+ if (property.equals(ISysMonitor.PROP_CODESTART)) return formatHex(p);
+ if (property.equals(ISysMonitor.PROP_CODEEND)) return formatHex(p);
+ if (property.equals(ISysMonitor.PROP_STACKSTART)) return formatHex(p);
+ if (property.equals(ISysMonitor.PROP_WCHAN)) return formatHex(p);
+ if (property.equals(ISysMonitor.PROP_FLAGS)) return formatBitSet(p);
+ if (property.equals(ISysMonitor.PROP_UTIME)) return formatTime(p);
+ if (property.equals(ISysMonitor.PROP_STIME)) return formatTime(p);
+ if (property.equals(ISysMonitor.PROP_CUTIME)) return formatTime(p);
+ if (property.equals(ISysMonitor.PROP_CSTIME)) return formatTime(p);
+ if (property.equals(ISysMonitor.PROP_STARTTIME)) return formatTime(p);
+ if (property.equals(ISysMonitor.PROP_ITREALVALUE)) return formatTime(p);
+ if (property.equals(TCFProcessResource.PROP_PC_UTIME)) return formatPercent(p);
+ if (property.equals(TCFProcessResource.PROP_PC_STIME)) return formatPercent(p);
+ if (p != null) return p.toString();
+ return null;
+ }
+
+ /**
+ * Returns the current value for the named property.
+ *
+ * @param property the name or key of the property as named by its property descriptor
+ * @param formatted indication of whether to return the value in formatted or raw form
+ * @return the current value of the given property
+ */
+ @Override
+ public Object getPropertyValue(Object property, boolean formatted) {
+ if (formatted) return getPropertyValue(property);
+
+ TCFRemoteProcess process = (TCFRemoteProcess)propertySourceInput;
+ Object p = process.getProperties().get(property);
+ if (p == null) {
+ if (property.equals(ISysMonitor.PROP_PID)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_PPID)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_CODESTART)) return BigInteger.ZERO;
+ if (property.equals(ISysMonitor.PROP_CODEEND)) return BigInteger.ZERO;
+ if (property.equals(ISysMonitor.PROP_STACKSTART)) return BigInteger.ZERO;
+ if (property.equals(ISysMonitor.PROP_WCHAN)) return BigInteger.ZERO;
+ if (property.equals(ISysMonitor.PROP_UTIME)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_STIME)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_CUTIME)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_CSTIME)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_STARTTIME)) return Long.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_ITREALVALUE)) return Long.valueOf(0);
+ if (property.equals(TCFProcessResource.PROP_PC_UTIME)) return Double.valueOf(0);
+ if (property.equals(TCFProcessResource.PROP_PC_STIME)) return Double.valueOf(0);
+ if (property.equals(ISysMonitor.PROP_CWD)) return "";
+ if (property.equals(ISysMonitor.PROP_FILE)) return "";
+ }
+ return p;
+ }
+
+ private String formatPercent(Object o) {
+ if (o instanceof Number) {
+ Number n = (Number)o;
+ return percent_format.format(n.doubleValue());
+ }
+ return null;
+ }
+
+ private String formatTime(Object o) {
+ if (o instanceof Number) {
+ BigInteger n = new BigInteger(o.toString());
+ BigInteger s[] = n.divideAndRemainder(BigInteger.valueOf(1000));
+ BigInteger m[] = s[0].divideAndRemainder(BigInteger.valueOf(60));
+ BigInteger h[] = m[0].divideAndRemainder(BigInteger.valueOf(60));
+ StringBuffer buf = new StringBuffer();
+ if (!h[0].equals(BigInteger.ZERO)) {
+ buf.append(h[0]);
+ buf.append("h "); //$NON-NLS-1$
+ }
+ if (buf.length() > 0 || !h[1].equals(BigInteger.ZERO)) {
+ buf.append(h[1]);
+ buf.append("m "); //$NON-NLS-1$
+ }
+ buf.append(m[1]);
+ buf.append('.');
+ String ms = s[1].toString();
+ buf.append("000".substring(ms.length())); //$NON-NLS-1$
+ buf.append(ms);
+ buf.append('s');
+ return buf.toString();
+ }
+ if (o == null) return null;
+ return o.toString();
+ }
+
+ private void formatHex(StringBuffer buf, BigInteger n, int cnt) {
+ BigInteger m[] = n.divideAndRemainder(BigInteger.valueOf(16));
+ if (cnt < 7 || !m[0].equals(BigInteger.ZERO)) {
+ formatHex(buf, m[0], cnt + 1);
+ }
+ int d = m[1].intValue();
+ buf.append((char)(d <= 9 ? '0' + d : 'a' + d - 10));
+ }
+
+ protected String formatHex(Object o) {
+ if (o instanceof Number) {
+ BigInteger n = o instanceof BigInteger ?
+ (BigInteger)o : new BigInteger(o.toString());
+ StringBuffer buf = new StringBuffer();
+ buf.append("0x"); //$NON-NLS-1$
+ formatHex(buf, n, 0);
+ return buf.toString();
+ }
+ if (o == null) return null;
+ return o.toString();
+ }
+
+ protected String formatBitSet(Object o) {
+ if (o instanceof Number) {
+ StringBuffer buf = new StringBuffer();
+ long n = ((Number)o).longValue();
+ for (int i = 0; i < 64; i++) {
+ if ((n & (1l << i)) != 0) {
+ if (buf.length() > 0) buf.append(',');
+ int i0 = i;
+ while (i < 63 && (n & (1l << (i + 1))) != 0) i++;
+ buf.append(i0);
+ if (i0 != i) {
+ buf.append(".."); //$NON-NLS-1$
+ buf.append(i);
+ }
+ }
+ }
+ return buf.toString();
+ }
+ if (o == null) return null;
+ return o.toString();
+ }
+
+ protected String formatState(String state) {
+ return state;
+ }
+
+ /**
+ * Return fully qualified name that uniquely identifies this remote object's remote parent within its subsystem
+ */
+ public String getAbsoluteParentName(Object element) {
+ IRemoteProcess process = (IRemoteProcess) element;
+ IRemoteProcess parent = process.getParentRemoteProcess();
+ if (parent != null) return parent.getAbsolutePath();
+ else return "/proc/0"; //$NON-NLS-1$
+ }
+
+ /**
+ * Given a remote object, returns it remote parent object. Eg, given a process, return the process that
+ * spawned it.
+ * <p>
+ * The shell is required in order to set the cursor to a busy state if a remote trip is required.
+ *
+ * @return an IRemoteProcess object for the parent
+ */
+ public Object getRemoteParent(Object element, IProgressMonitor monitor) throws Exception {
+ return ((IRemoteProcess) element).getParentRemoteProcess();
+ }
+
+ /**
+ * Given a remote object, return the unqualified names of the objects contained in that parent. This is
+ * used for testing for uniqueness on a rename operation, for example. Sometimes, it is not
+ * enough to just enumerate all the objects in the parent for this purpose, because duplicate
+ * names are allowed if the types are different, such as on iSeries. In this case return only
+ * the names which should be used to do name-uniqueness validation on a rename operation.
+ *
+ * @return an array of all file and folder names in the parent of the given IRemoteFile object
+ */
+ public String[] getRemoteParentNamesInUse(Object element, IProgressMonitor monitor) throws Exception {
+ String[] pids = EMPTY_STRING_LIST;
+
+ IRemoteProcess process = (IRemoteProcess) element;
+ String parentName = "" + process.getPPid(); //$NON-NLS-1$
+ if (parentName.equals("-1")) // given a root? //$NON-NLS-1$
+ return pids; // not much we can do. Should never happen: you can't rename a root!
+
+ Object[] children = getChildren(process.getParentRemoteProcess(), monitor);
+ if ((children == null) || (children.length == 0))
+ return pids;
+
+ pids = new String[children.length];
+ for (int idx = 0; idx < pids.length; idx++)
+ pids[idx] = "" + ((IRemoteProcess) children[idx]).getPid(); //$NON-NLS-1$
+
+ return pids;
+ }
+
+ public String getRemoteSubType(Object element) {
+ return null;
+ }
+
+ public String getRemoteType(Object element) {
+ IRemoteProcess process = (IRemoteProcess) element;
+ if (process.isRoot())
+ return ISystemProcessRemoteTypes.TYPE_ROOT;
+ else
+ return ISystemProcessRemoteTypes.TYPE_PROCESS;
+ }
+
+ public String getRemoteTypeCategory(Object element) {
+ return ISystemProcessRemoteTypes.TYPECATEGORY;
+ }
+
+ /**
+ * Return the subsystem factory id that owns this remote object
+ * The value must not be translated, so that property pages registered via xml can subset by it.
+ */
+ public String getSubSystemConfigurationId(Object element) {
+ IRemoteProcess process = (IRemoteProcess) element;
+ return process.getParentRemoteProcessSubSystem().getSubSystemConfiguration().getId();
+ }
+
+ public boolean refreshRemoteObject(Object oldElement, Object newElement) {
+ return false;
+ }
+
+ public boolean supportsUserDefinedActions(Object object) {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFServiceCommandShell.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFServiceCommandShell.java
new file mode 100644
index 000000000..f7c55c77d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFServiceCommandShell.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation 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
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
+ * Martin Oberhuber (Wind River) - [225510][api] Fix OutputRefreshJob API leakage
+ * Anna Dushistova (MontaVista) - [259414][api] refactor the "SSH Shell" to use the generic Terminal->IHostShell converter
+ * Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
+ * David McKnight (IBM) - [272032][ssh][telnet][local] shell output not setting line numbers when available
+ * Liping Ke (Intel Corp.)- Adapted from org.eclipse.rse.internal.subsystems.shells.ssh.SshServiceCommandShell
+ * Liping Ke (Intel Corp.)- [246987] Implement TCF Shell/terminal services
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.shells;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.rse.core.subsystems.ISubSystem;
+import org.eclipse.rse.internal.services.shells.TerminalServiceHostShell;
+import org.eclipse.rse.services.shells.IHostOutput;
+import org.eclipse.rse.services.shells.IHostShell;
+import org.eclipse.rse.services.shells.IHostShellChangeEvent;
+import org.eclipse.rse.services.shells.ParsedOutput;
+import org.eclipse.rse.services.shells.Patterns;
+import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
+import org.eclipse.rse.subsystems.shells.core.model.ISystemOutputRemoteTypes;
+import org.eclipse.rse.subsystems.shells.core.model.RemoteError;
+import org.eclipse.rse.subsystems.shells.core.model.RemoteOutput;
+import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
+import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteOutput;
+import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ServiceCommandShell;
+
+@SuppressWarnings("restriction")
+public class TCFServiceCommandShell extends ServiceCommandShell {
+ private Patterns _patterns;
+ private String _workingDir;
+ private String _curCommand;
+ private IRemoteFileSubSystem _fs;
+
+ public TCFServiceCommandShell(IRemoteCmdSubSystem cmdSS,
+ IHostShell hostShell) {
+ super(cmdSS, hostShell);
+ _patterns = new Patterns();
+ _patterns.update("cmd"); //$NON-NLS-1$
+ ISubSystem[] sses = cmdSS.getHost().getSubSystems();
+ for (int i = 0; i < sses.length; i++)
+ {
+ if (sses[i] instanceof IRemoteFileSubSystem)
+ {
+ _fs = (IRemoteFileSubSystem)sses[i];
+ break;
+ }
+ }
+ }
+
+ public Object getContext()
+ {
+ String workingDir = _workingDir;
+ if (workingDir != null && workingDir.length() > 0)
+ {
+ try {
+ return _fs.getRemoteFileObject(workingDir, new NullProgressMonitor());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ return null;
+
+ }
+
+ public String getContextString()
+ {
+ return _workingDir;
+ }
+
+ public void shellOutputChanged(IHostShellChangeEvent event)
+ {
+ IHostOutput[] lines = event.getLines();
+ boolean gotCommand = false;
+ ArrayList<RemoteOutput> outputs = new ArrayList<RemoteOutput>(lines.length);
+ for (int i = 0; i < lines.length; i++)
+ {
+ String line = lines[i].getString();
+ if (line.endsWith(getPromptCommand())) {
+ continue; //ignore our synthetic prompt command
+ }
+ ParsedOutput parsedMsg = null;
+ if (!gotCommand && line.equals(_curCommand)) {
+ gotCommand = true;
+ continue; //ignore remote command echo
+ } else
+ {
+ try
+ {
+ // Bug 160202: Remote shell dies.
+ if ((_curCommand == null) || (!_curCommand.trim().equals("ls"))) { //$NON-NLS-1$
+ parsedMsg = _patterns.matchLine(line);
+
+ // Bug 160202: Remote shell dies.
+ if (_curCommand != null) {
+ String temp = _curCommand.trim();
+ StringTokenizer tokenizer = new StringTokenizer(temp);
+
+ if (tokenizer.countTokens() == 2) {
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+
+ if ((token1.equals("ls")) && (token2.indexOf('-') == 0) && (token2.indexOf('l') > 0)) { //$NON-NLS-1$
+ if (line.startsWith("total")) { //$NON-NLS-1$
+ parsedMsg = null;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ RemoteOutput output = null;
+
+ String type = "stdout"; //$NON-NLS-1$
+
+ if (parsedMsg != null) {
+ type = parsedMsg.type;
+ }
+
+ if (event.isError()) {
+ output = new RemoteError(this, type);
+ }
+ else {
+ output = new RemoteOutput(this, type);
+ }
+
+ output.setText(line);
+ if (parsedMsg != null)
+ {
+ String file = parsedMsg.file;
+ if (type.equals(ISystemOutputRemoteTypes.TYPE_PROMPT))
+ {
+ _workingDir = file;
+ output.setAbsolutePath(_workingDir);
+ }
+ else if(_workingDir!=null)
+ {
+ IPath p = new Path(_workingDir).append(file);
+ output.setAbsolutePath(p.toString());
+ }
+ else
+ {
+ output.setAbsolutePath(file);
+ }
+ if (parsedMsg.line > 0){
+ output.setLine(parsedMsg.line);
+ }
+ }
+
+ addOutput(output);
+ outputs.add(output);
+ }
+
+ IRemoteOutput[] remoteOutputs = outputs.toArray(new IRemoteOutput[outputs.size()]);
+ notifyOutputChanged(remoteOutputs, false);
+ }
+
+ /**
+ * Return the prompt command, such that lines ending with the
+ * prompt command can be removed from output.
+ * Should be overridden in case the IHostShell used for this
+ * service is not an SshHostShell.
+ * @return String promptCommand
+ */
+ protected String getPromptCommand() {
+ IHostShell shell = getHostShell();
+ if (shell instanceof TerminalServiceHostShell) {
+ return ((TerminalServiceHostShell)shell).getPromptCommand();
+ }
+ //return something impossible such that nothing is ever matched
+ return "\uffff"; //$NON-NLS-1$
+ }
+
+ public void writeToShell(String cmd)
+ {
+ _curCommand = cmd;
+ _patterns.update(cmd);
+ super.writeToShell(cmd);
+
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFShellSubSystemConfiguration.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFShellSubSystemConfiguration.java
new file mode 100644
index 000000000..46b5902d1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFShellSubSystemConfiguration.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation 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
+ *
+ * Initial Contributors:
+ * The following IBM employees contributed to the Remote System Explorer
+ * component that contains this file: David McKnight, Kushal Munir,
+ * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
+ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
+ *
+ * Contributors:
+ * Martin Oberhuber (Wind River) - Adapted template for ssh service.
+ * Anna Dushistova (MontaVista) - [259414][api] refactor the "SSH Shell" to use the generic Terminal->IHostShell converter
+ * Liping Ke (Intel Corp.)- Adapted from org.eclipse.rse.subsystems.shells.ssh.SshShellSubSystemConfiguration
+ * Liping Ke (Intel Corp.)- [246987] Implement TCF Shell/terminal services
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.shells;
+
+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.services.shells.IHostShell;
+import org.eclipse.rse.services.shells.IShellService;
+import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
+import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IServiceCommandShell;
+import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystem;
+import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystemConfiguration;
+import org.eclipse.tm.internal.tcf.rse.*;
+import org.eclipse.tm.internal.tcf.rse.terminals.TCFTerminalService;
+
+
+public class TCFShellSubSystemConfiguration extends
+ ShellServiceSubSystemConfiguration {
+
+ public TCFShellSubSystemConfiguration() {
+ super();
+ }
+
+ /**
+ * Instantiate and return an instance of OUR subsystem.
+ * Do not populate it yet though!
+ * @see org.eclipse.rse.core.subsystems.SubSystemConfiguration#createSubSystemInternal(IHost)
+ */
+ public ISubSystem createSubSystemInternal(IHost host)
+ {
+ TCFConnectorService connectorService = (TCFConnectorService)getConnectorService(host);
+ ISubSystem subsys = new ShellServiceSubSystem(host, connectorService, createShellService(host));
+ return subsys;
+ }
+
+ public IConnectorService getConnectorService(IHost host) {
+ return TCFConnectorServiceManager.getInstance().getConnectorService(host, getServiceImplType());
+}
+
+ public void setConnectorService(IHost host,
+ IConnectorService connectorService) {
+ TCFConnectorServiceManager.getInstance().setConnectorService(host, getServiceImplType(), connectorService);
+ }
+
+ public Class<ITCFService> getServiceImplType()
+ {
+ return ITCFService.class;
+ }
+
+ public IServiceCommandShell createRemoteCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell) {
+ return new TCFServiceCommandShell(cmdSS, hostShell);
+ }
+
+ public IShellService createShellService(IHost host) {
+ TCFConnectorService cserv = (TCFConnectorService)getConnectorService(host);
+
+ return (IShellService) (new TCFTerminalService(cserv)).getAdapter(IShellService.class);
+ }
+
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalInputStream.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalInputStream.java
new file mode 100644
index 000000000..2c7d44e18
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalInputStream.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Intel Corporation. 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:
+ * Liping Ke (Intel Corp.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.shells;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IStreams;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+public class TCFTerminalInputStream extends InputStream {
+ private IStreams streams;
+ private boolean connected = true;;/* The stream is connected or not */
+ String is_id;
+ private int value;
+ private boolean bEof = false;;
+
+ public TCFTerminalInputStream(final IStreams streams, final String is_id) throws IOException{
+ if (streams == null)
+ throw new IOException("TCP streams is null");//$NON-NLS-1$
+ this.streams = streams;
+ this.is_id = is_id;
+ }
+
+ /* read must be synchronized */
+ @Override
+ public synchronized int read() throws IOException {
+ if (!connected)
+ throw new IOException("istream is not connected");//$NON-NLS-1$
+ if (bEof)
+ return -1;
+ try {
+ new TCFTask<Object>() {
+ public void run() {
+ streams.read(is_id, 1, new IStreams.DoneRead() {
+ public void doneRead(IToken token, Exception error, int lostSize,
+ byte[] data, boolean eos) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ bEof = eos;
+ if (data != null) {
+ value = (int)data[0];
+ }
+ else
+ value = -1;
+ done(this);
+ }
+ });
+ }
+ }.getIO();
+ }
+ catch (Exception e) {
+ e.printStackTrace();//$NON-NLS-1$
+ throw new IOException(e.getMessage());//$NON-NLS-1$
+ }
+ return value;
+ }
+
+ private static class Buffer {
+ byte[] buf;
+ Buffer() {
+ }
+ }
+ private Buffer buffer;
+
+ public synchronized int read(byte b[], final int off, final int len) throws IOException {
+
+
+ if (!connected)
+ throw new IOException("istream is not connected");//$NON-NLS-1$
+ if (bEof) return -1;
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+ try {
+ new TCFTask<Buffer>() {
+ public void run() {
+ streams.read(is_id, len, new IStreams.DoneRead() {
+ public void doneRead(IToken token, Exception error, int lostSize,
+ byte[] data, boolean eos) {
+ if (error != null) {
+ error(error);
+ return;
+ }
+ bEof = eos;
+ if (data != null) {
+ buffer = new Buffer();
+ buffer.buf = data;
+
+ }
+ done(buffer);
+ }
+ });
+ }
+ }.getIO();
+
+ if (buffer.buf != null) {
+ int length = buffer.buf.length;
+ System.arraycopy(buffer.buf, 0, b, off, length);
+ return length;
+ }
+ else if (bEof)
+ return -1;
+ else return 0;
+ } catch (Exception ee) {
+ throw new IOException(ee.getMessage());//$NON-NLS-1$
+ }
+ }
+
+ public void close() throws IOException {
+ if (!connected) return;
+ new TCFTask<Object>() {
+ public void run() {
+ streams.disconnect(is_id, new IStreams.DoneDisconnect() {
+ public void doneDisconnect(IToken token, Exception error) {
+ connected = false;
+ done(this);
+ }
+ });
+ }
+ }.getIO();
+ connected = false;
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalOutputStream.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalOutputStream.java
new file mode 100644
index 000000000..ffb0bae22
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalOutputStream.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Intel Corporation. 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:
+ * Liping Ke (Intel Corp.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.shells;
+
+import java.io.IOException;
+
+import java.io.OutputStream;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IStreams;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+public class TCFTerminalOutputStream extends OutputStream {
+
+ private final IStreams streams;
+ private boolean connected = true;
+ private boolean write_eof;
+ String os_id;
+
+ public TCFTerminalOutputStream(final IStreams streams, final String os_id) throws IOException{
+ if (streams == null) throw new IOException("istream is null");//$NON-NLS-1$
+ this.streams = streams;
+ this.os_id = os_id;
+ write_eof = false;
+ }
+
+ @Override
+ public synchronized void write(final byte b[], final int off, final int len) throws IOException {
+ /* If eof is written, we can't write anything into the stream */
+ if (!connected || write_eof)
+ throw new IOException("stream is not connected or write_eof already!");//$NON-NLS-1$
+ try {
+ new TCFTask<Object>() {
+ public void run() {
+ streams.write(os_id, b, off, len, new IStreams.DoneWrite() {
+ public void doneWrite(IToken token, Exception error) {
+ if (error != null) error(error);
+ done(this);
+ }
+ });
+
+ }
+ }.getIO();
+ }
+ catch (Exception e)
+ {
+ throw new IOException(e.getMessage());//$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public synchronized void write(int b) throws IOException {
+
+ try {
+ final byte[] buf = new byte[1];
+ buf[0] = (byte)b;
+ this.write(buf, 0, 1);
+ }
+ catch(IOException ioe) {
+ throw new IOException(ioe.getMessage());//$NON-NLS-1$
+ }
+
+ }
+
+ /* close must be called --Need to reconsider it in the future*/
+ public void close() throws IOException {
+ if (!connected)
+ return;
+ try {
+ new TCFTask<Object>() {
+ public void run() {
+ streams.eos(os_id, new IStreams.DoneEOS() {
+ public void doneEOS(IToken token, Exception error) {
+ write_eof = true;
+ done(this);
+ }
+ });
+ }
+ }.getIO();
+ new TCFTask<Object>() {
+ public void run() {
+ streams.disconnect(os_id, new IStreams.DoneDisconnect() {
+ public void doneDisconnect(IToken token, Exception error) {
+ connected = false;
+ done(this);
+ }
+ });
+
+ }
+ }.getIO();
+ }
+ catch(Exception e) {
+ throw new IOException(e.getMessage()); //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalShell.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalShell.java
new file mode 100644
index 000000000..f180dd7a5
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/shells/TCFTerminalShell.java
@@ -0,0 +1,444 @@
+ /*******************************************************************************
+ * Copyright (c) 2006, 2010 Wind River Systems, Inc., Intel Corporation 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:
+ * Liping Ke (Intel Corp.) - initial API and implementation
+ * Sheldon D'souza (Celunite) - LoginThread and readUntil implementation
+ * Liping Ke (Intel Corp.) - For non-login mode, we don't need detect command prompt
+ ******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.shells;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.rse.core.model.IPropertySet;
+import org.eclipse.rse.services.clientserver.PathUtility;
+import org.eclipse.rse.services.clientserver.messages.CommonMessages;
+import org.eclipse.rse.services.clientserver.messages.ICommonMessageIds;
+import org.eclipse.rse.services.clientserver.messages.SimpleSystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessage;
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.terminals.AbstractTerminalShell;
+import org.eclipse.rse.services.terminals.ITerminalService;
+import org.eclipse.rse.ui.SystemBasePlugin;
+import org.eclipse.tm.internal.tcf.rse.ITCFSessionProvider;
+import org.eclipse.tm.internal.tcf.rse.Messages;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFRSETask;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IStreams;
+import org.eclipse.tm.tcf.services.ITerminals;
+
+
+public class TCFTerminalShell extends AbstractTerminalShell {
+ private ITCFSessionProvider fSessionProvider;
+ private IChannel fChannel;
+ private String fPtyType;
+ private ITerminals.TerminalContext terminalContext;
+ private String fEncoding;
+ private InputStream fInputStream;
+ private OutputStream fOutputStream;
+ private Writer fOutputStreamWriter;
+ private int fWidth = 0;
+ private int fHeight = 0;
+ private String fContextID;
+ private String in_id;
+ private String out_id;
+ private boolean connected = false;
+ private ITerminals terminal;
+ private int status;
+
+ private IPropertySet tcfPropertySet = null;
+
+ private static String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
+ private ITerminals.TerminalsListener listeners = new ITerminals.TerminalsListener(){
+
+ public void exited(String terminalId, int exitCode) {
+
+ if(!terminalContext.getID().equals(terminalId))
+ return;
+ terminal.removeListener(listeners);
+ TCFTerminalShell.this.connected = false;
+ }
+
+
+ public void winSizeChanged(String terminalId, int newWidth,
+ int newHeight) {
+
+ }
+ };
+
+ /* LoginThread and readUntil functionality are cloned from TelnetConnectorService
+ * and then modified for our own needs
+ * */
+ private class LoginThread extends Thread {
+
+ private String username;
+ private String password;
+ private int status = ITCFSessionProvider.SUCCESS_CODE;
+ public LoginThread(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public void run() {
+ tcfPropertySet = ((TCFConnectorService)fSessionProvider).getTCFPropertySet();
+ /* By default, we only support non-login mode. If user open the
+ * switch on the agent side, he can also set the properties in
+ * TCF connection property*/
+ String login_required = tcfPropertySet.getPropertyValue(TCFConnectorService.PROPERTY_LOGIN_REQUIRED);
+
+ if (Boolean.valueOf(login_required).booleanValue()) {
+ String login_prompt = tcfPropertySet.getPropertyValue(TCFConnectorService.PROPERTY_LOGIN_PROMPT);
+ String password_prompt =tcfPropertySet.getPropertyValue(TCFConnectorService.PROPERTY_PASSWORD_PROMPT);
+ String command_prompt = tcfPropertySet.getPropertyValue(TCFConnectorService.PROPERTY_COMMAND_PROMPT);
+ String pwd_required = tcfPropertySet.getPropertyValue(TCFConnectorService.PROPERTY_PWD_REQUIRED);
+ status = ITCFSessionProvider.SUCCESS_CODE;
+ if (login_prompt != null && login_prompt.length() > 0) {
+ status = readUntil(login_prompt,fInputStream);
+ write(username + "\n"); //$NON-NLS-1$
+ }
+ if (Boolean.valueOf(pwd_required).booleanValue()) {
+ if (status == ITCFSessionProvider.SUCCESS_CODE && password_prompt != null && password_prompt.length() > 0) {
+ status = readUntil(password_prompt,fInputStream);
+ write(password + "\n"); //$NON-NLS-1$
+ }
+ }
+ if (status == ITCFSessionProvider.SUCCESS_CODE && command_prompt != null && command_prompt.length() > 0) {
+ status = readUntil(command_prompt,fInputStream);
+ write("\n"); //$NON-NLS-1$
+ }
+ } else {
+ status = ITCFSessionProvider.SUCCESS_CODE;
+ }
+ }
+
+ public int readUntil(String pattern,InputStream in) {
+ try {
+ char lastChar = pattern.charAt(pattern.length() - 1);
+ StringBuffer sb = new StringBuffer();
+ int ch = in.read();
+ while (ch >= 0) {
+ char tch = (char) ch;
+ sb.append(tch);
+ if (tch=='t' && sb.indexOf("incorrect") >= 0) { //$NON-NLS-1$
+ return ITCFSessionProvider.ERROR_CODE;
+ }
+ if (tch=='d' && sb.indexOf("closed") >= 0) { //$NON-NLS-1$
+ return ITCFSessionProvider.CONNECT_CLOSED;
+ }
+ if (tch == lastChar) {
+ if (sb.toString().endsWith(pattern)) {
+ return ITCFSessionProvider.SUCCESS_CODE;
+ }
+ }
+ ch = in.read();
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ SystemBasePlugin.logError(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), e);
+ }
+ return ITCFSessionProvider.CONNECT_CLOSED;
+ }
+
+ public int getLoginStatus() {
+ return this.status;
+ }
+
+ }
+
+ public void write(String value) {
+ try {
+ fOutputStream.write(value.getBytes());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private int login(String username, String password) throws InterruptedException
+ {
+ long millisToEnd = System.currentTimeMillis() + ITCFSessionProvider.TCP_CONNECT_TIMEOUT*1000;
+ LoginThread checkLogin = new LoginThread(username, password);
+ status = ITCFSessionProvider.ERROR_CODE;
+ checkLogin.start();
+ while (checkLogin.isAlive() && System.currentTimeMillis()<millisToEnd)
+ checkLogin.join(500);
+ status = checkLogin.getLoginStatus();
+ checkLogin.join();
+ return status;
+ }
+ /**
+ * Construct a new TCF connection.
+ *
+ * The TCF channel is immediately connected in the Constructor.
+ *
+ * @param sessionProvider TCF session provider
+ * @param ptyType Terminal type to set, or <code>null</code> if not
+ * relevant
+ * @param encoding The default encoding to use for initial command.
+ * @param environment Environment array to set, or <code>null</code> if
+ * not relevant.
+ * @param initialWorkingDirectory initial directory to open the Terminal in.
+ * Use <code>null</code> or empty String ("") to start in a
+ * default directory. Empty String will typically start in the
+ * home directory.
+ * @param commandToRun initial command to send.
+ * @throws SystemMessageException in case anything goes wrong. Channels and
+ * Streams are all cleaned up again in this case.
+ * @see ITerminalService
+ */
+ public TCFTerminalShell(final ITCFSessionProvider sessionProvider, final String ptyType,
+ final String encoding, final String[] environment,
+ String initialWorkingDirectory, String commandToRun)
+ throws SystemMessageException {
+ Map<String, Object> map_ids;
+ Exception nestedException = null;
+ try {
+ fSessionProvider = sessionProvider;
+ fEncoding = encoding;
+ fPtyType = ptyType;
+ fChannel = fSessionProvider.getChannel();
+
+ if (fChannel == null || fChannel.getState() != IChannel.STATE_OPEN)
+ throw new Exception("TCP channel is not connected!");//$NON-NLS-1$
+ if (((TCFConnectorService)sessionProvider).isSubscribed() == false)
+ ((TCFConnectorService)sessionProvider).subscribe();
+ assert (((TCFConnectorService)sessionProvider).isSubscribed());
+
+ new TCFRSETask<ITerminals.TerminalContext>() {
+ public void run() {
+ terminal = ((TCFConnectorService)sessionProvider).getService(ITerminals.class);
+ terminal.launch(ptyType, encoding, environment, new ITerminals.DoneLaunch() {
+ public void doneLaunch(IToken token, Exception error,
+ ITerminals.TerminalContext ctx) {
+
+ if (ctx != null) {
+ terminalContext = ctx;
+ terminal.addListener(listeners);
+ }
+
+ if (error != null) error(error);
+ else done(ctx);
+ }
+ });
+ }
+
+ }.getS(null, Messages.TCFTerminalService_Name);
+
+ fPtyType = terminalContext.getPtyType();
+ fEncoding = terminalContext.getEncoding();
+ fContextID = terminalContext.getID();
+ fWidth = terminalContext.getWidth();
+ fHeight = terminalContext.getHeight();
+ map_ids = terminalContext.getProperties();
+ in_id = (String)map_ids.get(ITerminals.PROP_STDOUT_ID);
+ out_id = (String)map_ids.get(ITerminals.PROP_STDIN_ID);
+
+ String user = fSessionProvider.getSessionUserId();
+ String password = fSessionProvider.getSessionPassword();
+ status = ITCFSessionProvider.ERROR_CODE;
+
+ IStreams streams = new TCFRSETask<IStreams>() {
+ public void run() {
+ done(((TCFConnectorService)sessionProvider).getService(IStreams.class));
+ }
+ }.getS(null, Messages.TCFTerminalService_Name);
+ fOutputStream = new TCFTerminalOutputStream(streams, out_id);
+ fInputStream = new TCFTerminalInputStream(streams, in_id);
+ if (fEncoding != null) {
+ fOutputStreamWriter = new BufferedWriter(new OutputStreamWriter(fOutputStream, encoding));
+ } else {
+ // default encoding == System.getProperty("file.encoding")
+ // TODO should try to determine remote encoding if possible
+ fOutputStreamWriter = new BufferedWriter(new OutputStreamWriter(fOutputStream));
+ }
+
+ try {
+ status = login(user, password);
+ }
+ finally
+ {
+ if ((status == ITCFSessionProvider.CONNECT_CLOSED))
+ {
+ //Give one time chance of retrying....
+ }
+
+ }
+
+ //give another chance of retrying
+ if ((status == ITCFSessionProvider.CONNECT_CLOSED))
+ {
+ ((TCFConnectorService)sessionProvider).unsubscribe();
+ ((TCFConnectorService)sessionProvider).subscribe();
+ assert (((TCFConnectorService)sessionProvider).isSubscribed());
+ status = login(user, password);
+ }
+
+ connected = true;
+ if (initialWorkingDirectory!=null && initialWorkingDirectory.length()>0
+ && !initialWorkingDirectory.equals(".") //$NON-NLS-1$
+ && !initialWorkingDirectory.equals("Command Shell") //$NON-NLS-1$ //FIXME workaround for bug 153047
+ ) {
+ writeToShell("cd " + PathUtility.enQuoteUnix(initialWorkingDirectory)); //$NON-NLS-1$
+ }
+
+ if (commandToRun != null && commandToRun.length() > 0) {
+ writeToShell(commandToRun);
+ }
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ nestedException = e;
+ }
+ finally {
+ if (status == ITCFSessionProvider.SUCCESS_CODE) {
+ }
+ else {
+ SystemMessage msg;
+
+ if (nestedException!=null) {
+ msg = new SimpleSystemMessage(org.eclipse.tm.internal.tcf.rse.Activator.PLUGIN_ID,
+ ICommonMessageIds.MSG_EXCEPTION_OCCURRED,
+ IStatus.ERROR,
+ CommonMessages.MSG_EXCEPTION_OCCURRED, nestedException);
+ } else {
+ String strErr;
+ if (status == ITCFSessionProvider.CONNECT_CLOSED)
+ strErr = "Connection closed!";//$NON-NLS-1$
+ else if (status == ITCFSessionProvider.ERROR_CODE)
+ strErr = "Login Incorrect or meet other unknown error!";//$NON-NLS-1$
+ else
+ strErr = "Not identified Errors";//$NON-NLS-1$
+
+ msg = new SimpleSystemMessage(org.eclipse.tm.internal.tcf.rse.Activator.PLUGIN_ID,
+ ICommonMessageIds.MSG_COMM_AUTH_FAILED,
+ IStatus.ERROR,
+ strErr,
+ "Meet error when trying to login in!");//$NON-NLS-1$
+ msg.makeSubstitution(((TCFConnectorService)fSessionProvider).getHost().getAliasName());
+ }
+ throw new SystemMessageException(msg);//$NON-NLS-1$
+ }
+ }
+
+ }
+
+ public void writeToShell(String command) throws IOException {
+ if (isActive()) {
+ if ("#break".equals(command)) { //$NON-NLS-1$
+ command = "\u0003"; // Unicode 3 == Ctrl+C //$NON-NLS-1$
+ } else {
+ command += "\r\n"; //$NON-NLS-1$
+ }
+ fOutputStreamWriter.write(command);
+ }
+ }
+
+ public void exit() {
+
+ if (fChannel == null || (fChannel.getState() == IChannel.STATE_CLOSED) || !connected) {
+ return;
+ }
+ try {
+ getOutputStream().close();
+ getInputStream().close();
+
+ }
+ catch (IOException ioe) {
+ ioe.printStackTrace();
+ } //$NON-NLS-1$
+
+ try {
+ new TCFRSETask<Object>() {
+ public void run() {
+ terminalContext.exit(new ITerminals.DoneCommand(){
+ public void doneCommand(IToken token,
+ Exception error) {
+ if (error != null)
+ error(error);
+ else {
+ done(this);
+ }
+ }
+ });
+ }}.getS(null, Messages.TCFShellService_Name); //seems no need block here. need further modification.
+ }
+ catch (SystemMessageException e) {
+ e.printStackTrace();
+ } //$NON-NLS-1$;
+ }
+
+ public InputStream getInputStream() {
+ return fInputStream;
+ }
+
+ public OutputStream getOutputStream() {
+ return fOutputStream;
+ }
+
+ public boolean isActive() {
+ if (fChannel != null && !(fChannel.getState() == IChannel.STATE_CLOSED) && connected) {
+ return true;
+ }
+ exit();
+ // shell is not active: check for session lost
+ return false;
+ }
+
+ public String getPtyType() {
+ return fPtyType;
+ }
+
+ public void setTerminalSize(int newWidth, int newHeight) {
+ if (fChannel == null || (fChannel.getState() == IChannel.STATE_CLOSED) || !connected) {
+ // do nothing
+ return;
+ }
+ fWidth = newWidth;
+ fHeight = newHeight;
+ try {
+ new TCFRSETask<Object>() {
+ public void run() {
+ if (fChannel != null && connected) {
+ terminal.setWinSize(fContextID, fWidth, fHeight, new ITerminals.DoneCommand(){
+
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null)
+ error(error);
+ else
+ done(this);
+
+ }});
+
+ }
+ else {
+ done(this);
+ }
+ }}.getS(null, Messages.TCFShellService_Name);
+ }
+ catch (SystemMessageException e) {
+ e.printStackTrace();
+ } //$NON-NLS-1$;
+ }
+
+ public String getDefaultEncoding() {
+ if (fEncoding != null) return fEncoding;
+ return defaultEncoding;
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalService.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalService.java
new file mode 100644
index 000000000..e3ee65dc4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalService.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Intel Corporation. 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:
+ * Liping Ke(Intel Corp.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.terminals;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
+import org.eclipse.rse.services.terminals.AbstractTerminalService;
+import org.eclipse.rse.services.terminals.ITerminalShell;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.ITCFSessionProvider;
+import org.eclipse.tm.internal.tcf.rse.Messages;
+import org.eclipse.tm.internal.tcf.rse.shells.TCFTerminalShell;
+
+public class TCFTerminalService extends AbstractTerminalService implements ITCFService{
+ private final ITCFSessionProvider fSessionProvider;
+
+ /**
+ * Return the TCF property set, and fill it with default values if it has
+ * not been created yet. Extender may override in order to set different
+ * default values.
+ *
+ * @return a property set holding properties understood by the TCF
+ * connector service.
+ */
+ public ITerminalShell launchTerminal(String ptyType, String encoding,
+ String[] environment, String initialWorkingDirectory,
+ String commandToRun, IProgressMonitor monitor)
+ throws SystemMessageException {
+ TCFTerminalShell hostShell = new TCFTerminalShell(fSessionProvider, ptyType, encoding, environment, initialWorkingDirectory, commandToRun);
+ return hostShell;
+ }
+
+
+ public TCFTerminalService(ITCFSessionProvider sessionProvider) {
+ fSessionProvider = sessionProvider;
+ }
+
+ public ITCFSessionProvider getSessionProvider() {
+ return fSessionProvider;
+ }
+ @Override
+ public String getName() {
+ return Messages.TCFTerminalService_Name;
+ }
+ @Override
+ public String getDescription() {
+ return Messages.TCFTerminalService_Description;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalServiceSubSystemConfiguration.java b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalServiceSubSystemConfiguration.java
new file mode 100644
index 000000000..817f1c7b2
--- /dev/null
+++ b/plugins/org.eclipse.tcf.rse/src/org/eclipse/tcf/internal/rse/terminals/TCFTerminalServiceSubSystemConfiguration.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 MontaVista Software, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yu-Fen Kuo (MontaVista) - initial API and implementation
+ * Anna Dushistova (MontaVista) - [240530][rseterminal][apidoc] Add terminals.rse Javadoc into org.eclipse.rse.doc.isv
+ * Liping Ke (Intel Corp.) - Adapted from TerminalServiceSubSystemConfiguration
+ * Liping Ke (Intel Corp.) - TCF terminal services subsystem implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.rse.terminals;
+
+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.services.terminals.ITerminalService;
+import org.eclipse.rse.subsystems.terminals.core.TerminalServiceSubSystem;
+import org.eclipse.rse.subsystems.terminals.core.TerminalServiceSubSystemConfiguration;
+import org.eclipse.tm.internal.tcf.rse.ITCFService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorService;
+import org.eclipse.tm.internal.tcf.rse.TCFConnectorServiceManager;
+
+public class TCFTerminalServiceSubSystemConfiguration extends
+ TerminalServiceSubSystemConfiguration {
+
+
+ /**
+ * Instantiate and return an instance of OUR subsystem. Do not populate it
+ * yet though!
+ *
+ * @see org.eclipse.rse.core.subsystems.SubSystemConfiguration#createSubSystemInternal(IHost)
+ */
+ public ISubSystem createSubSystemInternal(IHost host) {
+ TCFConnectorService connectorService = (TCFConnectorService) getConnectorService(host);
+ ISubSystem subsys = new TerminalServiceSubSystem(host,
+ connectorService, createTerminalService(host));
+ return subsys;
+ }
+
+ /**
+ * @inheritDoc
+ * @since 1.0
+ */
+ public ITerminalService createTerminalService(IHost host) {
+ TCFConnectorService cserv = (TCFConnectorService) getConnectorService(host);
+ return new TCFTerminalService(cserv);
+ }
+
+ public IConnectorService getConnectorService(IHost host) {
+ return TCFConnectorServiceManager.getInstance().getConnectorService(
+ host, getServiceImplType());
+ }
+
+ public void setConnectorService(IHost host,
+ IConnectorService connectorService) {
+ TCFConnectorServiceManager.getInstance().setConnectorService(host,
+ getServiceImplType(), connectorService);
+ }
+
+ public Class<ITCFService> getServiceImplType() {
+ return ITCFService.class;
+ }
+
+}

Back to the top