KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.ui.actions;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.core.resources.ResourcesPlugin;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Platform;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.core.runtime.jobs.Job;
29 import org.eclipse.debug.core.DebugException;
30 import org.eclipse.debug.core.DebugPlugin;
31 import org.eclipse.debug.core.IBreakpointManager;
32 import org.eclipse.debug.core.model.IBreakpoint;
33 import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
34 import org.eclipse.jdt.core.Flags;
35 import org.eclipse.jdt.core.IClassFile;
36 import org.eclipse.jdt.core.ICompilationUnit;
37 import org.eclipse.jdt.core.IField;
38 import org.eclipse.jdt.core.IJavaElement;
39 import org.eclipse.jdt.core.IMember;
40 import org.eclipse.jdt.core.IMethod;
41 import org.eclipse.jdt.core.IPackageDeclaration;
42 import org.eclipse.jdt.core.ISourceRange;
43 import org.eclipse.jdt.core.IType;
44 import org.eclipse.jdt.core.ITypeParameter;
45 import org.eclipse.jdt.core.JavaModelException;
46 import org.eclipse.jdt.core.Signature;
47 import org.eclipse.jdt.core.dom.AST;
48 import org.eclipse.jdt.core.dom.ASTParser;
49 import org.eclipse.jdt.core.dom.CompilationUnit;
50 import org.eclipse.jdt.debug.core.IJavaBreakpoint;
51 import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
52 import org.eclipse.jdt.debug.core.IJavaFieldVariable;
53 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
54 import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
55 import org.eclipse.jdt.debug.core.IJavaType;
56 import org.eclipse.jdt.debug.core.IJavaWatchpoint;
57 import org.eclipse.jdt.debug.core.JDIDebugModel;
58 import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
59 import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
60 import org.eclipse.jdt.internal.debug.ui.DebugWorkingCopyManager;
61 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
62 import org.eclipse.jdt.ui.IWorkingCopyManager;
63 import org.eclipse.jdt.ui.JavaUI;
64 import org.eclipse.jface.text.BadLocationException;
65 import org.eclipse.jface.text.IDocument;
66 import org.eclipse.jface.text.IRegion;
67 import org.eclipse.jface.text.ITextSelection;
68 import org.eclipse.jface.viewers.ISelection;
69 import org.eclipse.jface.viewers.IStructuredSelection;
70 import org.eclipse.jface.viewers.StructuredSelection;
71 import org.eclipse.ui.IEditorInput;
72 import org.eclipse.ui.IEditorPart;
73 import org.eclipse.ui.IWorkbenchPart;
74 import org.eclipse.ui.texteditor.IDocumentProvider;
75 import org.eclipse.ui.texteditor.IEditorStatusLine;
76 import org.eclipse.ui.texteditor.ITextEditor;
77
78 /**
79  * Toggles a line breakpoint in a Java editor.
80  *
81  * @since 3.0
82  */

83 public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtension {
84     
85     private static final String JavaDoc EMPTY_STRING = ""; //$NON-NLS-1$
86

87     /**
88      * Constructor
89      */

90     public ToggleBreakpointAdapter() {
91         // initialize helper in UI thread
92
ActionDelegateHelper.getDefault();
93     }
94
95     /**
96      * Convenience method for printing messages to the status line
97      * @param message the message to be displayed
98      * @param part the currently active workbench part
99      */

100     protected void report(final String JavaDoc message, final IWorkbenchPart part) {
101         JDIDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable JavaDoc() {
102             public void run() {
103                 IEditorStatusLine statusLine = (IEditorStatusLine) part.getAdapter(IEditorStatusLine.class);
104                 if (statusLine != null) {
105                     if (message != null) {
106                         statusLine.setMessage(true, message, null);
107                     } else {
108                         statusLine.setMessage(true, null, null);
109                     }
110                 }
111                 if (message != null && JDIDebugUIPlugin.getActiveWorkbenchShell() != null) {
112                     JDIDebugUIPlugin.getActiveWorkbenchShell().getDisplay().beep();
113                 }
114             }
115         });
116     }
117
118     /**
119      * Returns the <code>IType</code> for the given selection
120      * @param selection the current text selection
121      * @return the <code>IType</code> for the text selection or <code>null</code>
122      */

123     protected IType getType(ITextSelection selection) {
124         IMember member = ActionDelegateHelper.getDefault().getCurrentMember(selection);
125         IType type = null;
126         if (member instanceof IType) {
127             type = (IType) member;
128         } else if (member != null) {
129             type = member.getDeclaringType();
130         }
131         // bug 52385: we don't want local and anonymous types from compilation
132
// unit,
133
// we are getting 'not-always-correct' names for them.
134
try {
135             while (type != null && !type.isBinary() && type.isLocal()) {
136                 type = type.getDeclaringType();
137             }
138         } catch (JavaModelException e) {
139             JDIDebugUIPlugin.log(e);
140         }
141         return type;
142     }
143
144     /**
145      * Returns the IType associated with the <code>IJavaElement</code> passed in
146      * @param element the <code>IJavaElement</code> to get the type from
147      * @return the corresponding <code>IType</code> for the <code>IJavaElement</code>, or <code>null</code> if there is not one.
148      * @since 3.3
149      */

150     protected IType getType(IJavaElement element) {
151         switch(element.getElementType()) {
152             case IJavaElement.FIELD: {
153                 return ((IField)element).getDeclaringType();
154             }
155             case IJavaElement.METHOD: {
156                 return ((IMethod)element).getDeclaringType();
157             }
158             case IJavaElement.TYPE: {
159                 return (IType)element;
160             }
161             default: {
162                 return null;
163             }
164         }
165     }
166     
167     /* (non-Javadoc)
168      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
169      */

