/*
 * Copyright 1998-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.jdi;

import com.sun.jdi.connect.*;
import com.sun.jdi.connect.spi.Connection;
import java.util.List;
import java.io.IOException;

/**
 * A manager of connections to target virtual machines. The
 * VirtualMachineManager allows one application to debug
 * multiple target VMs. (Note that the converse is not
 * supported; a target VM can be debugged by only one
 * debugger application.) This interface
 * contains methods to manage connections
 * to remote target VMs and to obtain the {@link VirtualMachine}
 * mirror for available target VMs.
 * <p>
 * Connections can be made using one of several different
 * {@link com.sun.jdi.connect.Connector} objects. Each connector encapsulates
 * a different way of connecting the debugger with a target VM.
 * <p>
 * The VirtualMachineManager supports many different scenarios for
 * connecting a debugger to a virtual machine. Four examples
 * are presented in the table below. The
 * examples use the command line syntax in Sun's implementation.
 * Some {@link com.sun.jdi.connect.Connector} implementations may require slightly
 * different handling than presented below.
 * <p>
 * <TABLE BORDER WIDTH="75%" SUMMARY="Four scenarios for connecting a debugger
 *  to a virtual machine">
 * <TR>
 * <TH scope=col>Scenario</TH>
 * <TH scope=col>Description</TH>
 * <TR>
 * <TD>Debugger launches target VM (simplest, most-common scenario)</TD>
 *
 * <TD>Debugger calls the
 * {@link com.sun.jdi.connect.LaunchingConnector#launch(java.util.Map)}
 * method of the default connector, obtained with {@link #defaultConnector}. The
 * target VM is launched, and a connection between that VM and the
 * debugger is established. A {@link VirtualMachine} mirror is returned.
 * <P>Or, for more control
 * <UL>
 * <LI>
 * Debugger selects a connector from the list returned by
 * {@link #launchingConnectors} with desired characteristics
 * (for example, transport type, etc.).
 * <LI>
 * Debugger calls the
 * {@link com.sun.jdi.connect.LaunchingConnector#launch(java.util.Map)}
 * method of the selected connector. The
 * target VM is launched, and a connection between that VM and the
 * debugger is established. A {@link VirtualMachine} mirror is returned.
 * </UL>
 * </TD>
 * </TR>
 * <TR>
 * <TD>Debugger attaches to previously-running VM</TD>
 * <TD>
 * <UL>
 * <LI>
 * Target VM is launched using the options
 * <code>-agentlib:jdwp=transport=xxx,server=y</code>
 * </LI>
 * <LI>
 * Target VM generates and outputs the tranport-specific address at which it will
 * listen for a connection.</LI>
 * <LI>
 * Debugger is launched. Debugger selects a connector in the list
 * returned by {@link #attachingConnectors} matching the transport with
 * the name "xxx".
 * <LI>
 * Debugger presents the default connector parameters (obtained through
 * {@link com.sun.jdi.connect.Connector#defaultArguments()}) to the end user,
 * allowing the user to
 * fill in the transport-specific address generated by the target VM.
 * <LI>
 * Debugger calls the {@link com.sun.jdi.connect.AttachingConnector#attach(java.util.Map)} method
 * of the selected to attach to the target VM. A {@link VirtualMachine}
 * mirror is returned.
 * </UL>
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD>Target VM attaches to previously-running debugger</TD>
 * <TD>
 * <LI>
 * At startup, debugger selects one or more connectors from
 * the list returned by {@link #listeningConnectors} for one or more
 * transports.</LI>
 * <LI>
 * Debugger calls the {@link com.sun.jdi.connect.ListeningConnector#startListening(java.util.Map)} method for each selected
 * connector. For each call, a transport-specific address string is
 * generated and returned. The debugger makes the transport names and
 * corresponding address strings available to the end user.
 * <LI>
 * Debugger calls
 * {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)}
 * for each selected connector to wait for
 * a target VM to connect.</LI>
 * <LI>
 * Later, target VM is launched by end user with the options
 * <code>-agentlib:jdwp=transport=xxx,address=yyy</code>
 * where "xxx" the transport for one of the connectors selected by the
 * the debugger and "yyy"
 * is the address generated by
 * {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)} for that
 * transport.</LI>
 * <LI>
 * Debugger's call to {@link com.sun.jdi.connect.ListeningConnector#accept(java.util.Map)} returns
 * a {@link VirtualMachine} mirror.</LI>
 * </TD>
 * </TR>
 *
 * <TR>
 * <TD>Target VM launches debugger (sometimes called "Just-In-Time" debugging)</TD>
 * <TD>
 * <LI>
 * Target VM is launched with the options
 * <code>-agentlib:jdwp=launch=cmdline,onuncaught=y,transport=xxx,server=y</code>
 * </LI>
 * <LI>
 * Later, an uncaught exception is thrown in the target VM. The target
 * VM generates the tranport-specific address at which it will
 * listen for a connection.
 * <LI>Target VM launches the debugger with the following items concatenated
 * together (separated by spaces) to form the command line:
 * <UL>
 * <LI> The launch= value
 * <LI> The transport= value
 * <LI> The generated transport-specific address at which VM is listening for
 * debugger connection.
 * </UL>
 * <LI>
 * Upon launch, debugger selects a connector in the list
 * returned by {@link #attachingConnectors} matching the transport with
 * the name "xxx".
 * <LI>
 * Debugger changes the default connector parameters (obtained through
 * {@link com.sun.jdi.connect.Connector#defaultArguments()}) to specify
 * the transport specific address at which the VM is listenig. Optionally,
 * other connector arguments can be presented to the user.
 * <LI>
 * Debugger calls the
 * {@link com.sun.jdi.connect.AttachingConnector#attach(java.util.Map)} method
 * of the selected to attach to the target VM. A {@link VirtualMachine}
 * mirror is returned.
 * </TD>
 * </TR>
 * </TABLE>
 *
 * <p> Connectors are created at start-up time. That is, they
 * are created the first time that {@link
 * com.sun.jdi.Bootstrap#virtualMachineManager()} is invoked.
 * The list of all Connectors created at start-up time can be
 * obtained from the VirtualMachineManager by invoking the
 * {@link #allConnectors allConnectors} method.
 *
 * <p> Connectors are created at start-up time if they are
 * installed on the platform. In addition, Connectors are created
 * automatically by the VirtualMachineManager to encapsulate any
 * {@link com.sun.jdi.connect.spi.TransportService} implementations
 * that are installed on the platform. These two mechanisms for
 * creating Connectors are described here.
 *
 * <p> A Connector is installed on the platform if it is installed
 * in a jar file that is visible to the defining class loader of
 * the {@link com.sun.jdi.connect.Connector} type,
 * and that jar file contains a provider configuration file named
 * <tt>com.sun.jdi.connect.Connector</tt> in the resource directory
 * <tt>META-INF/services</tt>, and the provider configuration file
 * lists the full-qualified class name of the Connector
 * implementation. A Connector is a class that implements the
 * {@link com.sun.jdi.connect.Connector Connector} interface. More
 * appropriately the class implements one of the specific Connector
 * types, namely {@link com.sun.jdi.connect.AttachingConnector
 * AttachingConnector}, {@link com.sun.jdi.connect.ListeningConnector
 * ListeningConnector}, or {@link com.sun.jdi.connect.LaunchingConnector
 * LaunchingConnector}. The format of the provider configuration file
 * is one fully-qualified class name per line. Space and tab characters
 * surrounding each class, as well as blank lines are ignored. The
 * comment character is <tt>'#'</tt> (<tt>0x23</tt>), and on each
 * line all characters following the first comment character are
 * ignored. The file must be encoded in UTF-8.
 *
 * <p> At start-up time the VirtualMachineManager attempts to load
 * and instantiate (using the no-arg constructor) each class listed
 * in the provider configuration file. Exceptions thrown when loading
 * or creating the Connector are caught and ignored. In other words,
 * the start-up process continues despite of errors.
 *
 * <p> In addition to Connectors installed on the platform the
 * VirtualMachineManager will also create Connectors to encapsulate
 * any {@link com.sun.jdi.connect.spi.TransportService} implementations
 * that are installed on the platform. A TransportService is
 * installed on the platform if it installed in a jar file that is
 * visible to the defining class loader for the
 * {@link com.sun.jdi.connect.spi.TransportService} type, and that jar
 * file contains a provider configuration file named
 * <tt>com.sun.jdi.connect.spi.TransportService</tt> in the resource
 * directory <tt>META-INF/services</tt>, and the provider
 * configuration file lists the the full-qualified class name of the
 * TransportService implementation. A TransportService is a concrete
 * sub-class of {@link com.sun.jdi.connect.spi.TransportService
 * TransportService}. The format of the provider configuration file
 * is the same as the provider configuration file for Connectors
 * except that each class listed must be the fully-qualified class
 * name of a class that implements the TransportService interface.
 *
 * <p> For each TransportService installed on the platform, the
 * VirtualMachineManager creates a corresponding
 * {@link com.sun.jdi.connect.AttachingConnector} and
 * {@link com.sun.jdi.connect.ListeningConnector}. These
 * Connectors are created to encapsulate a {@link
 * com.sun.jdi.connect.Transport Transport} that in turn
 * encapsulates the TransportService.
 * The AttachingConnector will be named based on the name of the
 * transport service concatenated with the string <tt>Attach</tt>.
 * For example, if the transport service {@link
 * com.sun.jdi.connect.spi.TransportService#name() name()} method
 * returns <tt>telepathic</tt> then the AttachingConnector will
 * be named <tt>telepathicAttach</tt>. Similiarly the ListeningConnector
 * will be named with the string <tt>Listen</tt> tagged onto the
 * name of the transport service. The {@link
 * com.sun.jdi.connect.Connector#description() description()} method
 * of both the AttachingConnector, and the ListeningConnector, will
 * delegate to the {@link com.sun.jdi.connect.spi.TransportService#description()
 * description()} method of the underlying transport service. Both
 * the AttachingConnector and the ListeningConnector will have two
 * Connector {@link com.sun.jdi.connect.Connector$Argument Arguments}.
 * A {@link com.sun.jdi.connect.Connector$StringArgument StringArgument}
 * named <tt>address</tt> is the connector argument to specify the
 * address to attach too, or to listen on. A
 * {@link com.sun.jdi.connect.Connector$IntegerArgument IntegerArgument}
 * named <tt>timeout</tt> is the connector argument to specify the
 * timeout when attaching, or accepting. The timeout connector may be
 * ignored depending on if the transport service supports an attach
 * timeout or accept timeout.
 *
 * <p> Initialization of the virtual machine manager will fail, that is
 * {@link com.sun.jdi.Bootstrap#virtualMachineManager()} will throw an
 * error if the virtual machine manager is unable to create any
 * connectors.
 *
 * @author Gordon Hirsch
 * @since  1.3
 */
