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:
014: import org.eclipse.core.resources.IMarker;
015: import org.eclipse.core.resources.IResource;
016: import org.eclipse.core.resources.IWorkspaceRunnable;
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.core.runtime.IStatus;
020: import org.eclipse.core.runtime.Status;
021: import org.eclipse.debug.core.DebugException;
022: import org.eclipse.debug.core.model.IBreakpoint;
023: import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
024: import org.eclipse.jdt.debug.core.IJavaObject;
025: import org.eclipse.jdt.debug.core.IJavaThread;
026: import org.eclipse.jdt.debug.core.JDIDebugModel;
027: import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
028: import org.eclipse.jdt.internal.debug.core.model.JDIThread;
029:
030: import com.sun.jdi.ObjectReference;
031: import com.sun.jdi.ReferenceType;
032: import com.sun.jdi.ThreadReference;
033: import com.sun.jdi.event.ClassPrepareEvent;
034: import com.sun.jdi.request.ClassPrepareRequest;
035: import com.sun.jdi.request.EventRequest;
036:
037: /**
038: * Class prepare breakpoint.
039: *
040: * @since 3.0
041: */
042: public class JavaClassPrepareBreakpoint extends JavaBreakpoint
043: implements IJavaClassPrepareBreakpoint {
044:
045: private static final String JAVA_CLASS_PREPARE_BREAKPOINT = "org.eclipse.jdt.debug.javaClassPrepareBreakpointMarker"; //$NON-NLS-1$
046:
047: /**
048: * Class prepare breakpoint attribute storing the type of member this
049: * breakpoint is associated with
050: * (value <code>"org.eclipse.jdt.debug.core.memberType"</code>), encoded
051: * as an integer.
052: */
053: protected static final String MEMBER_TYPE = "org.eclipse.jdt.debug.core.memberType"; //$NON-NLS-1$
054:
055: /**
056: * Creates and returns a Java class prepare breakpoint for the
057: * given type.
058: * @param resource the resource on which to create the associated
059: * breakpoint marker
060: * @param typeName the fully qualified name of the type for
061: * which to create the breakpoint
062: * @param memberType one of <code>TYPE_CLASS</code> or <code>TYPE_INTERFACE</code>
063: * @param charStart the first character index associated with the breakpoint,
064: * or -1 if unspecified, in the source file in which the breakpoint is set
065: * @param charEnd the last character index associated with the breakpoint,
066: * or -1 if unspecified, in the source file in which the breakpoint is set
067: * @param add whether to add this breakpoint to the breakpoint manager
068: * @return a Java class prepare breakpoint
069: * @exception DebugException if unable to create the associated marker due
070: * to a lower level exception.
071: */
072: public JavaClassPrepareBreakpoint(final IResource resource,
073: final String typeName, final int memberType,
074: final int charStart, final int charEnd, final boolean add,
075: final Map attributes) throws DebugException {
076: IWorkspaceRunnable wr = new IWorkspaceRunnable() {
077:
078: public void run(IProgressMonitor monitor)
079: throws CoreException {
080: // create the marker
081: setMarker(resource
082: .createMarker(JAVA_CLASS_PREPARE_BREAKPOINT));
083:
084: // add attributes
085: attributes.put(IBreakpoint.ID, getModelIdentifier());
086: attributes.put(IMarker.CHAR_START, new Integer(
087: charStart));
088: attributes.put(IMarker.CHAR_END, new Integer(charEnd));
089: attributes.put(TYPE_NAME, typeName);
090: attributes.put(MEMBER_TYPE, new Integer(memberType));
091: attributes.put(ENABLED, Boolean.TRUE);
092: attributes.put(SUSPEND_POLICY, new Integer(
093: getDefaultSuspendPolicy()));
094:
095: ensureMarker().setAttributes(attributes);
096:
097: register(add);
098: }
099:
100: };
101: run(getMarkerRule(resource), wr);
102: }
103:
104: public JavaClassPrepareBreakpoint() {
105: }
106:
107: /**
108: * Creates event requests for the given target
109: */
110: protected void createRequests(JDIDebugTarget target)
111: throws CoreException {
112: if (target.isTerminated() || shouldSkipBreakpoint()) {
113: return;
114: }
115: String referenceTypeName = getTypeName();
116: if (referenceTypeName == null) {
117: return;
118: }
119:
120: ClassPrepareRequest request = target.createClassPrepareRequest(
121: referenceTypeName, null, false);
122: configureRequestHitCount(request);
123: updateEnabledState(request, target);
124: registerRequest(request, target);
125: // TODO: do we show anything for types already loaded?
126: incrementInstallCount();
127: }
128:
129: /**
130: * Remove the given request from the given target. If the request
131: * is the breakpoint request associated with this breakpoint,
132: * decrement the install count.
133: */
134: protected void deregisterRequest(EventRequest request,
135: JDIDebugTarget target) throws CoreException {
136: target.removeJDIEventListener(this , request);
137: // A request may be getting deregistered because the breakpoint has
138: // been deleted. It may be that this occurred because of a marker deletion.
139: // Don't try updating the marker (decrementing the install count) if
140: // it no longer exists.
141: if (getMarker().exists()) {
142: decrementInstallCount();
143: }
144: }
145:
146: /* (non-Javadoc)
147: *
148: * Not supported for class prepare breakpoints.
149: *
150: * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addInstanceFilter(com.sun.jdi.request.EventRequest, com.sun.jdi.ObjectReference)
151: */
152: protected void addInstanceFilter(EventRequest request,
153: ObjectReference object) {
154: }
155:
156: /* (non-Javadoc)
157: *
158: * This method not used for class prepare breakpoints.
159: *
160: * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#newRequest(org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget, com.sun.jdi.ReferenceType)
161: */
162: protected EventRequest[] newRequests(JDIDebugTarget target,
163: ReferenceType type) throws CoreException {
164: return null;
165: }
166:
167: /* (non-Javadoc)
168: *
169: * Not supported for class prepare breakpoints.
170: *
171: * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#setRequestThreadFilter(com.sun.jdi.request.EventRequest, com.sun.jdi.ThreadReference)
172: */
173: protected void setRequestThreadFilter(EventRequest request,
174: ThreadReference thread) {
175: }
176:
177: /* (non-Javadoc)
178: * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#handleClassPrepareEvent(com.sun.jdi.event.ClassPrepareEvent, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
179: */
180: public boolean handleClassPrepareEvent(ClassPrepareEvent event,
181: JDIDebugTarget target) {
182: try {
183: if (isEnabled()
184: && event.referenceType().name().equals(
185: getTypeName())) {
186: ThreadReference threadRef = event.thread();
187: JDIThread thread = target.findThread(threadRef);
188: if (thread == null || thread.isIgnoringBreakpoints()) {
189: return true;
190: }
191: return handleBreakpointEvent(event, target, thread);
192: }
193: } catch (CoreException e) {
194: }
195: return true;
196: }
197:
198: /* (non-Javadoc)
199: * @see org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint#getMemberType()
200: */
201: public int getMemberType() throws CoreException {
202: return ensureMarker().getAttribute(MEMBER_TYPE,
203: IJavaClassPrepareBreakpoint.TYPE_CLASS);
204: }
205:
206: /* (non-Javadoc)
207: * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsInstanceFilters()
208: */
209: public boolean supportsInstanceFilters() {
210: return false;
211: }
212:
213: /* (non-Javadoc)
214: * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#addInstanceFilter(org.eclipse.jdt.debug.core.IJavaObject)
215: */
216: public void addInstanceFilter(IJavaObject object)
217: throws CoreException {
218: throw new CoreException(
219: new Status(
220: IStatus.ERROR,
221: JDIDebugModel.getPluginIdentifier(),
222: DebugException.REQUEST_FAILED,
223: JDIDebugBreakpointMessages.JavaClassPrepareBreakpoint_2,
224: null));
225: }
226:
227: /* (non-Javadoc)
228: * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setThreadFilter(org.eclipse.jdt.debug.core.IJavaThread)
229: */
230: public void setThreadFilter(IJavaThread thread)
231: throws CoreException {
232: throw new CoreException(
233: new Status(
234: IStatus.ERROR,
235: JDIDebugModel.getPluginIdentifier(),
236: DebugException.REQUEST_FAILED,
237: JDIDebugBreakpointMessages.JavaClassPrepareBreakpoint_3,
238: null));
239: }
240:
241: /* (non-Javadoc)
242: * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsThreadFilters()
243: */
244: public boolean supportsThreadFilters() {
245: return false;
246: }
247: }
|