170     public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
171         toggleLineBreakpoints(part, selection, false);
172     }
173     
174     /**
175      * Toggles a line breakpoint.
176      * @param part the currently active workbench part
177      * @param selection the current selection
178      * @param bestMatch if we should make a best match or not
179      */

180     public void toggleLineBreakpoints(final IWorkbenchPart part, final ISelection selection, final boolean bestMatch) {
181         Job job = new Job("Toggle Line Breakpoint") { //$NON-NLS-1$
182
protected IStatus run(IProgressMonitor monitor) {
183                 ITextEditor editor = getTextEditor(part);
184                 if (editor != null && selection instanceof ITextSelection) {
185                     if (monitor.isCanceled()) {
186                         return Status.CANCEL_STATUS;
187                     }
188                     try {
189                         report(null, part);
190                         ISelection sel = selection;
191                         if(!(selection instanceof IStructuredSelection)) {
192                             sel = translateToMembers(part, selection);
193                         }
194                         if(isInterface(sel, part)) {
195                             report(ActionMessages.ToggleBreakpointAdapter_6, part);
196                             return Status.OK_STATUS;
197                         }
198                         if(sel instanceof IStructuredSelection) {
199                             IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement();
200                             IType type = null;
201                             if(member.getElementType() == IJavaElement.TYPE) {
202                                 type = (IType) member;
203                             }
204                             else {
205                                 type = member.getDeclaringType();
206                             }
207                             String JavaDoc tname = createQualifiedTypeName(type);
208                             IResource resource = BreakpointUtils.getBreakpointResource(type);
209                             int lnumber = ((ITextSelection) selection).getStartLine() + 1;
210                             IJavaLineBreakpoint existingBreakpoint = JDIDebugModel.lineBreakpointExists(resource, tname, lnumber);
211                             if (existingBreakpoint != null) {
212                                 DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(existingBreakpoint, true);
213                                 return Status.OK_STATUS;
214                             }
215                             Map JavaDoc attributes = new HashMap JavaDoc(10);
216                             IDocumentProvider documentProvider = editor.getDocumentProvider();
217                             if (documentProvider == null) {
218                                 return Status.CANCEL_STATUS;
219                             }
220                             IDocument document = documentProvider.getDocument(editor.getEditorInput());
221                             try {
222                                 IRegion line = document.getLineInformation(lnumber - 1);
223                                 int start = line.getOffset();
224                                 int end = start + line.getLength() - 1;
225                                 BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
226                             }
227                             catch (BadLocationException ble) {JDIDebugUIPlugin.log(ble);}
228                             IJavaLineBreakpoint breakpoint = JDIDebugModel.createLineBreakpoint(resource, tname, lnumber, -1, -1, 0, true, attributes);
229                             new BreakpointLocationVerifierJob(document, breakpoint, lnumber, bestMatch, tname, type, resource, editor).schedule();
230                         }
231                         else {
232                             report(ActionMessages.ToggleBreakpointAdapter_3, part);
233                             return Status.OK_STATUS;
234                         }
235                     }
236                     catch (CoreException ce) {return ce.getStatus();}
237                 }
238                 return Status.OK_STATUS;
239             }
240         };
241         job.setSystem(true);
242         job.schedule();
243     }
244
245     /*
246      * (non-Javadoc)
247      *
248      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(IWorkbenchPart,
249      * ISelection)
250      */

251     public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
252         if (isRemote(part, selection)) {
253             return false;
254         }
255         return selection instanceof ITextSelection;
256     }
257
258     /*
259      * (non-Javadoc)
260      *
261      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart,
262      * org.eclipse.jface.viewers.ISelection)
263      */

