KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > dialogs > FilteredTypesSelectionDialog


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.ui.dialogs;
12
13 import java.io.IOException JavaDoc;
14 import java.io.StringReader JavaDoc;
15 import java.io.StringWriter JavaDoc;
16 import java.lang.reflect.InvocationTargetException JavaDoc;
17 import java.text.MessageFormat JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Comparator JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.core.runtime.SubProgressMonitor;
30 import org.eclipse.core.runtime.jobs.IJobManager;
31 import org.eclipse.core.runtime.jobs.Job;
32
33 import org.eclipse.swt.graphics.Color;
34 import org.eclipse.swt.graphics.Image;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Control;
38 import org.eclipse.swt.widgets.Display;
39 import org.eclipse.swt.widgets.Item;
40 import org.eclipse.swt.widgets.Shell;
41 import org.eclipse.swt.widgets.Table;
42 import org.eclipse.swt.widgets.Text;
43
44 import org.eclipse.jface.action.Action;
45 import org.eclipse.jface.action.IAction;
46 import org.eclipse.jface.action.IMenuManager;
47 import org.eclipse.jface.action.Separator;
48 import org.eclipse.jface.dialogs.IDialogSettings;
49 import org.eclipse.jface.dialogs.MessageDialog;
50 import org.eclipse.jface.operation.IRunnableContext;
51 import org.eclipse.jface.operation.IRunnableWithProgress;
52 import org.eclipse.jface.resource.ImageDescriptor;
53 import org.eclipse.jface.util.IPropertyChangeListener;
54 import org.eclipse.jface.util.PropertyChangeEvent;
55 import org.eclipse.jface.viewers.ILabelDecorator;
56 import org.eclipse.jface.viewers.ISelection;
57 import org.eclipse.jface.viewers.LabelProvider;
58 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
59
60 import org.eclipse.jface.text.ITextSelection;
61
62 import org.eclipse.ui.IMemento;
63 import org.eclipse.ui.IWorkbenchWindow;
64 import org.eclipse.ui.IWorkingSet;
65 import org.eclipse.ui.PlatformUI;
66 import org.eclipse.ui.WorkbenchException;
67 import org.eclipse.ui.XMLMemento;
68 import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
69 import org.eclipse.ui.dialogs.ISelectionStatusValidator;
70 import org.eclipse.ui.dialogs.PreferencesUtil;
71 import org.eclipse.ui.dialogs.SearchPattern;
72
73 import org.eclipse.jdt.core.Flags;
74 import org.eclipse.jdt.core.IPackageFragmentRoot;
75 import org.eclipse.jdt.core.IType;
76 import org.eclipse.jdt.core.JavaConventions;
77 import org.eclipse.jdt.core.JavaCore;
78 import org.eclipse.jdt.core.JavaModelException;
79 import org.eclipse.jdt.core.WorkingCopyOwner;
80 import org.eclipse.jdt.core.search.IJavaSearchConstants;
81 import org.eclipse.jdt.core.search.IJavaSearchScope;
82 import org.eclipse.jdt.core.search.SearchEngine;
83 import org.eclipse.jdt.core.search.TypeNameMatch;
84 import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
85 import org.eclipse.jdt.core.search.TypeNameRequestor;
86
87 import org.eclipse.jdt.internal.corext.util.Messages;
88 import org.eclipse.jdt.internal.corext.util.OpenTypeHistory;
89 import org.eclipse.jdt.internal.corext.util.Strings;
90 import org.eclipse.jdt.internal.corext.util.TypeFilter;
91 import org.eclipse.jdt.internal.corext.util.TypeInfoRequestorAdapter;
92
93 import org.eclipse.jdt.launching.IVMInstall;
94 import org.eclipse.jdt.launching.IVMInstallType;
95 import org.eclipse.jdt.launching.JavaRuntime;
96 import org.eclipse.jdt.launching.LibraryLocation;
97
98 import org.eclipse.jdt.ui.JavaElementLabels;
99 import org.eclipse.jdt.ui.JavaUI;
100 import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension;
101 import org.eclipse.jdt.ui.dialogs.ITypeInfoImageProvider;
102 import org.eclipse.jdt.ui.dialogs.ITypeSelectionComponent;
103 import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension;
104
105 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
106 import org.eclipse.jdt.internal.ui.JavaPlugin;
107 import org.eclipse.jdt.internal.ui.JavaUIMessages;
108 import org.eclipse.jdt.internal.ui.preferences.TypeFilterPreferencePage;
109 import org.eclipse.jdt.internal.ui.search.JavaSearchScopeFactory;
110 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
111 import org.eclipse.jdt.internal.ui.util.TypeNameMatchLabelProvider;
112 import org.eclipse.jdt.internal.ui.viewsupport.ColoredJavaElementLabels;
113 import org.eclipse.jdt.internal.ui.viewsupport.ColoredString;
114 import org.eclipse.jdt.internal.ui.viewsupport.ColoredViewersManager;
115 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
116 import org.eclipse.jdt.internal.ui.viewsupport.OwnerDrawSupport;
117 import org.eclipse.jdt.internal.ui.workingsets.WorkingSetFilterActionGroup;
118
119 /**
120  * Shows a list of Java types to the user with a text entry field for a string
121  * pattern used to filter the list of types.
122  *
123  * @since 3.3
124  */

