1 /******************************************************************************* 2 * Copyright (c) 2000, 2012 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdi.internal.event; 15 16 import java.io.DataInputStream; 17 import java.io.IOException; 18 import java.lang.reflect.Field; 19 import java.util.HashMap; 20 import java.util.Map; 21 22 import org.eclipse.jdi.internal.MirrorImpl; 23 import org.eclipse.jdi.internal.ThreadReferenceImpl; 24 import org.eclipse.jdi.internal.VirtualMachineImpl; 25 import org.eclipse.jdi.internal.request.RequestID; 26 27 import com.sun.jdi.ThreadReference; 28 import com.sun.jdi.event.Event; 29 import com.sun.jdi.request.EventRequest; 30 31 /** 32 * This class implements the corresponding interfaces declared by the JDI 33 * specification. See the com.sun.jdi package for more information. 34 * 35 */ 36 public abstract class EventImpl extends MirrorImpl implements Event { 37 /** Constants for EventKind. */ 38 public static final byte EVENT_SINGLE_STEP = 1; 39 public static final byte EVENT_BREAKPOINT = 2; 40 public static final byte EVENT_FRAME_POP = 3; 41 public static final byte EVENT_EXCEPTION = 4; 42 public static final byte EVENT_USER_DEFINED = 5; 43 public static final byte EVENT_THREAD_START = 6; 44 public static final byte EVENT_THREAD_END = 7; 45 public static final byte EVENT_CLASS_PREPARE = 8; 46 public static final byte EVENT_CLASS_UNLOAD = 9; 47 public static final byte EVENT_CLASS_LOAD = 10; 48 public static final byte EVENT_FIELD_ACCESS = 20; 49 public static final byte EVENT_FIELD_MODIFICATION = 21; 50 public static final byte EVENT_EXCEPTION_CATCH = 30; 51 public static final byte EVENT_METHOD_ENTRY = 40; 52 public static final byte EVENT_METHOD_EXIT = 41; 53 public static final byte EVENT_METHOD_EXIT_WITH_RETURN_VALUE = 42; 54 public static final byte EVENT_MONITOR_CONTENDED_ENTER = 43; 55 public static final byte EVENT_MONITOR_CONTENDED_ENTERED = 44; 56 public static final byte EVENT_MONITOR_WAIT = 45; 57 public static final byte EVENT_MONITOR_WAITED = 46; 58 public static final byte EVENT_VM_INIT = 90; 59 public static final byte EVENT_VM_DEATH = 99; 60 public static final byte EVENT_VM_DISCONNECTED = 100; // Never sent by 61 // across JDWP. 62 public static final byte EVENT_VM_START = EVENT_VM_INIT; 63 public static final byte EVENT_THREAD_DEATH = EVENT_THREAD_END; 64 65 /** ThreadReference of thread that generated this event. */ 66 protected ThreadReferenceImpl fThreadRef; 67 68 /** Mapping of command codes to strings. */ 69 private static HashMap<Integer, String> fEventKindMap = null; 70 71 /** Request ID of event. */ 72 private RequestID fRequestID; 73 74 /** The EventRequest that requested this event. */ 75 private EventRequest fRequest; 76 77 /** 78 * Creates new EventImpl, only used by subclasses. 79 */ EventImpl(String description, VirtualMachineImpl vmImpl, RequestID requestID)80 protected EventImpl(String description, VirtualMachineImpl vmImpl, 81 RequestID requestID) { 82 super(description, vmImpl); 83 fRequestID = requestID; 84 } 85 86 /** 87 * @return Returns ThreadReference of thread that generated this event. 88 */ thread()89 public ThreadReference thread() { 90 return fThreadRef; 91 } 92 93 /** 94 * @return Returns requestID. 95 */ requestID()96 public RequestID requestID() { 97 return fRequestID; 98 } 99 100 /** 101 * @return Returns string representation. 102 */ 103 @Override toString()104 public String toString() { 105 return super.toString() + ": " + fRequestID; //$NON-NLS-1$ 106 } 107 108 /** 109 * @return Creates, reads and returns new EventImpl. 110 */ read(MirrorImpl target, DataInputStream dataInStream)111 public static EventImpl read(MirrorImpl target, DataInputStream dataInStream) 112 throws IOException { 113 byte eventKind = target.readByte( 114 "event kind", eventKindMap(), dataInStream); //$NON-NLS-1$ 115 RequestID requestID = RequestID.read(target, dataInStream); 116 117 // Create, read and return Event of eventKind. 118 EventImpl result; 119 switch (eventKind) { 120 case 0: 121 return null; 122 case AccessWatchpointEventImpl.EVENT_KIND: 123 result = AccessWatchpointEventImpl.read(target, requestID, 124 dataInStream); 125 break; 126 case BreakpointEventImpl.EVENT_KIND: 127 result = BreakpointEventImpl.read(target, requestID, dataInStream); 128 break; 129 case ClassPrepareEventImpl.EVENT_KIND: 130 result = ClassPrepareEventImpl 131 .read(target, requestID, dataInStream); 132 break; 133 case ClassUnloadEventImpl.EVENT_KIND: 134 result = ClassUnloadEventImpl.read(target, requestID, dataInStream); 135 break; 136 case ExceptionEventImpl.EVENT_KIND: 137 result = ExceptionEventImpl.read(target, requestID, dataInStream); 138 break; 139 case MethodEntryEventImpl.EVENT_KIND: 140 result = MethodEntryEventImpl.read(target, requestID, dataInStream); 141 break; 142 case MethodExitEventImpl.EVENT_KIND: 143 result = MethodExitEventImpl.read(target, requestID, dataInStream); 144 break; 145 case EVENT_METHOD_EXIT_WITH_RETURN_VALUE: 146 result = MethodExitEventImpl.readWithReturnValue(target, requestID, 147 dataInStream); 148 break; 149 case MonitorContendedEnteredEventImpl.EVENT_KIND: 150 result = MonitorContendedEnteredEventImpl.read(target, requestID, 151 dataInStream); 152 break; 153 case MonitorContendedEnterEventImpl.EVENT_KIND: 154 result = MonitorContendedEnterEventImpl.read(target, requestID, 155 dataInStream); 156 break; 157 case MonitorWaitedEventImpl.EVENT_KIND: 158 result = MonitorWaitedEventImpl.read(target, requestID, 159 dataInStream); 160 break; 161 case MonitorWaitEventImpl.EVENT_KIND: 162 result = MonitorWaitEventImpl.read(target, requestID, dataInStream); 163 break; 164 case ModificationWatchpointEventImpl.EVENT_KIND: 165 result = ModificationWatchpointEventImpl.read(target, requestID, 166 dataInStream); 167 break; 168 case StepEventImpl.EVENT_KIND: 169 result = StepEventImpl.read(target, requestID, dataInStream); 170 break; 171 case ThreadDeathEventImpl.EVENT_KIND: 172 result = ThreadDeathEventImpl.read(target, requestID, dataInStream); 173 break; 174 case ThreadStartEventImpl.EVENT_KIND: 175 result = ThreadStartEventImpl.read(target, requestID, dataInStream); 176 break; 177 case VMDeathEventImpl.EVENT_KIND: 178 result = VMDeathEventImpl.read(target, requestID, dataInStream); 179 break; 180 case VMDisconnectEventImpl.EVENT_KIND: 181 result = VMDisconnectEventImpl 182 .read(target, requestID, dataInStream); 183 break; 184 case VMStartEventImpl.EVENT_KIND: 185 result = VMStartEventImpl.read(target, requestID, dataInStream); 186 break; 187 default: 188 throw new IOException( 189 EventMessages.EventImpl_Read_invalid_EventKind___1 190 + eventKind); 191 } 192 193 // Find and store original request. 194 if (!requestID.isNull()) 195 result.fRequest = target.virtualMachineImpl().eventRequestManagerImpl().findRequest(result); 196 197 return result; 198 } 199 200 /** 201 * @return Returns EventRequest that caused this event to be generated by 202 * the Virtual Machine. 203 */ 204 @Override request()205 public EventRequest request() { 206 return fRequest; 207 } 208 209 /** 210 * Retrieves constant mappings. 211 */ getConstantMaps()212 public static void getConstantMaps() { 213 if (fEventKindMap != null) 214 return; 215 216 java.lang.reflect.Field[] fields = EventImpl.class.getDeclaredFields(); 217 fEventKindMap = new HashMap<>(); 218 for (Field field : fields) { 219 if ((field.getModifiers() & java.lang.reflect.Modifier.PUBLIC) == 0 220 || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 221 || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0) 222 continue; 223 224 try { 225 String name = field.getName(); 226 Integer intValue = Integer.valueOf(field.getInt(null)); 227 228 if (name.startsWith("EVENT_")) { //$NON-NLS-1$ 229 name = name.substring(6); 230 fEventKindMap.put(intValue, name); 231 } 232 } catch (IllegalAccessException e) { 233 // Will not occur for own class. 234 } catch (IllegalArgumentException e) { 235 // Should not occur. 236 // We should take care that all public static final constants 237 // in this class are numbers that are convertible to int. 238 } 239 } 240 } 241 242 /** 243 * @return Returns a map with string representations of tags. 244 */ eventKindMap()245 public static Map<Integer, String> eventKindMap() { 246 getConstantMaps(); 247 return fEventKindMap; 248 } 249 } 250