KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > core > breakpoints > JavaStratumLineBreakpoint


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.debug.core.breakpoints;
12
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.ListIterator JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IWorkspaceRunnable;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.debug.core.DebugException;
25 import org.eclipse.debug.core.DebugPlugin;
26 import org.eclipse.debug.core.IStatusHandler;
27 import org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint;
28 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
29 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
30
31 import com.sun.jdi.AbsentInformationException;
32 import com.sun.jdi.ClassNotPreparedException;
33 import com.sun.jdi.Location;
34 import com.sun.jdi.NativeMethodException;
35 import com.sun.jdi.ReferenceType;
36 import com.sun.jdi.VMDisconnectedException;
37 import com.sun.jdi.VirtualMachine;
38
39 /**
40  * A line breakpoint identified by its source file
41  * name and/or path, and stratum that it is relative to.
42  *
43  * @since 3.0
44  */

45 public class JavaStratumLineBreakpoint extends JavaLineBreakpoint implements IJavaStratumLineBreakpoint {
46     private static final String JavaDoc PATTERN= "org.eclipse.jdt.debug.pattern"; //$NON-NLS-1$
47
private static final String JavaDoc STRATUM= "org.eclipse.jdt.debug.stratum"; //$NON-NLS-1$
48
private static final String JavaDoc SOURCE_PATH= "org.eclipse.jdt.debug.source_path"; //$NON-NLS-1$
49
private static final String JavaDoc STRATUM_BREAKPOINT= "org.eclipse.jdt.debug.javaStratumLineBreakpointMarker"; //$NON-NLS-1$
50
private String JavaDoc[] fTypeNamePatterns;
51     // corresponds to type name patterns with beginning/trailing '*' removed
52
private String JavaDoc[] fSuffix;
53     private String JavaDoc[] fPrefix;
54
55     public JavaStratumLineBreakpoint() {
56     }
57
58     /**
59      * Creates and returns a line breakpoint identified by its source file
60      * name and/or path, and stratum that it is relative to.
61      *
62      * @param resource the resource on which to create the associated breakpoint
63      * marker
64      * @param stratum the stratum in which the source name, source path and line number
65      * are relative, or <code>null</code>. If <code>null</code> or if the specified stratum
66      * is not defined for a type, the source name, source path and line number are
67      * relative to the type's default stratum.
68      * @param sourceName the simple name of the source file in which the breakpoint is
69      * set, or <code>null</code>. The breakpoint will install itself in classes that have a source
70      * file name debug attribute that matches this value in the specified stratum,
71      * and satisfies the class name pattern and source path attribute. When <code>null</code>,
72      * the source file name debug attribute is not considered.
73      * @param sourcePath the qualified source file name in which the breakpoint is
74      * set, or <code>null</code>. The breakpoint will install itself in classes that
75      * have a source file path in the specified stratum that matches this value, and
76      * satisfies the class name pattern and source name attribute. When <code>null</code>,
77      * the source path attribute is not considered.
78      * @param classNamePattern the class name pattern to which the breakpoint should
79      * be restricted, or <code>null</code>. The breakpoint will install itself in each type that
80      * matches this class name pattern, with a satisfying source name and source path.
81      * Patterns may begin or end with '*', which matches 0 or more characters. A pattern that
82      * does not contain a '*' is equivalent to a pattern ending in '*'. Specifying <code>null</code>,
83      * or an empty string is the equivalent to "*".
84      * @param lineNumber the lineNumber on which the breakpoint is set - line
85      * numbers are 1 based, associated with the source file (stratum) in which
86      * the breakpoint is set
87      * @param charStart the first character index associated with the breakpoint,
88      * or -1 if unspecified, in the source file in which the breakpoint is set
89      * @param charEnd the last character index associated with the breakpoint,
90      * or -1 if unspecified, in the source file in which the breakpoint is set
91      * @param hitCount the number of times the breakpoint will be hit before
92      * suspending execution - 0 if it should always suspend
93      * @param register whether to add this breakpoint to the breakpoint manager
94      * @param attributes a map of client defined attributes that should be assigned
95      * to the underlying breakpoint marker on creation, or <code>null</code> if none.
96      * @return a stratum breakpoint
97      * @exception CoreException If this method fails. Reasons include:<ul>
98      *<li>Failure creating underlying marker. The exception's status contains
99      * the underlying exception responsible for the failure.</li></ul>
100      * @since 3.0
101      */

102     public JavaStratumLineBreakpoint(IResource resource, String JavaDoc stratum, String JavaDoc sourceName, String JavaDoc sourcePath, String JavaDoc classNamePattern, int lineNumber, int charStart, int charEnd, int hitCount, boolean register, Map JavaDoc attributes) throws DebugException {
103         this(resource, stratum, sourceName, sourcePath, classNamePattern, lineNumber, charStart, charEnd, hitCount, register, attributes, STRATUM_BREAKPOINT);
104     }
105     
106     protected JavaStratumLineBreakpoint(final IResource resource, final String JavaDoc stratum, final String JavaDoc sourceName, final String JavaDoc sourcePath, final String JavaDoc classNamePattern, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final boolean register, final Map JavaDoc attributes, final String JavaDoc markerType) throws DebugException {
107         IWorkspaceRunnable wr= new IWorkspaceRunnable() {
108             public void run(IProgressMonitor monitor) throws CoreException {
109     
110                 // create the marker
111
setMarker(resource.createMarker(markerType));
112                 
113                 // modify pattern
114
String JavaDoc pattern = classNamePattern;
115                 if (pattern != null && pattern.length() == 0) {
116                     pattern = null;
117                 }
118                 
119                 // add attributes
120
addLineBreakpointAttributes(attributes, getModelIdentifier(), true, lineNumber, charStart, charEnd);
121                 addStratumPatternAndHitCount(attributes, stratum, sourceName, sourcePath, pattern, hitCount);
122                 // set attributes
123
attributes.put(SUSPEND_POLICY, new Integer JavaDoc(getDefaultSuspendPolicy()));
124                 ensureMarker().setAttributes(attributes);
125                 
126                 register(register);
127             }
128         };
129         run(getMarkerRule(resource), wr);
130     }
131
132     /**
133      * Adds the class name pattern and hit count attributes to the gvien map.
134      */

135     protected void addStratumPatternAndHitCount(Map JavaDoc attributes, String JavaDoc stratum, String JavaDoc sourceName, String JavaDoc sourcePath, String JavaDoc pattern, int hitCount) {
136         attributes.put(PATTERN, pattern);
137         attributes.put(STRATUM, stratum);
138         if (sourceName != null) {
139             attributes.put(SOURCE_NAME, sourceName);
140         }
141         if (sourcePath != null) {
142             attributes.put(SOURCE_PATH, sourcePath);
143         }
144         if (hitCount > 0) {
145             attributes.put(HIT_COUNT, new Integer JavaDoc(hitCount));
146             attributes.put(EXPIRED, Boolean.FALSE);
147         }
148     }
149     
150     /* (non-Javadoc)
151      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#installableReferenceType(com.sun.jdi.ReferenceType, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
152      */

153     protected boolean installableReferenceType(ReferenceType type, JDIDebugTarget target) throws CoreException {
154
155         // check the type name.
156
String JavaDoc typeName= type.name();
157         if (!validType(typeName)) {
158             return false;
159         }
160         String JavaDoc stratum = getStratum();
161         // check the source name.
162
String JavaDoc bpSourceName= getSourceName();
163         if (bpSourceName != null) {
164             List JavaDoc sourceNames;
165             try {
166                 sourceNames= type.sourceNames(stratum);
167             } catch (AbsentInformationException e1) {
168                 return false;
169             } catch (VMDisconnectedException e) {
170                 if (!target.isAvailable()) {
171                     return false;
172                 }
173                 throw e;
174             }
175             if (!containsMatch(sourceNames, bpSourceName)) {
176                 return false;
177             }
178         }
179         
180         String JavaDoc bpSourcePath= getSourcePath();
181         if (bpSourcePath != null) {
182             // check that source paths match
183
List JavaDoc sourcePaths;
184             try {
185                 sourcePaths= type.sourcePaths(stratum);
186             } catch (AbsentInformationException e1) {
187                 return false;
188             } catch (VMDisconnectedException e) {
189                 if (!target.isAvailable()) {
190                     return false;
191                 }
192                 throw e;
193             }
194             if (!containsMatch(sourcePaths, bpSourcePath)) {
195                 return false;
196             }
197         }
198         return queryInstallListeners(target, type);
199     }
200     
201     private boolean containsMatch(List JavaDoc strings, String JavaDoc key) {
202         for (Iterator JavaDoc iter = strings.iterator(); iter.hasNext();) {
203             if (((String JavaDoc) iter.next()).equals(key)) {
204                 return true;
205             }
206         }
207         return false;
208     }
209     
210     /**
211      * @param typeName
212      * @return
213      */

214     private boolean validType(String JavaDoc typeName) throws CoreException {
215
216         String JavaDoc[] patterns = getTypeNamePatterns();
217         for (int i=0; i<patterns.length; i++) {
218             if (fSuffix[i] != null) {
219                 // pattern starting with '*'
220
if (fSuffix[i].length() == 0) {
221                     return true;
222                 }
223                 if (typeName.endsWith(fSuffix[i]))
224                     return true;
225             } else if (fPrefix[i] != null) {
226                 if (typeName.startsWith(fPrefix[i]))
227                     return true;
228             } else {
229                 if (typeName.startsWith(patterns[i]))
230                     return true;
231             }
232         }
233
234         // return false if we cannot find a type name to match
235
return false;
236     }
237
238     /**
239      * Returns a list of locations for the given line number in the given type.
240      * Returns <code>null</code> if a location cannot be determined.
241      */

242     protected List JavaDoc determineLocations(int lineNumber, ReferenceType type, JDIDebugTarget target) {
243         List JavaDoc locations;
244         String JavaDoc sourcePath;
245         try {
246             locations= type.locationsOfLine(getStratum(), getSourceName(), lineNumber);
247             sourcePath= getSourcePath();
248         } catch (AbsentInformationException aie) {
249             IStatus status= new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), NO_LINE_NUMBERS, JDIDebugBreakpointMessages.JavaLineBreakpoint_Absent_Line_Number_Information_1, null);
250             IStatusHandler handler= DebugPlugin.getDefault().getStatusHandler(status);
251             if (handler != null) {
252                 try {
253                     handler.handleStatus(status, type);
254                 } catch (CoreException e) {
255                 }
256             }
257             return null;
258         } catch (NativeMethodException e) {
259             return null;
260         } catch (VMDisconnectedException e) {
261             return null;
262         } catch (ClassNotPreparedException e) {
263             // could be a nested type that is not yet loaded
264
return null;
265         } catch (RuntimeException JavaDoc e) {
266             // not able to retrieve line info
267
target.internalError(e);
268             return null;
269         } catch (CoreException e) {
270             // not able to retrieve line info
271
JDIDebugPlugin.log(e);
272             return null;
273         }
274         
275         if (sourcePath == null) {
276             if (locations.size() > 0) {
277                 return locations;
278             }
279         } else {
280             for (ListIterator JavaDoc iter = locations.listIterator(); iter.hasNext();) {
281                 Location location = (Location) iter.next();
282                 try {
283                     if (!sourcePath.equals(location.sourcePath())) {
284                         iter.remove();
285                     }
286                 } catch (AbsentInformationException e1) {
287                     // nothing to do;
288
}
289             }
290             if (locations.size() > 0) {
291                 return locations;
292             }
293         }
294         
295         return null;
296     }
297     
298     /* (non-Javadoc)
299      * @see org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint#getPattern()
300      */