264     public void toggleMethodBreakpoints(final IWorkbenchPart part, final ISelection finalSelection) {
265         Job job = new Job("Toggle Method Breakpoints") { //$NON-NLS-1$
266
protected IStatus run(IProgressMonitor monitor) {
267                 if (monitor.isCanceled()) {
268                     return Status.CANCEL_STATUS;
269                 }
270                 try {
271                     report(null, part);
272                     ISelection selection = finalSelection;
273                     if(!(selection instanceof IStructuredSelection)) {
274                         selection = translateToMembers(part, selection);
275                     }
276                     if(isInterface(selection, part)) {
277                         report(ActionMessages.ToggleBreakpointAdapter_7, part);
278                         return Status.OK_STATUS;
279                     }
280                     if (selection instanceof IStructuredSelection) {
281                         IMethod[] members = getMethods((IStructuredSelection) selection);
282                         if (members.length == 0) {
283                             report(ActionMessages.ToggleBreakpointAdapter_9, part);
284                             return Status.OK_STATUS;
285                         }
286                         IJavaBreakpoint breakpoint = null;
287                         ISourceRange range = null;
288                         Map JavaDoc attributes = null;
289                         IType type = null;
290                         String JavaDoc signature = null;
291                         String JavaDoc mname = null;
292                         for (int i = 0, length = members.length; i < length; i++) {
293                             breakpoint = getMethodBreakpoint(members[i]);
294                             if (breakpoint == null) {
295                                 int start = -1;
296                                 int end = -1;
297                                 range = members[i].getNameRange();
298                                 if (range != null) {
299                                     start = range.getOffset();
300                                     end = start + range.getLength();
301                                 }
302                                 attributes = new HashMap JavaDoc(10);
303                                 BreakpointUtils.addJavaBreakpointAttributes(attributes, members[i]);
304                                 type = members[i].getDeclaringType();
305                                 signature = members[i].getSignature();
306                                 mname = members[i].getElementName();
307                                 if (members[i].isConstructor()) {
308                                     mname = "<init>"; //$NON-NLS-1$
309
if (type.isEnum()) {
310                                         signature = "(Ljava.lang.String;I" + signature.substring(1); //$NON-NLS-1$
311
}
312                                 }
313                                 if (!type.isBinary()) {
314                                     signature = resolveMethodSignature(type, signature);
315                                     if (signature == null) {
316                                         report(ActionMessages.ManageMethodBreakpointActionDelegate_methodNonAvailable, part);
317                                         return Status.OK_STATUS;
318                                     }
319                                 }
320                                 JDIDebugModel.createMethodBreakpoint(BreakpointUtils.getBreakpointResource(members[i]), createQualifiedTypeName(type), mname, signature, true, false, false, -1, start, end, 0, true, attributes);
321                             } else {
322                                 DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
323                             }
324                         }
325                     }
326                     else {
327                         report(ActionMessages.ToggleBreakpointAdapter_4, part);
328                         return Status.OK_STATUS;
329                     }
330                 } catch (CoreException e) {
331                     return e.getStatus();
332                 }
333                 return Status.OK_STATUS;
334             }
335         };
336         job.setSystem(true);
337         job.schedule();
338     }
339     
340     /**
341      * Toggles a class load breakpoint
342      * @param part the part
343      * @param selection the current selection
344      * @since 3.3
345      */

346     public void toggleClassBreakpoints(final IWorkbenchPart part, final ISelection selection) {
347         Job job = new Job("Toggle Class Load Breakpoints") { //$NON-NLS-1$
348
protected IStatus run(IProgressMonitor monitor) {
349                 if (monitor.isCanceled()) {
350                     return Status.CANCEL_STATUS;
351                 }
352                 try {
353                     report(null, part);
354                     ISelection sel = selection;
355                     if(!(selection instanceof IStructuredSelection)) {
356                         sel = translateToMembers(part, selection);
357                     }
358                     if(isInterface(sel, part)) {
359                         report(ActionMessages.ToggleBreakpointAdapter_1, part);
360                         return Status.OK_STATUS;
361                     }
362                     if(sel instanceof IStructuredSelection) {
363                         IMember member = (IMember)((IStructuredSelection)sel).getFirstElement();
364                         IType type = (IType) member;
365                         IBreakpoint existing = getClassLoadBreakpoint(type);
366                         if (existing != null) {
367                             existing.delete();
368                         }
369                         else {
370                             HashMap JavaDoc map = new HashMap JavaDoc(10);
371                             BreakpointUtils.addJavaBreakpointAttributes(map, type);
372                             ISourceRange range= type.getNameRange();
373                             int start = -1;
374                             int end = -1;
375                             if (range != null) {
376                                 start = range.getOffset();
377                                 end = start + range.getLength();
378                             }
379                             JDIDebugModel.createClassPrepareBreakpoint(BreakpointUtils.getBreakpointResource(member), createQualifiedTypeName(type), IJavaClassPrepareBreakpoint.TYPE_CLASS, start, end, true, map);
380                         }
381                     }
382                     else {
383                         report(ActionMessages.ToggleBreakpointAdapter_0, part);
384                         return Status.OK_STATUS;
385                     }
386                 }
387                 catch (CoreException e) {
388                     return e.getStatus();
389                 }
390                 return Status.OK_STATUS;
391             }
392         };
393         job.setSystem(true);
394         job.schedule();
395     }
396     
397     /**
398      * Returns the class load breakpoint for the specified type or null if none found
399      * @param type the type to search for a class load breakpoint for
400      * @return the existing class load breakpoint, or null if none
401      * @throws CoreException
402      * @since 3.3
403      */

404     protected IBreakpoint getClassLoadBreakpoint(IType type) throws CoreException {
405         IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
406         IBreakpoint existing = null;
407         IJavaBreakpoint breakpoint = null;
408         for (int i = 0; i < breakpoints.length; i++) {
409             breakpoint = (IJavaBreakpoint) breakpoints[i];
410             if (breakpoint instanceof IJavaClassPrepareBreakpoint && createQualifiedTypeName(type).equals(breakpoint.getTypeName())) {
411                 existing = breakpoint;
412                 break;
413             }
414         }
415         return existing;
416     }
417         
418     /**
419      * Returns the package qualified name, while accounting for the fact that a source file might
420      * not have a project
421      * @param type the type to ensure the package qualified name is created for
422      * @return the package qualified name
423      * @since 3.3
424      */

425     private String JavaDoc createQualifiedTypeName(IType type) {
426         String JavaDoc tname = type.getFullyQualifiedName();
427         try {
428             if(!type.getJavaProject().exists()) {
429                 String JavaDoc packName = null;
430                 if (type.isBinary()) {
431                     packName = type.getPackageFragment().getElementName();
432                 } else {
433                     IPackageDeclaration[] pd = type.getCompilationUnit().getPackageDeclarations();
434                     if(pd.length > 0) {
435                         packName = pd[0].getElementName();
436                     }
437                 }
438                 if(packName != null && !packName.equals(EMPTY_STRING)) {
439                     tname = packName+"."+tname; //$NON-NLS-1$
440
}
441             }
442             if(type.isAnonymous()) {
443                 //prune the $# from the name
444
int idx = tname.indexOf('$');
445                 if(idx > -1) {
446                     tname = tname.substring(0, idx);
447                 }
448             }
449         }
450         catch (JavaModelException e) {}
451         return tname;
452     }
453     
454     /**
455      * gets the <code>IJavaElement</code> from the editor input
456      * @param input the current editor input
457      * @return the corresponding <code>IJavaElement</code>
458      * @since 3.3
459      */

