| /* |
| * 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; |
| } |
| |
| } |