KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > propertypages > ExceptionFilterEditor


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.propertypages;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.jdt.core.IJavaElement;
18 import org.eclipse.jdt.core.IType;
19 import org.eclipse.jdt.core.JavaModelException;
20 import org.eclipse.jdt.core.search.SearchEngine;
21 import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
22 import org.eclipse.jdt.internal.debug.ui.ExceptionHandler;
23 import org.eclipse.jdt.internal.debug.ui.Filter;
24 import org.eclipse.jdt.internal.debug.ui.FilterLabelProvider;
25 import org.eclipse.jdt.internal.debug.ui.FilterViewerComparator;
26 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
27 import org.eclipse.jdt.ui.IJavaElementSearchConstants;
28 import org.eclipse.jdt.ui.JavaUI;
29 import org.eclipse.jface.dialogs.Dialog;
30 import org.eclipse.jface.dialogs.IDialogConstants;
31 import org.eclipse.jface.viewers.CheckStateChangedEvent;
32 import org.eclipse.jface.viewers.CheckboxTableViewer;
33 import org.eclipse.jface.viewers.ColumnLayoutData;
34 import org.eclipse.jface.viewers.ColumnWeightData;
35 import org.eclipse.jface.viewers.ICheckStateListener;
36 import org.eclipse.jface.viewers.ISelection;
37 import org.eclipse.jface.viewers.ISelectionChangedListener;
38 import org.eclipse.jface.viewers.IStructuredContentProvider;
39 import org.eclipse.jface.viewers.IStructuredSelection;
40 import org.eclipse.jface.viewers.SelectionChangedEvent;
41 import org.eclipse.jface.viewers.TableLayout;
42 import org.eclipse.jface.viewers.Viewer;
43 import org.eclipse.swt.SWT;
44 import org.eclipse.swt.custom.TableEditor;
45 import org.eclipse.swt.events.FocusAdapter;
46 import org.eclipse.swt.events.FocusEvent;
47 import org.eclipse.swt.events.KeyAdapter;
48 import org.eclipse.swt.events.KeyEvent;
49 import org.eclipse.swt.events.SelectionAdapter;
50 import org.eclipse.swt.events.SelectionEvent;
51 import org.eclipse.swt.events.SelectionListener;
52 import org.eclipse.swt.graphics.Font;
53 import org.eclipse.swt.graphics.FontMetrics;
54 import org.eclipse.swt.graphics.GC;
55 import org.eclipse.swt.layout.GridData;
56 import org.eclipse.swt.layout.GridLayout;
57 import org.eclipse.swt.widgets.Button;
58 import org.eclipse.swt.widgets.Composite;
59 import org.eclipse.swt.widgets.Event;
60 import org.eclipse.swt.widgets.Label;
61 import org.eclipse.swt.widgets.Listener;
62 import org.eclipse.swt.widgets.Shell;
63 import org.eclipse.swt.widgets.Table;
64 import org.eclipse.swt.widgets.TableColumn;
65 import org.eclipse.swt.widgets.TableItem;
66 import org.eclipse.swt.widgets.Text;
67 import org.eclipse.ui.PlatformUI;
68 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
69 import org.eclipse.ui.dialogs.SelectionDialog;
70
71
72 public class ExceptionFilterEditor {
73
74     protected static final String JavaDoc DEFAULT_PACKAGE = "(default package)"; //$NON-NLS-1$
75
private IJavaExceptionBreakpoint fBreakpoint;
76     private Button fAddFilterButton;
77     private Button fAddPackageButton;
78     private Button fAddTypeButton;
79     private Button fRemoveFilterButton;
80     private Text fEditorText;
81     private String JavaDoc fInvalidEditorText = null;
82     private TableEditor fTableEditor;
83     private TableItem fNewTableItem;
84     private Filter fNewFilter;
85     private CheckboxTableViewer fFilterViewer;
86     private Table fFilterTable;
87     private FilterContentProvider fFilterContentProvider;
88     
89     private SelectionListener fSelectionListener= new SelectionAdapter() {
90         public void widgetSelected(SelectionEvent e) {
91             Object JavaDoc source = e.getSource();
92             if (source == fAddTypeButton) {
93                 addType();
94             } else if (source == fAddPackageButton) {
95                 addPackage();
96             } else if (source == fAddFilterButton) {
97                 editFilter();
98             } else if (source == fRemoveFilterButton) {
99                 removeFilters();
100             }
101         }
102     };
103
104     public ExceptionFilterEditor(Composite parent, JavaExceptionBreakpointAdvancedPage page) {
105         fBreakpoint = (IJavaExceptionBreakpoint) page.getBreakpoint();
106         // top level container
107
Composite outer = new Composite(parent, SWT.NONE);
108         GridLayout layout = new GridLayout();
109         layout.numColumns = 2;
110         layout.marginHeight = 0;
111         layout.marginWidth = 0;
112
113         outer.setLayout(layout);
114         GridData gd = new GridData(GridData.FILL_BOTH);
115         outer.setLayoutData(gd);
116         outer.setFont(parent.getFont());
117         // filter table
118
Label label= new Label(outer, SWT.NONE);
119         label.setText(PropertyPageMessages.ExceptionFilterEditor_5);
120         label.setFont(parent.getFont());
121         gd= new GridData();
122         gd.horizontalSpan= 2;
123         label.setLayoutData(gd);
124         
125         fFilterTable = new Table(outer, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
126
127         TableLayout tableLayout = new TableLayout();
128         ColumnLayoutData[] columnLayoutData = new ColumnLayoutData[1];
129         columnLayoutData[0] = new ColumnWeightData(100);
130         tableLayout.addColumnData(columnLayoutData[0]);
131         fFilterTable.setLayout(tableLayout);
132         fFilterTable.setFont(parent.getFont());
133         new TableColumn(fFilterTable, SWT.NONE);
134
135         fFilterViewer = new CheckboxTableViewer(fFilterTable);
136         fTableEditor = new TableEditor(fFilterTable);
137         fFilterViewer.setLabelProvider(new FilterLabelProvider());
138         fFilterViewer.setComparator(new FilterViewerComparator());
139         fFilterContentProvider = new FilterContentProvider(fFilterViewer);
140         fFilterViewer.setContentProvider(fFilterContentProvider);
141         // input just needs to be non-null
142
fFilterViewer.setInput(this);
143         gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
144         gd.widthHint = 100;
145         gd.heightHint = 100;
146         fFilterViewer.getTable().setLayoutData(gd);
147         fFilterViewer.addCheckStateListener(new ICheckStateListener() {
148             public void checkStateChanged(CheckStateChangedEvent event) {
149                 Filter filter = (Filter) event.getElement();
150                 fFilterContentProvider.toggleFilter(filter);
151             }
152         });
153         fFilterViewer.addSelectionChangedListener(new ISelectionChangedListener() {
154             public void selectionChanged(SelectionChangedEvent event) {
155                 ISelection selection = event.getSelection();
156                 if (selection.isEmpty()) {
157                     fRemoveFilterButton.setEnabled(false);
158                 } else {
159                     fRemoveFilterButton.setEnabled(true);
160                 }
161             }
162         });
163         fFilterViewer.getTable().addKeyListener(new KeyAdapter() {
164             public void keyPressed(KeyEvent event) {
165                 if (event.character == SWT.DEL && event.stateMask == 0) {
166                     removeFilters();
167                 }
168             }
169         });
170
171         createFilterButtons(outer);
172     }
173
174     protected void doStore() {
175         Object JavaDoc[] filters = fFilterContentProvider.getElements(null);
176         List JavaDoc inclusionFilters = new ArrayList JavaDoc(filters.length);
177         List JavaDoc exclusionFilters = new ArrayList JavaDoc(filters.length);
178         for (int i = 0; i < filters.length; i++) {
179             Filter filter = (Filter) filters[i];
180             String JavaDoc name = filter.getName();
181             if (name.equals(DEFAULT_PACKAGE)) {
182                 name = ""; //$NON-NLS-1$
183
}
184             if (filter.isChecked()) {
185                 inclusionFilters.add(name);
186             } else {
187                 exclusionFilters.add(name);
188             }
189         }
190         try {
191             fBreakpoint.setInclusionFilters((String JavaDoc[]) inclusionFilters.toArray(new String JavaDoc[inclusionFilters.size()]));
192             fBreakpoint.setExclusionFilters((String JavaDoc[]) exclusionFilters.toArray(new String JavaDoc[exclusionFilters.size()]));
193         } catch (CoreException ce) {
194             JDIDebugUIPlugin.log(ce);
195         }
196
197     }
198
199     private void createFilterButtons(Composite container) {
200         // button container
201
Font font= container.getFont();
202         Composite buttonContainer = new Composite(container, SWT.NONE);
203         buttonContainer.setFont(font);
204         GridData gd = new GridData(GridData.FILL_VERTICAL);
205         buttonContainer.setLayoutData(gd);
206         GridLayout buttonLayout = new GridLayout();
207         buttonLayout.numColumns = 1;
208         buttonLayout.marginHeight = 0;
209         buttonLayout.marginWidth = 0;
210         buttonContainer.setLayout(buttonLayout);
211
212         fAddFilterButton = createPushButton(buttonContainer,
213                 PropertyPageMessages.ExceptionFilterEditor_6,
214                 PropertyPageMessages.ExceptionFilterEditor_7);
215         fAddTypeButton = createPushButton(buttonContainer,
216                 PropertyPageMessages.ExceptionFilterEditor_8,
217                 PropertyPageMessages.ExceptionFilterEditor_9);
218         fAddPackageButton = createPushButton(buttonContainer,
219                 PropertyPageMessages.ExceptionFilterEditor_10,
220                 PropertyPageMessages.ExceptionFilterEditor_11);
221         fRemoveFilterButton = createPushButton(buttonContainer,
222                 PropertyPageMessages.ExceptionFilterEditor_12,
223                 PropertyPageMessages.ExceptionFilterEditor_13);
224         fRemoveFilterButton.setEnabled(false);
225     }
226     
227     /**
228      * Creates a fully configured push button with the given label and tooltip.
229      */

230     private Button createPushButton(Composite parent, String JavaDoc text, String JavaDoc tooltipText) {
231         Button button = new Button(parent, SWT.PUSH);
232         button.setFont(parent.getFont());
233         button.setText(text);
234         button.setToolTipText(tooltipText);
235         GridData gd = getButtonGridData(button);
236         button.setLayoutData(gd);
237         button.addSelectionListener(fSelectionListener);
238         return button;
239     }
240
241     private static GridData getButtonGridData(Button button) {
242         GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
243         GC gc = new GC(button);
244         gc.setFont(button.getFont());
245         FontMetrics fontMetrics = gc.getFontMetrics();
246         gc.dispose();
247         int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_WIDTH);
248         gd.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
249         return gd;
250     }
251
252     /**
253      * Create a new filter in the table (with the default 'new filter' value),
254      * then open up an in-place editor on it.
255      */

256     private void editFilter() {
257         // if a previous edit is still in progress, finish it
258
if (fEditorText != null) {
259             validateChangeAndCleanup();
260         }
261
262         fNewFilter = fFilterContentProvider.addFilter(""); //$NON-NLS-1$
263
fNewTableItem = fFilterTable.getItem(0);
264
265         // create & configure Text widget for editor
266
// Fix for bug 1766. Border behavior on for text fields varies per platform.
267
// On Motif, you always get a border, on other platforms,
268
// you don't. Specifying a border on Motif results in the characters
269
// getting pushed down so that only there very tops are visible. Thus,
270
// we have to specify different style constants for the different platforms.
271
int textStyles = SWT.SINGLE | SWT.LEFT;
272         if (!SWT.getPlatform().equals("motif")) { //$NON-NLS-1$
273
textStyles |= SWT.BORDER;
274         }
275         fEditorText = new Text(fFilterTable, textStyles);
276         GridData gd = new GridData(GridData.FILL_BOTH);
277         fEditorText.setLayoutData(gd);
278
279         // set the editor
280
fTableEditor.horizontalAlignment = SWT.LEFT;
281         fTableEditor.grabHorizontal = true;
282         fTableEditor.setEditor(fEditorText, fNewTableItem, 0);
283
284         // get the editor ready to use
285
fEditorText.setText(fNewFilter.getName());
286         fEditorText.selectAll();
287         setEditorListeners(fEditorText);
288         fEditorText.setFocus();
289     }
290
291     private void setEditorListeners(Text text) {
292         // CR means commit the changes, ESC means abort and don't commit
293
text.addKeyListener(new KeyAdapter() {
294             public void keyReleased(KeyEvent event) {
295                 if (event.character == SWT.CR) {
296                     if (fInvalidEditorText != null) {
297                         fEditorText.setText(fInvalidEditorText);
298                         fInvalidEditorText = null;
299                     } else {
300                         validateChangeAndCleanup();
301                     }
302                 } else if (event.character == SWT.ESC) {
303                     removeNewFilter();
304                     cleanupEditor();
305                 }
306             }
307         });
308         // Consider loss of focus on the editor to mean the same as CR
309
text.addFocusListener(new FocusAdapter() {
310             public void focusLost(FocusEvent event) {
311                 if (fInvalidEditorText != null) {
312                     fEditorText.setText(fInvalidEditorText);
313                     fInvalidEditorText = null;
314                 } else {
315                     validateChangeAndCleanup();
316                 }
317             }
318         });
319         // Consume traversal events from the text widget so that CR doesn't
320
// traverse away to dialog's default button. Without this, hitting
321
// CR in the text field closes the entire dialog.
322
text.addListener(SWT.Traverse, new Listener() {
323             public void handleEvent(Event event) {
324                 event.doit = false;
325             }
326         });
327     }
328
329     private void validateChangeAndCleanup() {
330         String JavaDoc trimmedValue = fEditorText.getText().trim();
331         // if the new value is blank, remove the filter
332
if (trimmedValue.length() < 1) {
333             removeNewFilter();
334         }
335         // if it's invalid, beep and leave sitting in the editor
336
else if (!validateEditorInput(trimmedValue)) {
337             fInvalidEditorText = trimmedValue;
338             fEditorText.setText(PropertyPageMessages.ExceptionFilterEditor_14);
339             fEditorText.getDisplay().beep();
340             return;
341             // otherwise, commit the new value if not a duplicate
342
} else {
343             Object JavaDoc[] filters = fFilterContentProvider.getElements(null);
344             for (int i = 0; i < filters.length; i++) {
345                 Filter filter = (Filter) filters[i];
346                 if (filter.getName().equals(trimmedValue)) {
347                     removeNewFilter();
348                     cleanupEditor();
349                     return;
350                 }
351             }
352             fNewTableItem.setText(trimmedValue);
353             fNewFilter.setName(trimmedValue);
354             fFilterViewer.refresh();
355         }
356         cleanupEditor();
357     }
358
359     /**
360      * A valid filter is simply one that is a valid Java identifier.
361      * and, as defined in the JDI spec, the regular expressions used for
362      * scoping must be limited to exact matches or patterns that
363      * begin with '*' or end with '*'. Beyond this, a string cannot be validated
364      * as corresponding to an existing type or package (and this is probably not
365      * even desirable).
366      */

367     private boolean validateEditorInput(String JavaDoc trimmedValue) {
368         char firstChar = trimmedValue.charAt(0);
369         if (!Character.isJavaIdentifierStart(firstChar)) {
370             if (!(firstChar == '*')) {
371                 return false;
372             }
373         }
374         int length = trimmedValue.length();
375         for (int i = 1; i < length; i++) {
376             char c = trimmedValue.charAt(i);
377             if (!Character.isJavaIdentifierPart(c)) {
378                 if (c == '.' && i != (length - 1)) {
379                     continue;
380                 }
381                 if (c == '*' && i == (length - 1)) {
382                     continue;
383                 }
384                 return false;
385             }
386         }
387         return true;
388     }
389
390     /**
391      * Cleanup all widgetry & resources used by the in-place editing
392      */

393     private void cleanupEditor() {
394         if (fEditorText != null) {
395             fNewFilter = null;
396             fNewTableItem = null;
397             fTableEditor.setEditor(null, null, 0);
398             fEditorText.getDisplay().asyncExec(new Runnable JavaDoc() {
399                 public void run() {
400                     fEditorText.dispose();
401                     fEditorText = null;
402                 }
403             });
404         }
405     }
406
407     private void removeFilters() {
408         IStructuredSelection selection = (IStructuredSelection) fFilterViewer.getSelection();
409         fFilterContentProvider.removeFilters(selection.toArray());
410     }
411
412     private void removeNewFilter() {
413         fFilterContentProvider.removeFilters(new Object JavaDoc[] { fNewFilter });
414     }
415
416     private void addPackage() {
417         Shell shell = fAddPackageButton.getDisplay().getActiveShell();
418         ElementListSelectionDialog dialog = null;
419         try {
420             dialog = JDIDebugUIPlugin.createAllPackagesDialog(shell, null, false);
421         } catch (JavaModelException jme) {
422             String JavaDoc title = PropertyPageMessages.ExceptionFilterEditor_15;
423             String JavaDoc message = PropertyPageMessages.ExceptionFilterEditor_16;
424             ExceptionHandler.handle(jme, title, message);
425             return;
426         }
427         if (dialog == null) {
428             return;
429         }
430         dialog.setTitle(PropertyPageMessages.ExceptionFilterEditor_15);
431         dialog.setMessage(PropertyPageMessages.ExceptionFilterEditor_18);
432         dialog.setMultipleSelection(true);
433         if (dialog.open() == IDialogConstants.CANCEL_ID) {
434             return;
435         }
436         Object JavaDoc[] packages = dialog.getResult();
437         if (packages != null) {
438             for (int i = 0; i < packages.length; i++) {
439                 IJavaElement pkg = (IJavaElement) packages[i];
440                 String JavaDoc filter = pkg.getElementName();
441                 if (filter.length() < 1) {
442                     filter = DEFAULT_PACKAGE;
443                 } else {
444                     filter += ".*"; //$NON-NLS-1$
445
}
446                 Filter f = fFilterContentProvider.addFilter(filter);
447                 fFilterContentProvider.checkFilter(f, true);
448             }
449         }
450     }
451
452     private void addType() {
453         Shell shell = fAddTypeButton.getDisplay().getActiveShell();
454         SelectionDialog dialog = null;
455         try {
456             dialog = JavaUI.createTypeDialog(shell, PlatformUI.getWorkbench().getProgressService(), SearchEngine.createWorkspaceScope(), IJavaElementSearchConstants.CONSIDER_CLASSES, false);
457         } catch (JavaModelException jme) {
458             String JavaDoc title = PropertyPageMessages.ExceptionFilterEditor_19;
459             String JavaDoc message = PropertyPageMessages.ExceptionFilterEditor_20;
460             ExceptionHandler.handle(jme, title, message);
461             return;
462         }
463
464         dialog.setTitle(PropertyPageMessages.ExceptionFilterEditor_19);
465         dialog.setMessage(PropertyPageMessages.ExceptionFilterEditor_22);
466         if (dialog.open() == IDialogConstants.CANCEL_ID) {
467             return;
468         }
469
470         Object JavaDoc[] types = dialog.getResult();
471         IType type;
472         if (types != null) {
473             for (int i = 0; i < types.length; i++) {
474                 type = (IType) types[i];
475                 Filter f = fFilterContentProvider.addFilter(type.getFullyQualifiedName());
476                 fFilterContentProvider.checkFilter(f, true);
477             }
478         }
479     }
480
481     /**
482      * Content provider for the table. Content consists of instances of Filter.
483      */

484     protected class FilterContentProvider implements IStructuredContentProvider {
485
486         private CheckboxTableViewer fViewer;
487         private List JavaDoc fFilters;
488
489         public FilterContentProvider(CheckboxTableViewer viewer) {
490             fViewer = viewer;
491             populateFilters();
492         }
493
494         protected void populateFilters() {
495             String JavaDoc[] iFilters = null;
496             String JavaDoc[] eFilters = null;
497             try {
498                 iFilters = fBreakpoint.getInclusionFilters();
499                 eFilters = fBreakpoint.getExclusionFilters();
500             } catch (CoreException ce) {
501                 JDIDebugUIPlugin.log(ce);
502                 iFilters = new String JavaDoc[] {
503                 };
504                 eFilters = new String JavaDoc[] {
505                 };
506             }
507             fFilters = new ArrayList JavaDoc();
508             populateFilters(iFilters, true);
509             populateFilters(eFilters, false);
510
511         }
512
513         protected void populateFilters(String JavaDoc[] filters, boolean checked) {
514             for (int i = 0; i < filters.length; i++) {
515                 String JavaDoc name = filters[i];
516                 if (name.length() == 0) {
517                     name = DEFAULT_PACKAGE;
518                 }
519                 Filter filter = addFilter(name);
520                 checkFilter(filter, checked);
521             }
522         }
523
524         public Filter addFilter(String JavaDoc name) {
525             Filter filter = new Filter(name, false);
526             if (!fFilters.contains(filter)) {
527                 fFilters.add(filter);
528                 fViewer.add(filter);
529             }
530             return filter;
531         }
532
533         public void removeFilters(Object JavaDoc[] filters) {
534             for (int i = 0; i < filters.length; i++) {
535                 Filter filter = (Filter) filters[i];
536                 fFilters.remove(filter);
537             }
538             fViewer.remove(filters);
539         }
540
541         public void toggleFilter(Filter filter) {
542             boolean newState = !filter.isChecked();
543             filter.setChecked(newState);
544             fViewer.setChecked(filter, newState);
545         }
546
547         public void checkFilter(Filter filter, boolean checked) {
548             filter.setChecked(checked);
549             fViewer.setChecked(filter, checked);
550         }
551
552         /**
553          * @see IStructuredContentProvider#getElements(Object)
554          */

555         public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
556             return fFilters.toArray();
557         }
558
559         /**
560          * @see IContentProvider#inputChanged(Viewer, Object, Object)
561          */

562         public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
563         }
564
565         /**
566          * @see IContentProvider#dispose()
567          */

568         public void dispose() {
569         }
570     }
571
572 }
573
Popular Tags