460     private IJavaElement getJavaElement(IEditorInput input) {
461         IJavaElement je = JavaUI.getEditorInputJavaElement(input);
462         if(je != null) {
463             return je;
464         }
465         //try to get from the working copy manager
466
return DebugWorkingCopyManager.getWorkingCopy(input, false);
467     }
468     
469     /*
470      * (non-Javadoc)
471      *
472      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart,
473      * org.eclipse.jface.viewers.ISelection)
474      */

475     public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
476         if (isRemote(part, selection)) {
477             return false;
478         }
479         if (selection instanceof IStructuredSelection) {
480             IStructuredSelection ss = (IStructuredSelection) selection;
481             return getMethods(ss).length > 0;
482         }
483         return (selection instanceof ITextSelection) && isMethod((ITextSelection) selection, part);
484     }
485     
486     /**
487      * Returns whether the given part/selection is remote (viewing a repository)
488      *
489      * @param part
490      * @param selection
491      * @return
492      */

493     protected boolean isRemote(IWorkbenchPart part, ISelection selection) {
494         if (selection instanceof IStructuredSelection) {
495             IStructuredSelection ss = (IStructuredSelection) selection;
496             Object JavaDoc element = ss.getFirstElement();
497             if(element instanceof IMember) {
498                 IMember member = (IMember) element;
499                 return !member.getJavaProject().getProject().exists();
500             }
501         }
502         ITextEditor editor = getTextEditor(part);
503         if (editor != null) {
504             IEditorInput input = editor.getEditorInput();
505             Object JavaDoc adapter = Platform.getAdapterManager().getAdapter(input, "org.eclipse.team.core.history.IFileRevision"); //$NON-NLS-1$
506
return adapter != null;
507         }
508         return false;
509     }
510     
511     /**
512      * Returns the text editor associated with the given part or <code>null</code>
513      * if none. In case of a multi-page editor, this method should be used to retrieve
514      * the correct editor to perform the breakpoint operation on.
515      *
516      * @param part workbench part
517      * @return text editor part or <code>null</code>
518      */

519     protected ITextEditor getTextEditor(IWorkbenchPart part) {
520         if (part instanceof ITextEditor) {
521             return (ITextEditor) part;
522         }
523         return (ITextEditor) part.getAdapter(ITextEditor.class);
524     }
525
526     /**
527      * Returns the methods from the selection, or an empty array
528      * @param selection the selection to get the methods from
529      * @return an array of the methods from the selection or an empty array
530      */

531     protected IMethod[] getMethods(IStructuredSelection selection) {
532         if (selection.isEmpty()) {
533             return new IMethod[0];
534         }
535         List JavaDoc methods = new ArrayList JavaDoc(selection.size());
536         Iterator JavaDoc iterator = selection.iterator();
537         while (iterator.hasNext()) {
538             Object JavaDoc thing = iterator.next();
539             try {
540                 if (thing instanceof IMethod) {
541                     IMethod method = (IMethod) thing;
542                     if (!Flags.isAbstract(method.getFlags())) {
543                         methods.add(method);
544                     }
545                 }
546             }
547             catch (JavaModelException e) {}
548         }
549         return (IMethod[]) methods.toArray(new IMethod[methods.size()]);
550     }
551
552     /**
553      * Returns if the text selection is a valid method or not
554      * @param selection the text selection
555      * @param part the associated workbench part
556      * @return true if the selection is a valid method, false otherwise
557      */

558     private boolean isMethod(ITextSelection selection, IWorkbenchPart part) {
559         ITextEditor editor = getTextEditor(part);
560         if(editor != null) {
561             IJavaElement element = getJavaElement(editor.getEditorInput());
562             if(element != null) {
563                 try {
564                     if(element instanceof ICompilationUnit) {
565                         element = ((ICompilationUnit) element).getElementAt(selection.getOffset());
566                     }
567                     else if(element instanceof IClassFile) {
568                         element = ((IClassFile) element).getElementAt(selection.getOffset());
569                     }
570                     return element != null && element.getElementType() == IJavaElement.METHOD;
571                 }
572                 catch (JavaModelException e) {return false;}
573             }
574         }
575         return false;
576     }
577     
578     /**
579      * Returns a list of <code>IField</code> and <code>IJavaFieldVariable</code> in the given selection.
580      * When an <code>IField</code> can be resolved for an <code>IJavaFieldVariable</code>, it is
581      * returned in favour of the variable.
582      *
583      * @param selection
584      * @return list of <code>IField</code> and <code>IJavaFieldVariable</code>, possibly empty
585      * @throws CoreException
586      */

