001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.launching;
011:
012: import java.io.IOException;
013: import java.net.ConnectException;
014: import java.net.UnknownHostException;
015: import com.ibm.icu.text.MessageFormat;
016: import java.util.ArrayList;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.Map;
020:
021: import org.eclipse.core.runtime.CoreException;
022: import org.eclipse.core.runtime.IProgressMonitor;
023: import org.eclipse.core.runtime.IStatus;
024: import org.eclipse.core.runtime.NullProgressMonitor;
025: import org.eclipse.core.runtime.Status;
026: import org.eclipse.core.runtime.SubProgressMonitor;
027: import org.eclipse.debug.core.ILaunch;
028: import org.eclipse.debug.core.ILaunchConfiguration;
029: import org.eclipse.debug.core.model.IDebugTarget;
030: import org.eclipse.jdi.Bootstrap;
031: import org.eclipse.jdi.TimeoutException;
032: import org.eclipse.jdt.debug.core.JDIDebugModel;
033: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
034: import org.eclipse.jdt.launching.IVMConnector;
035:
036: import com.sun.jdi.VMDisconnectedException;
037: import com.sun.jdi.VirtualMachine;
038: import com.sun.jdi.connect.AttachingConnector;
039: import com.sun.jdi.connect.Connector;
040: import com.sun.jdi.connect.IllegalConnectorArgumentsException;
041:
042: /**
043: * A standard socket attaching connector
044: */
045: public class SocketAttachConnector implements IVMConnector {
046:
047: /**
048: * Return the socket transport attaching connector
049: *
050: * @exception CoreException if unable to locate the connector
051: */
052: protected static AttachingConnector getAttachingConnector()
053: throws CoreException {
054: AttachingConnector connector = null;
055: Iterator iter = Bootstrap.virtualMachineManager()
056: .attachingConnectors().iterator();
057: while (iter.hasNext()) {
058: AttachingConnector lc = (AttachingConnector) iter.next();
059: if (lc.name().equals("com.sun.jdi.SocketAttach")) { //$NON-NLS-1$
060: connector = lc;
061: break;
062: }
063: }
064: if (connector == null) {
065: abort(
066: LaunchingMessages.SocketAttachConnector_Socket_attaching_connector_not_available_3,
067: null,
068: IJavaLaunchConfigurationConstants.ERR_SHARED_MEMORY_CONNECTOR_UNAVAILABLE);
069: }
070: return connector;
071: }
072:
073: /**
074: * @see IVMConnector#getIdentifier()
075: */
076: public String getIdentifier() {
077: return IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR;
078: }
079:
080: /**
081: * @see IVMConnector#getName()
082: */
083: public String getName() {
084: return LaunchingMessages.SocketAttachConnector_Standard__Socket_Attach__4;
085: }
086:
087: /**
088: * Throws a core exception with an error status object built from
089: * the given message, lower level exception, and error code.
090: *
091: * @param message the status message
092: * @param exception lower level exception associated with the
093: * error, or <code>null</code> if none
094: * @param code error code
095: */
096: protected static void abort(String message, Throwable exception,
097: int code) throws CoreException {
098: throw new CoreException(new Status(IStatus.ERROR,
099: LaunchingPlugin.getUniqueIdentifier(), code, message,
100: exception));
101: }
102:
103: /* (non-Javadoc)
104: * @see org.eclipse.jdt.launching.IVMConnector#connect(java.util.Map, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.debug.core.ILaunch)
105: */
106: public void connect(Map arguments, IProgressMonitor monitor,
107: ILaunch launch) throws CoreException {
108: if (monitor == null) {
109: monitor = new NullProgressMonitor();
110: }
111:
112: IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
113: subMonitor
114: .beginTask(
115: LaunchingMessages.SocketAttachConnector_Connecting____1,
116: 2);
117: subMonitor
118: .subTask(LaunchingMessages.SocketAttachConnector_Configuring_connection____1);
119:
120: AttachingConnector connector = getAttachingConnector();
121: String portNumberString = (String) arguments.get("port"); //$NON-NLS-1$
122: if (portNumberString == null) {
123: abort(
124: LaunchingMessages.SocketAttachConnector_Port_unspecified_for_remote_connection__2,
125: null,
126: IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_PORT);
127: }
128: String host = (String) arguments.get("hostname"); //$NON-NLS-1$
129: if (host == null) {
130: abort(
131: LaunchingMessages.SocketAttachConnector_Hostname_unspecified_for_remote_connection__4,
132: null,
133: IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_HOSTNAME);
134: }
135: Map map = connector.defaultArguments();
136:
137: Connector.Argument param = (Connector.Argument) map
138: .get("hostname"); //$NON-NLS-1$
139: param.setValue(host);
140: param = (Connector.Argument) map.get("port"); //$NON-NLS-1$
141: param.setValue(portNumberString);
142:
143: String timeoutString = (String) arguments.get("timeout"); //$NON-NLS-1$
144: if (timeoutString != null) {
145: param = (Connector.Argument) map.get("timeout"); //$NON-NLS-1$
146: param.setValue(timeoutString);
147: }
148:
149: ILaunchConfiguration configuration = launch
150: .getLaunchConfiguration();
151: boolean allowTerminate = false;
152: if (configuration != null) {
153: allowTerminate = configuration
154: .getAttribute(
155: IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE,
156: false);
157: }
158: subMonitor.worked(1);
159: subMonitor
160: .subTask(LaunchingMessages.SocketAttachConnector_Establishing_connection____2);
161: try {
162: VirtualMachine vm = connector.attach(map);
163: String vmLabel = constructVMLabel(vm, host,
164: portNumberString, configuration);
165: IDebugTarget debugTarget = JDIDebugModel.newDebugTarget(
166: launch, vm, vmLabel, null, allowTerminate, true);
167: launch.addDebugTarget(debugTarget);
168: subMonitor.worked(1);
169: subMonitor.done();
170: } catch (TimeoutException e) {
171: abort(
172: LaunchingMessages.SocketAttachConnector_0,
173: e,
174: IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
175: } catch (UnknownHostException e) {
176: abort(
177: MessageFormat
178: .format(
179: LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_because_of_unknown_host____0___1,
180: new String[] { host }),
181: e,
182: IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
183: } catch (ConnectException e) {
184: abort(
185: LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_as_connection_was_refused_2,
186: e,
187: IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
188: } catch (IOException e) {
189: abort(
190: LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_1,
191: e,
192: IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
193: } catch (IllegalConnectorArgumentsException e) {
194: abort(
195: LaunchingMessages.SocketAttachConnector_Failed_to_connect_to_remote_VM_1,
196: e,
197: IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
198: }
199: }
200:
201: /**
202: * Helper method that constructs a human-readable label for a remote VM.
203: */
204: protected String constructVMLabel(VirtualMachine vm, String host,
205: String port, ILaunchConfiguration configuration) {
206: String name = null;
207: try {
208: name = vm.name();
209: } catch (TimeoutException e) {
210: // do nothing
211: } catch (VMDisconnectedException e) {
212: // do nothing
213: }
214: if (name == null) {
215: if (configuration == null) {
216: name = ""; //$NON-NLS-1$
217: } else {
218: name = configuration.getName();
219: }
220: }
221: StringBuffer buffer = new StringBuffer(name);
222: buffer.append('[');
223: buffer.append(host);
224: buffer.append(':');
225: buffer.append(port);
226: buffer.append(']');
227: return buffer.toString();
228: }
229:
230: /**
231: * @see IVMConnector#getDefaultArguments()
232: */
233: public Map getDefaultArguments() throws CoreException {
234: Map def = getAttachingConnector().defaultArguments();
235: Connector.IntegerArgument arg = (Connector.IntegerArgument) def
236: .get("port"); //$NON-NLS-1$
237: arg.setValue(8000);
238: return def;
239: }
240:
241: /**
242: * @see IVMConnector#getArgumentOrder()
243: */
244: public List getArgumentOrder() {
245: List list = new ArrayList(2);
246: list.add("hostname"); //$NON-NLS-1$
247: list.add("port"); //$NON-NLS-1$
248: return list;
249: }
250:
251: }
|