public interface VirtualMachineManager {

    /**
     * Identifies the default connector. This connector should
     * be used as the launching connector when selection of a
     * connector with specific characteristics is unnecessary.
     *
     * @return the default {@link com.sun.jdi.connect.LaunchingConnector}
     */
    LaunchingConnector defaultConnector();

    /**
     * Returns the list of known {@link com.sun.jdi.connect.LaunchingConnector} objects.
     * Any of the returned objects can be used to launch a new target
     * VM and immediately create a {@link VirtualMachine} mirror for it.
     *
     * Note that a target VM launched by a launching connector is not
     * guaranteed to be stable until after the {@link com.sun.jdi.event.VMStartEvent} has been
     * received.
     * @return a list of {@link com.sun.jdi.connect.LaunchingConnector} objects.
     */
    List<LaunchingConnector> launchingConnectors();

    /**
     * Returns the list of known {@link com.sun.jdi.connect.AttachingConnector} objects.
     * Any of the returned objects can be used to attach to an existing target
     * VM and create a {@link VirtualMachine} mirror for it.
     *
     * @return a list of {@link com.sun.jdi.connect.AttachingConnector} objects.
     */
    List<AttachingConnector> attachingConnectors();

    /**
     * Returns the list of known {@link com.sun.jdi.connect.ListeningConnector} objects.
     * Any of the returned objects can be used to listen for a
     * connection initiated by a target VM
     * and create a {@link VirtualMachine} mirror for it.
     *
     * @return a list of {@link com.sun.jdi.connect.ListeningConnector} objects.
     */
    List<ListeningConnector> listeningConnectors();