587     protected List JavaDoc getFields(IStructuredSelection selection) throws CoreException {
588         if (selection.isEmpty()) {
589             return Collections.EMPTY_LIST;
590         }
591         List JavaDoc fields = new ArrayList JavaDoc(selection.size());
592         Iterator JavaDoc iterator = selection.iterator();
593         while (iterator.hasNext()) {
594             Object JavaDoc thing = iterator.next();
595             if (thing instanceof IField) {
596                 fields.add(thing);
597             } else if (thing instanceof IJavaFieldVariable) {
598                 IField field = getField((IJavaFieldVariable) thing);
599                 if (field == null) {
600                     fields.add(thing);
601                 } else {
602                     fields.add(field);
603                 }
604             }
605         }
606         return fields;
607     }
608
609     /**
610      * Returns if the structured selection is itself or is part of an interface
611      * @param selection the current selection
612      * @return true if the selection is part of an interface, false otherwise
613      * @since 3.2
614      */

615     private boolean isInterface(ISelection selection, IWorkbenchPart part) {
616         try {
617             ISelection sel = selection;
618             if(!(sel instanceof IStructuredSelection)) {
619                 sel = translateToMembers(part, selection);
620             }
621             if(sel instanceof IStructuredSelection) {
622                 Object JavaDoc obj = ((IStructuredSelection)sel).getFirstElement();
623                 if(obj instanceof IMember) {
624                     IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement();
625                     if(member.getElementType() == IJavaElement.TYPE) {
626                         return ((IType)member).isInterface();
627                     }
628                     return member.getDeclaringType().isInterface();
629                 }
630                 else if(obj instanceof IJavaFieldVariable) {
631                     IJavaFieldVariable var = (IJavaFieldVariable) obj;
632                     IType type = JavaDebugUtils.resolveType(var.getDeclaringType());
633                     return type != null && type.isInterface();
634                 }
635             }
636         }
637         catch (CoreException e1) {}
638         return false;
639     }
640     
641     /**
642      * Returns if the text selection is a field selection or not
643      * @param selection the text selection
644      * @param part the associated workbench part
645      * @return true if the text selection is a valid field for a watchpoint, false otherwise
646      * @since 3.3
647      */

648     private boolean isField(ITextSelection selection, IWorkbenchPart part) {
649         ITextEditor editor = getTextEditor(part);
650         if(editor != null) {
651             IJavaElement element = getJavaElement(editor.getEditorInput());
652             if(element != null) {
653                 try {
654                     if(element instanceof ICompilationUnit) {
655                         element = ((ICompilationUnit) element).getElementAt(selection.getOffset());
656                     }
657                     else if(element instanceof IClassFile) {
658                         element = ((IClassFile) element).getElementAt(selection.getOffset());
659                     }
660                     return element != null && element.getElementType() == IJavaElement.FIELD;
661                 }
662                 catch (JavaModelException e) {return false;}
663             }
664         }
665         return false;
666     }
667     
668     /**
669      * Determines if the selection is a field or not
670      * @param selection the current selection
671      * @return true if the selection is a field false otherwise
672      */

673     private boolean isFields(IStructuredSelection selection) {
674         if (!selection.isEmpty()) {
675             try {
676                 Iterator JavaDoc iterator = selection.iterator();
677                 while (iterator.hasNext()) {
678                     Object JavaDoc thing = iterator.next();
679                     if (thing instanceof IField) {
680                         int flags = ((IField)thing).getFlags();
681                         return !Flags.isFinal(flags) & !(Flags.isFinal(flags) & Flags.isStatic(flags));
682                     }
683                     else if(thing instanceof IJavaFieldVariable) {
684                         IJavaFieldVariable fv = (IJavaFieldVariable)thing;
685                         return !fv.isFinal() & !(fv.isFinal() & fv.isStatic());
686                     }
687                 }
688             }
689             catch(JavaModelException e) {return false;}
690             catch(DebugException de) {return false;}
691         }
692         return false;
693     }
694     
695     /*
696      * (non-Javadoc)
697      *
698      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart,
699      * org.eclipse.jface.viewers.ISelection)
700      */

701     public void toggleWatchpoints(final IWorkbenchPart part, final ISelection finalSelection) {
702         Job job = new Job("Toggle Watchpoints") { //$NON-NLS-1$
703
protected IStatus run(IProgressMonitor monitor) {
704                 if (monitor.isCanceled()) {
705                     return Status.CANCEL_STATUS;
706                 }
707                 try {
708                     report(null, part);
709                     ISelection selection = finalSelection;
710                     if(!(selection instanceof IStructuredSelection)) {
711                         selection = translateToMembers(part, finalSelection);
712                     }
713                     if(isInterface(selection, part)) {
714                         report(ActionMessages.ToggleBreakpointAdapter_5, part);
715                         return Status.OK_STATUS;
716                     }
717                     boolean allowed = false;
718                     if (selection instanceof IStructuredSelection) {
719                         List JavaDoc fields = getFields((IStructuredSelection) selection);
720                         if (fields.isEmpty()) {
721                             report(ActionMessages.ToggleBreakpointAdapter_10, part);
722                             return Status.OK_STATUS;
723                         }
724                         Iterator JavaDoc theFields = fields.iterator();
725                         IField javaField = null;
726                         IResource resource = null;
727                         String JavaDoc typeName = null;
728                         String JavaDoc fieldName = null;
729                         Object JavaDoc element = null;
730                         Map JavaDoc attributes = null;
731                         IJavaBreakpoint breakpoint = null;
732                         while (theFields.hasNext()) {
733                             element = theFields.next();
734                             if (element instanceof IField) {
735                                 javaField = (IField) element;
736                                 IType type = javaField.getDeclaringType();
737                                 typeName = createQualifiedTypeName(type);
738                                 fieldName = javaField.getElementName();
739                                 int f = javaField.getFlags();
740                                 boolean fin = Flags.isFinal(f);
741                                 allowed = !(fin) & !(Flags.isStatic(f) & fin);
742                             }
743                             breakpoint = getWatchpoint(typeName, fieldName);
744                             if (breakpoint == null) {
745                                 if(!allowed) {
746                                     toggleLineBreakpoints(part, finalSelection);
747                                     return Status.OK_STATUS;
748                                 }
749                                 int start = -1;
750                                 int end = -1;
751                                 attributes = new HashMap JavaDoc(10);
752                                 IType type = javaField.getDeclaringType();
753                                 ISourceRange range = javaField.getNameRange();
754                                 if (range != null) {
755                                     start = range.getOffset();
756                                     end = start + range.getLength();
757                                 }
758                                 BreakpointUtils.addJavaBreakpointAttributes(attributes, javaField);
759                                 resource = BreakpointUtils.getBreakpointResource(type);
760                                 JDIDebugModel.createWatchpoint(resource, typeName, fieldName, -1, start, end, 0, true, attributes);
761                             } else {
762                                 DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
763                             }
764                         }
765                     }
766                     else {
767                         report(ActionMessages.ToggleBreakpointAdapter_2, part);
768                         return Status.OK_STATUS;
769                     }
770                 } catch (CoreException e) {return e.getStatus();}
771                 return Status.OK_STATUS;
772             }
773         };
774         job.setSystem(true);
775         job.schedule();
776     }
777     
778     /**
779      * Returns any existing watchpoint for the given field, or <code>null</code> if none.
780      *
781      * @param typeName fully qualified type name on which watchpoint may exist
782      * @param fieldName field name
783      * @return any existing watchpoint for the given field, or <code>null</code> if none
784      * @throws CoreException
785      */

