KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > actions > BreakpointLocationVerifierJob


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 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.ui.actions;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.core.resources.IResource;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.core.runtime.jobs.Job;
22 import org.eclipse.debug.core.DebugPlugin;
23 import org.eclipse.jdt.core.IJavaElement;
24 import org.eclipse.jdt.core.IJavaProject;
25 import org.eclipse.jdt.core.IType;
26 import org.eclipse.jdt.core.JavaCore;
27 import org.eclipse.jdt.core.dom.AST;
28 import org.eclipse.jdt.core.dom.ASTParser;
29 import org.eclipse.jdt.core.dom.CompilationUnit;
30 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
31 import org.eclipse.jdt.debug.core.JDIDebugModel;
32 import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
33 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
34 import org.eclipse.jface.text.BadLocationException;
35 import org.eclipse.jface.text.IDocument;
36 import org.eclipse.jface.text.IRegion;
37 import org.eclipse.jface.text.TextSelection;
38 import org.eclipse.swt.widgets.Display;
39 import org.eclipse.ui.IEditorPart;
40 import org.eclipse.ui.texteditor.IEditorStatusLine;
41
42 import com.ibm.icu.text.MessageFormat;
43
44 /**
45  * Job used to verify the position of a breakpoint
46  */

47 public class BreakpointLocationVerifierJob extends Job {
48
49     /**
50      * The document which contains the code source.
51      */

52     private IDocument fDocument;
53     
54     /**
55      * The temporary breakpoint that has been set. Can be <code>null</code> if the callee was not able
56      * to check if a breakpoint was already set at this position.
57      */

58     private IJavaLineBreakpoint fBreakpoint;
59     
60     /**
61      * The number of the line where the breakpoint has been requested.
62      */

63     private int fLineNumber;
64     
65     /**
66      * The qualified type name of the class where the temporary breakpoint as been set.
67      * Can be <code>null</code> if fBreakpoint is null.
68      */

69     private String JavaDoc fTypeName;
70     
71     /**
72      * The type in which should be set the breakpoint.
73      */

74     private IType fType;
75     
76     /**
77      * Indicate if the search for a valid location should be limited to a line
78      * or expanded to field and method declaration.
79      */

80     private boolean fBestMatch;
81
82     /**
83      * The resource in which should be set the breakpoint.
84      */

85     private IResource fResource;
86     
87     /**
88      * The current IEditorPart
89      */

90     private IEditorPart fEditorPart;
91     
92     /**
93      * The status line to use to display errors
94      */

95     private IEditorStatusLine fStatusLine;
96     
97     public BreakpointLocationVerifierJob(IDocument document, IJavaLineBreakpoint breakpoint, int lineNumber, boolean bestMatch, String JavaDoc typeName, IType type, IResource resource, IEditorPart editorPart) {
98         super(ActionMessages.BreakpointLocationVerifierJob_breakpoint_location);
99         fDocument= document;
100         fBreakpoint= breakpoint;
101         fLineNumber= lineNumber;
102         fBestMatch= bestMatch;
103         fTypeName= typeName;
104         fType= type;
105         fResource= resource;
106         fEditorPart= editorPart;
107         fStatusLine= (IEditorStatusLine) editorPart.getAdapter(IEditorStatusLine.class);
108         setSystem(true);
109     }
110     
111     /* (non-Javadoc)
112      * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
113      */

114     public IStatus run(IProgressMonitor monitor) {
115         ASTParser parser = ASTParser.newParser(AST.JLS3);
116         char[] source = fDocument.get().toCharArray();
117         parser.setSource(source);
118         IJavaElement javaElement = JavaCore.create(fResource);
119         IJavaProject project= null;
120         if (javaElement != null) {
121             Map JavaDoc options=JavaCore.getDefaultOptions();
122             project= javaElement.getJavaProject();
123             String JavaDoc compilerCompliance = JavaCore.VERSION_1_5;
124             String JavaDoc compilerSource = JavaCore.VERSION_1_5;
125             if (project != null) {
126                 compilerCompliance = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
127                 compilerSource = project.getOption(JavaCore.COMPILER_SOURCE, true);
128             }
129             options.put(JavaCore.COMPILER_COMPLIANCE, compilerCompliance);
130             options.put(JavaCore.COMPILER_SOURCE, compilerSource);
131             parser.setCompilerOptions(options);
132         }
133         CompilationUnit compilationUnit= (CompilationUnit)parser.createAST(null);
134         ValidBreakpointLocationLocator locator= new ValidBreakpointLocationLocator(compilationUnit, fLineNumber, false, fBestMatch);
135         compilationUnit.accept(locator);
136         if (locator.isBindingsRequired()) {
137             if (javaElement != null) {
138                 // try again with bindings if required and available
139
String JavaDoc unitName = null;
140                 if (fType == null) {
141                     String JavaDoc name = fResource.getName();
142                     if (JavaCore.isJavaLikeFileName(name)) {
143                         unitName = name;
144                     }
145                 } else {
146                     if (fType.isBinary()) {
147                         String JavaDoc className= fType.getClassFile().getElementName();
148                         int nameLength= className.indexOf('$');
149                         if (nameLength < 0) {
150                             nameLength= className.indexOf('.');
151                         }
152                         unitName= className.substring(0, nameLength) + ".java"; //$NON-NLS-1$
153
} else {
154                         unitName= fType.getCompilationUnit().getElementName();
155                     }
156                 }
157                 if (unitName != null) {
158                     parser = ASTParser.newParser(AST.JLS3);
159                     parser.setSource(source);
160                     parser.setProject(project);
161                     parser.setUnitName(unitName);
162                     parser.setResolveBindings(true);
163                     compilationUnit= (CompilationUnit)parser.createAST(null);
164                     locator= new ValidBreakpointLocationLocator(compilationUnit, fLineNumber, true, fBestMatch);
165                     compilationUnit.accept(locator);
166                 }
167             }
168         }
169         int lineNumber= locator.getLineLocation();
170         String JavaDoc typeName= locator.getFullyQualifiedTypeName();
171         
172         try {
173             switch (locator.getLocationType()) {
174                 case ValidBreakpointLocationLocator.LOCATION_LINE:
175                     return manageLineBreakpoint(typeName, lineNumber);
176                 case ValidBreakpointLocationLocator.LOCATION_METHOD:
177                     if (fBreakpoint != null) {
178                         DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
179                     }
180                     new ToggleBreakpointAdapter().toggleMethodBreakpoints(fEditorPart, new TextSelection(locator.getMemberOffset(), 0));
181                     break;
182                 case ValidBreakpointLocationLocator.LOCATION_FIELD:
183                     if (fBreakpoint != null) {
184                         DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
185                     }
186                     new ToggleBreakpointAdapter().toggleWatchpoints(fEditorPart, new TextSelection(locator.getMemberOffset(), 0));
187                     break;
188                 default:
189                     // cannot find a valid location
190
report(ActionMessages.BreakpointLocationVerifierJob_not_valid_location);
191                     if (fBreakpoint != null) {
192                         DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
193                     }
194                     return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.BreakpointLocationVerifierJob_not_valid_location, null);
195             }
196         } catch (CoreException e) {
197             JDIDebugUIPlugin.log(e);
198         }
199         return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.BreakpointLocationVerifierJob_breakpoint_set, null);
200         
201     }
202     
203     /**
204      * Determines the placement of the line breakpoint, and ensures that duplicates are not created
205      * and that notification is sent in the event of collisions
206      * @param typeName the fully qualified name of the type to add the line breakpoint to
207      * @param lineNumber the number we wish to put the breakpoint on
208      * @return the status of the line breakpoint placement
209      */

