1 /*
   2  * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.jdi.connect.spi;
  27 
  28 import java.io.IOException;
  29 import com.sun.jdi.connect.TransportTimeoutException;
  30 
  31 /**
  32  * A transport service for connections between a debugger and
  33  * a target VM.
  34  *
  35  * <p> A transport service is a concrete subclass of this class
  36  * that has a zero-argument constructor and implements the abstract
  37  * methods specified below. It is the underlying service
  38  * used by a {@link com.sun.jdi.connect.Transport} for
  39  * connections between a debugger and a target VM.
  40  *
  41  * <p> A transport service is used to establish a connection
  42  * between a debugger and a target VM, and to transport Java
  43  * Debug Wire Protocol (JDWP) packets over an underlying
  44  * communication protocol. In essence a transport service
  45  * implementation binds JDWP (as specified in the
  46  * <a href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
  47  * JDWP specification</a>) to an underlying communication
  48  * protocol. A transport service implementation provides
  49  * a reliable JDWP packet transportation service. JDWP
  50  * packets are sent to and from the target VM without duplication
  51  * or data loss. A transport service implementation may be
  52  * based on an underlying communication protocol that is
  53  * reliable or unreliable. If the underlying communication
  54  * protocol is reliable then the transport service implementation
  55  * may be relatively simple and may only need to transport JDWP
  56  * packets as payloads of the underlying communication
  57  * protocol. In the case of an unreliable communication
  58  * protocol the transport service implementation may include
  59  * additional protocol support in order to ensure that packets
  60  * are not duplicated and that there is no data loss. The
  61  * details of such protocols are specific to the implementation
  62  * but may involve techniques such as the <i>positive
  63  * acknowledgment with retransmission</i> technique used in
  64  * protocols such as the Transmission Control Protocol (TCP)
  65  * (see <a href="http://www.ietf.org/rfc/rfc0793.txt"> RFC 793
  66  * </a>).
  67  *
  68  * <p> A transport service can be used to initiate a connection
  69  * to a target VM. This is done by invoking the {@link #attach}
  70  * method. Alternatively, a transport service can listen and
  71  * accept connections initiated by a target VM. This is done
  72  * by invoking the {@link #startListening(String)} method to
  73  * put the transport into listen mode. Then the {@link #accept}
  74  * method is used to accept a connection initiated by a
  75  * target VM.
  76  *
  77  * @since 1.5
  78  */
  79 
  80 public abstract class TransportService {
  81 
  82     /**
  83      * Returns a name to identify the transport service.
  84      *
  85      * @return  The name of the transport service
  86      */
  87     public abstract String name();
  88 
  89     /**
  90      * Returns a description of the transport service.
  91      *
  92      * @return  The description of the transport service
  93      */
  94     public abstract String description();
  95 
  96     /**
  97      * The transport service capabilities.
  98      */
  99     public static abstract class Capabilities {
 100 
 101         /**
 102          * Tells whether or not this transport service can support
 103          * multiple concurrent connections to a single address that
 104          * it is listening on.
 105          *
 106          * @return  <tt>true</tt> if, and only if, this transport
 107          *          service supports multiple connections.
 108          */
 109         public abstract boolean supportsMultipleConnections();
 110 
 111 
 112         /**
 113          * Tell whether or not this transport service supports a timeout
 114          * when attaching to a target VM.
 115          *
 116          * @return      <tt>true</tt> if, and only if, this transport
 117          *              service supports attaching with a timeout.
 118          *
 119          * @see #attach(String,long,long)
 120          */
 121         public abstract boolean supportsAttachTimeout();
 122 
 123         /**
 124          * Tell whether or not this transport service supports a
 125          * timeout while waiting for a target VM to connect.
 126          *
 127          * @return  <tt>true</tt> if, and only if, this transport
 128          *          service supports timeout while waiting for
 129          *          a target VM to connect.
 130          *
 131          * @see #accept(TransportService.ListenKey,long,long)
 132          */
 133         public abstract boolean supportsAcceptTimeout();
 134 
 135         /**
 136          * Tells whether or not this transport service supports a
 137          * timeout when handshaking with the target VM.
 138          *
 139          * @return  <tt>true</tt> if, and only if, this transport
 140          *          service supports a timeout while handshaking
 141          *          with the target VM.
 142          *
 143          * @see #attach(String,long,long)
 144          * @see #accept(TransportService.ListenKey,long,long)
 145          */
 146         public abstract boolean supportsHandshakeTimeout();
 147 
 148     }
 149 
 150     /**
 151      * Returns the capabilities of the transport service.
 152      *
 153      * @return  the transport service capabilities
 154      */
 155     public abstract Capabilities capabilities();
 156 
 157     /**
 158      * Attaches to the specified address.
 159      *
 160      * <p> Attaches to the specified address and returns a connection
 161      * representing the bi-directional communication channel to the
 162      * target VM.
 163      *
 164      * <p> Attaching to the target VM involves two steps:
 165      * First, a connection is established to specified address. This
 166      * is followed by a handshake to ensure that the connection is
 167      * to a target VM. The handshake involves the exchange
 168      * of a string <i>JDWP-Handshake</i> as specified in the <a
 169      * href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
 170      * Java Debug Wire Protocol</a> specification.
 171      *
 172      * @param   address
 173      *          The address of the target VM.
 174      *
 175      * @param   attachTimeout
 176      *          If this transport service supports an attach timeout,
 177      *          and if <tt>attachTimeout</tt> is positive, then it specifies
 178      *          the timeout, in milliseconds (more or less), to use
 179      *          when attaching to the target VM.  If the transport service
 180      *          does not support an attach timeout, or if <tt>attachTimeout</tt>
 181      *          is specified as zero then attach without any timeout.
 182      *
 183      * @param   handshakeTimeout
 184      *          If this transport service supports a handshake timeout,
 185      *          and if <tt>handshakeTimeout</tt> is positive, then it
 186      *          specifies the timeout, in milliseconds (more or less), to
 187      *          use when handshaking with the target VM. The exact
 188      *          usage of the timeout are specific to the transport service.
 189      *          A transport service may, for example, use the handshake
 190      *          timeout as the inter-character timeout while waiting for
 191      *          the <i>JDWP-Handshake</i> message from the target VM.
 192      *          Alternatively, a transport service may, for example,
 193      *          use the handshakeTimeout as a timeout for the duration of the
 194      *          handshake exchange.
 195      *          If the transport service does not support a handshake
 196      *          timeout, or if <tt>handshakeTimeout</tt> is specified
 197      *          as zero then the handshake does not timeout if there
 198      *          isn't a response from the target VM.
 199      *
 200      * @return  The Connection representing the bi-directional
 201      *          communication channel to the target VM.
 202      *
 203      * @throws  TransportTimeoutException
 204      *          If a timeout occurs while establishing the connection.
 205      *
 206      * @throws  IOException
 207      *          If an I/O error occurs (including a timeout when
 208      *          handshaking).
 209      *
 210      * @throws  IllegalArgumentException
 211      *          If the address is invalid or the value of the
 212      *          attach timeout or handshake timeout is negative.
 213      *
 214      * @see TransportService.Capabilities#supportsAttachTimeout()
 215      */
 216     public abstract Connection attach(String address, long attachTimeout,
 217         long handshakeTimeout) throws IOException;
 218 
 219     /**
 220      * A <i>listen key</i>.
 221      *
 222      * <p> A <tt>TransportService</tt> may listen on multiple, yet
 223      * different, addresses at the same time. To uniquely identify
 224      * each <tt>listener</tt> a listen key is created each time that
 225      * {@link #startListening startListening} is called. The listen
 226      * key is used in calls to the {@link #accept accept} method
 227      * to accept inbound connections to that listener. A listen
 228      * key is valid until it is used as an argument to {@link
 229      * #stopListening stopListening} to stop the transport
 230      * service from listening on an address.
 231      */
 232     public static abstract class ListenKey {
 233 
 234         /**
 235          * Returns a string representation of the listen key.
 236          */
 237         public abstract String address();
 238     }
 239 
 240     /**
 241      * Listens on the specified address for inbound connections.
 242      *
 243      * <p> This method starts the transport service listening on
 244      * the specified address so that it can subsequently accept
 245      * an inbound connection. It does not wait until an inbound
 246      * connection is established.
 247      *
 248      * @param   address
 249      *          The address to start listening for connections,
 250      *          or <tt>null</tt> to listen on an address choosen
 251      *          by the transport service.
 252      *
 253      * @return  a listen key to be used in subsequent calls to be
 254      *          {@link #accept accept} or {@link #stopListening
 255      *          stopListening} methods.
 256      *
 257      * @throws  IOException
 258      *          If an I/O error occurs.
 259      *
 260      * @throws  IllegalArgumentException
 261      *          If the specific address is invalid
 262      */
 263     public abstract ListenKey startListening(String address) throws IOException;
 264 
 265     /**
 266      * Listens on an address choosen by the transport service.
 267      *
 268      * <p> This convenience method works as if by invoking {@link
 269      * #startListening(String) startListening(<tt>null</tt>)}. </p>
 270      *
 271      * @return  a listen key to be used in subsequent calls to be
 272      *          {@link #accept accept} or {@link #stopListening
 273      *          stopListening} methods.
 274      *
 275      * @throws  IOException
 276      *          If an I/O error occurs.
 277      */
 278     public abstract ListenKey startListening() throws IOException;
 279 
 280     /**
 281      * Stop listening for inbound connections.
 282      *
 283      * <p> Invoking this method while another thread is blocked
 284      * in {@link #accept accept}, with the same listen key,
 285      * waiting to accept a connection will cause that thread to
 286      * throw an IOException. If the thread blocked in accept
 287      * has already accepted a connection from a target VM and
 288      * is in the process of handshaking with the target VM then
 289      * invoking this method will not cause the thread to throw
 290      * an exception.
 291      *
 292      * @param   listenKey
 293      *          The listen key obtained from a previous call to {@link
 294      *          #startListening(String)} or {@link #startListening()}.
 295      *
 296      * @throws  IllegalArgumentException
 297      *          If the listen key is invalid
 298      *
 299      * @throws  IOException
 300      *          If an I/O error occurs.
 301      */
 302     public abstract void stopListening(ListenKey listenKey) throws IOException;
 303 
 304     /**
 305      * Accept a connection from a target VM.
 306      *
 307      * <p> Waits (indefinitely or with timeout) to accept a connection
 308      * from a target VM. Returns a connection representing the
 309      * bi-directional communication channel to the target VM.
 310      *
 311      * <p> Accepting a connection from a target VM involves two
 312      * steps. First, the transport service waits to accept
 313      * the connection from the target VM. Once the connection is
 314      * established a handshake is performed to ensure that the
 315      * connection is indeed to a target VM. The handshake involves
 316      * the exchange of a string <i>JDWP-Handshake</i> as specified
 317      * in the <a
 318      * href="../../../../../../../../../technotes/guides/jpda/jdwp-spec.html">
 319      * Java Debug Wire Protocol</a> specification.
 320      *
 321      * @param   listenKey
 322      *          A listen key obtained from a previous call to {@link
 323      *          #startListening(String)} or {@link #startListening()}.
 324      *
 325      * @param   acceptTimeout
 326      *          if this transport service supports an accept timeout, and
 327      *          if <tt>acceptTimeout</tt> is positive then block for up to
 328      *          <tt>acceptTimeout</tt> milliseconds, more or less, while waiting
 329      *          for the target VM to connect.
 330      *          If the transport service does not support an accept timeout
 331      *          or if <tt>acceptTimeout</tt> is zero then block indefinitely
 332      *          for a target VM to connect.
 333      *
 334      * @param   handshakeTimeout
 335      *          If this transport service supports a handshake timeout,
 336      *          and if <tt>handshakeTimeout</tt> is positive, then it
 337      *          specifies the timeout, in milliseconds (more or less), to
 338      *          use when handshaking with the target VM. The exact
 339      *          usage of the timeout is specific to the transport service.
 340      *          A transport service may, for example, use the handshake
 341      *          timeout as the inter-character timeout while waiting for
 342      *          the <i>JDWP-Handshake</i> message from the target VM.
 343      *          Alternatively, a transport service may, for example,
 344      *          use the timeout as a timeout for the duration of the
 345      *          handshake exchange.
 346      *          If the transport service does not support a handshake
 347      *          timeout, of if <tt>handshakeTimeout</tt> is specified
 348      *          as zero then the handshake does not timeout if there
 349      *          isn't a response from the target VM.
 350      *
 351      * @return  The Connection representing the bi-directional
 352      *          communication channel to the target VM.
 353      *
 354      * @throws  TransportTimeoutException
 355      *          If a timeout occurs while waiting for a target VM
 356      *          to connect.
 357      *
 358      * @throws  IOException
 359      *          If an I/O error occurs (including a timeout when
 360      *          handshaking).
 361      *
 362      * @throws  IllegalArgumentException
 363      *          If the value of the acceptTimeout argument, or
 364      *          handshakeTimeout is negative, or an invalid listen key
 365      *          is provided.
 366      *
 367      * @throws  IllegalStateException
 368      *          If {@link #stopListening stopListening} has already been
 369      *          called with this listen key and the transport service
 370      *          is no longer listening for inbound connections.
 371      *
 372      * @see TransportService.Capabilities#supportsAcceptTimeout()
 373      */
 374     public abstract Connection accept(ListenKey listenKey, long acceptTimeout,
 375         long handshakeTimeout) throws IOException;
 376 
 377 }