| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.core.breakpoints; |
| |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; |
| import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint; |
| import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; |
| |
| import com.sun.jdi.ClassType; |
| import com.sun.jdi.Location; |
| import com.sun.jdi.Method; |
| import com.sun.jdi.ReferenceType; |
| import com.sun.jdi.request.BreakpointRequest; |
| import com.sun.jdi.request.EventRequest; |
| |
| /** |
| * A line breakpoint at the first executable location in a specific method. |
| */ |
| |
| public class JavaMethodEntryBreakpoint extends JavaLineBreakpoint implements |
| IJavaMethodEntryBreakpoint { |
| |
| protected static final String JAVA_METHOD_ENTRY_BREAKPOINT = "org.eclipse.jdt.debug.javaMethodEntryBreakpointMarker"; //$NON-NLS-1$ |
| |
| /** |
| * Breakpoint attribute storing the name of the method in which a breakpoint |
| * is contained. (value <code>"org.eclipse.jdt.debug.core.methodName"</code> |
| * ). This attribute is a <code>String</code>. |
| */ |
| private static final String METHOD_NAME = "org.eclipse.jdt.debug.core.methodName"; //$NON-NLS-1$ |
| |
| /** |
| * Breakpoint attribute storing the signature of the method in which a |
| * breakpoint is contained. (value |
| * <code>"org.eclipse.jdt.debug.core.methodSignature"</code>). This |
| * attribute is a <code>String</code>. |
| */ |
| private static final String METHOD_SIGNATURE = "org.eclipse.jdt.debug.core.methodSignature"; //$NON-NLS-1$ |
| |
| /** |
| * Cache of method name attribute |
| */ |
| private String fMethodName = null; |
| |
| /** |
| * Cache of method signature attribute |
| */ |
| private String fMethodSignature = null; |
| |
| /** |
| * Constructs a new method breakpoint |
| */ |
| public JavaMethodEntryBreakpoint() { |
| } |
| |
| public JavaMethodEntryBreakpoint(final IResource resource, |
| final String typeName, final String methodName, |
| final String methodSignature, final int lineNumber, |
| final int charStart, final int charEnd, final int hitCount, |
| final boolean register, final Map<String, Object> attributes) throws CoreException { |
| IWorkspaceRunnable wr = new IWorkspaceRunnable() { |
| @Override |
| public void run(IProgressMonitor monitor) throws CoreException { |
| // create the marker |
| setMarker(resource.createMarker(JAVA_METHOD_ENTRY_BREAKPOINT)); |
| |
| // add attributes |
| addLineBreakpointAttributes(attributes, getModelIdentifier(), |
| true, lineNumber, charStart, charEnd); |
| addMethodNameAndSignature(attributes, methodName, |
| methodSignature); |
| addTypeNameAndHitCount(attributes, typeName, hitCount); |
| // set attributes |
| attributes.put(SUSPEND_POLICY, new Integer( |
| getDefaultSuspendPolicy())); |
| ensureMarker().setAttributes(attributes); |
| |
| register(register); |
| } |
| |
| }; |
| run(getMarkerRule(resource), wr); |
| } |
| |
| /** |
| * Adds the method name and signature attributes to the given attribute map, |
| * and initializes the local cache of method name and signature. |
| */ |
| private void addMethodNameAndSignature(Map<String, Object> attributes, String methodName, |
| String methodSignature) { |
| if (methodName != null) { |
| attributes.put(METHOD_NAME, methodName); |
| } |
| if (methodSignature != null) { |
| attributes.put(METHOD_SIGNATURE, methodSignature); |
| } |
| fMethodName = methodName; |
| fMethodSignature = methodSignature; |
| } |
| |
| /** |
| * @see IJavaMethodEntryBreakpoint#getMethodName() |
| */ |
| @Override |
| public String getMethodName() { |
| return fMethodName; |
| } |
| |
| /** |
| * @see IJavaMethodEntryBreakpoint#getMethodSignature() |
| */ |
| @Override |
| public String getMethodSignature() { |
| return fMethodSignature; |
| } |
| |
| /** |
| * Initialize cache of attributes |
| * |
| * @see IBreakpoint#setMarker(IMarker) |
| */ |
| @Override |
| public void setMarker(IMarker marker) throws CoreException { |
| super.setMarker(marker); |
| fMethodName = marker.getAttribute(METHOD_NAME, null); |
| fMethodSignature = marker.getAttribute(METHOD_SIGNATURE, null); |
| } |
| |
| /** |
| * @see IJavaLineBreakpoint#supportsCondition() |
| */ |
| @Override |
| public boolean supportsCondition() { |
| return false; |
| } |
| |
| /** |
| * @see JavaBreakpoint#newRequests(JDIDebugTarget, ReferenceType) |
| */ |
| @Override |
| protected EventRequest[] newRequests(JDIDebugTarget target, |
| ReferenceType type) throws CoreException { |
| try { |
| if (type instanceof ClassType) { |
| ClassType clazz = (ClassType) type; |
| Method method = clazz.concreteMethodByName(getMethodName(), |
| getMethodSignature()); |
| if (method == null) { |
| return null; |
| } |
| Location location = method.location(); |
| if (location == null || location.codeIndex() == -1) { |
| return null; |
| } |
| BreakpointRequest req = type.virtualMachine() |
| .eventRequestManager() |
| .createBreakpointRequest(location); |
| configureRequest(req, target); |
| return new EventRequest[] { req }; |
| } |
| return null; |
| } catch (RuntimeException e) { |
| target.internalError(e); |
| return null; |
| } |
| } |
| } |