125 public class FilteredTypesSelectionDialog extends FilteredItemsSelectionDialog implements ITypeSelectionComponent {
126     
127     /**
128      * Disabled "Show Container for Duplicates because of
129      * https://bugs.eclipse.org/bugs/show_bug.cgi?id=184693 .
130      */

131     private static final boolean BUG_184693= true;
132
133     private static final String JavaDoc DIALOG_SETTINGS= "org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog"; //$NON-NLS-1$
134

135     private static final String JavaDoc SHOW_CONTAINER_FOR_DUPLICATES= "ShowContainerForDuplicates"; //$NON-NLS-1$
136

137     private static final String JavaDoc WORKINGS_SET_SETTINGS= "WorkingSet"; //$NON-NLS-1$
138

139     private WorkingSetFilterActionGroup fFilterActionGroup;
140
141     private final TypeItemLabelProvider fTypeInfoLabelProvider;
142
143     private String JavaDoc fTitle;
144
145     private ShowContainerForDuplicatesAction fShowContainerForDuplicatesAction;
146
147     private IJavaSearchScope fSearchScope;
148     
149     private boolean fAllowScopeSwitching;
150
151     private final int fElementKinds;
152
153     private final ITypeInfoFilterExtension fFilterExtension;
154
155     private final TypeSelectionExtension fExtension;
156
157     private ISelectionStatusValidator fValidator;
158
159     private final TypeInfoUtil fTypeInfoUtil;
160     
161     private static boolean fgFirstTime= true;
162
163     private final TypeItemsComparator fTypeItemsComparator;
164     
165     private int fTypeFilterVersion= 0;
166
167     /**
168      * Creates new FilteredTypesSelectionDialog instance
169      *
170      * @param parent
171      * shell to parent the dialog on
172      * @param multi
173      * <code>true</code> if multiple selection is allowed
174      * @param context
175      * context used to execute long-running operations associated
176      * with this dialog
177      * @param scope
178      * scope used when searching for types
179      * @param elementKinds
180      * flags defining nature of searched elements; the only valid
181      * values are: <code>IJavaSearchConstants.TYPE</code>
182      * <code>IJavaSearchConstants.ANNOTATION_TYPE</code>
183      * <code>IJavaSearchConstants.INTERFACE</code>
184      * <code>IJavaSearchConstants.ENUM</code>
185      * <code>IJavaSearchConstants.CLASS_AND_INTERFACE</code>
186      * <code>IJavaSearchConstants.CLASS_AND_ENUM</code>.
187      * Please note that the bitwise OR combination of the elementary
188      * constants is not supported.
189      */

190     public FilteredTypesSelectionDialog(Shell parent, boolean multi, IRunnableContext context, IJavaSearchScope scope, int elementKinds) {
191         this(parent, multi, context, scope, elementKinds, null);
192     }
193
194     /**
195      * Creates new FilteredTypesSelectionDialog instance.
196      *
197      * @param shell
198      * shell to parent the dialog on
199      * @param multi
200      * <code>true</code> if multiple selection is allowed
201      * @param context
202      * context used to execute long-running operations associated
203      * with this dialog
204      * @param scope
205      * scope used when searching for types. If the scope is <code>null</code>,
206      * then workspace is scope is used as default, and the user can
207      * choose a working set as scope.
208      * @param elementKinds
209      * flags defining nature of searched elements; the only valid
210      * values are: <code>IJavaSearchConstants.TYPE</code>
211      * <code>IJavaSearchConstants.ANNOTATION_TYPE</code>
212      * <code>IJavaSearchConstants.INTERFACE</code>
213      * <code>IJavaSearchConstants.ENUM</code>
214      * <code>IJavaSearchConstants.CLASS_AND_INTERFACE</code>
215      * <code>IJavaSearchConstants.CLASS_AND_ENUM</code>.
216      * Please note that the bitwise OR combination of the elementary
217      * constants is not supported.
218      * @param extension
219      * an extension of the standard type selection dialog; See
220      * {@link TypeSelectionExtension}
221      */

222     public FilteredTypesSelectionDialog(Shell shell, boolean multi, IRunnableContext context, IJavaSearchScope scope, int elementKinds, TypeSelectionExtension extension) {
223         super(shell, multi);
224         
225         setSelectionHistory(new TypeSelectionHistory());
226
227         if (scope == null) {
228             fAllowScopeSwitching= true;
229             scope= SearchEngine.createWorkspaceScope();
230         }
231         PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.TYPE_SELECTION_DIALOG2);
232
233         fElementKinds= elementKinds;
234         fExtension= extension;
235         fFilterExtension= (extension == null) ? null : extension.getFilterExtension();
236         fSearchScope= scope;
237
238         if (extension != null) {
239             fValidator= extension.getSelectionValidator();
240         }
241
242         fTypeInfoUtil= new TypeInfoUtil(extension != null ? extension.getImageProvider() : null);
243
244         fTypeInfoLabelProvider= new TypeItemLabelProvider();
245
246         setListLabelProvider(fTypeInfoLabelProvider);
247         setListSelectionLabelDecorator(fTypeInfoLabelProvider);
248         setDetailsLabelProvider(new TypeItemDetailsLabelProvider(fTypeInfoUtil));
249         
250         fTypeItemsComparator= new TypeItemsComparator();
251     }
252
253     /*
254      * (non-Javadoc)
255      *
256      * @see org.eclipse.ui.dialogs.SelectionDialog#setTitle(java.lang.String)
257      */

258     public void setTitle(String JavaDoc title) {
259         super.setTitle(title);
260         fTitle= title;
261     }
262
263     /**
264      * Adds or replaces subtitle of the dialog
265      *
266      * @param text
267      * the new subtitle for this dialog
268      */

269     private void setSubtitle(String JavaDoc text) {
270         if (text == null || text.length() == 0) {
271             getShell().setText(fTitle);
272         } else {
273             getShell().setText(Messages.format(JavaUIMessages.FilteredTypeSelectionDialog_titleFormat, new String JavaDoc[] { fTitle, text }));
274         }
275     }
276
277     /*
278      * (non-Javadoc)
279      *
280      * @see org.eclipse.ui.dialogs.AbstractSearchDialog#getDialogSettings()
281      */

282     protected IDialogSettings getDialogSettings() {
283         IDialogSettings settings= JavaPlugin.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS);
284
285         if (settings == null) {
286             settings= JavaPlugin.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS);
287         }
288
289         return settings;
290     }
291
292     /*
293      * (non-Javadoc)
294      *
295      * @see org.eclipse.ui.dialogs.AbstractSearchDialog#storeDialog(org.eclipse.jface.dialogs.IDialogSettings)
296      */

297     protected void storeDialog(IDialogSettings settings) {
298         super.storeDialog(settings);
299
300         if (! BUG_184693) {
301             settings.put(SHOW_CONTAINER_FOR_DUPLICATES, fShowContainerForDuplicatesAction.isChecked());
302         }
303
304         if (fFilterActionGroup != null) {
305             XMLMemento memento= XMLMemento.createWriteRoot("workingSet"); //$NON-NLS-1$
306
fFilterActionGroup.saveState(memento);
307             fFilterActionGroup.dispose();
308             StringWriter JavaDoc writer= new StringWriter JavaDoc();
309             try {
310                 memento.save(writer);
311                 settings.put(WORKINGS_SET_SETTINGS, writer.getBuffer().toString());
312             } catch (IOException JavaDoc e) {
313                 // don't do anything. Simply don't store the settings
314
JavaPlugin.log(e);
315             }
316         }
317     }
318
319     /*
320      * (non-Javadoc)
321      *
322      * @see org.eclipse.ui.dialogs.AbstractSearchDialog#restoreDialog(org.eclipse.jface.dialogs.IDialogSettings)
323      */

324     protected void restoreDialog(IDialogSettings settings) {
325         super.restoreDialog(settings);
326
327         if (! BUG_184693) {
328             boolean showContainer= settings.getBoolean(SHOW_CONTAINER_FOR_DUPLICATES);
329             fShowContainerForDuplicatesAction.setChecked(showContainer);
330             fTypeInfoLabelProvider.setContainerInfo(showContainer);
331         } else {
332             fTypeInfoLabelProvider.setContainerInfo(true);
333         }
334         
335         if (fAllowScopeSwitching) {
336             String JavaDoc setting= settings.get(WORKINGS_SET_SETTINGS);
337             if (setting != null) {
338                 try {
339                     IMemento memento= XMLMemento.createReadRoot(new StringReader JavaDoc(setting));
340                     fFilterActionGroup.restoreState(memento);
341                 } catch (WorkbenchException e) {
342                     // don't do anything. Simply don't restore the settings
343
JavaPlugin.log(e);
344                 }
345             }
346             IWorkingSet ws= fFilterActionGroup.getWorkingSet();
347             if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) {
348                 setSearchScope(SearchEngine.createWorkspaceScope());
349                 setSubtitle(null);
350             } else {
351                 setSearchScope(JavaSearchScopeFactory.getInstance().createJavaSearchScope(ws, true));
352                 setSubtitle(ws.getLabel());
353             }
354         }
355
356         // TypeNameMatch[] types = OpenTypeHistory.getInstance().getTypeInfos();
357
//
358
// for (int i = 0; i < types.length; i++) {
359
// TypeNameMatch type = types[i];
360
// accessedHistoryItem(type);
361
// }
362
}
363
364     /*
365      * (non-Javadoc)
366      *
367      * @see org.eclipse.ui.dialogs.AbstractSearchDialog#fillViewMenu(org.eclipse.jface.action.IMenuManager)
368      */

