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 com.ibm.icu.text.MessageFormat;
013: import java.util.Iterator;
014: import java.util.List;
015: import java.util.Map;
016:
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.resources.IWorkspaceRunnable;
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IProgressMonitor;
021: import org.eclipse.debug.core.DebugException;
022: import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint;
023: import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
024: import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
025:
026: import com.sun.jdi.AbsentInformationException;
027: import com.sun.jdi.ReferenceType;
028: import com.sun.jdi.VMDisconnectedException;
029: import com.sun.jdi.VirtualMachine;
030:
031: public class JavaPatternBreakpoint extends JavaLineBreakpoint implements
032: IJavaPatternBreakpoint {
033:
034: private static final String PATTERN_BREAKPOINT = "org.eclipse.jdt.debug.javaPatternBreakpointMarker"; //$NON-NLS-1$
035:
036: /**
037: * Breakpoint attribute storing the pattern identifier of the source
038: * file in which a breakpoint is created
039: * (value <code>"org.eclipse.jdt.debug.core.pattern"</code>). This attribute is a <code>String</code>.
040: */
041: protected static final String PATTERN = "org.eclipse.jdt.debug.core.pattern"; //$NON-NLS-1$
042:
043: public JavaPatternBreakpoint() {
044: }
045:
046: /**
047: * @see JDIDebugModel#createPatternBreakpoint(IResource, String, int, int, int, int, boolean, Map)
048: */
049: public JavaPatternBreakpoint(IResource resource, String sourceName,
050: String pattern, int lineNumber, int charStart, int charEnd,
051: int hitCount, boolean add, Map attributes)
052: throws DebugException {
053: this (resource, sourceName, pattern, lineNumber, charStart,
054: charEnd, hitCount, add, attributes, PATTERN_BREAKPOINT);
055: }
056:
057: public JavaPatternBreakpoint(final IResource resource,
058: final String sourceName, final String pattern,
059: final int lineNumber, final int charStart,
060: final int charEnd, final int hitCount, final boolean add,
061: final Map attributes, final String markerType)
062: throws DebugException {
063: IWorkspaceRunnable wr = new IWorkspaceRunnable() {
064: public void run(IProgressMonitor monitor)
065: throws CoreException {
066:
067: // create the marker
068: setMarker(resource.createMarker(markerType));
069:
070: // add attributes
071: addLineBreakpointAttributes(attributes,
072: getModelIdentifier(), true, lineNumber,
073: charStart, charEnd);
074: addPatternAndHitCount(attributes, sourceName, pattern,
075: hitCount);
076: // set attributes
077: attributes.put(SUSPEND_POLICY, new Integer(
078: getDefaultSuspendPolicy()));
079: ensureMarker().setAttributes(attributes);
080:
081: register(add);
082: }
083: };
084: run(getMarkerRule(resource), wr);
085: }
086:
087: /**
088: * @see JavaBreakpoint#getReferenceTypeName()
089: */
090: protected String getReferenceTypeName() {
091: String name = ""; //$NON-NLS-1$
092: try {
093: name = getPattern();
094: } catch (CoreException ce) {
095: JDIDebugPlugin.log(ce);
096: }
097: return name;
098: }
099:
100: /**
101: * @see JavaBreakpoint#installableReferenceType(ReferenceType)
102: */
103: protected boolean installableReferenceType(ReferenceType type,
104: JDIDebugTarget target) throws CoreException {
105: // if the source name attribute is specified, check for a match with the
106: // debug attribute (if available)
107: if (getSourceName() != null) {
108: String sourceName = null;
109: try {
110: sourceName = type.sourceName();
111: } catch (AbsentInformationException e) {
112: // unable to compare
113: } catch (VMDisconnectedException e) {
114: if (!target.isAvailable()) {
115: return false;
116: }
117: target
118: .targetRequestFailed(
119: MessageFormat
120: .format(
121: JDIDebugBreakpointMessages.JavaPatternBreakpoint_exception_source_name,
122: new String[] {
123: e.toString(),
124: type.name() }),
125: e);
126: // execution will not reach this line, as
127: // #targetRequestFailed will throw an exception
128: return false;
129: } catch (RuntimeException e) {
130: target
131: .targetRequestFailed(
132: MessageFormat
133: .format(
134: JDIDebugBreakpointMessages.JavaPatternBreakpoint_exception_source_name,
135: new String[] {
136: e.toString(),
137: type.name() }),
138: e);
139: // execution will not reach this line, as
140: // #targetRequestFailed will throw an exception
141: return false;
142: }
143:
144: // if the debug attribute matches the source name, attempt installion
145: if (sourceName != null) {
146: if (!getSourceName().equalsIgnoreCase(sourceName)) {
147: return false;
148: }
149: }
150: }
151:
152: String pattern = getPattern();
153: String queriedType = type.name();
154: if (pattern == null || queriedType == null) {
155: return false;
156: }
157: if (queriedType.startsWith(pattern)) {
158: // query registered listeners to see if this pattern breakpoint should
159: // be installed in the given target
160: return queryInstallListeners(target, type);
161: }
162: return false;
163: }
164:
165: /**
166: * Adds the class name pattern and hit count attributes to the given map.
167: */
168: protected void addPatternAndHitCount(Map attributes,
169: String sourceName, String pattern, int hitCount) {
170: attributes.put(PATTERN, pattern);
171: if (sourceName != null) {
172: attributes.put(SOURCE_NAME, sourceName);
173: }
174: if (hitCount > 0) {
175: attributes.put(HIT_COUNT, new Integer(hitCount));
176: attributes.put(EXPIRED, Boolean.FALSE);
177: }
178: }
179:
180: /**
181: * @see IJavaPatternBreakpoint#getPattern()
182: */
183: public String getPattern() throws CoreException {
184: return (String) ensureMarker().getAttribute(PATTERN);
185: }
186:
187: /**
188: * @see IJavaPatternBreakpoint#getSourceName()
189: */
190: public String getSourceName() throws CoreException {
191: return (String) ensureMarker().getAttribute(SOURCE_NAME);
192: }
193:
194: protected void createRequests(JDIDebugTarget target)
195: throws CoreException {
196: if (target.isTerminated() || shouldSkipBreakpoint()) {
197: return;
198: }
199: String referenceTypeName = getReferenceTypeName();
200: if (referenceTypeName == null) {
201: return;
202: }
203:
204: String classPrepareTypeName = referenceTypeName;
205: // create request to listen to class loads
206: //name may only be partially resolved
207: if (!referenceTypeName.endsWith("*")) { //$NON-NLS-1$
208: classPrepareTypeName = classPrepareTypeName + '*';
209: }
210: registerRequest(target
211: .createClassPrepareRequest(classPrepareTypeName),
212: target);
213:
214: // create breakpoint requests for each class currently loaded
215: VirtualMachine vm = target.getVM();
216: if (vm == null) {
217: target
218: .requestFailed(
219: JDIDebugBreakpointMessages.JavaPatternBreakpoint_Unable_to_add_breakpoint___VM_disconnected__1,
220: null);
221: }
222: List classes = null;
223: try {
224: classes = vm.allClasses();
225: } catch (RuntimeException e) {
226: target.targetRequestFailed(
227: JDIDebugBreakpointMessages.JavaPatternBreakpoint_0,
228: e);
229: }
230: if (classes != null) {
231: Iterator iter = classes.iterator();
232: String typeName = null;
233: ReferenceType type = null;
234: while (iter.hasNext()) {
235: type = (ReferenceType) iter.next();
236: typeName = type.name();
237: if (typeName != null
238: && typeName.startsWith(referenceTypeName)) {
239: createRequest(target, type);
240: }
241: }
242: }
243: }
244: }
|