Package org.eclipse.jdi.internal

Source Code of org.eclipse.jdi.internal.MirrorImpl

/*******************************************************************************
* Copyright (c) 2000, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdi.internal;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import org.eclipse.jdi.Bootstrap;
import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
import org.eclipse.jdi.internal.jdwp.JdwpPacket;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
import org.eclipse.jdi.internal.jdwp.JdwpString;
import org.eclipse.jdt.internal.debug.core.JDIDebugOptions;

import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.InternalException;
import com.sun.jdi.InvalidStackFrameException;
import com.sun.jdi.Mirror;
import com.sun.jdi.NativeMethodException;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VMMismatchException;
import com.sun.jdi.VMOutOfMemoryException;
import com.sun.jdi.VirtualMachine;

/**
* this class implements the corresponding interfaces declared by the JDI
* specification. See the com.sun.jdi package for more information.
*
*/
public class MirrorImpl implements Mirror {

  /** Description of Mirror object. */
  protected String fDescription;
  /** Virtual Machine of Mirror object. */
  private VirtualMachineImpl fVirtualMachineImpl;
  /**
   * VerboseWriter where verbose info is written to, null if no verbose must
   * be given.
   */
  protected VerboseWriter fVerboseWriter = null;
  /**
   * True if a Jdwp request has been sent to the VM and the response is not
   * yet (fully) processed.
   */
  private boolean fPendingJdwpRequest = false;

  /**
   * Constructor only to be used by Virtual Machine objects: stores
   * description of Mirror object and Virtual Machine.
   */
  public MirrorImpl(String description) {
    fDescription = description;
    fVirtualMachineImpl = (VirtualMachineImpl) this;
    PrintWriter writer = ((VirtualMachineManagerImpl) org.eclipse.jdi.Bootstrap
        .virtualMachineManager()).verbosePrintWriter();
    if (writer != null)
      fVerboseWriter = new VerboseWriter(writer);
  }

  /**
   * Constructor stores description of Mirror object and its Virtual Machine.
   */
  public MirrorImpl(String description, VirtualMachineImpl virtualMachineImpl) {
    fVirtualMachineImpl = virtualMachineImpl;
    fDescription = description;
    PrintWriter writer = ((VirtualMachineManagerImpl) org.eclipse.jdi.Bootstrap
        .virtualMachineManager()).verbosePrintWriter();
    if (writer != null)
      fVerboseWriter = new VerboseWriter(writer);
  }

  /**
   * @return Returns description of Mirror object.
   */
  @Override
  public String toString() {
    return fDescription;
  }

  /**
   * @return Returns Virtual Machine of Mirror object.
   */
  public VirtualMachine virtualMachine() {
    return fVirtualMachineImpl;
  }

  /**
   * @return Returns Virtual Machine implementation of Mirror object.
   */
  public VirtualMachineImpl virtualMachineImpl() {
    return fVirtualMachineImpl;
  }