786     private IJavaWatchpoint getWatchpoint(String JavaDoc typeName, String JavaDoc fieldName) throws CoreException {
787         IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
788         IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
789         for (int i = 0; i < breakpoints.length; i++) {
790             IBreakpoint breakpoint = breakpoints[i];
791             if (breakpoint instanceof IJavaWatchpoint) {
792                 IJavaWatchpoint watchpoint = (IJavaWatchpoint) breakpoint;
793                 if (typeName.equals(watchpoint.getTypeName()) && fieldName.equals(watchpoint.getFieldName())) {
794                     return watchpoint;
795                 }
796             }
797         }
798         return null;
799     }
800
801     /**
802      * Returns the resolved method signature for the specified type
803      * @param type the declaring type the method is contained in
804      * @param methodSignature the method signature to resolve
805      * @return the resolved method signature
806      * @throws JavaModelException
807      */

808     public static String JavaDoc resolveMethodSignature(IType type, String JavaDoc methodSignature) throws JavaModelException {
809         String JavaDoc[] parameterTypes = Signature.getParameterTypes(methodSignature);
810         int length = parameterTypes.length;
811         String JavaDoc[] resolvedParameterTypes = new String JavaDoc[length];
812         for (int i = 0; i < length; i++) {
813             resolvedParameterTypes[i] = resolveType(type, parameterTypes[i]);
814             if (resolvedParameterTypes[i] == null) {
815                 return null;
816             }
817         }
818         String JavaDoc resolvedReturnType = resolveType(type, Signature.getReturnType(methodSignature));
819         if (resolvedReturnType == null) {
820             return null;
821         }
822         return Signature.createMethodSignature(resolvedParameterTypes, resolvedReturnType);
823     }
824
825     /**
826      * Resolves the the type for its given signature
827      * @param type the type
828      * @param typeSignature the types signature
829      * @return the resolved type name
830      * @throws JavaModelException
831      */

832     private static String JavaDoc resolveType(IType type, String JavaDoc typeSignature) throws JavaModelException {
833         int count = Signature.getArrayCount(typeSignature);
834         String JavaDoc elementTypeSignature = Signature.getElementType(typeSignature);
835         if (elementTypeSignature.length() == 1) {
836             // no need to resolve primitive types
837
return typeSignature;
838         }
839         String JavaDoc elementTypeName = Signature.toString(elementTypeSignature);
840         String JavaDoc[][] resolvedElementTypeNames = type.resolveType(elementTypeName);
841         if (resolvedElementTypeNames == null || resolvedElementTypeNames.length != 1) {
842             // check if type parameter
843
ITypeParameter[] typeParameters = type.getTypeParameters();
844             for (int i = 0; i < typeParameters.length; i++) {
845                 ITypeParameter parameter = typeParameters[i];
846                 if (parameter.getElementName().equals(elementTypeName)) {
847                     String JavaDoc[] bounds = parameter.getBounds();
848                     if (bounds.length == 0) {
849                         return "Ljava/lang/Object;"; //$NON-NLS-1$
850
} else {
851                         String JavaDoc bound = Signature.createTypeSignature(bounds[0], false);
852                         return resolveType(type, bound);
853                     }
854                 }
855             }
856             // the type name cannot be resolved
857
return null;
858         }
859
860         String JavaDoc[] types = resolvedElementTypeNames[0];
861         types[1] = types[1].replace('.', '$');
862         
863         String JavaDoc resolvedElementTypeName = Signature.toQualifiedName(types);
864         String JavaDoc resolvedElementTypeSignature = EMPTY_STRING;
865         if(types[0].equals(EMPTY_STRING)) {
866             resolvedElementTypeName = resolvedElementTypeName.substring(1);
867             resolvedElementTypeSignature = Signature.createTypeSignature(resolvedElementTypeName, true);
868         }
869         else {
870             resolvedElementTypeSignature = Signature.createTypeSignature(resolvedElementTypeName, true).replace('.', '/');
871         }
872
873         return Signature.createArraySignature(resolvedElementTypeSignature, count);
874     }
875
876     /**
877      * Returns the resource associated with the specified editor part
878      * @param editor the currently active editor part
879      * @return the corresponding <code>IResource</code> from the editor part
880      */