369     protected void fillViewMenu(IMenuManager menuManager) {
370         super.fillViewMenu(menuManager);
371
372         if (! BUG_184693) {
373             fShowContainerForDuplicatesAction= new ShowContainerForDuplicatesAction();
374             menuManager.add(fShowContainerForDuplicatesAction);
375         }
376         if (fAllowScopeSwitching) {
377             fFilterActionGroup= new WorkingSetFilterActionGroup(getShell(), JavaPlugin.getActivePage(), new IPropertyChangeListener() {
378                 public void propertyChange(PropertyChangeEvent event) {
379                     IWorkingSet ws= (IWorkingSet) event.getNewValue();
380                     if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) {
381                         setSearchScope(SearchEngine.createWorkspaceScope());
382                         setSubtitle(null);
383                     } else {
384                         setSearchScope(JavaSearchScopeFactory.getInstance().createJavaSearchScope(ws, true));
385                         setSubtitle(ws.getLabel());
386                     }
387     
388                     applyFilter();
389                 }
390             });
391             fFilterActionGroup.fillViewMenu(menuManager);
392         }
393         
394         menuManager.add(new Separator());
395         menuManager.add(new TypeFiltersPreferencesAction());
396     }
397
398     /*
399      * (non-Javadoc)
400      *
401      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
402      */

403     protected Control createExtendedContentArea(Composite parent) {
404         Control addition= null;
405
406         if (fExtension != null) {
407
408             addition= fExtension.createContentArea(parent);
409             if (addition != null) {
410                 GridData gd= new GridData(GridData.FILL_HORIZONTAL);
411                 gd.horizontalSpan= 2;
412                 addition.setLayoutData(gd);
413
414             }
415             
416             fExtension.initialize(this);
417         }
418
419         return addition;
420     }
421
422     /*
423      * (non-Javadoc)
424      *
425      * @see org.eclipse.ui.dialogs.SelectionDialog#setResult(java.util.List)
426      */

427     protected void setResult(List JavaDoc newResult) {
428
429         List JavaDoc resultToReturn= new ArrayList JavaDoc();
430
431         for (int i= 0; i < newResult.size(); i++) {
432             if (newResult.get(i) instanceof TypeNameMatch) {
433                 IType type= ((TypeNameMatch) newResult.get(i)).getType();
434                 if (type.exists()) {
435                     // items are added to history in the
436
// org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#computeResult()
437
// method
438
resultToReturn.add(type);
439                 } else {
440                     TypeNameMatch typeInfo= (TypeNameMatch) newResult.get(i);
441                     IPackageFragmentRoot root= typeInfo.getPackageFragmentRoot();
442                     String JavaDoc containerName= JavaElementLabels.getElementLabel(root, JavaElementLabels.ROOT_QUALIFIED);
443                     String JavaDoc message= Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_dialogMessage, new String JavaDoc[] { typeInfo.getFullyQualifiedName(), containerName });
444                     MessageDialog.openError(getShell(), fTitle, message);
445                     getSelectionHistory().remove(typeInfo);
446                 }
447             }
448         }
449
450         super.setResult(resultToReturn);
451     }
452
453     /*
454      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#create()
455      */

456     public void create() {
457         super.create();
458         Control patternControl= getPatternControl();
459         if (patternControl instanceof Text) {
460             TextFieldNavigationHandler.install((Text) patternControl);
461         }
462     }
463     
464     /*
465      * (non-Javadoc)
466      *
467      * @see org.eclipse.jface.window.Window#open()
468      */

469     public int open() {
470         if (getInitialPattern() == null) {
471             IWorkbenchWindow window= JavaPlugin.getActiveWorkbenchWindow();
472             if (window != null) {
473                 ISelection selection= window.getSelectionService().getSelection();
474                 if (selection instanceof ITextSelection) {
475                     String JavaDoc text= ((ITextSelection) selection).getText();
476                     if (text != null) {
477                         text= text.trim();
478                         if (text.length() > 0 && JavaConventions.validateJavaTypeName(text, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3).isOK()) {
479                             setInitialPattern(text, FULL_SELECTION);
480                         }
481                     }
482                 }
483             }
484         }
485         return super.open();
486     }
487
488     /**
489      * Sets a new validator.
490      *
491      * @param validator
492      * the new validator
493      */

494     public void setValidator(ISelectionStatusValidator validator) {
495         fValidator= validator;
496     }
497
498     /*
499      * (non-Javadoc)
500      *
501      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
502      */

503     protected ItemsFilter createFilter() {
504         return new TypeItemsFilter(fSearchScope, fElementKinds, fFilterExtension);
505     }
506     
507     protected Control createContents(Composite parent) {
508         Control contents= super.createContents(parent);
509         if (ColoredViewersManager.showColoredLabels()) {
510             if (contents instanceof Composite) {
511                 Table listControl= findTableControl((Composite) contents);
512                 if (listControl != null) {
513                     installOwnerDraw(listControl);
514                 }
515             }
516         }
517         return contents;
518     }
519     
520     private void installOwnerDraw(Table tableControl) {
521         new OwnerDrawSupport(tableControl) { // installs the owner draw listeners
522
public ColoredString getColoredLabel(Item item) {
523                 String JavaDoc text= item.getText();
524                 ColoredString str= new ColoredString(text);
525                 int index= text.indexOf('-');
526                 if (index != -1) {
527                     str.colorize(index, str.length() - index, ColoredJavaElementLabels.QUALIFIER_STYLE);
528                 }
529                 return str;
530             }
531
532             public Color getColor(String JavaDoc foregroundColorName, Display display) {
533                 return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(foregroundColorName);
534             }
535         };
536     }
537
538     private Table findTableControl(Composite composite) {
539         Control[] children= composite.getChildren();
540         for (int i= 0; i < children.length; i++) {
541             Control curr= children[i];
542             if (curr instanceof Table) {
543                 return (Table) curr;
544             } else if (curr instanceof Composite) {
545                 Table res= findTableControl((Composite) curr);
546                 if (res != null) {
547                     return res;
548                 }
549             }
550         }
551         return null;
552     }
553     
554     
555
556     /*
557      * (non-Javadoc)
558      *
559      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider,
560      * org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter,
561      * org.eclipse.core.runtime.IProgressMonitor)
562      */

563     protected void fillContentProvider(AbstractContentProvider provider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException {
564         TypeItemsFilter typeSearchFilter= (TypeItemsFilter) itemsFilter;
565         TypeSearchRequestor requestor= new TypeSearchRequestor(provider, typeSearchFilter);
566         SearchEngine engine= new SearchEngine((WorkingCopyOwner) null);
567         String JavaDoc packPattern= typeSearchFilter.getPackagePattern();
568         progressMonitor.setTaskName(JavaUIMessages.FilteredTypesSelectionDialog_searchJob_taskName);
569         
570         /*
571          * Setting the filter into match everything mode avoids filtering twice
572          * by the same pattern (the search engine only provides filtered
573          * matches). For the case when the pattern is a camel case pattern with
574          * a terminator, the filter is not set to match everything mode because
575          * jdt.core's SearchPattern does not support that case.
576          */

577         String JavaDoc typePattern= itemsFilter.getPattern();
578         int matchRule= typeSearchFilter.getMatchRule();
579         if (matchRule == SearchPattern.RULE_CAMELCASE_MATCH) {
580              // If the pattern is empty, the RULE_BLANK_MATCH will be chosen, so we don't have to check the pattern length
581
char lastChar= typePattern.charAt(typePattern.length() - 1);
582
583             if (lastChar == '<' || lastChar == ' ') {
584                 typePattern= typePattern.substring(0, typePattern.length() - 1);
585             } else {
586                 typeSearchFilter.setMatchEverythingMode(true);
587             }
588         } else {
589             typeSearchFilter.setMatchEverythingMode(true);
590         }
591
592         try {
593             engine.searchAllTypeNames(packPattern == null ? null : packPattern.toCharArray(),
594                     typeSearchFilter.getPackageFlags(), //TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=176017
595
typePattern.toCharArray(),
596                     matchRule, //TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=176017
597
typeSearchFilter.getElementKind(),
598                     typeSearchFilter.getSearchScope(),
599                     requestor,
600                     IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
601                     progressMonitor);
602         } finally {
603             typeSearchFilter.setMatchEverythingMode(false);
604         }
605     }
606
607     /*
608      * (non-Javadoc)
609      *
610      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
611      */

612     protected Comparator JavaDoc getItemsComparator() {
613         return fTypeItemsComparator;
614     }
615
616     /*
617      * (non-Javadoc)
618      *
619      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
620      */

621     public String JavaDoc getElementName(Object JavaDoc item) {
622         TypeNameMatch type= (TypeNameMatch) item;
623         return fTypeInfoUtil.getText(type);
624     }
625
626     /*
627      * (non-Javadoc)
628      *
629      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)
630      */

631     protected IStatus validateItem(Object JavaDoc item) {
632
633         if (item == null)
634             return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.ERROR, "", null); //$NON-NLS-1$
635

636         if (fValidator != null) {
637             IType type= ((TypeNameMatch) item).getType();
638             if (!type.exists())
639                 return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.ERROR, Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_error_type_doesnot_exist, ((TypeNameMatch) item).getFullyQualifiedName()), null);
640             Object JavaDoc[] elements= { type };
641             return fValidator.validate(elements);
642         } else
643             return new Status(IStatus.OK, JavaPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$
644
}
645
646     /**
647      * Sets search scope used when searching for types.
648      *
649      * @param scope
650      * the new scope
651      */

