001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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: * Ivan Popov - Bug 184211: JDI connectors throw NullPointerException if used separately
011: * from Eclipse
012: *******************************************************************************/package org.eclipse.jdi.internal.connect;
013:
014: import java.io.IOException;
015: import java.util.HashMap;
016: import java.util.Map;
017:
018: import org.eclipse.jdi.internal.VirtualMachineManagerImpl;
019:
020: import com.sun.jdi.VirtualMachine;
021: import com.sun.jdi.connect.IllegalConnectorArgumentsException;
022: import com.sun.jdi.connect.ListeningConnector;
023:
024: public class SocketListeningConnectorImpl extends ConnectorImpl
025: implements ListeningConnector {
026: /** Port to which is attached. */
027: private int fPort;
028: /** Timeout before accept returns. */
029: private int fTimeout;
030:
031: /**
032: * Creates new SocketAttachingConnectorImpl.
033: */
034: public SocketListeningConnectorImpl(
035: VirtualMachineManagerImpl virtualMachineManager) {
036: super (virtualMachineManager);
037:
038: // Create communication protocol specific transport.
039: SocketTransportImpl transport = new SocketTransportImpl();
040: setTransport(transport);
041: }
042:
043: /**
044: * @return Returns the default arguments.
045: */
046: public Map defaultArguments() {
047: HashMap arguments = new HashMap(1);
048:
049: // Port
050: IntegerArgumentImpl intArg = new IntegerArgumentImpl(
051: "port", ConnectMessages.SocketListeningConnectorImpl_Port_number_at_which_to_listen_for_VM_connections_1, ConnectMessages.SocketListeningConnectorImpl_Port_2, true, SocketTransportImpl.MIN_PORTNR, SocketTransportImpl.MAX_PORTNR); //$NON-NLS-1$
052: arguments.put(intArg.name(), intArg);
053:
054: // Timeout
055: intArg = new IntegerArgumentImpl(
056: "timeout", ConnectMessages.SocketListeningConnectorImpl_Timeout_before_accept_returns_3, ConnectMessages.SocketListeningConnectorImpl_Timeout_4, false, 0, Integer.MAX_VALUE); //$NON-NLS-1$
057: arguments.put(intArg.name(), intArg);
058:
059: return arguments;
060: }
061:
062: /**
063: * @return Returns a short identifier for the connector.
064: */
065: public String name() {
066: return "com.sun.jdi.SocketListen"; //$NON-NLS-1$
067: }
068:
069: /**
070: * @return Returns a human-readable description of this connector and its purpose.
071: */
072: public String description() {
073: return ConnectMessages.SocketListeningConnectorImpl_Accepts_socket_connections_initiated_by_other_VMs_5;
074: }
075:
076: /**
077: * Retrieves connection arguments.
078: */
079: private void getConnectionArguments(Map connectionArgs)
080: throws IllegalConnectorArgumentsException {
081: String attribute = "port"; //$NON-NLS-1$
082: try {
083: // If listening port is not specified, use port 0
084: IntegerArgument argument = (IntegerArgument) connectionArgs
085: .get(attribute);
086: if (argument != null && argument.value() != null) {
087: fPort = argument.intValue();
088: } else {
089: fPort = 0;
090: }
091: // Note that timeout is not used in SUN's ListeningConnector, but is used by our
092: // LaunchingConnector.
093: attribute = "timeout"; //$NON-NLS-1$
094: argument = (IntegerArgument) connectionArgs.get(attribute);
095: if (argument != null && argument.value() != null) {
096: fTimeout = argument.intValue();
097: } else {
098: fTimeout = 0;
099: }
100: } catch (ClassCastException e) {
101: throw new IllegalConnectorArgumentsException(
102: ConnectMessages.SocketListeningConnectorImpl_Connection_argument_is_not_of_the_right_type_6,
103: attribute);
104: } catch (NullPointerException e) {
105: throw new IllegalConnectorArgumentsException(
106: ConnectMessages.SocketListeningConnectorImpl_Necessary_connection_argument_is_null_7,
107: attribute);
108: } catch (NumberFormatException e) {
109: throw new IllegalConnectorArgumentsException(
110: ConnectMessages.SocketListeningConnectorImpl_Connection_argument_is_not_a_number_8,
111: attribute);
112: }
113: }
114:
115: /**
116: * Listens for one or more connections initiated by target VMs.
117: * @return Returns the address at which the connector is listening for a connection.
118: */
119: public String startListening(Map connectionArgs)
120: throws IOException, IllegalConnectorArgumentsException {
121: getConnectionArguments(connectionArgs);
122: String result = null;
123: try {
124: result = ((SocketTransportImpl) fTransport)
125: .startListening(fPort);
126: } catch (IllegalArgumentException e) {
127: throw new IllegalConnectorArgumentsException(
128: ConnectMessages.SocketListeningConnectorImpl_ListeningConnector_Socket_Port,
129: "port"); //$NON-NLS-1$
130: }
131: return result;
132: }
133:
134: /**
135: * Cancels listening for connections.
136: */
137: public void stopListening(Map connectionArgs) throws IOException {
138: ((SocketTransportImpl) fTransport).stopListening();
139: }
140:
141: /**
142: * Waits for a target VM to attach to this connector.
143: * @return Returns a connected Virtual Machine.
144: */
145: public VirtualMachine accept(Map connectionArgs)
146: throws IOException, IllegalConnectorArgumentsException {
147: getConnectionArguments(connectionArgs);
148: SocketConnection connection = (SocketConnection) ((SocketTransportImpl) fTransport)
149: .accept(fTimeout, 0);
150: return establishedConnection(connection);
151: }
152:
153: /**
154: * @return Returns whether this listening connector supports multiple connections for a single argument map.
155: */
156: public boolean supportsMultipleConnections() {
157: return true;
158: }
159:
160: /**
161: * @return Returns port number that is listened to.
162: */
163: public int listeningPort() {
164: return fPort;
165: }
166: }
|