    /**
     * Returns the list of all known {@link com.sun.jdi.connect.Connector} objects.
     *
     * @return a list of {@link com.sun.jdi.connect.Connector} objects.
     */
     List<Connector> allConnectors();

    /**
     * Lists all target VMs which are connected to the debugger.
     * The list includes {@link VirtualMachine} instances for
     * any target VMs which initiated a connection
     * and any
     * target VMs to which this manager has initiated a connection.
     * A target VM will remain in this list
     * until the VM is disconnected.
     * {@link com.sun.jdi.event.VMDisconnectEvent} is placed in the event queue
     * after the VM is removed from the list.
     *
     * @return a list of {@link VirtualMachine} objects, each mirroring
     * a target VM.
     */
     List<VirtualMachine> connectedVirtualMachines();

     /**
      * Returns the major version number of the JDI interface.
      * See {@link VirtualMachine#version} target VM version and
      * information and
      * {@link VirtualMachine#description} more version information.
      *
      * @return the integer major version number.
      */
     int majorInterfaceVersion();

     /**
      * Returns the minor version number of the JDI interface.
      * See {@link VirtualMachine#version} target VM version and
      * information and
      * {@link VirtualMachine#description} more version information.
      *
      * @return the integer minor version number
      */
     int minorInterfaceVersion();