652     private void setSearchScope(IJavaSearchScope scope) {
653         fSearchScope= scope;
654     }
655     
656     /*
657      * We only have to ensure history consistency here since the search engine
658      * takes care of working copies.
659      */

660     private static class ConsistencyRunnable implements IRunnableWithProgress {
661         public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
662             if (fgFirstTime) {
663                 // Join the initialize after load job.
664
IJobManager manager= Job.getJobManager();
665                 manager.join(JavaUI.ID_PLUGIN, monitor);
666             }
667             OpenTypeHistory history= OpenTypeHistory.getInstance();
668             if (fgFirstTime || history.isEmpty()) {
669                 if (history.needConsistencyCheck()) {
670                     monitor.beginTask(JavaUIMessages.TypeSelectionDialog_progress_consistency, 100);
671                     refreshSearchIndices(new SubProgressMonitor(monitor, 90));
672                     history.checkConsistency(new SubProgressMonitor(monitor, 10));
673                 } else {
674                     refreshSearchIndices(monitor);
675                 }
676                 monitor.done();
677                 fgFirstTime= false;
678             } else {
679                 history.checkConsistency(monitor);
680             }
681         }
682         public static boolean needsExecution() {
683             OpenTypeHistory history= OpenTypeHistory.getInstance();
684             return fgFirstTime || history.isEmpty() || history.needConsistencyCheck();
685         }
686         private void refreshSearchIndices(IProgressMonitor monitor) throws InvocationTargetException JavaDoc {
687             try {
688                 new SearchEngine().searchAllTypeNames(
689                         null,
690                         0,
691                         // make sure we search a concrete name. This is faster according to Kent
692
"_______________".toCharArray(), //$NON-NLS-1$
693
SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_CASE_SENSITIVE,
694                         IJavaSearchConstants.ENUM,
695                         SearchEngine.createWorkspaceScope(),
696                         new TypeNameRequestor() {},
697                         IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
698                         monitor);
699             } catch (JavaModelException e) {
700                 throw new InvocationTargetException JavaDoc(e);
701             }
702         }
703     }
704     
705     /*
706      * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#reloadCache(boolean, org.eclipse.core.runtime.IProgressMonitor)
707      */

708     public void reloadCache(boolean checkDuplicates, IProgressMonitor monitor) {
709         IProgressMonitor remainingMonitor;
710         if (ConsistencyRunnable.needsExecution()) {
711             monitor.beginTask(JavaUIMessages.TypeSelectionDialog_progress_consistency, 10);
712             try {
713                 ConsistencyRunnable runnable= new ConsistencyRunnable();
714                 runnable.run(new SubProgressMonitor(monitor, 1));
715             } catch (InvocationTargetException JavaDoc e) {
716                 ExceptionHandler.handle(e, JavaUIMessages.TypeSelectionDialog_error3Title, JavaUIMessages.TypeSelectionDialog_error3Message);
717                 close();
718                 return;
719             } catch (InterruptedException JavaDoc e) {
720                 // cancelled by user
721
close();
722                 return;
723             }
724             remainingMonitor= new SubProgressMonitor(monitor, 9);
725         } else {
726             remainingMonitor= monitor;
727         }
728         super.reloadCache(checkDuplicates, remainingMonitor);
729         monitor.done();
730     }
731
732     /*
733      * @see org.eclipse.jdt.ui.dialogs.ITypeSelectionComponent#triggerSearch()
734      */

735     public void triggerSearch() {
736         fTypeFilterVersion++;
737         applyFilter();
738     }
739
740     /**
741      * The <code>ShowContainerForDuplicatesAction</code> provides means to
742      * show/hide container information for duplicate elements.
743      */

744     private class ShowContainerForDuplicatesAction extends Action {
745
746         /**
747          * Creates a new instance of the class
748          */

749         public ShowContainerForDuplicatesAction() {
750             super(JavaUIMessages.FilteredTypeSelectionDialog_showContainerForDuplicatesAction, IAction.AS_CHECK_BOX);
751         }
752
753         /*
754          * (non-Javadoc)
755          *
756          * @see org.eclipse.jface.action.Action#run()
757          */

758         public void run() {
759             fTypeInfoLabelProvider.setContainerInfo(isChecked());
760         }
761     }
762     
763     private class TypeFiltersPreferencesAction extends Action {
764         
765         public TypeFiltersPreferencesAction() {
766             super(JavaUIMessages.FilteredTypesSelectionDialog_TypeFiltersPreferencesAction_label);
767         }
768         
769         /*
770          * (non-Javadoc)
771          *
772          * @see org.eclipse.jface.action.Action#run()
773          */

774         public void run() {
775             String JavaDoc typeFilterID= TypeFilterPreferencePage.TYPE_FILTER_PREF_PAGE_ID;
776             PreferencesUtil.createPreferenceDialogOn(getShell(), typeFilterID, new String JavaDoc[] { typeFilterID }, null).open();
777             triggerSearch();
778         }
779     }
780
781     /**
782      * A <code>LabelProvider</code> for (the table of) types.
783      */

784     private class TypeItemLabelProvider extends LabelProvider implements ILabelDecorator {
785
786         private boolean fContainerInfo;
787
788
789         /**
790          * Construct a new <code>TypeItemLabelProvider</code>. F
791          */

792         public TypeItemLabelProvider() {
793
794         }
795
796         public void setContainerInfo(boolean containerInfo) {
797             fContainerInfo= containerInfo;
798             fireLabelProviderChanged(new LabelProviderChangedEvent(this));
799         }
800
801         private boolean isInnerType(TypeNameMatch match) {
802             return match.getTypeQualifiedName().indexOf('.') != -1;
803         }
804
805         /*
806          * (non-Javadoc)
807          *
808          * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
809          */

810         public Image getImage(Object JavaDoc element) {
811             if (!(element instanceof TypeNameMatch)) {
812                 return super.getImage(element);
813             }
814
815             TypeNameMatch type= (TypeNameMatch) element;
816
817             ImageDescriptor iD= JavaElementImageProvider.getTypeImageDescriptor(isInnerType(type), false, type.getModifiers(), false);
818             
819             return JavaPlugin.getImageDescriptorRegistry().get(iD);
820         }
821
822         /*
823          * (non-Javadoc)
824          *
825          * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
826          */

827         public String JavaDoc getText(Object JavaDoc element) {
828             if (!(element instanceof TypeNameMatch)) {
829                 return super.getText(element);
830             }
831
832             if (fContainerInfo && isDuplicateElement(element)) {
833                 return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element);
834             }
835
836             if (!fContainerInfo && isDuplicateElement(element)) {
837                 return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element);
838             }
839
840             return fTypeInfoUtil.getText(element);
841         }
842
843         /*
844          * (non-Javadoc)
845          *
846          * @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image,
847          * java.lang.Object)
848          */