  /**
   * Processing before each Jdwp event.
   */
  public void initJdwpEventSet(JdwpCommandPacket commandPacket) {
    if (fVerboseWriter != null) {
      fVerboseWriter.println("Received event set"); //$NON-NLS-1$
      fVerboseWriter.println("length", commandPacket.getLength()); //$NON-NLS-1$
      fVerboseWriter.println("id", commandPacket.getId()); //$NON-NLS-1$
      fVerboseWriter.println(
          "flags", commandPacket.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
      fVerboseWriter.println(
          "command set", (byte) (commandPacket.getCommand() >>> 8)); //$NON-NLS-1$
      fVerboseWriter
          .println("command", (byte) commandPacket.getCommand()); //$NON-NLS-1$
    }
  }

  /**
   * Processing after each Jdwp Event.
   */
  public void handledJdwpEventSet() {
    if (fVerboseWriter != null) {
      fVerboseWriter.println();
      fVerboseWriter.flush();
    }
  }

  /**
   * Processing before each Jdwp request. Note that this includes building the
   * request message and parsing the response.
   */
  public void initJdwpRequest() {
    if (fVerboseWriter != null) {
      fVerboseWriter.gotoPosition(6);
    }
  }

  /**
   * Writes command packet header if verbose is on.
   */
  public void writeVerboseCommandPacketHeader(JdwpCommandPacket commandPacket) {
    if (fVerboseWriter != null) {
      int command = commandPacket.getCommand();
      int currentPosition = fVerboseWriter.position();
      fVerboseWriter.gotoPosition(0);
      fVerboseWriter.print("Sending command ("); //$NON-NLS-1$
      fVerboseWriter.printValue(command, JdwpCommandPacket.commandMap());
      fVerboseWriter.println(")"); //$NON-NLS-1$
      fVerboseWriter.println("length", commandPacket.getLength()); //$NON-NLS-1$
      fVerboseWriter.println("id", commandPacket.getId()); //$NON-NLS-1$
      fVerboseWriter.println(
          "flags", commandPacket.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
      fVerboseWriter.println("command set", (byte) (command >>> 8)); //$NON-NLS-1$
      fVerboseWriter.println("command", (byte) command); //$NON-NLS-1$
      fVerboseWriter.gotoPosition(currentPosition);
    }
  }

  /**
   * Processing after each Jdwp Request.
   */
  public void handledJdwpRequest() {
    if (fVerboseWriter != null && fPendingJdwpRequest) {
      fVerboseWriter.println();
      fVerboseWriter.flush();
    }
    fPendingJdwpRequest = false;
  }

  /**
   * Performs a VM request.
   *
   * @return Returns reply data.
   */
  public JdwpReplyPacket requestVM(int command, byte[] outData) {
    JdwpCommandPacket commandPacket = new JdwpCommandPacket(command);
    commandPacket.setData(outData);
    long sent = System.currentTimeMillis();
    fVirtualMachineImpl.packetSendManager().sendPacket(commandPacket);
    fPendingJdwpRequest = true;
    writeVerboseCommandPacketHeader(commandPacket);

    JdwpReplyPacket reply = fVirtualMachineImpl.packetReceiveManager()
        .getReply(commandPacket);
    long recieved = System.currentTimeMillis();
    if (JDIDebugOptions.DEBUG_JDI_REQUEST_TIMES) {
      StringBuffer buf = new StringBuffer();
      buf.append(JDIDebugOptions.FORMAT.format(new Date(sent)));
      buf.append(" JDI Request: "); //$NON-NLS-1$
      buf.append(commandPacket.toString());
      buf.append("\n\tResponse Time: "); //$NON-NLS-1$
      buf.append(recieved - sent);
      buf.append("ms"); //$NON-NLS-1$
      buf.append(" length: "); //$NON-NLS-1$
      buf.append(reply.getLength());
      JDIDebugOptions.trace(buf.toString());
    }
    if (fVerboseWriter != null) {
      fVerboseWriter.println();
      fVerboseWriter.println("Received reply"); //$NON-NLS-1$
      fVerboseWriter.println("length", reply.getLength()); //$NON-NLS-1$
      fVerboseWriter.println("id", reply.getId()); //$NON-NLS-1$
      fVerboseWriter.println(
          "flags", reply.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
      fVerboseWriter
          .println(
              "error code", reply.errorCode(), JdwpReplyPacket.errorMap()); //$NON-NLS-1$
    }

    return reply;
  }

  /**
   * Performs a VM request.
   *
   * @return Returns reply data.
   */
  public JdwpReplyPacket requestVM(int command, ByteArrayOutputStream outData) {
    return requestVM(command, outData.toByteArray());
  }

  /**
   * Performs a VM request for a specified object.
   *
   * @return Returns reply data.
   */
  public JdwpReplyPacket requestVM(int command, ObjectReferenceImpl object) {
    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    DataOutputStream dataOutStream = new DataOutputStream(byteOutStream);
    try {
      object.write(this, dataOutStream);
    } catch (IOException e) {
      defaultIOExceptionHandler(e);
    }
    return requestVM(command, byteOutStream);
  }

  /**
   * Performs a VM request for a specified object.
   *
   * @return Returns reply data.
   */
  public JdwpReplyPacket requestVM(int command, ReferenceTypeImpl refType) {
    ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
    DataOutputStream dataOutStream = new DataOutputStream(byteOutStream);
    try {
      refType.write(this, dataOutStream);
    } catch (IOException e) {
      defaultIOExceptionHandler(e);
    }
    return requestVM(command, byteOutStream);
  }

  /**
   * Performs a VM request.
   *
   * @return Returns reply data.
   */
  public JdwpReplyPacket requestVM(int command) {
    return requestVM(command, (byte[]) null);
  }

  /**
   * Performs default error handling.
   */
  public void defaultReplyErrorHandler(int error) {
    switch (error) {
    case JdwpReplyPacket.NONE:
      break;
    case JdwpReplyPacket.INVALID_OBJECT:
      throw new ObjectCollectedException();
    case JdwpReplyPacket.INVALID_CLASS:
      throw new ClassNotPreparedException();
    case JdwpReplyPacket.CLASS_NOT_PREPARED:
      throw new ClassNotPreparedException();
    case JdwpReplyPacket.OUT_OF_MEMORY:
      throw new VMOutOfMemoryException();
    case JdwpReplyPacket.ILLEGAL_ARGUMENT:
      throw new IllegalArgumentException();
    case JdwpReplyPacket.NATIVE_METHOD:
      throw new NativeMethodException();
    case JdwpReplyPacket.INVALID_FRAMEID:
      throw new InvalidStackFrameException();
    case JdwpReplyPacket.NOT_IMPLEMENTED:
      throw new UnsupportedOperationException();
    case JdwpReplyPacket.HCR_OPERATION_REFUSED:
      throw new org.eclipse.jdi.hcr.OperationRefusedException();
    case JdwpReplyPacket.VM_DEAD:
      throw new VMDisconnectedException();
    default:
      throw new InternalException(
          JDIMessages.MirrorImpl_Got_error_code_in_reply___1 + error,
          error);
    }
  }

  /**
   * Performs default handling of IOException in creating or interpreting a
   * Jdwp packet.
   */
  public void defaultIOExceptionHandler(Exception e) {
    throw new InternalException(JDIMessages.MirrorImpl_Got_invalid_data___2
        + e);
  }

  /**
   * Waits for a specified command packet from the VM.
   *
   * @return Returns Command Packet from VM.
   */
  public final JdwpCommandPacket getCommandVM(int command, long timeout)
      throws InterruptedException {
    return fVirtualMachineImpl.packetReceiveManager().getCommand(command,
        timeout);
  }

  /**
   * @exception VMMismatchException
   *                is thrown if the Mirror argument and this mirror do not
   *                belong to the same VirtualMachine.
   */
  public void checkVM(Mirror mirror) throws VMMismatchException {
    if (((MirrorImpl) mirror).virtualMachineImpl() != this
        .virtualMachineImpl())
      throw new VMMismatchException();
  }

  /**
   * Disconnects VM.
   */
  public void disconnectVM() {
    fVirtualMachineImpl.setDisconnected(true);
    fVirtualMachineImpl.packetSendManager().disconnectVM();
    fVirtualMachineImpl.packetReceiveManager().disconnectVM();
    ((VirtualMachineManagerImpl) Bootstrap.virtualMachineManager())
        .removeConnectedVM(fVirtualMachineImpl);
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public byte readByte(String description, DataInputStream in)
      throws IOException {
    byte result = in.readByte();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public short readShort(String description, DataInputStream in)
      throws IOException {
    short result = in.readShort();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public int readInt(String description, DataInputStream in)
      throws IOException {
    int result = in.readInt();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public long readLong(String description, DataInputStream in)
      throws IOException {
    long result = in.readLong();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public byte readByte(String description, Map<Integer, String> valueToString,
      DataInputStream in) throws IOException {
    byte result = in.readByte();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, valueToString);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public short readShort(String description, Map<Integer, String> valueToString,
      DataInputStream in) throws IOException {
    short result = in.readShort();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, valueToString);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public int readInt(String description, Map<Integer, String> valueToString, DataInputStream in)
      throws IOException {
    int result = in.readInt();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, valueToString);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public String readString(String description, DataInputStream in)
      throws IOException {
    String result = JdwpString.read(in);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public boolean readBoolean(String description, DataInputStream in)
      throws IOException {
    boolean result = in.readBoolean();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public char readChar(String description, DataInputStream in)
      throws IOException {
    char result = in.readChar();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public double readDouble(String description, DataInputStream in)
      throws IOException {
    double result = in.readDouble();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public float readFloat(String description, DataInputStream in)
      throws IOException {
    float result = in.readFloat();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public byte[] readByteArray(int length, String description,
      DataInputStream in) throws IOException {
    byte[] result = new byte[length];
    in.readFully(result);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result);
    }
    return result;
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeByte(byte value, String description, DataOutputStream out)
      throws IOException {
    out.writeByte(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeShort(short value, String description, DataOutputStream out)
      throws IOException {
    out.writeShort(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeInt(int value, String description, DataOutputStream out)
      throws IOException {
    out.writeInt(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeLong(long value, String description, DataOutputStream out)
      throws IOException {
    out.writeLong(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeByte(byte value, String description, Map<Integer, String> valueToString,
      DataOutputStream out) throws IOException {
    out.writeByte(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, valueToString);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeShort(short value, String description, Map<Integer, String> valueToString,
      DataOutputStream out) throws IOException {
    out.writeShort(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, valueToString);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeInt(int value, String description, Map<Integer, String> valueToString,
      DataOutputStream out) throws IOException {
    out.writeInt(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, valueToString);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeString(String value, String description,
      DataOutputStream out) throws IOException {
    JdwpString.write(value, out);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeBoolean(boolean value, String description,
      DataOutputStream out) throws IOException {
    out.writeBoolean(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeChar(char value, String description, DataOutputStream out)
      throws IOException {
    out.writeChar(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeDouble(double value, String description,
      DataOutputStream out) throws IOException {
    out.writeDouble(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeFloat(float value, String description, DataOutputStream out)
      throws IOException {
    out.writeFloat(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeShort(short value, String description, String[] bitNames,
      DataOutputStream out) throws IOException {
    out.writeShort(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, bitNames);
    }
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeInt(int value, String description, String[] bitNames,
      DataOutputStream out) throws IOException {
    out.writeInt(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, bitNames);
    }
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public byte readByte(String description, String[] bitNames,
      DataInputStream in) throws IOException {
    byte result = in.readByte();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, bitNames);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public short readShort(String description, String[] bitNames,
      DataInputStream in) throws IOException {
    short result = in.readShort();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, bitNames);
    }
    return result;
  }

  /**
   * Reads Jdwp data and, if verbose is on, outputs verbose info.
   *
   * @return Returns value that has been read.
   */
  public int readInt(String description, String[] bitNames, DataInputStream in)
      throws IOException {
    int result = in.readInt();
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, result, bitNames);
    }
    return result;
  }

  /**
   * Writes Jdwp data and, if verbose is on, outputs verbose info.
   */
  public void writeByte(byte value, String description, String[] bitNames,
      DataOutputStream out) throws IOException {
    out.writeByte(value);
    if (fVerboseWriter != null) {
      fVerboseWriter.println(description, value, bitNames);
    }
  }

  /**
   * @return Returns VerboseWriter where verbose info is written to, null if
   *         no verbose must be given.
   */
  public VerboseWriter verboseWriter() {
    return fVerboseWriter;
  }
}
TOP

Related Classes of org.eclipse.jdi.internal.MirrorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.