     /**
      * Create a virtual machine mirror for a target VM.
      *
      * <p> Creates a virtual machine mirror for a target VM
      * for which a {@link com.sun.jdi.connect.spi.Connection Connection}
      * already exists. A Connection is created when a {@link
      * com.sun.jdi.connect.Connector Connector} establishes
      * a connection and successfully handshakes with a target VM.
      * A Connector can then use this method to create a virtual machine
      * mirror to represent the composite state of the target VM.
      *
      * <p> The <tt>process</tt> argument specifies the
      * {@link java.lang.Process} object for the taget VM. It may be
      * specified as <tt>null</tt>. If the target VM is launched
      * by a {@link com.sun.jdi.connect.LaunchingConnector
      * LaunchingConnector} the <tt>process</tt> argument should be
      * specified, otherwise calling {@link com.sun.jdi.VirtualMachine#process()}
      * on the created virtual machine will return <tt>null</tt>.
      *
      * <p> This method exists so that Connectors may create
      * a virtual machine mirror when a connection is established
      * to a target VM. Only developers creating new Connector
      * implementations should need to make direct use of this
      * method. </p>
      *
      * @param  connection
      *         The open connection to the target VM.
      *
      * @param  process
      *         If launched, the {@link java.lang.Process} object for
      *         the target VM. <tt>null</tt> if not launched.
      *
      * @return new virtual machine representing the target VM.
      *
      * @throws IOException
      *         if an I/O error occurs
      *
      * @throws IllegalStateException
      *         if the connection is not open
      *
      * @see com.sun.jdi.connect.spi.Connection#isOpen()
      * @see com.sun.jdi.VirtualMachine#process()
      *
      * @since 1.5
      */
     VirtualMachine createVirtualMachine(Connection connection, Process process) throws IOException;

     /**
      * Creates a new virtual machine.
      *
      * <p> This convenience method works as if by invoking {@link
      * #createVirtualMachine(Connection, Process)} method and
      * specifying <tt>null</tt> as the <tt>process</tt> argument.
      *
      * <p> This method exists so that Connectors may create
      * a virtual machine mirror when a connection is established
      * to a target VM. Only developers creating new Connector
      * implementations should need to make direct use of this
      * method. </p>
      *
      * @return the new virtual machine
      *
      * @throws IOException
      *         if an I/O error occurs
      *
      * @throws IllegalStateException
      *         if the connection is not open
      *
      * @since 1.5
      */
     VirtualMachine createVirtualMachine(Connection connection) throws IOException;
}