849         public Image decorateImage(Image image, Object JavaDoc element) {
850             return null;
851         }
852
853         /*
854          * (non-Javadoc)
855          *
856          * @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String,
857          * java.lang.Object)
858          */

859         public String JavaDoc decorateText(String JavaDoc text, Object JavaDoc element) {
860             if (!(element instanceof TypeNameMatch)) {
861                 return null;
862             }
863
864             if (fContainerInfo && isDuplicateElement(element)) {
865                 return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element);
866             }
867
868             return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element);
869         }
870
871     }
872
873     /**
874      * A <code>LabelProvider</code> for the label showing type details.
875      */

876     private static class TypeItemDetailsLabelProvider extends LabelProvider {
877
878         private final TypeNameMatchLabelProvider fLabelProvider= new TypeNameMatchLabelProvider(TypeNameMatchLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeNameMatchLabelProvider.SHOW_ROOT_POSTFIX);
879
880         private final TypeInfoUtil fTypeInfoUtil;
881
882         public TypeItemDetailsLabelProvider(TypeInfoUtil typeInfoUtil) {
883             fTypeInfoUtil= typeInfoUtil;
884         }
885
886         /*
887          * (non-Javadoc)
888          *
889          * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
890          */

891         public Image getImage(Object JavaDoc element) {
892             if (element instanceof TypeNameMatch) {
893                 return fLabelProvider.getImage((element));
894             }
895
896             return super.getImage(element);
897         }
898
899         /*
900          * (non-Javadoc)
901          *
902          * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
903          */

904         public String JavaDoc getText(Object JavaDoc element) {
905             if (element instanceof TypeNameMatch) {
906                 return fTypeInfoUtil.getQualificationText((TypeNameMatch) element);
907             }
908
909             return super.getText(element);
910         }
911     }
912
913     private static class TypeInfoUtil {
914
915         private final ITypeInfoImageProvider fProviderExtension;
916
917         private final TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter();
918
919         private final Map JavaDoc fLib2Name= new HashMap JavaDoc();
920
921         private final String JavaDoc[] fInstallLocations;
922
923         private final String JavaDoc[] fVMNames;
924
925         private boolean fFullyQualifyDuplicates;
926
927         public TypeInfoUtil(ITypeInfoImageProvider extension) {
928             fProviderExtension= extension;
929             List JavaDoc locations= new ArrayList JavaDoc();
930             List JavaDoc labels= new ArrayList JavaDoc();
931             IVMInstallType[] installs= JavaRuntime.getVMInstallTypes();
932             for (int i= 0; i < installs.length; i++) {
933                 processVMInstallType(installs[i], locations, labels);
934             }
935             fInstallLocations= (String JavaDoc[]) locations.toArray(new String JavaDoc[locations.size()]);
936             fVMNames= (String JavaDoc[]) labels.toArray(new String JavaDoc[labels.size()]);
937
938         }
939
940         public void setFullyQualifyDuplicates(boolean value) {
941             fFullyQualifyDuplicates= value;
942         }
943
944         private void processVMInstallType(IVMInstallType installType, List JavaDoc locations, List JavaDoc labels) {
945             if (installType != null) {
946                 IVMInstall[] installs= installType.getVMInstalls();
947                 boolean isMac= Platform.OS_MACOSX.equals(Platform.getOS());
948                 final String JavaDoc HOME_SUFFIX= "/Home"; //$NON-NLS-1$
949
for (int i= 0; i < installs.length; i++) {
950                     String JavaDoc label= getFormattedLabel(installs[i].getName());
951                     LibraryLocation[] libLocations= installs[i].getLibraryLocations();
952                     if (libLocations != null) {
953                         processLibraryLocation(libLocations, label);
954                     } else {
955                         String JavaDoc filePath= installs[i].getInstallLocation().getAbsolutePath();
956                         // on MacOS X install locations end in an additional
957
// "/Home" segment; remove it
958
if (isMac && filePath.endsWith(HOME_SUFFIX))
959                             filePath= filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1);
960                         locations.add(filePath);
961                         labels.add(label);
962                     }
963                 }
964             }
965         }
966
967         private void processLibraryLocation(LibraryLocation[] libLocations, String JavaDoc label) {
968             for (int l= 0; l < libLocations.length; l++) {
969                 LibraryLocation location= libLocations[l];
970                 fLib2Name.put(location.getSystemLibraryPath().toOSString(), label);
971             }
972         }
973
974         private String JavaDoc getFormattedLabel(String JavaDoc name) {
975             return Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_library_name_format, name);
976         }
977
978         public String JavaDoc getText(Object JavaDoc element) {
979             return ((TypeNameMatch) element).getSimpleTypeName();
980         }
981
982         public String JavaDoc getQualifiedText(TypeNameMatch type) {
983             StringBuffer JavaDoc result= new StringBuffer JavaDoc();
984             result.append(type.getSimpleTypeName());
985             String JavaDoc containerName= type.getTypeContainerName();
986             result.append(JavaElementLabels.CONCAT_STRING);
987             if (containerName.length() > 0) {
988                 result.append(containerName);
989             } else {
990                 result.append(JavaUIMessages.FilteredTypesSelectionDialog_default_package);
991             }
992             return result.toString();
993         }
994
995         public String JavaDoc getFullyQualifiedText(TypeNameMatch type) {
996             StringBuffer JavaDoc result= new StringBuffer JavaDoc();
997             result.append(type.getSimpleTypeName());
998             String JavaDoc containerName= type.getTypeContainerName();
999             if (containerName.length() > 0) {
1000                result.append(JavaElementLabels.CONCAT_STRING);
1001                result.append(containerName);
1002            }
1003            result.append(JavaElementLabels.CONCAT_STRING);
1004            result.append(getContainerName(type));
1005            return result.toString();
1006        }
1007
1008        public String JavaDoc getText(TypeNameMatch last, TypeNameMatch current, TypeNameMatch next) {
1009            StringBuffer JavaDoc result= new StringBuffer JavaDoc();
1010            int qualifications= 0;
1011            String JavaDoc currentTN= current.getSimpleTypeName();
1012            result.append(currentTN);
1013            String JavaDoc currentTCN= getTypeContainerName(current);
1014            if (last != null) {
1015                String JavaDoc lastTN= last.getSimpleTypeName();
1016                String JavaDoc lastTCN= getTypeContainerName(last);
1017                if (currentTCN.equals(lastTCN)) {
1018                    if (currentTN.equals(lastTN)) {
1019                        result.append(JavaElementLabels.CONCAT_STRING);
1020                        result.append(currentTCN);
1021                        result.append(JavaElementLabels.CONCAT_STRING);
1022                        result.append(getContainerName(current));
1023                        return result.toString();
1024                    }
1025                } else if (currentTN.equals(lastTN)) {
1026                    qualifications= 1;
1027                }
1028            }
1029            if (next != null) {
1030                String JavaDoc nextTN= next.getSimpleTypeName();
1031                String JavaDoc nextTCN= getTypeContainerName(next);
1032                if (currentTCN.equals(nextTCN)) {
1033                    if (currentTN.equals(nextTN)) {
1034                        result.append(JavaElementLabels.CONCAT_STRING);
1035                        result.append(currentTCN);
1036                        result.append(JavaElementLabels.CONCAT_STRING);
1037                        result.append(getContainerName(current));
1038                        return result.toString();
1039                    }
1040                } else if (currentTN.equals(nextTN)) {
1041                    qualifications= 1;
1042                }
1043            }
1044            if (qualifications > 0) {
1045                result.append(JavaElementLabels.CONCAT_STRING);
1046                result.append(currentTCN);
1047                if (fFullyQualifyDuplicates) {
1048                    result.append(JavaElementLabels.CONCAT_STRING);
1049                    result.append(getContainerName(current));
1050                }
1051            }
1052            return result.toString();
1053        }
1054
1055        public String JavaDoc getQualificationText(TypeNameMatch type) {
1056            StringBuffer JavaDoc result= new StringBuffer JavaDoc();
1057            String JavaDoc containerName= type.getTypeContainerName();
1058            if (containerName.length() > 0) {
1059                result.append(containerName);
1060                result.append(JavaElementLabels.CONCAT_STRING);
1061            }
1062            result.append(getContainerName(type));
1063            return result.toString();
1064        }
1065
1066        private boolean isInnerType(TypeNameMatch match) {
1067            return match.getTypeQualifiedName().indexOf('.') != -1;
1068        }
1069
1070        public ImageDescriptor getImageDescriptor(Object JavaDoc element) {
1071            TypeNameMatch type= (TypeNameMatch) element;
1072            if (fProviderExtension != null) {
1073                fAdapter.setMatch(type);
1074                ImageDescriptor descriptor= fProviderExtension.getImageDescriptor(fAdapter);
1075                if (descriptor != null)
1076                    return descriptor;
1077            }
1078            return JavaElementImageProvider.getTypeImageDescriptor(isInnerType(type), false, type.getModifiers(), false);
1079        }
1080
1081        private String JavaDoc getTypeContainerName(TypeNameMatch info) {
1082            String JavaDoc result= info.getTypeContainerName();
1083            if (result.length() > 0)
1084                return result;
1085            return JavaUIMessages.FilteredTypesSelectionDialog_default_package;
1086        }
1087
1088        private String JavaDoc getContainerName(TypeNameMatch type) {
1089            IPackageFragmentRoot root= type.getPackageFragmentRoot();
1090            if (root.isExternal()) {
1091                String JavaDoc name= root.getPath().toOSString();
1092                for (int i= 0; i < fInstallLocations.length; i++) {
1093                    if (name.startsWith(fInstallLocations[i])) {
1094                        return fVMNames[i];
1095                    }
1096                }
1097                String JavaDoc lib= (String JavaDoc) fLib2Name.get(name);
1098                if (lib != null)
1099                    return lib;
1100            }
1101            StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
1102            JavaElementLabels.getPackageFragmentRootLabel(root, JavaElementLabels.ROOT_QUALIFIED | JavaElementLabels.ROOT_VARIABLE, buf);
1103            return buf.toString();
1104        }
1105    }
1106
1107    /**
1108     * Filters types using pattern, scope, element kind and filter extension.
1109     */

