package org.rubypeople.rdt.debug.core; import java.util.HashMap; import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IBreakpointManager; import org.eclipse.debug.core.model.IBreakpoint; import org.rubypeople.rdt.debug.core.model.IRubyExceptionBreakpoint; import org.rubypeople.rdt.internal.debug.core.breakpoints.RubyExceptionBreakpoint; import org.rubypeople.rdt.internal.debug.core.breakpoints.RubyLineBreakpoint; import org.rubypeople.rdt.internal.debug.core.breakpoints.RubyMethodBreakpoint; public class RdtDebugModel { /** * Creates and returns an exception breakpoint for an exception with the given name. The marker associated with the * breakpoint will be created on the specified resource. Caught and uncaught specify where the exception should * cause thread suspensions - that is, in caught and/or uncaught locations. Checked indicates if the given exception * is a checked exception. * * @param resource * the resource on which to create the associated breakpoint marker * @param exceptionName * the fully qualified name of the exception for which to create the breakpoint * @param caught * whether to suspend in caught locations * @param uncaught * whether to suspend in uncaught locations * @param checked * whether the exception is a checked exception (i.e. compiler detected) * @param register * whether to add this breakpoint to the breakpoint manager * @param attributes * a map of client defined attributes that should be assigned to the underlying breakpoint marker on * creation or <code>null</code> if none. * @return an exception breakpoint * @exception CoreException * If this method fails. Reasons include: * <ul> * <li>Failure creating underlying marker. The exception's status contains the underlying exception * responsible for the failure.</li> * </ul> * @since 2.0 */ public static IRubyExceptionBreakpoint createExceptionBreakpoint(IResource resource, String exceptionName, boolean register, Map attributes) throws CoreException { if (attributes == null) { attributes = new HashMap(10); } return new RubyExceptionBreakpoint(resource, exceptionName, register, attributes); } /** * Creates and returns a line breakpoint in the type with the given name, at the given line number. The marker * associated with the breakpoint will be created on the specified resource. If a character range within the line is * known, it may be specified by charStart/charEnd. If hitCount is > 0, the breakpoint will suspend execution when * it is "hit" the specified number of times. * * @param resource * the resource on which to create the associated breakpoint marker * @param typeName * the fully qualified name of the type the breakpoint is to be installed in. If the breakpoint is to be * installed in an inner type, it is sufficient to provide the name of the top level enclosing type. If * an inner class name is specified, it should be formatted as the associated class file name (i.e. with * <code>$</code>). For example, <code>example.SomeClass$InnerType</code>, could be specified, but * <code>example.SomeClass</code> is sufficient. * @param lineNumber * the lineNumber on which the breakpoint is set - line numbers are 1 based, associated with the source * file in which the breakpoint is set * @param register * whether to add this breakpoint to the breakpoint manager * @param attributes * a map of client defined attributes that should be assigned to the underlying breakpoint marker on * creation, or <code>null</code> if none. * @return a line breakpoint * @exception CoreException * If this method fails. Reasons include: * <ul> * <li>Failure creating underlying marker. The exception's status contains the underlying exception * responsible for the failure.</li> * </ul> * @since 2.0 */ public static IRubyLineBreakpoint createLineBreakpoint(IResource resource, String fileName, String typeName, int lineNumber, boolean register, Map attributes) throws CoreException { if (attributes == null) { attributes = new HashMap(10); } return new RubyLineBreakpoint(resource, fileName, typeName, lineNumber, -1, -1, 0, register, attributes); } /** * Returns a Ruby line breakpoint that is already registered with the breakpoint manager for a type with the given * name at the given line number in the given resource. * * @param resource * the resource * @param typeName * fully qualified type name * @param lineNumber * line number * @return a Ruby line breakpoint that is already registered with the breakpoint manager for a type with the given * name at the given line number or <code>null</code> if no such breakpoint is registered * @exception CoreException * if unable to retrieve the associated marker attributes (line number). * @since 3.1 */ public static IRubyLineBreakpoint lineBreakpointExists(IResource resource, String typeName, int lineNumber) throws CoreException { if (resource == null) return null; String modelId = getModelIdentifier(); String markerType = RubyLineBreakpoint.getMarkerType(); IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); IBreakpoint[] breakpoints = manager.getBreakpoints(modelId); for (int i = 0; i < breakpoints.length; i++) { if (!(breakpoints[i] instanceof IRubyLineBreakpoint)) { continue; } IRubyLineBreakpoint breakpoint = (IRubyLineBreakpoint) breakpoints[i]; if (breakpoint == null) continue; IMarker marker = breakpoint.getMarker(); if (marker != null && marker.exists() && marker.getType().equals(markerType)) { String breakpointTypeName = breakpoint.getTypeName(); if (equals(breakpointTypeName, typeName) && breakpoint.getLineNumber() == lineNumber && resource.equals(marker.getResource())) { return breakpoint; } } } return null; } private static boolean equals(String breakpointTypeName, String typeName) { if (breakpointTypeName == null) return typeName == null; return breakpointTypeName.equals(typeName); } /** * Returns the identifier for the JDI debug model plug-in * * @return plug-in identifier */ public static String getModelIdentifier() { return RdtDebugCorePlugin.MODEL_IDENTIFIER; } /** * Creates and returns a method breakpoint with the specified criteria. * * @param resource * the resource on which to create the associated breakpoint marker * @param typePattern * the pattern specifying the fully qualified name of type(s) this breakpoint suspends execution in. * Patterns are limited to exact matches and patterns that begin or end with '*'. * @param methodName * the name of the method(s) this breakpoint suspends execution in, or <code>null</code> if this * breakpoint does not suspend execution based on method name * @param entry * whether this breakpoint causes execution to suspend on entry of methods * @param exit * whether this breakpoint causes execution to suspend on exit of methods * @param lineNumber * the lineNumber on which the breakpoint is set - line numbers are 1 based, associated with the source * file in which the breakpoint is set * @param charStart * the first character index associated with the breakpoint, or -1 if unspecified, in the source file in * which the breakpoint is set * @param charEnd * the last character index associated with the breakpoint, or -1 if unspecified, in the source file in * which the breakpoint is set * @param hitCount * the number of times the breakpoint will be hit before suspending execution - 0 if it should always * suspend * @param register * whether to add this breakpoint to the breakpoint manager * @param attributes * a map of client defined attributes that should be assigned to the underlying breakpoint marker on * creation, or <code>null</code> if none. * @return a method breakpoint * @exception CoreException * If this method fails. Reasons include: * <ul> * <li>Failure creating underlying marker. The exception's status contains the underlying exception * responsible for the failure.</li> * </ul> * @since 2.0 */ public static IRubyMethodBreakpoint createMethodBreakpoint(IResource resource, String typePattern, String methodName, boolean entry, boolean exit, int lineNumber, int charStart, int charEnd, int hitCount, boolean register, Map attributes) throws CoreException { if (attributes == null) { attributes = new HashMap(10); } return new RubyMethodBreakpoint(resource, typePattern, methodName, entry, exit, lineNumber, charStart, charEnd, hitCount, register, attributes); } }