blob: b4f46112c861f9428a94e03ad9c3783289f84039 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Anton V. Karnachuk
*/
/**
* Created on 17.03.2005
*/
package org.apache.harmony.jpda.tests.framework.jdwp;
import org.apache.harmony.jpda.tests.framework.TestErrorException;
/**
* This class represent parsed EventPacket with received event set data.
*/
public class ParsedEvent {
private byte suspendPolicy;
private int requestID;
private byte eventKind;
/**
* Create new instance with specified data.
*/
protected ParsedEvent(byte suspendPolicy, Packet packet, byte eventKind) {
this.suspendPolicy = suspendPolicy;
this.requestID = packet.getNextValueAsInt();
this.eventKind = eventKind;
}
/**
* Returns RequestID of this event set.
*
* @return RequestID of this event set
*/
public int getRequestID() {
return requestID;
}
/**
* Returns suspend policy of this event set.
*
* @return suspend policy of this event set
*/
public byte getSuspendPolicy() {
return suspendPolicy;
}
/**
* @return Returns the eventKind.
*/
public byte getEventKind() {
return eventKind;
}
/**
* The class extends ParsedEvent by associating it with a thread.
*/
public static class EventThread extends ParsedEvent {
private long threadID;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
protected EventThread(byte suspendPolicy, Packet packet, byte eventKind) {
super(suspendPolicy, packet, eventKind);
this.threadID = packet.getNextValueAsThreadID();
}
/**
* @return Returns the thread id.
*/
public long getThreadID() {
return threadID;
}
}
/**
* The class extends EventThread by associating it with a location.
*/
public static class EventThreadLocation extends EventThread {
private Location location;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
protected EventThreadLocation(byte suspendPolicy, Packet packet,
byte eventKind) {
super(suspendPolicy, packet, eventKind);
this.location = packet.getNextValueAsLocation();
}
/**
* @return Returns the location.
*/
public Location getLocation() {
return location;
}
}
/**
* The class extends EventThread by associating it with monitor object and location.
*/
private static class EventThreadMonitor extends EventThread {
private TaggedObject taggedObject;
private Location location;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
protected EventThreadMonitor(byte suspendPolicy, Packet packet,
byte eventKind) {
super(suspendPolicy, packet, eventKind);
this.taggedObject = packet.getNextValueAsTaggedObject();
this.location = packet.getNextValueAsLocation();
}
/**
* @return Returns the location.
*/
public Location getLocation() {
return location;
}
/**
* @return Returns the taggedObject.
*/
public TaggedObject getTaggedObject() {
return taggedObject;
}
}
/**
* The class implements JDWP VM_START event.
*/
public static final class Event_VM_START extends EventThread {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_VM_START(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.VM_START);
}
}
/**
* The class implements JDWP SINGLE_STEP event.
*/
public static final class Event_SINGLE_STEP extends EventThreadLocation {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_SINGLE_STEP(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.SINGLE_STEP);
}
}
/**
* The class implements JDWP BREAKPOINT event.
*/
public static final class Event_BREAKPOINT extends EventThreadLocation {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_BREAKPOINT(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.BREAKPOINT);
}
}
/**
* The class implements JDWP METHOD_ENTRY event.
*/
public static final class Event_METHOD_ENTRY extends EventThreadLocation {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_METHOD_ENTRY(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.METHOD_ENTRY);
}
}
/**
* The class implements JDWP METHOD_EXIT event.
*/
public static final class Event_METHOD_EXIT extends EventThreadLocation {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_METHOD_EXIT(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.METHOD_EXIT);
}
}
/**
* The class implements JDWP METHOD_EXIT_WITH_RETURN_VALUE event.
*/
public static final class Event_METHOD_EXIT_WITH_RETURN_VALUE extends EventThreadLocation {
private Value returnValue;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_METHOD_EXIT_WITH_RETURN_VALUE(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.METHOD_EXIT_WITH_RETURN_VALUE);
returnValue = packet.getNextValueAsValue();
}
public Value getReturnValue(){
return returnValue;
}
}
/**
* The class implements JDWP MONITOR_CONTENDED_ENTER event.
*/
public static final class Event_MONITOR_CONTENDED_ENTER extends EventThreadMonitor {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_MONITOR_CONTENDED_ENTER(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.MONITOR_CONTENDED_ENTER);
}
}
/**
* The class implements JDWP MONITOR_CONTENDED_ENTERED event.
*/
public static final class Event_MONITOR_CONTENDED_ENTERED extends EventThreadMonitor {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_MONITOR_CONTENDED_ENTERED(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.MONITOR_CONTENDED_ENTERED);
}
}
/**
* The class implements JDWP METHOD_EXIT_WITH_RETURN_VALUE event.
*/
public static final class Event_MONITOR_WAIT extends EventThreadMonitor {
private long timeout;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_MONITOR_WAIT(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.MONITOR_WAIT);
this.timeout = packet.getNextValueAsLong();
}
public long getTimeout(){
return timeout;
}
}
/**
* The class implements JDWP METHOD_EXIT_WITH_RETURN_VALUE event.
*/
public static final class Event_MONITOR_WAITED extends EventThreadMonitor {
private boolean timed_out;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_MONITOR_WAITED(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.MONITOR_WAITED);
this.timed_out = packet.getNextValueAsBoolean();
}
public boolean getTimedout(){
return timed_out;
}
}
/**
* The class implements JDWP EXCEPTION event.
*/
public static final class Event_EXCEPTION extends EventThreadLocation {
private TaggedObject exception;
private Location catchLocation;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_EXCEPTION(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.EXCEPTION);
exception = packet.getNextValueAsTaggedObject();
catchLocation = packet.getNextValueAsLocation();
}
/**
* @return Returns the location of the caught exception.
*/
public Location getCatchLocation() {
return catchLocation;
}
/**
* @return Returns the exception.
*/
public TaggedObject getException() {
return exception;
}
}
/**
* The class implements JDWP THREAD_START event.
*/
public static final class Event_THREAD_START extends EventThread {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_THREAD_START(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.THREAD_START);
}
}
/**
* The class implements JDWP THREAD_DEATH event.
*/
public static final class Event_THREAD_DEATH extends EventThread {
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_THREAD_DEATH(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.THREAD_DEATH);
}
}
/**
* The class implements JDWP CLASS_PREPARE event.
*/
public static final class Event_CLASS_PREPARE extends EventThread {
private byte refTypeTag;
private long typeID;
private String signature;
private int status;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
protected Event_CLASS_PREPARE(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.CLASS_PREPARE);
refTypeTag = packet.getNextValueAsByte();
typeID = packet.getNextValueAsReferenceTypeID();
signature = packet.getNextValueAsString();
status = packet.getNextValueAsInt();
}
/**
* @return Returns the refTypeTag.
*/
public byte getRefTypeTag() {
return refTypeTag;
}
/**
* @return Returns the signature.
*/
public String getSignature() {
return signature;
}
/**
* @return Returns the status.
*/
public int getStatus() {
return status;
}
/**
* @return Returns the typeID.
*/
public long getTypeID() {
return typeID;
}
}
/**
* The class implements JDWP CLASS_UNLOAD event.
*/
public static final class Event_CLASS_UNLOAD extends ParsedEvent {
private String signature;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_CLASS_UNLOAD(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.CLASS_UNLOAD);
signature = packet.getNextValueAsString();
}
/**
* @return Returns the signature.
*/
public String getSignature() {
return signature;
}
}
/**
* The class implements JDWP FIELD_ACCESS event.
*/
public static final class Event_FIELD_ACCESS extends EventThreadLocation {
private byte refTypeTag;
private long typeID;
private long fieldID;
private TaggedObject object;
/**
* A constructor.
*
* @param suspendPolicy
* @param packet
*/
private Event_FIELD_ACCESS(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.FIELD_ACCESS);
refTypeTag = packet.getNextValueAsByte();
typeID = packet.getNextValueAsReferenceTypeID();
fieldID = packet.getNextValueAsFieldID();
object = packet.getNextValueAsTaggedObject();
}
/**
* @return Returns the fieldID.
*/
public long getFieldID() {
return fieldID;
}
/**
* @return Returns the object.
*/
public TaggedObject getObject() {
return object;
}
/**
* @return Returns the refTypeTag.
*/
public byte getRefTypeTag() {
return refTypeTag;
}
/**
* @return Returns the typeID.
*/
public long getTypeID() {
return typeID;
}
}
/**
* The class implements JDWP FIELD_MODIFICATION event.
*/
public static final class Event_FIELD_MODIFICATION extends
EventThreadLocation {
private byte refTypeTag;
private long typeID;
private long fieldID;
private TaggedObject object;
private Value valueToBe;
/**
* A constructor.
* @param suspendPolicy
* @param packet
*/
private Event_FIELD_MODIFICATION(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet,
JDWPConstants.EventKind.FIELD_MODIFICATION);
refTypeTag = packet.getNextValueAsByte();
typeID = packet.getNextValueAsReferenceTypeID();
fieldID = packet.getNextValueAsFieldID();
object = packet.getNextValueAsTaggedObject();
valueToBe = packet.getNextValueAsValue();
}
/**
* @return Returns the fieldID.
*/
public long getFieldID() {
return fieldID;
}
/**
* @return Returns the object.
*/
public TaggedObject getObject() {
return object;
}
/**
* @return Returns the refTypeTag.
*/
public byte getRefTypeTag() {
return refTypeTag;
}
/**
* @return Returns the typeID.
*/
public long getTypeID() {
return typeID;
}
/**
* @return Returns the valueToBe.
*/
public Value getValueToBe() {
return valueToBe;
}
}
/**
* The class implements JDWP VM_DEATH event.
*/
public static final class Event_VM_DEATH extends ParsedEvent {
/**
* A constructor.
* @param suspendPolicy
* @param packet
*/
private Event_VM_DEATH(byte suspendPolicy, Packet packet) {
super(suspendPolicy, packet, JDWPConstants.EventKind.VM_DEATH);
}
}
/**
* Returns array of ParsedEvent extracted from given EventPacket.
*
* @param packet
* EventPacket to parse events
* @return array of extracted ParsedEvents
*/
public static ParsedEvent[] parseEventPacket(Packet packet) {
Packet packetCopy = new Packet(packet.toBytesArray());
// Suspend Policy field
byte suspendPolicy = packetCopy.getNextValueAsByte();
// Number of events
int eventCount = packetCopy.getNextValueAsInt();
ParsedEvent[] events = new ParsedEvent[eventCount];
// For all events in packet
for (int i = 0; i < eventCount; i++) {
byte eventKind = packetCopy.getNextValueAsByte();
switch (eventKind) {
case JDWPConstants.EventKind.VM_START: {
events[i] = new Event_VM_START(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.SINGLE_STEP: {
events[i] = new Event_SINGLE_STEP(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.BREAKPOINT: {
events[i] = new Event_BREAKPOINT(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.METHOD_ENTRY: {
events[i] = new Event_METHOD_ENTRY(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.METHOD_EXIT: {
events[i] = new Event_METHOD_EXIT(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.METHOD_EXIT_WITH_RETURN_VALUE: {
events[i] = new Event_METHOD_EXIT_WITH_RETURN_VALUE(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.MONITOR_CONTENDED_ENTER: {
events[i] = new Event_MONITOR_CONTENDED_ENTER(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.MONITOR_CONTENDED_ENTERED: {
events[i] = new Event_MONITOR_CONTENDED_ENTERED(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.MONITOR_WAIT: {
events[i] = new Event_MONITOR_WAIT(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.MONITOR_WAITED: {
events[i] = new Event_MONITOR_WAITED(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.EXCEPTION: {
events[i] = new Event_EXCEPTION(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.THREAD_START: {
events[i] = new Event_THREAD_START(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.THREAD_DEATH: {
events[i] = new Event_THREAD_DEATH(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.CLASS_PREPARE: {
events[i] = new Event_CLASS_PREPARE(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.CLASS_UNLOAD: {
events[i] = new Event_CLASS_UNLOAD(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.FIELD_ACCESS: {
events[i] = new Event_FIELD_ACCESS(suspendPolicy, packetCopy);
break;
}
case JDWPConstants.EventKind.FIELD_MODIFICATION: {
events[i] = new Event_FIELD_MODIFICATION(suspendPolicy,
packetCopy);
break;
}
case JDWPConstants.EventKind.VM_DEATH: {
events[i] = new Event_VM_DEATH(suspendPolicy, packetCopy);
break;
}
default: {
throw new TestErrorException("Unexpected kind of event: "
+ eventKind);
}
}
}
return events;
}
}