001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.debug.core.breakpoints;
011:
012: import java.util.Map;
013: import org.eclipse.core.resources.IMarker;
014: import org.eclipse.core.resources.IResource;
015: import org.eclipse.core.resources.IWorkspaceRunnable;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IProgressMonitor;
018: import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint;
019: import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
020: import com.sun.jdi.ClassType;
021: import com.sun.jdi.Location;
022: import com.sun.jdi.Method;
023: import com.sun.jdi.ReferenceType;
024: import com.sun.jdi.request.BreakpointRequest;
025: import com.sun.jdi.request.EventRequest;
026:
027: /**
028: * A line breakpoint at the first executable location in a specific method.
029: */
030:
031: public class JavaMethodEntryBreakpoint extends JavaLineBreakpoint
032: implements IJavaMethodEntryBreakpoint {
033:
034: private static final String JAVA_METHOD_ENTRY_BREAKPOINT = "org.eclipse.jdt.debug.javaMethodEntryBreakpointMarker"; //$NON-NLS-1$
035:
036: /**
037: * Breakpoint attribute storing the name of the method
038: * in which a breakpoint is contained.
039: * (value <code>"org.eclipse.jdt.debug.core.methodName"</code>). This attribute is a <code>String</code>.
040: */
041: private static final String METHOD_NAME = "org.eclipse.jdt.debug.core.methodName"; //$NON-NLS-1$
042:
043: /**
044: * Breakpoint attribute storing the signature of the method
045: * in which a breakpoint is contained.
046: * (value <code>"org.eclipse.jdt.debug.core.methodSignature"</code>). This attribute is a <code>String</code>.
047: */
048: private static final String METHOD_SIGNATURE = "org.eclipse.jdt.debug.core.methodSignature"; //$NON-NLS-1$
049:
050: /**
051: * Cache of method name attribute
052: */
053: private String fMethodName = null;
054:
055: /**
056: * Cache of method signature attribute
057: */
058: private String fMethodSignature = null;
059:
060: /**
061: * Constructs a new unconfigured method breakpoint
062: */
063: public JavaMethodEntryBreakpoint() {
064: }
065:
066: public JavaMethodEntryBreakpoint(final IResource resource,
067: final String typeName, final String methodName,
068: final String methodSignature, final int lineNumber,
069: final int charStart, final int charEnd, final int hitCount,
070: final boolean register, final Map attributes)
071: throws CoreException {
072: IWorkspaceRunnable wr = new IWorkspaceRunnable() {
073: public void run(IProgressMonitor monitor)
074: throws CoreException {
075: // create the marker
076: setMarker(resource
077: .createMarker(JAVA_METHOD_ENTRY_BREAKPOINT));
078:
079: // add attributes
080: addLineBreakpointAttributes(attributes,
081: getModelIdentifier(), true, lineNumber,
082: charStart, charEnd);
083: addMethodNameAndSignature(attributes, methodName,
084: methodSignature);
085: addTypeNameAndHitCount(attributes, typeName, hitCount);
086: //set attributes
087: attributes.put(SUSPEND_POLICY, new Integer(
088: getDefaultSuspendPolicy()));
089: ensureMarker().setAttributes(attributes);
090:
091: register(register);
092: }
093:
094: };
095: run(getMarkerRule(resource), wr);
096: }
097:
098: /**
099: * Adds the method name and signature attributes to the
100: * given attribute map, and intializes the local cache
101: * of method name and signature.
102: */
103: private void addMethodNameAndSignature(Map attributes,
104: String methodName, String methodSignature) {
105: if (methodName != null) {
106: attributes.put(METHOD_NAME, methodName);
107: }
108: if (methodSignature != null) {
109: attributes.put(METHOD_SIGNATURE, methodSignature);
110: }
111: fMethodName = methodName;
112: fMethodSignature = methodSignature;
113: }
114:
115: /**
116: * @see IJavaMethodEntryBreakpoint#getMethodName()
117: */
118: public String getMethodName() {
119: return fMethodName;
120: }
121:
122: /**
123: * @see IJavaMethodEntryBreakpoint#getMethodSignature()
124: */
125: public String getMethodSignature() {
126: return fMethodSignature;
127: }
128:
129: /**
130: * Initialize cache of attributes
131: *
132: * @see IBreakpoint#setMarker(IMarker)
133: */
134: public void setMarker(IMarker marker) throws CoreException {
135: super .setMarker(marker);
136: fMethodName = marker.getAttribute(METHOD_NAME, null);
137: fMethodSignature = marker.getAttribute(METHOD_SIGNATURE, null);
138: }
139:
140: /**
141: * @see IJavaLineBreakpoint#supportsCondition()
142: */
143: public boolean supportsCondition() {
144: return false;
145: }
146:
147: /**
148: * @see JavaBreakpoint#newRequests(JDIDebugTarget, ReferenceType)
149: */
150: protected EventRequest[] newRequests(JDIDebugTarget target,
151: ReferenceType type) throws CoreException {
152: try {
153: if (type instanceof ClassType) {
154: ClassType clazz = (ClassType) type;
155: Method method = clazz.concreteMethodByName(
156: getMethodName(), getMethodSignature());
157: if (method == null) {
158: return null;
159: }
160: Location location = method.location();
161: if (location == null || location.codeIndex() == -1) {
162: return null;
163: }
164: BreakpointRequest req = type.virtualMachine()
165: .eventRequestManager().createBreakpointRequest(
166: location);
167: configureRequest(req, target);
168: return new EventRequest[] { req };
169: }
170: return null;
171: } catch (RuntimeException e) {
172: target.internalError(e);
173: return null;
174: }
175: }
176: }
|