1110    private class TypeItemsFilter extends ItemsFilter {
1111
1112        private static final int TYPE_MODIFIERS= Flags.AccEnum | Flags.AccAnnotation | Flags.AccInterface;
1113
1114        private final IJavaSearchScope fScope;
1115
1116        private final boolean fIsWorkspaceScope;
1117
1118        private final int fElemKind;
1119
1120        private final ITypeInfoFilterExtension fFilterExt;
1121
1122        private final TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter();
1123
1124        private SearchPattern fPackageMatcher;
1125        
1126        private boolean fMatchEverything= false;
1127        
1128        private final int fMyTypeFilterVersion= fTypeFilterVersion;
1129
1130        /**
1131         * Creates instance of TypeItemsFilter
1132         *
1133         * @param scope
1134         * @param elementKind
1135         * @param extension
1136         */

1137        public TypeItemsFilter(IJavaSearchScope scope, int elementKind, ITypeInfoFilterExtension extension) {
1138            super(new TypeSearchPattern());
1139            fScope= scope;
1140            fIsWorkspaceScope= scope == null ? false : scope.equals(SearchEngine.createWorkspaceScope());
1141            fElemKind= elementKind;
1142            fFilterExt= extension;
1143            String JavaDoc stringPackage= ((TypeSearchPattern) patternMatcher).getPackagePattern();
1144            if (stringPackage != null) {
1145                fPackageMatcher= new SearchPattern();
1146                fPackageMatcher.setPattern(stringPackage);
1147            } else {
1148                fPackageMatcher= null;
1149            }
1150        }
1151
1152        /*
1153         * (non-Javadoc)
1154         *
1155         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isSubFilter(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter)
1156         */

1157        public boolean isSubFilter(ItemsFilter filter) {
1158            if (!super.isSubFilter(filter))
1159                return false;
1160            TypeItemsFilter typeItemsFilter= (TypeItemsFilter) filter;
1161            if (fScope != typeItemsFilter.getSearchScope())
1162                return false;
1163            if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion())
1164                return false;
1165            return getPattern().indexOf('.', filter.getPattern().length()) == -1;
1166        }
1167
1168        public boolean equalsFilter(ItemsFilter iFilter) {
1169            if (!super.equalsFilter(iFilter))
1170                return false;
1171            if (!(iFilter instanceof TypeItemsFilter))
1172                return false;
1173            TypeItemsFilter typeItemsFilter= (TypeItemsFilter) iFilter;
1174            if (fScope != typeItemsFilter.getSearchScope())
1175                return false;
1176            if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion())
1177                return false;
1178            return true;
1179        }
1180
1181        public int getElementKind() {
1182            return fElemKind;
1183        }
1184
1185        public ITypeInfoFilterExtension getFilterExtension() {
1186            return fFilterExt;
1187        }
1188
1189        public IJavaSearchScope getSearchScope() {
1190            return fScope;
1191        }
1192
1193        public int getMyTypeFilterVersion() {
1194            return fMyTypeFilterVersion;
1195        }
1196        
1197        public String JavaDoc getPackagePattern() {
1198            if (fPackageMatcher == null)
1199                return null;
1200            return fPackageMatcher.getPattern();
1201        }
1202
1203        public int getPackageFlags() {
1204            if (fPackageMatcher == null)
1205                return SearchPattern.RULE_EXACT_MATCH;
1206
1207            return fPackageMatcher.getMatchRule();
1208        }
1209
1210        public boolean matchesRawNamePattern(TypeNameMatch type) {
1211            return Strings.startsWithIgnoreCase(type.getSimpleTypeName(), getPattern());
1212        }
1213
1214        public boolean matchesCachedResult(TypeNameMatch type) {
1215            if (!(matchesPackage(type) && matchesFilterExtension(type)))
1216                return false;
1217            return matchesName(type);
1218        }
1219
1220        public boolean matchesHistoryElement(TypeNameMatch type) {
1221            if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type)))
1222                return false;
1223            return matchesName(type);
1224        }
1225
1226        public boolean matchesFilterExtension(TypeNameMatch type) {
1227            if (fFilterExt == null)
1228                return true;
1229            fAdapter.setMatch(type);
1230            return fFilterExt.select(fAdapter);
1231        }
1232
1233        private boolean matchesName(TypeNameMatch type) {
1234            return matches(type.getSimpleTypeName());
1235        }
1236
1237        private boolean matchesPackage(TypeNameMatch type) {
1238            if (fPackageMatcher == null)
1239                return true;
1240            return fPackageMatcher.matches(type.getPackageName());
1241        }
1242
1243        private boolean matchesScope(TypeNameMatch type) {
1244            if (fIsWorkspaceScope)
1245                return true;
1246            return fScope.encloses(type.getType());
1247
1248        }
1249
1250        private boolean matchesModifiers(TypeNameMatch type) {
1251            if (fElemKind == IJavaSearchConstants.TYPE)
1252                return true;
1253            int modifiers= type.getModifiers() & TYPE_MODIFIERS;
1254            switch (fElemKind) {
1255            case IJavaSearchConstants.CLASS:
1256                return modifiers == 0;
1257            case IJavaSearchConstants.ANNOTATION_TYPE:
1258                return Flags.isAnnotation(modifiers);
1259            case IJavaSearchConstants.INTERFACE:
1260                return Flags.isInterface(modifiers);
1261            case IJavaSearchConstants.ENUM:
1262                return Flags.isEnum(modifiers);
1263            case IJavaSearchConstants.CLASS_AND_INTERFACE:
1264                return modifiers == 0 || Flags.isInterface(modifiers);
1265            case IJavaSearchConstants.CLASS_AND_ENUM:
1266                return modifiers == 0 || Flags.isEnum(modifiers);
1267            }
1268            return false;
1269        }
1270        
1271        /**
1272         * Set filter to "match everything" mode.
1273         *
1274         * @param matchEverything if <code>true</code>, {@link #matchItem(Object)} always returns true.
1275         * If <code>false</code>, the filter is enabled.
1276         */

