View Javadoc
1 /* 2 * $Id: EventRecorder.java,v 1.4 2003/07/22 00:07:22 trondandersen Exp $ 3 * Copyright 2003 OErjan Nygaard Austvold. All rights reserved. 4 */ 5 package org.jdiseq; 6 7 import com.sun.jdi.*; 8 import com.sun.jdi.event.*; 9 import com.sun.jdi.request.EventRequestManager; 10 import com.sun.jdi.request.MethodEntryRequest; 11 import com.sun.jdi.request.MethodExitRequest; 12 13 import java.util.ArrayList; 14 import java.util.Collections; 15 import java.util.List; 16 17 /*** 18 * This class implements a recorder for selected JDI events. 19 * Listeneres interested in receiving events implements the {@link JdiEventListener} and 20 * registers with an instance of this class. 21 * <code>JdiEventListener</code> 22 * <p>Changelog: 23 * <pre> 24 * $Log: EventRecorder.java,v $ 25 * Revision 1.4 2003/07/22 00:07:22 trondandersen 26 * Removed Jython test cases 27 * . 28 * 29 * Revision 1.3 2003/05/05 17:39:04 trondandersen 30 * Inserted initial configuration class and SettingUtil retriever. 31 * Added jython test for these classes. Inserted a logging class. 32 * . 33 * 34 * Revision 1.2 2003/04/02 19:48:47 austvold 35 * Minor updates. Mostly adaptation to new event and eventlistener name. 36 * General brush-up on javadoc comments. 37 * Removal of auto-added revision and date-of-commit members. 38 * 39 * Revision 1.1.1.1 2003/03/28 08:18:23 austvold 40 * Initial import. 41 * 42 * </pre> 43 * 44 * @author Ørjan Nygaard Austvold <austvold@acm.org> 45 * @version $Id: EventRecorder.java,v 1.4 2003/07/22 00:07:22 trondandersen Exp $ 46 */ 47 class EventRecorder implements Runnable { 48 private JdiRemoteVMConnector vmConnector; 49 private Filter filter; 50 // private Thread recorder; 51 private List eventListeners; 52 53 54 /*** 55 * Sole constructor. 56 * @param vmConnector the vmConnector to record events from. 57 * @param filter a filter for events. 58 */ 59 EventRecorder(JdiRemoteVMConnector vmConnector, Filter filter) { 60 this.vmConnector = vmConnector; 61 this.filter = filter; 62 eventListeners = Collections.synchronizedList(new ArrayList()); 63 } 64 65 66 /*** 67 * Starts a recording session. 68 * @throws JdiConnectionException if anything bad happens. 69 */ 70 void startRecording() throws JdiConnectionException { 71 if (vmConnector.isConnected() == false) { 72 throw new JdiConnectionException("Not connected."); 73 } 74 // recorder = new Thread(this, "EventRecorder"); 75 // recorder.start(); 76 run(); 77 } 78 79 80 /*** 81 * Stops the recording session, if any such session exists. 82 */ 83 public void stopRecording() { 84 // recorder.interrupt(); 85 // recorder = null; 86 } 87 88 89 /*** 90 * Adds a listener for JDI events. 91 * After registration the listner will begin to receive JDI events. 92 * @param l the listener to add 93 */ 94 public void addEventListener(JdiEventListener l) { 95 eventListeners.add(l); 96 } 97 98 99 /*** 100 * Removes a listener. 101 * After removal the listner will not receive anymore JDI events. 102 * @param l the listner to remove 103 */ 104 public void removeEventListener(JdiEventListener l) { 105 eventListeners.remove(l); 106 } 107 108 109 110 /*** 111 * Notifies JDI event listeners about a new JDI event. 112 * @param e the event that occured 113 */ 114 private void notifyJdiEventListeners(JdiEvent e) { 115 // TODO: shouldn't we make a copy of the list before iteration 116 for (int i = 0; i < eventListeners.size(); i++) { 117 JdiEventListener l = (JdiEventListener) eventListeners.get(i); 118 if (e.isMethodEntry()) { 119 l.methodEntered(e); 120 } else { 121 l.methodExited(e); 122 } 123 } 124 } 125 126 127 /*** 128 * Registers the filter an waits for new JDI events from the debugee. 129 * // TODO: It's a design flaw that this method is public... 130 */ 131 public void run() { 132 EventRequestManager erm = vmConnector.getVm().eventRequestManager(); 133 134 MethodEntryRequest mer = erm.createMethodEntryRequest(); 135 MethodExitRequest mlr = erm.createMethodExitRequest(); 136 137 String[] classIncludes = filter.getClassIncludes(); 138 for (int i = 0; i < filter.getClassIncludes().length; i++) { 139 mer.addClassFilter(classIncludes[i]); 140 mlr.addClassFilter(classIncludes[i]); 141 } 142 String[] classExcludes = filter.getClassExcludes(); 143 for (int i = 0; i < classExcludes.length; i++) { 144 mer.addClassExclusionFilter(classExcludes[i]); 145 mlr.addClassExclusionFilter(classExcludes[i]); 146 } 147 148 mer.enable(); 149 mlr.enable(); 150 151 EventQueue eq = vmConnector.getVm().eventQueue(); 152 vmConnector.getVm().resume(); 153 while (true) { 154 try { 155 EventSet eventSet = eq.remove(); 156 for (EventIterator ei = eventSet.eventIterator(); ei.hasNext();) { 157 Event e = ei.nextEvent(); 158 if (e instanceof LocatableEvent) { 159 Method method = null; 160 boolean methodEntry = false; 161 162 if (e instanceof MethodEntryEvent) { 163 method = ((MethodEntryEvent) e).method(); 164 methodEntry = true; 165 } else if (e instanceof MethodExitEvent) { 166 method = ((MethodExitEvent) e).method(); 167 methodEntry = false; 168 } else { 169 continue; // does other LocatableEvents exists? 170 } 171 172 ThreadReference threadRef = ((LocatableEvent) e).thread(); 173 174 ObjectReference objectRef = null; 175 try { 176 StackFrame sf = threadRef.frame(threadRef.frameCount() - 1); 177 objectRef = sf.thisObject(); 178 } catch (IncompatibleThreadStateException e1) { 179 e1.printStackTrace(); // how to handle? 180 objectRef = null; 181 } 182 183 ReferenceType declaringType = 184 ((LocatableEvent) e).location().declaringType(); 185 186 JdiEvent me = new JdiEvent(methodEntry, 187 method, threadRef, objectRef, declaringType); 188 notifyJdiEventListeners(me); 189 } 190 } 191 // vm is always paused after removal of events from the event queue 192 eventSet.resume(); 193 } catch (InterruptedException e) { 194 break; // we're told to stop recording 195 } 196 } // end whle 197 } 198 }

This page was automatically generated by Maven