881     protected static IResource getResource(IEditorPart editor) {
882         IEditorInput editorInput = editor.getEditorInput();
883         IResource resource = (IResource) editorInput.getAdapter(IFile.class);
884         if (resource == null) {
885             resource = ResourcesPlugin.getWorkspace().getRoot();
886         }
887         return resource;
888     }
889
890     /**
891      * Returns a handle to the specified method or <code>null</code> if none.
892      *
893      * @param editorPart
894      * the editor containing the method
895      * @param typeName
896      * @param methodName
897      * @param signature
898      * @return handle or <code>null</code>
899      */

900     protected IMethod getMethodHandle(IEditorPart editorPart, String JavaDoc typeName, String JavaDoc methodName, String JavaDoc signature) throws CoreException {
901         IJavaElement element = (IJavaElement) editorPart.getEditorInput().getAdapter(IJavaElement.class);
902         IType type = null;
903         if (element instanceof ICompilationUnit) {
904             IType[] types = ((ICompilationUnit) element).getAllTypes();
905             for (int i = 0; i < types.length; i++) {
906                 if (types[i].getFullyQualifiedName().equals(typeName)) {
907                     type = types[i];
908                     break;
909                 }
910             }
911         } else if (element instanceof IClassFile) {
912             type = ((IClassFile) element).getType();
913         }
914         if (type != null) {
915             String JavaDoc[] sigs = Signature.getParameterTypes(signature);
916             return type.getMethod(methodName, sigs);
917         }
918         return null;
919     }
920
921     /**
922      * Returns the <code>IJavaBreakpoint</code> from the specified <code>IMember</code>
923      * @param element the element to get the breakpoint from
924      * @return the current breakpoint from the element or <code>null</code>
925      */

926     protected IJavaBreakpoint getMethodBreakpoint(IMember element) {
927         IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
928         IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
929         if (element instanceof IMethod) {
930             IMethod method = (IMethod) element;
931             for (int i = 0; i < breakpoints.length; i++) {
932                 IBreakpoint breakpoint = breakpoints[i];
933                 if (breakpoint instanceof IJavaMethodBreakpoint) {
934                     IJavaMethodBreakpoint methodBreakpoint = (IJavaMethodBreakpoint) breakpoint;
935                     IMember container = null;
936                     try {
937                         container = BreakpointUtils.getMember(methodBreakpoint);
938                     } catch (CoreException e) {
939                         JDIDebugUIPlugin.log(e);
940                         return null;
941                     }
942                     if (container == null) {
943                         try {
944                             if (method.getDeclaringType().getFullyQualifiedName().equals(methodBreakpoint.getTypeName()) &&
945                                     method.getElementName().equals(methodBreakpoint.getMethodName()) &&
946                                     methodBreakpoint.getMethodSignature().equals(resolveMethodSignature(method.getDeclaringType(), method.getSignature()))) {
947                                 return methodBreakpoint;
948                             }
949                         } catch (CoreException e) {
950                             JDIDebugUIPlugin.log(e);
951                         }
952                     } else {
953                         if (container instanceof IMethod) {
954                             if(method.getDeclaringType().equals(container.getDeclaringType())) {
955                                 if (method.getDeclaringType().getFullyQualifiedName().equals(container.getDeclaringType().getFullyQualifiedName())) {
956                                     if (method.isSimilar((IMethod) container)) {
957                                         return methodBreakpoint;
958                                     }
959                                 }
960                             }
961                         }
962                     }
963                 }
964             }
965         }
966         return null;
967     }
968
969     /**
970      * Returns the compilation unit from the editor
971      * @param editor the editor to get the compilation unit from
972      * @return the compilation unit or <code>null</code>
973      * @throws CoreException
974      */

975     protected CompilationUnit parseCompilationUnit(ITextEditor editor) throws CoreException {
976         IEditorInput editorInput = editor.getEditorInput();
977         IDocumentProvider documentProvider = editor.getDocumentProvider();
978         if (documentProvider == null) {
979             throw new CoreException(Status.CANCEL_STATUS);
980         }
981         IDocument document = documentProvider.getDocument(editorInput);
982         ASTParser parser = ASTParser.newParser(AST.JLS3);
983         parser.setSource(document.get().toCharArray());
984         return (CompilationUnit) parser.createAST(null);
985     }
986
987     /*
988      * (non-Javadoc)
989      *
990      * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints(org.eclipse.ui.IWorkbenchPart,
991      * org.eclipse.jface.viewers.ISelection)
992      */

993     public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
994         if (isRemote(part, selection)) {
995             return false;
996         }
997         if (selection instanceof IStructuredSelection) {
998             IStructuredSelection ss = (IStructuredSelection) selection;
999             return isFields(ss);
1000        }
1001        return (selection instanceof ITextSelection) && isField((ITextSelection) selection, part);
1002    }
1003    
1004    /**
1005     * Returns a selection of the member in the given text selection, or the
1006     * original selection if none.
1007     *
1008     * @param part
1009     * @param selection
1010     * @return a structured selection of the member in the given text selection,
1011     * or the original selection if none
1012     * @exception CoreException
1013     * if an exception occurs
1014     */