210     public IStatus manageLineBreakpoint(String JavaDoc typeName, int lineNumber) {
211         try {
212             boolean differentLineNumber= lineNumber != fLineNumber;
213             IJavaLineBreakpoint breakpoint= JDIDebugModel.lineBreakpointExists(fResource, typeName, lineNumber);
214             boolean breakpointExist= breakpoint != null;
215             if (fBreakpoint == null) {
216                 if (breakpointExist) {
217                     if (differentLineNumber) {
218                         // There is already a breakpoint on the valid line.
219
report(MessageFormat.format(ActionMessages.BreakpointLocationVerifierJob_0, new String JavaDoc[]{Integer.toString(lineNumber)}));
220                         return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.BreakpointLocationVerifierJob_not_valid_location, null);
221                     }
222                     // There is already a breakpoint on the valid line, but it's also the requested line.
223
// Removing the existing breakpoint.
224
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
225                     return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.BreakpointLocationVerifierJob_breakpointRemoved, null);
226                 }
227                 createNewBreakpoint(lineNumber, typeName);
228                 return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.BreakpointLocationVerifierJob_breakpoint_set, null);
229             }
230             if (differentLineNumber) {
231                 if (breakpointExist) {
232                     // there is already a breakpoint on the valid line.
233
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
234                     report(MessageFormat.format(ActionMessages.BreakpointLocationVerifierJob_0, new String JavaDoc[]{Integer.toString(lineNumber)}));
235                     return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.BreakpointLocationVerifierJob_not_valid_location, null);
236                 }
237                 replaceBreakpoint(lineNumber, typeName);
238                 return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, ActionMessages.BreakpointLocationVerifierJob_breakpointMovedToValidPosition, null);
239             }
240             if (!typeName.equals(fTypeName)) {
241                 replaceBreakpoint(lineNumber, typeName);
242                 return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, ActionMessages.BreakpointLocationVerifierJob_breakpointSetToRightType, null);
243             }
244         } catch (CoreException e) {
245             JDIDebugUIPlugin.log(e);
246         }
247         return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.BreakpointLocationVerifierJob_breakpoint_set, null);
248     }
249     
250     /**
251      * Remove the temporary breakpoint and create a new breakpoint at the right position.
252      */

253     private void replaceBreakpoint(int lineNumber, String JavaDoc typeName) throws CoreException {
254         createNewBreakpoint(lineNumber, typeName);
255         DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
256     }
257
258     /**
259      * Create a new breakpoint at the right position.
260      */

261     private void createNewBreakpoint(int lineNumber, String JavaDoc typeName) throws CoreException {
262         Map JavaDoc newAttributes = new HashMap JavaDoc(10);
263         if (fType != null) {
264             try {
265                 IRegion line= fDocument.getLineInformation(lineNumber - 1);
266                 int start= line.getOffset();
267                 int end= start + line.getLength() - 1;
268                 BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(newAttributes, fType, start, end);
269             } catch (BadLocationException ble) {
270                 JDIDebugUIPlugin.log(ble);
271             }
272         }
273         JDIDebugModel.createLineBreakpoint(fResource, typeName, lineNumber, -1, -1, 0, true, newAttributes);
274     }
275
276     /**
277      * Reports any status to the current active workbench shell
278      * @param message the message to display
279      */

280     protected void report(final String JavaDoc message) {
281         JDIDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable JavaDoc() {
282             public void run() {
283                 if (fStatusLine != null) {
284                     fStatusLine.setMessage(true, message, null);
285                 }
286                 if (message != null && JDIDebugUIPlugin.getActiveWorkbenchShell() != null) {
287                     Display.getCurrent().beep();
288                 }
289             }
290         });
291     }
292 }
293
Popular Tags