301     public String JavaDoc getPattern() throws CoreException {
302         return ensureMarker().getAttribute(PATTERN, "*"); //$NON-NLS-1$
303
}
304
305     /* (non-Javadoc)
306      * @see org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint#getSourceName()
307      */

308     public String JavaDoc getSourceName() throws CoreException {
309         return (String JavaDoc) ensureMarker().getAttribute(SOURCE_NAME);
310     }
311
312     /* (non-Javadoc)
313      * @see org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint#getStratum()
314      */

315     public String JavaDoc getStratum() throws CoreException {
316         return (String JavaDoc) ensureMarker().getAttribute(STRATUM);
317     }
318     
319     /* (non-Javadoc)
320      * @see org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint#getSourcePath()
321      */

322     public String JavaDoc getSourcePath() throws CoreException {
323         return (String JavaDoc) ensureMarker().getAttribute(SOURCE_PATH);
324     }
325
326     protected void createRequests(JDIDebugTarget target) throws CoreException {
327         if (target.isTerminated() || shouldSkipBreakpoint()) {
328             return;
329         }
330         
331         String JavaDoc[] patterns = null;
332         try {
333             patterns = getTypeNamePatterns();
334         } catch (CoreException e1) {
335             JDIDebugPlugin.log(e1);
336             return;
337         }
338         
339         String JavaDoc sourceName = getSourceName();
340         for (int i=0; i<patterns.length; i++)
341         {
342             String JavaDoc classPrepareTypeName= patterns[i];
343             // create request to listen to class loads
344
//name may only be partially resolved
345
registerRequest(target.createClassPrepareRequest(classPrepareTypeName, null, true, sourceName), target);
346         }
347         
348         // create breakpoint requests for each class currently loaded
349
VirtualMachine vm = target.getVM();
350         if (vm == null) {
351             target.requestFailed(JDIDebugBreakpointMessages.JavaPatternBreakpoint_Unable_to_add_breakpoint___VM_disconnected__1, null);
352         }
353         List JavaDoc classes = null;
354         try {
355             classes= vm.allClasses();
356         } catch (RuntimeException JavaDoc e) {
357             target.targetRequestFailed(JDIDebugBreakpointMessages.JavaPatternBreakpoint_0, e);
358         }
359         if (classes != null) {
360             Iterator JavaDoc iter = classes.iterator();
361             while (iter.hasNext()) {
362                 ReferenceType type= (ReferenceType)iter.next();
363                 if (installableReferenceType(type, target)) {
364                     createRequest(target, type);
365                 }
366             }
367         }
368     }
369
370     public synchronized String JavaDoc[] getTypeNamePatterns() throws CoreException
371     {
372         if (fTypeNamePatterns != null)
373             return fTypeNamePatterns;
374             
375         String JavaDoc patterns = getPattern();
376         
377         // delimit by ","
378
fTypeNamePatterns = patterns.split(","); //$NON-NLS-1$
379
fSuffix = new String JavaDoc[fTypeNamePatterns.length];
380         fPrefix = new String JavaDoc[fTypeNamePatterns.length];
381         for (int i = 0; i < fTypeNamePatterns.length; i++) {
382             fTypeNamePatterns[i] = fTypeNamePatterns[i].trim();
383             String JavaDoc pattern = fTypeNamePatterns[i];
384             if (pattern.charAt(0) == '*') {
385                 if (pattern.length() > 1) {
386                     fSuffix[i] = pattern.substring(1);
387                 } else {
388                     fSuffix[i] = ""; //$NON-NLS-1$
389
}
390             } else if (pattern.charAt(pattern.length() - 1) == '*') {
391                 fPrefix[i] = pattern.substring(0, pattern.length() - 1);
392             }
393         }
394         
395         return fTypeNamePatterns;
396     }
397     
398 }
399
Popular Tags