1015    protected ISelection translateToMembers(IWorkbenchPart part, ISelection selection) throws CoreException {
1016        ITextEditor textEditor = getTextEditor(part);
1017        if (textEditor != null && selection instanceof ITextSelection) {
1018            ITextSelection textSelection = (ITextSelection) selection;
1019            IEditorInput editorInput = textEditor.getEditorInput();
1020            IDocumentProvider documentProvider = textEditor.getDocumentProvider();
1021            if (documentProvider == null) {
1022                throw new CoreException(Status.CANCEL_STATUS);
1023            }
1024            IDocument document = documentProvider.getDocument(editorInput);
1025            int offset = textSelection.getOffset();
1026            if (document != null) {
1027                try {
1028                    IRegion region = document.getLineInformationOfOffset(offset);
1029                    int end = region.getOffset() + region.getLength();
1030                    while (Character.isWhitespace(document.getChar(offset)) && offset < end) {
1031                        offset++;
1032                    }
1033                } catch (BadLocationException e) {}
1034            }
1035            IMember m = null;
1036            IClassFile classFile = (IClassFile) editorInput.getAdapter(IClassFile.class);
1037            if (classFile != null) {
1038                IJavaElement e = classFile.getElementAt(offset);
1039                if (e instanceof IMember) {
1040                    m = (IMember) e;
1041                }
1042            } else {
1043                IWorkingCopyManager manager = JavaUI.getWorkingCopyManager();
1044                ICompilationUnit unit = manager.getWorkingCopy(editorInput);
1045                if (unit != null) {
1046                    synchronized (unit) {
1047                        unit.reconcile(ICompilationUnit.NO_AST , false, null, null);
1048                    }
1049                }
1050                else {
1051                    unit = DebugWorkingCopyManager.getWorkingCopy(editorInput, false);
1052                    if(unit != null) {
1053                        synchronized (unit) {
1054                            unit.reconcile(ICompilationUnit.NO_AST, false, null, null);
1055                        }
1056                    }
1057                }
1058                IJavaElement e = unit.getElementAt(offset);
1059                if (e instanceof IMember) {
1060                    m = (IMember) e;
1061                }
1062            }
1063            if (m != null) {
1064                return new StructuredSelection(m);
1065            }
1066        }
1067        return selection;
1068    }
1069
1070    /**
1071     * Return the associated IField (Java model) for the given
1072     * IJavaFieldVariable (JDI model)
1073     */

1074    private IField getField(IJavaFieldVariable variable) throws CoreException {
1075        String JavaDoc varName = null;
1076        try {
1077            varName = variable.getName();
1078        } catch (DebugException x) {
1079            JDIDebugUIPlugin.log(x);
1080            return null;
1081        }
1082        IField field;
1083        IJavaType declaringType = variable.getDeclaringType();
1084        IType type = JavaDebugUtils.resolveType(declaringType);
1085        if (type != null) {
1086            field = type.getField(varName);
1087            if (field.exists()) {
1088                return field;
1089            }
1090        }
1091        return null;
1092    }
1093
1094    /*
1095     * (non-Javadoc)
1096     *
1097     * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#toggleBreakpoints(org.eclipse.ui.IWorkbenchPart,
1098     * org.eclipse.jface.viewers.ISelection)
1099     */

1100    public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
1101        ISelection sel = translateToMembers(part, selection);
1102        if(sel instanceof IStructuredSelection) {
1103            IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement();
1104            int mtype = member.getElementType();
1105            if(mtype == IJavaElement.FIELD || mtype == IJavaElement.METHOD) {
1106                // remove line breakpoint if present first
1107
if (selection instanceof ITextSelection) {
1108                    ITextSelection ts = (ITextSelection) selection;
1109                    IType declaringType = member.getDeclaringType();
1110                    IResource resource = BreakpointUtils.getBreakpointResource(declaringType);
1111                    IJavaLineBreakpoint breakpoint = JDIDebugModel.lineBreakpointExists(resource, createQualifiedTypeName(declaringType), ts.getStartLine() + 1);
1112                    if (breakpoint != null) {
1113                        breakpoint.delete();
1114                        return;
1115                    }
1116                    CompilationUnit unit = parseCompilationUnit(getTextEditor(part));
1117                    ValidBreakpointLocationLocator loc = new ValidBreakpointLocationLocator(unit, ts.getStartLine()+1, true, true);
1118                    unit.accept(loc);
1119                    if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_METHOD) {
1120                        toggleMethodBreakpoints(part, sel);
1121                    }
1122                    else if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_FIELD) {
1123                        toggleWatchpoints(part, ts);
1124                    }
1125                    else if(loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_LINE) {
1126                        toggleLineBreakpoints(part, ts);
1127                    }
1128                }
1129            }
1130            else if(member.getElementType() == IJavaElement.TYPE) {
1131                toggleClassBreakpoints(part, sel);
1132            }
1133            else {
1134                //fall back to old behavior, always create a line breakpoint
1135
toggleLineBreakpoints(part, selection, true);
1136            }
1137        }
1138    }
1139
1140    /*
1141     * (non-Javadoc)
1142     *
1143     * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#canToggleBreakpoints(org.eclipse.ui.IWorkbenchPart,
1144     * org.eclipse.jface.viewers.ISelection)
1145     */

1146    public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
1147        if (isRemote(part, selection)) {
1148            return false;
1149        }
1150        return canToggleLineBreakpoints(part, selection);
1151    }
1152}
1153
Popular Tags