001: /*
002: * MethodBreakpoint.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: MethodBreakpoint.java,v 1.4 2003/05/25 01:25:14 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.jdb;
023:
024: import com.sun.jdi.InvalidTypeException;
025: import com.sun.jdi.Location;
026: import com.sun.jdi.Method;
027: import com.sun.jdi.ReferenceType;
028: import com.sun.jdi.request.EventRequest;
029: import com.sun.jdi.request.EventRequestManager;
030: import java.util.Iterator;
031: import java.util.List;
032: import org.armedbear.j.Buffer;
033: import org.armedbear.j.Editor;
034: import org.armedbear.j.FastStringBuffer;
035: import org.armedbear.j.JavaSource;
036: import org.armedbear.j.Line;
037: import org.armedbear.j.LocalTag;
038: import org.armedbear.j.Log;
039: import org.armedbear.j.Utilities;
040:
041: public final class MethodBreakpoint extends ResolvableBreakpoint {
042: private final String methodName;
043:
044: public MethodBreakpoint(Jdb jdb, String className, String methodName) {
045: super (jdb);
046: this .className = className;
047: this .methodName = methodName;
048: }
049:
050: public String getMethodName() {
051: return methodName;
052: }
053:
054: public EventRequest resolveEventRequest(ReferenceType refType)
055: throws Exception {
056: Method method = findMatchingMethod(refType);
057: if (method == null)
058: throw new InvalidTypeException();
059: Location location = method.location();
060: if (location == null)
061: throw new InvalidTypeException(); // Abstract or native method.
062: EventRequestManager erm = refType.virtualMachine()
063: .eventRequestManager();
064: EventRequest er = erm.createBreakpointRequest(location);
065: er.setSuspendPolicy(EventRequest.SUSPEND_ALL);
066: er.enable();
067: setBreakpointInSource(refType, method);
068: return er;
069: }
070:
071: // BUG! Overloads are not handled correctly.
072: private Method findMatchingMethod(ReferenceType refType) {
073: Iterator iter = refType.methods().iterator();
074: while (iter.hasNext()) {
075: Method method = (Method) iter.next();
076: if (method.name().equals(methodName))
077: return method;
078: }
079: return null;
080: }
081:
082: private void setBreakpointInSource(ReferenceType refType,
083: Method method) {
084: file = JavaSource.findSource(refType.name(), jdb
085: .getSourcePath());
086: if (file == null) {
087: Log.debug("setBreakpointInSource findSource returned null");
088: return;
089: }
090: Buffer buf = Editor.getBuffer(file);
091: if (buf == null)
092: return;
093: if (!buf.initialized())
094: buf.initialize();
095: if (!buf.isLoaded())
096: buf.load();
097: List tags = buf.getTags(true);
098: if (tags == null)
099: return;
100: String lookFor = refType.name();
101: // Remove package prefix.
102: int index = lookFor.lastIndexOf('.');
103: if (index >= 0)
104: lookFor = lookFor.substring(index + 1);
105: lookFor += '.';
106: lookFor += method.name();
107: Log.debug("lookFor = |" + lookFor + "|");
108: Line begin = null;
109: Line end = null;
110: for (int i = 0; i < tags.size(); i++) {
111: LocalTag tag = (LocalTag) tags.get(i);
112: if (tag.getName() != null) {
113: if (tag.getName().equals(lookFor)) {
114: begin = tag.getLine();
115: if (++i < tags.size()) {
116: tag = (LocalTag) tags.get(i);
117: end = tag.getLine();
118: }
119: break;
120: }
121: }
122: }
123: if (begin == null)
124: return;
125: // Look for first line of actual code.
126: for (Line ln = begin.next(); ln != end && ln != null; ln = ln
127: .next()) {
128: String text = ln.getText().trim();
129: if (!text.startsWith("//")) {
130: if (text.indexOf('=') >= 0 || text.indexOf('(') >= 0) {
131: // Line looks like code.
132: ln.setAnnotation(new BreakpointAnnotation(this ));
133: line = ln;
134: break;
135: }
136: }
137: }
138: }
139:
140: public void resolved() {
141: if (file != null) {
142: Buffer buffer = Editor.getBufferList().findBuffer(file);
143: if (buffer != null)
144: buffer.repaint();
145: }
146: if (line != null)
147: line.setAnnotation(new BreakpointAnnotation(this ));
148: jdb.log("Breakpoint resolved: " + getLocationString());
149: }
150:
151: public String getLocationString() {
152: FastStringBuffer sb = new FastStringBuffer();
153: if (className != null) {
154: sb.append(className);
155: sb.append('.');
156: }
157: sb.append(methodName);
158: if (!isResolved())
159: sb.append(' ');
160: return sb.toString();
161: }
162:
163: public String toString() {
164: FastStringBuffer sb = new FastStringBuffer();
165: if (className != null) {
166: sb.append(className);
167: sb.append('.');
168: }
169: sb.append(methodName);
170: if (!isResolved()) {
171: sb.append(' ');
172: sb.append("(deferred)");
173: }
174: return sb.toString();
175: }
176:
177: public String toXml() {
178: int indent = 4;
179: final String separator = System.getProperty("line.separator");
180: FastStringBuffer sb = new FastStringBuffer(Utilities
181: .spaces(indent));
182: sb.append("<breakpoint");
183: sb.append(separator);
184: if (className != null) {
185: sb.append(Utilities.spaces(indent + 2));
186: sb.append("className=\"");
187: sb.append(className);
188: sb.append('"');
189: sb.append(separator);
190: }
191: if (methodName != null) {
192: sb.append(Utilities.spaces(indent + 2));
193: sb.append("methodName=\"");
194: sb.append(methodName);
195: sb.append('"');
196: sb.append(separator);
197: }
198: sb.append(Utilities.spaces(indent));
199: sb.append("/>");
200: sb.append(separator);
201: return sb.toString();
202: }
203: }
|