1277        public void setMatchEverythingMode(boolean matchEverything) {
1278            this.fMatchEverything= matchEverything;
1279        }
1280
1281        /*
1282         * (non-Javadoc)
1283         *
1284         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isConsistentItem(java.lang.Object)
1285         */

1286        public boolean isConsistentItem(Object JavaDoc item) {
1287            return true;
1288        }
1289
1290        /*
1291         * (non-Javadoc)
1292         *
1293         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#matchItem(java.lang.Object)
1294         */

1295        public boolean matchItem(Object JavaDoc item) {
1296
1297            if (fMatchEverything)
1298                return true;
1299
1300            TypeNameMatch type= (TypeNameMatch) item;
1301            if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type)))
1302                return false;
1303            return matchesName(type);
1304        }
1305        
1306        /*
1307         * (non-Javadoc)
1308         *
1309         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#matchesRawNamePattern(java.lang.Object)
1310         */

1311        public boolean matchesRawNamePattern(Object JavaDoc item) {
1312            TypeNameMatch type= (TypeNameMatch) item;
1313            return matchesRawNamePattern(type);
1314        }
1315
1316    }
1317
1318    /**
1319     * Extends functionality of SearchPatterns
1320     */

1321    private static class TypeSearchPattern extends SearchPattern {
1322
1323        private String JavaDoc packagePattern;
1324
1325        /*
1326         * (non-Javadoc)
1327         *
1328         * @see org.eclipse.ui.dialogs.SearchPattern#setPattern(java.lang.String)
1329         */

1330        public void setPattern(String JavaDoc stringPattern) {
1331            String JavaDoc pattern= stringPattern;
1332            String JavaDoc packPattern= null;
1333            int index= stringPattern.lastIndexOf("."); //$NON-NLS-1$
1334
if (index != -1) {
1335                packPattern= evaluatePackagePattern(stringPattern.substring(0, index));
1336                pattern= stringPattern.substring(index + 1);
1337                if (pattern.length() == 0)
1338                    pattern= "**"; //$NON-NLS-1$
1339
}
1340            super.setPattern(pattern);
1341            packagePattern= packPattern;
1342        }
1343
1344        /*
1345         * Transforms o.e.j to o*.e*.j*
1346         */

1347        private String JavaDoc evaluatePackagePattern(String JavaDoc s) {
1348            StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
1349            boolean hasWildCard= false;
1350            for (int i= 0; i < s.length(); i++) {
1351                char ch= s.charAt(i);
1352                if (ch == '.') {
1353                    if (!hasWildCard) {
1354                        buf.append('*');
1355                    }
1356                    hasWildCard= false;
1357                } else if (ch == '*' || ch == '?') {
1358                    hasWildCard= true;
1359                }
1360                buf.append(ch);
1361            }
1362            if (!hasWildCard) {
1363                buf.append('*');
1364            }
1365            return buf.toString();
1366        }
1367
1368        /*
1369         * (non-Javadoc)
1370         *
1371         * @see org.eclipse.ui.dialogs.SearchPattern#isNameCharAllowed(char)
1372         */

1373        protected boolean isNameCharAllowed(char nameChar) {
1374            return super.isNameCharAllowed(nameChar);
1375        }
1376
1377        /*
1378         * (non-Javadoc)
1379         *
1380         * @see org.eclipse.ui.dialogs.SearchPattern#isPatternCharAllowed(char)
1381         */

1382        protected boolean isPatternCharAllowed(char patternChar) {
1383            return super.isPatternCharAllowed(patternChar);
1384        }
1385
1386        /*
1387         * (non-Javadoc)
1388         *
1389         * @see org.eclipse.ui.dialogs.SearchPattern#isValidCamelCaseChar(char)
1390         */

1391        protected boolean isValidCamelCaseChar(char ch) {
1392            return super.isValidCamelCaseChar(ch);
1393        }
1394
1395        /**
1396         * @return the packagePattern
1397         */

1398        public String JavaDoc getPackagePattern() {
1399            return packagePattern;
1400        }
1401
1402    }
1403
1404    /**
1405     * A <code>TypeSearchRequestor</code> collects matches filtered using
1406     * <code>TypeItemsFilter</code>. The attached content provider is filled
1407     * on the basis of the collected entries (instances of
1408     * <code>TypeNameMatch</code>).
1409     */

1410    private static class TypeSearchRequestor extends TypeNameMatchRequestor {
1411        private volatile boolean fStop;
1412
1413        private final AbstractContentProvider fContentProvider;
1414
1415        private final TypeItemsFilter fTypeItemsFilter;
1416
1417        public TypeSearchRequestor(AbstractContentProvider contentProvider, TypeItemsFilter typeItemsFilter) {
1418            super();
1419            fContentProvider= contentProvider;
1420            fTypeItemsFilter= typeItemsFilter;
1421        }
1422
1423        public void cancel() {
1424            fStop= true;
1425        }
1426
1427        /*
1428         * (non-Javadoc)
1429         *
1430         * @see org.eclipse.jdt.core.search.TypeNameMatchRequestor#acceptTypeNameMatch(org.eclipse.jdt.core.search.TypeNameMatch)
1431         */

1432        public void acceptTypeNameMatch(TypeNameMatch match) {
1433            if (fStop)
1434                return;
1435            if (TypeFilter.isFiltered(match))
1436                return;
1437            if (fTypeItemsFilter.matchesFilterExtension(match))
1438                fContentProvider.add(match, fTypeItemsFilter);
1439        }
1440
1441    }
1442
1443    /**
1444     * Compares TypeItems is used during sorting
1445     */

