langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java
author iris
Thu, 21 Jul 2016 07:43:17 -0700
changeset 39809 74b7aea686d8
parent 39807 ba0ff343d241
child 40767 c7908e8c786b
permissions -rw-r--r--
8161236: Runtime.Version.{compareTo, equals}IgnoreOpt should be renamed Reviewed-by: alanb, rfield, ksrini
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     1
/*
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     2
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     4
 *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    10
 *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    15
 * accompanied this code).
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    16
 *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    20
 *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    23
 * questions.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    24
 */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    25
package jdk.jshell.execution;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    26
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    27
import jdk.jshell.spi.ExecutionEnv;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    28
import java.io.IOException;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    29
import java.io.InputStream;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    30
import java.io.ObjectInput;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    31
import java.io.ObjectInputStream;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    32
import java.io.ObjectOutput;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    33
import java.io.ObjectOutputStream;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    34
import java.io.OutputStream;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    35
import java.util.Map;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    36
import java.util.Map.Entry;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    37
import java.util.function.Consumer;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    38
import com.sun.jdi.VirtualMachine;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    39
import jdk.jshell.spi.ExecutionControl;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    40
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    41
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    42
/**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    43
 * Miscellaneous utility methods for setting-up implementations of
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    44
 * {@link ExecutionControl}. Particularly implementations with remote
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    45
 * execution.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    46
 *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    47
 * @author Jan Lahoda
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    48
 * @author Robert Field
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    49
 */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    50
public class Util {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    51
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    52
    // never instanciated
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    53
    private Util() {}
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    54
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    55
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    56
     * Create a composite {@link ExecutionControl.Generator} instance that, when
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    57
     * generating, will try each specified generator until successfully creating
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    58
     * an {@link ExecutionControl} instance, or, if all fail, will re-throw the
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    59
     * first exception.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    60
     *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    61
     * @param gec0 the first instance to try
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    62
     * @param gecs the second through Nth instance to try
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    63
     * @return the fail-over generator
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    64
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    65
    public static ExecutionControl.Generator failOverExecutionControlGenerator(
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    66
            ExecutionControl.Generator gec0, ExecutionControl.Generator... gecs) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    67
        return (ExecutionEnv env) -> {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    68
            Throwable thrown;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    69
            try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    70
                return gec0.generate(env);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    71
            } catch (Throwable ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    72
                thrown = ex;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    73
            }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    74
            for (ExecutionControl.Generator gec : gecs) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    75
                try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    76
                    return gec.generate(env);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    77
                } catch (Throwable ignore) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    78
                    // only care about the first, and only if they all fail
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    79
                }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    80
            }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    81
            throw thrown;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    82
        };
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    83
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    84
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    85
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    86
     * Forward commands from the input to the specified {@link ExecutionControl}
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    87
     * instance, then responses back on the output.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    88
     * @param ec the direct instance of {@link ExecutionControl} to process commands
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    89
     * @param in the command input
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    90
     * @param out the command response output
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    91
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    92
    public static void forwardExecutionControl(ExecutionControl ec,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    93
            ObjectInput in, ObjectOutput out) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    94
        new ExecutionControlForwarder(ec, in, out).commandLoop();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    95
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    96
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    97
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    98
     * Forward commands from the input to the specified {@link ExecutionControl}
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
    99
     * instance, then responses back on the output.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   100
     * @param ec the direct instance of {@link ExecutionControl} to process commands
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   101
     * @param inStream the stream from which to create the command input
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   102
     * @param outStream the stream that will carry {@code System.out},
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   103
     * {@code System.err}, any specified auxiliary channels, and the
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   104
     * command response output.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   105
     * @param streamMap a map between names of additional streams to carry and setters
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   106
     * for the stream
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   107
     * @throws IOException if there are errors using the passed streams
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   108
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   109
    public static void forwardExecutionControlAndIO(ExecutionControl ec,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   110
            InputStream inStream, OutputStream outStream,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   111
            Map<String, Consumer<OutputStream>> streamMap) throws IOException {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   112
        ObjectInputStream cmdIn = new ObjectInputStream(inStream);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   113
        for (Entry<String, Consumer<OutputStream>> e : streamMap.entrySet()) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   114
            e.getValue().accept(multiplexingOutputStream(e.getKey(), outStream));
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   115
        }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   116
        ObjectOutputStream cmdOut = new ObjectOutputStream(multiplexingOutputStream("command", outStream));
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   117
        forwardExecutionControl(ec, cmdIn, cmdOut);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   118
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   119
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   120
    static OutputStream multiplexingOutputStream(String label, OutputStream outputStream) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   121
        return new MultiplexingOutputStream(label, outputStream);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   122
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   123
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   124
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   125
     * Reads from an InputStream which has been packetized and write its contents
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   126
     * to the out and err OutputStreams; Copies the command stream.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   127
     * @param input the packetized input stream
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   128
     * @param streamMap a map between stream names and the output streams to forward
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   129
     * @return the command stream
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   130
     * @throws IOException if setting up the streams raised an exception
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   131
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   132
    public static ObjectInput remoteInput(InputStream input,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   133
            Map<String, OutputStream> streamMap) throws IOException {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   134
        PipeInputStream commandIn = new PipeInputStream();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   135
        new DemultiplexInput(input, commandIn, streamMap).start();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   136
        return new ObjectInputStream(commandIn);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   137
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   138
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   139
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   140
     * Monitor the JDI event stream for {@link com.sun.jdi.event.VMDeathEvent}
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   141
     * and {@link com.sun.jdi.event.VMDisconnectEvent}. If encountered, invokes
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   142
     * {@code unbiddenExitHandler}.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   143
     *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   144
     * @param vm the virtual machine to check
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   145
     * @param unbiddenExitHandler the handler, which will accept the exit
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   146
     * information
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   147
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   148
    public static void detectJDIExitEvent(VirtualMachine vm, Consumer<String> unbiddenExitHandler) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   149
        if (vm.canBeModified()) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   150
            new JDIEventHandler(vm, unbiddenExitHandler).start();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   151
        }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   152
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   153
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   154
    /**
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   155
     * Creates a Thread that will ship all input to the remote agent.
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   156
     *
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   157
     * @param inputStream the user input
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   158
     * @param outStream the input to the remote agent
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   159
     * @param handler a failure handler
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   160
     */
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   161
    public static void forwardInputToRemote(final InputStream inputStream,
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   162
            final OutputStream outStream, final Consumer<Exception> handler) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   163
        Thread thr = new Thread("input reader") {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   164
            @Override
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   165
            public void run() {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   166
                try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   167
                    byte[] buf = new byte[256];
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   168
                    int cnt;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   169
                    while ((cnt = inputStream.read(buf)) != -1) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   170
                        outStream.write(buf, 0, cnt);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   171
                        outStream.flush();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   172
                    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   173
                } catch (Exception ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   174
                    handler.accept(ex);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   175
                }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   176
            }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   177
        };
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   178
        thr.setPriority(Thread.MAX_PRIORITY - 1);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   179
        thr.start();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   180
    }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   181
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents:
diff changeset
   182
}