1446    private static class TypeItemsComparator implements Comparator JavaDoc {
1447
1448        private final Map JavaDoc fLib2Name= new HashMap JavaDoc();
1449
1450        private final String JavaDoc[] fInstallLocations;
1451
1452        private final String JavaDoc[] fVMNames;
1453
1454        /**
1455         * Creates new instance of TypeItemsComparator
1456         */

1457        public TypeItemsComparator() {
1458            List JavaDoc locations= new ArrayList JavaDoc();
1459            List JavaDoc labels= new ArrayList JavaDoc();
1460            IVMInstallType[] installs= JavaRuntime.getVMInstallTypes();
1461            for (int i= 0; i < installs.length; i++) {
1462                processVMInstallType(installs[i], locations, labels);
1463            }
1464            fInstallLocations= (String JavaDoc[]) locations.toArray(new String JavaDoc[locations.size()]);
1465            fVMNames= (String JavaDoc[]) labels.toArray(new String JavaDoc[labels.size()]);
1466        }
1467
1468        private void processVMInstallType(IVMInstallType installType, List JavaDoc locations, List JavaDoc labels) {
1469            if (installType != null) {
1470                IVMInstall[] installs= installType.getVMInstalls();
1471                boolean isMac= Platform.OS_MACOSX.equals(Platform.getOS());
1472                final String JavaDoc HOME_SUFFIX= "/Home"; //$NON-NLS-1$
1473
for (int i= 0; i < installs.length; i++) {
1474                    String JavaDoc label= getFormattedLabel(installs[i].getName());
1475                    LibraryLocation[] libLocations= installs[i].getLibraryLocations();
1476                    if (libLocations != null) {
1477                        processLibraryLocation(libLocations, label);
1478                    } else {
1479                        String JavaDoc filePath= installs[i].getInstallLocation().getAbsolutePath();
1480                        // on MacOS X install locations end in an additional
1481
// "/Home" segment; remove it
1482
if (isMac && filePath.endsWith(HOME_SUFFIX))
1483                            filePath= filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1);
1484                        locations.add(filePath);
1485                        labels.add(label);
1486                    }
1487                }
1488            }
1489        }
1490
1491        private void processLibraryLocation(LibraryLocation[] libLocations, String JavaDoc label) {
1492            for (int l= 0; l < libLocations.length; l++) {
1493                LibraryLocation location= libLocations[l];
1494                fLib2Name.put(location.getSystemLibraryPath().toString(), label);
1495            }
1496        }
1497
1498        private String JavaDoc getFormattedLabel(String JavaDoc name) {
1499            return MessageFormat.format(JavaUIMessages.FilteredTypesSelectionDialog_library_name_format, new Object JavaDoc[] { name });
1500        }
1501
1502        /*
1503         * (non-Javadoc)
1504         *
1505         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
1506         */

1507        public int compare(Object JavaDoc left, Object JavaDoc right) {
1508
1509            TypeNameMatch leftInfo= (TypeNameMatch) left;
1510            TypeNameMatch rightInfo= (TypeNameMatch) right;
1511
1512            int result= compareName(leftInfo.getSimpleTypeName(), rightInfo.getSimpleTypeName());
1513            if (result != 0)
1514                return result;
1515            result= compareTypeContainerName(leftInfo.getTypeContainerName(), rightInfo.getTypeContainerName());
1516            if (result != 0)
1517                return result;
1518
1519            int leftCategory= getElementTypeCategory(leftInfo);
1520            int rightCategory= getElementTypeCategory(rightInfo);
1521            if (leftCategory < rightCategory)
1522                return -1;
1523            if (leftCategory > rightCategory)
1524                return +1;
1525            return compareContainerName(leftInfo, rightInfo);
1526        }
1527
1528        private int compareName(String JavaDoc leftString, String JavaDoc rightString) {
1529            int result= leftString.compareToIgnoreCase(rightString);
1530            if (result != 0 || rightString.length() == 0) {
1531                return result;
1532            } else if (Strings.isLowerCase(leftString.charAt(0)) && !Strings.isLowerCase(rightString.charAt(0))) {
1533                return +1;
1534            } else if (Strings.isLowerCase(rightString.charAt(0)) && !Strings.isLowerCase(leftString.charAt(0))) {
1535                return -1;
1536            } else {
1537                return leftString.compareTo(rightString);
1538            }
1539        }
1540
1541        private int compareTypeContainerName(String JavaDoc leftString, String JavaDoc rightString) {
1542            int leftLength= leftString.length();
1543            int rightLength= rightString.length();
1544            if (leftLength == 0 && rightLength > 0)
1545                return -1;
1546            if (leftLength == 0 && rightLength == 0)
1547                return 0;
1548            if (leftLength > 0 && rightLength == 0)
1549                return +1;
1550            return compareName(leftString, rightString);
1551        }
1552
1553        private int compareContainerName(TypeNameMatch leftType, TypeNameMatch rightType) {
1554            return getContainerName(leftType).compareTo(getContainerName(rightType));
1555        }
1556
1557        private String JavaDoc getContainerName(TypeNameMatch type) {
1558            IPackageFragmentRoot root= type.getPackageFragmentRoot();
1559            if (root.isExternal()) {
1560                String JavaDoc name= root.getPath().toOSString();
1561                for (int i= 0; i < fInstallLocations.length; i++) {
1562                    if (name.startsWith(fInstallLocations[i])) {
1563                        return fVMNames[i];
1564                    }
1565                }
1566                String JavaDoc lib= (String JavaDoc) fLib2Name.get(name);
1567                if (lib != null)
1568                    return lib;
1569            }
1570            StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
1571            JavaElementLabels.getPackageFragmentRootLabel(root, JavaElementLabels.ROOT_QUALIFIED | JavaElementLabels.ROOT_VARIABLE, buf);
1572            return buf.toString();
1573        }
1574
1575        private int getElementTypeCategory(TypeNameMatch type) {
1576            try {
1577                if (type.getPackageFragmentRoot().getKind() == IPackageFragmentRoot.K_SOURCE)
1578                    return 0;
1579            } catch (JavaModelException e) {
1580                JavaPlugin.log(e);
1581            }
1582            return 1;
1583        }
1584    }
1585
1586    /**
1587     * Extends the <code>SelectionHistory</code>, providing support for
1588     * <code>OpenTypeHistory</code>.
1589     */

1590    protected class TypeSelectionHistory extends SelectionHistory {
1591
1592        /**
1593         * Creates new instance of TypeSelectionHistory
1594         */

1595
1596        public TypeSelectionHistory() {
1597            super();
1598        }
1599
1600        /*
1601         * (non-Javadoc)
1602         *
1603         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#accessed(java.lang.Object)
1604         */

1605        public synchronized void accessed(Object JavaDoc object) {
1606            super.accessed(object);
1607        }
1608
1609        /*
1610         * (non-Javadoc)
1611         *
1612         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#remove(java.lang.Object)
1613         */

1614        public synchronized boolean remove(Object JavaDoc element) {
1615            OpenTypeHistory.getInstance().remove((TypeNameMatch) element);
1616            return super.remove(element);
1617        }
1618
1619        /*
1620         * (non-Javadoc)
1621         *
1622         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#load(org.eclipse.ui.IMemento)
1623         */

1624        public void load(IMemento memento) {
1625            TypeNameMatch[] types= OpenTypeHistory.getInstance().getTypeInfos();
1626
1627            for (int i= 0; i < types.length; i++) {
1628                TypeNameMatch type= types[i];
1629                accessed(type);
1630            }
1631        }
1632
1633        /*
1634         * (non-Javadoc)
1635         *
1636         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#save(org.eclipse.ui.IMemento)
1637         */

1638        public void save(IMemento memento) {
1639            persistHistory();
1640        }
1641
1642        /**
1643         * Stores contents of the local history into persistent history
1644         * container.
1645         */

1646        private synchronized void persistHistory() {
1647            if (getReturnCode() == OK) {
1648                Object JavaDoc[] items= getHistoryItems();
1649                for (int i= 0; i < items.length; i++) {
1650                    OpenTypeHistory.getInstance().accessed((TypeNameMatch) items[i]);
1651                }
1652            }
1653        }
1654
1655        protected Object JavaDoc restoreItemFromMemento(IMemento element) {
1656            return null;
1657        }
1658
1659        /*
1660         * (non-Javadoc)
1661         *
1662         * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object,
1663         * org.eclipse.ui.IMemento)
1664         */

1665        protected void storeItemToMemento(Object JavaDoc item, IMemento element) {
1666
1667        }
1668
1669    }
1670
1671}
1672
Popular Tags