/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.ui.dialogs; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.dialogs.SearchPattern; import org.eclipse.wst.jsdt.core.IPackageFragmentRoot; import org.eclipse.wst.jsdt.core.IType; import org.eclipse.wst.jsdt.core.JavaScriptConventions; import org.eclipse.wst.jsdt.core.JavaScriptCore; import org.eclipse.wst.jsdt.core.JavaScriptModelException; import org.eclipse.wst.jsdt.core.WorkingCopyOwner; import org.eclipse.wst.jsdt.core.compiler.CharOperation; import org.eclipse.wst.jsdt.core.infer.IInferEngine; import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants; import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope; import org.eclipse.wst.jsdt.core.search.SearchEngine; import org.eclipse.wst.jsdt.core.search.TypeNameMatch; import org.eclipse.wst.jsdt.core.search.TypeNameMatchRequestor; import org.eclipse.wst.jsdt.core.search.TypeNameRequestor; import org.eclipse.wst.jsdt.internal.corext.util.Messages; import org.eclipse.wst.jsdt.internal.corext.util.OpenTypeHistory; import org.eclipse.wst.jsdt.internal.corext.util.Strings; import org.eclipse.wst.jsdt.internal.corext.util.TypeFilter; import org.eclipse.wst.jsdt.internal.corext.util.TypeInfoRequestorAdapter; import org.eclipse.wst.jsdt.internal.ui.IJavaHelpContextIds; import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin; import org.eclipse.wst.jsdt.internal.ui.JavaUIMessages; import org.eclipse.wst.jsdt.internal.ui.preferences.TypeFilterPreferencePage; import org.eclipse.wst.jsdt.internal.ui.search.JavaSearchScopeFactory; import org.eclipse.wst.jsdt.internal.ui.util.ExceptionHandler; import org.eclipse.wst.jsdt.internal.ui.util.TypeNameMatchLabelProvider; import org.eclipse.wst.jsdt.internal.ui.viewsupport.ColoredJavaElementLabels; import org.eclipse.wst.jsdt.internal.ui.viewsupport.ColoredString; import org.eclipse.wst.jsdt.internal.ui.viewsupport.ColoredViewersManager; import org.eclipse.wst.jsdt.internal.ui.viewsupport.JavaElementImageProvider; import org.eclipse.wst.jsdt.internal.ui.viewsupport.OwnerDrawSupport; import org.eclipse.wst.jsdt.internal.ui.workingsets.WorkingSetFilterActionGroup; import org.eclipse.wst.jsdt.launching.IVMInstall; import org.eclipse.wst.jsdt.launching.IVMInstallType; import org.eclipse.wst.jsdt.launching.JavaRuntime; import org.eclipse.wst.jsdt.launching.LibraryLocation; import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels; import org.eclipse.wst.jsdt.ui.JavaScriptUI; import org.eclipse.wst.jsdt.ui.dialogs.ITypeInfoFilterExtension; import org.eclipse.wst.jsdt.ui.dialogs.ITypeInfoImageProvider; import org.eclipse.wst.jsdt.ui.dialogs.ITypeSelectionComponent; import org.eclipse.wst.jsdt.ui.dialogs.TypeSelectionExtension; /** * Shows a list of Java types to the user with a text entry field for a string * pattern used to filter the list of types. * * */ public class FilteredTypesSelectionDialog extends FilteredItemsSelectionDialog implements ITypeSelectionComponent { /** * Disabled "Show Container for Duplicates because of * https://bugs.eclipse.org/bugs/show_bug.cgi?id=184693 . */ private static final boolean BUG_184693= true; private static final String DIALOG_SETTINGS= "org.eclipse.wst.jsdt.internal.ui.dialogs.FilteredTypesSelectionDialog"; //$NON-NLS-1$ private static final String SHOW_CONTAINER_FOR_DUPLICATES= "ShowContainerForDuplicates"; //$NON-NLS-1$ private static final String WORKINGS_SET_SETTINGS= "WorkingSet"; //$NON-NLS-1$ private WorkingSetFilterActionGroup fFilterActionGroup; private final TypeItemLabelProvider fTypeInfoLabelProvider; private String fTitle; private ShowContainerForDuplicatesAction fShowContainerForDuplicatesAction; private IJavaScriptSearchScope fSearchScope; private boolean fAllowScopeSwitching; private final int fElementKinds; private final ITypeInfoFilterExtension fFilterExtension; private final TypeSelectionExtension fExtension; private ISelectionStatusValidator fValidator; private final TypeInfoUtil fTypeInfoUtil; private static boolean fgFirstTime= true; private final TypeItemsComparator fTypeItemsComparator; private int fTypeFilterVersion= 0; /** * Creates new FilteredTypesSelectionDialog instance * * @param parent * shell to parent the dialog on * @param multi * <code>true</code> if multiple selection is allowed * @param context * context used to execute long-running operations associated * with this dialog * @param scope * scope used when searching for types * @param elementKinds * flags defining nature of searched elements; the only valid * values are: <code>IJavaScriptSearchConstants.TYPE</code> * <code>IJavaScriptSearchConstants.ANNOTATION_TYPE</code> * <code>IJavaScriptSearchConstants.INTERFACE</code> * <code>IJavaScriptSearchConstants.ENUM</code> * <code>IJavaScriptSearchConstants.CLASS_AND_INTERFACE</code> * <code>IJavaScriptSearchConstants.CLASS_AND_ENUM</code>. * Please note that the bitwise OR combination of the elementary * constants is not supported. */ public FilteredTypesSelectionDialog(Shell parent, boolean multi, IRunnableContext context, IJavaScriptSearchScope scope, int elementKinds) { this(parent, multi, context, scope, elementKinds, null); } /** * Creates new FilteredTypesSelectionDialog instance. * * @param shell * shell to parent the dialog on * @param multi * <code>true</code> if multiple selection is allowed * @param context * context used to execute long-running operations associated * with this dialog * @param scope * scope used when searching for types. If the scope is <code>null</code>, * then workspace is scope is used as default, and the user can * choose a working set as scope. * @param elementKinds * flags defining nature of searched elements; the only valid * values are: <code>IJavaScriptSearchConstants.TYPE</code> * <code>IJavaScriptSearchConstants.ANNOTATION_TYPE</code> * <code>IJavaScriptSearchConstants.INTERFACE</code> * <code>IJavaScriptSearchConstants.ENUM</code> * <code>IJavaScriptSearchConstants.CLASS_AND_INTERFACE</code> * <code>IJavaScriptSearchConstants.CLASS_AND_ENUM</code>. * Please note that the bitwise OR combination of the elementary * constants is not supported. * @param extension * an extension of the standard type selection dialog; See * {@link TypeSelectionExtension} */ public FilteredTypesSelectionDialog(Shell shell, boolean multi, IRunnableContext context, IJavaScriptSearchScope scope, int elementKinds, TypeSelectionExtension extension) { super(shell, multi); setSelectionHistory(new TypeSelectionHistory()); if (scope == null) { fAllowScopeSwitching= true; scope= SearchEngine.createWorkspaceScope(); } PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.TYPE_SELECTION_DIALOG2); fElementKinds= elementKinds; fExtension= extension; fFilterExtension= (extension == null) ? null : extension.getFilterExtension(); fSearchScope= scope; if (extension != null) { fValidator= extension.getSelectionValidator(); } fTypeInfoUtil= new TypeInfoUtil(extension != null ? extension.getImageProvider() : null); fTypeInfoLabelProvider= new TypeItemLabelProvider(); setListLabelProvider(fTypeInfoLabelProvider); setListSelectionLabelDecorator(fTypeInfoLabelProvider); setDetailsLabelProvider(new TypeItemDetailsLabelProvider(fTypeInfoUtil)); fTypeItemsComparator= new TypeItemsComparator(); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SelectionDialog#setTitle(java.lang.String) */ public void setTitle(String title) { super.setTitle(title); fTitle= title; } /** * Adds or replaces subtitle of the dialog * * @param text * the new subtitle for this dialog */ private void setSubtitle(String text) { if (text == null || text.length() == 0) { getShell().setText(fTitle); } else { getShell().setText(Messages.format(JavaUIMessages.FilteredTypeSelectionDialog_titleFormat, new String[] { fTitle, text })); } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.AbstractSearchDialog#getDialogSettings() */ protected IDialogSettings getDialogSettings() { IDialogSettings settings= JavaScriptPlugin.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS); if (settings == null) { settings= JavaScriptPlugin.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS); } return settings; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.AbstractSearchDialog#storeDialog(org.eclipse.jface.dialogs.IDialogSettings) */ protected void storeDialog(IDialogSettings settings) { super.storeDialog(settings); if (! BUG_184693) { settings.put(SHOW_CONTAINER_FOR_DUPLICATES, fShowContainerForDuplicatesAction.isChecked()); } if (fFilterActionGroup != null) { XMLMemento memento= XMLMemento.createWriteRoot("workingSet"); //$NON-NLS-1$ fFilterActionGroup.saveState(memento); fFilterActionGroup.dispose(); StringWriter writer= new StringWriter(); try { memento.save(writer); settings.put(WORKINGS_SET_SETTINGS, writer.getBuffer().toString()); } catch (IOException e) { // don't do anything. Simply don't store the settings JavaScriptPlugin.log(e); } } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.AbstractSearchDialog#restoreDialog(org.eclipse.jface.dialogs.IDialogSettings) */ protected void restoreDialog(IDialogSettings settings) { super.restoreDialog(settings); if (! BUG_184693) { boolean showContainer= settings.getBoolean(SHOW_CONTAINER_FOR_DUPLICATES); fShowContainerForDuplicatesAction.setChecked(showContainer); fTypeInfoLabelProvider.setContainerInfo(showContainer); } else { fTypeInfoLabelProvider.setContainerInfo(true); } if (fAllowScopeSwitching) { String setting= settings.get(WORKINGS_SET_SETTINGS); if (setting != null) { try { IMemento memento= XMLMemento.createReadRoot(new StringReader(setting)); fFilterActionGroup.restoreState(memento); } catch (WorkbenchException e) { // don't do anything. Simply don't restore the settings JavaScriptPlugin.log(e); } } IWorkingSet ws= fFilterActionGroup.getWorkingSet(); if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) { setSearchScope(SearchEngine.createWorkspaceScope()); setSubtitle(null); } else { setSearchScope(JavaSearchScopeFactory.getInstance().createJavaSearchScope(ws, true)); setSubtitle(ws.getLabel()); } } // TypeNameMatch[] types = OpenTypeHistory.getInstance().getTypeInfos(); // // for (int i = 0; i < types.length; i++) { // TypeNameMatch type = types[i]; // accessedHistoryItem(type); // } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.AbstractSearchDialog#fillViewMenu(org.eclipse.jface.action.IMenuManager) */ protected void fillViewMenu(IMenuManager menuManager) { super.fillViewMenu(menuManager); if (! BUG_184693) { fShowContainerForDuplicatesAction= new ShowContainerForDuplicatesAction(); menuManager.add(fShowContainerForDuplicatesAction); } if (fAllowScopeSwitching) { fFilterActionGroup= new WorkingSetFilterActionGroup(getShell(), JavaScriptPlugin.getActivePage(), new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { IWorkingSet ws= (IWorkingSet) event.getNewValue(); if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) { setSearchScope(SearchEngine.createWorkspaceScope()); setSubtitle(null); } else { setSearchScope(JavaSearchScopeFactory.getInstance().createJavaSearchScope(ws, true)); setSubtitle(ws.getLabel()); } applyFilter(); } }); fFilterActionGroup.fillViewMenu(menuManager); } //no type filter preference pages currently exist for JSDT //menuManager.add(new Separator()); //menuManager.add(new TypeFiltersPreferencesAction()); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite) */ protected Control createExtendedContentArea(Composite parent) { Control addition= null; if (fExtension != null) { addition= fExtension.createContentArea(parent); if (addition != null) { GridData gd= new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan= 2; addition.setLayoutData(gd); } fExtension.initialize(this); } return addition; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SelectionDialog#setResult(java.util.List) */ protected void setResult(List newResult) { List resultToReturn= new ArrayList(); for (int i= 0; i < newResult.size(); i++) { if (newResult.get(i) instanceof TypeNameMatch) { IType type= ((TypeNameMatch) newResult.get(i)).getType(); if (type.exists()) { // items are added to history in the // org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#computeResult() // method resultToReturn.add(type); } else { TypeNameMatch typeInfo= (TypeNameMatch) newResult.get(i); IPackageFragmentRoot root= typeInfo.getPackageFragmentRoot(); String containerName= JavaScriptElementLabels.getElementLabel(root, JavaScriptElementLabels.ROOT_QUALIFIED); String message= Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_dialogMessage, new String[] { typeInfo.getFullyQualifiedName(), containerName }); MessageDialog.openError(getShell(), fTitle, message); getSelectionHistory().remove(typeInfo); } } } super.setResult(resultToReturn); } /* * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#create() */ public void create() { super.create(); Control patternControl= getPatternControl(); if (patternControl instanceof Text) { TextFieldNavigationHandler.install((Text) patternControl); } } /* * (non-Javadoc) * * @see org.eclipse.jface.window.Window#open() */ public int open() { if (getInitialPattern() == null) { IWorkbenchWindow window= JavaScriptPlugin.getActiveWorkbenchWindow(); if (window != null) { ISelection selection= window.getSelectionService().getSelection(); if (selection instanceof ITextSelection) { String text= ((ITextSelection) selection).getText(); if (text != null) { text= text.trim(); if (text.length() > 0 && JavaScriptConventions.validateJavaScriptTypeName(text, JavaScriptCore.VERSION_1_3, JavaScriptCore.VERSION_1_3).isOK()) { setInitialPattern(text, FULL_SELECTION); } } } } } return super.open(); } /** * Sets a new validator. * * @param validator * the new validator */ public void setValidator(ISelectionStatusValidator validator) { fValidator= validator; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter() */ protected ItemsFilter createFilter() { return new TypeItemsFilter(fSearchScope, fElementKinds, fFilterExtension); } protected Control createContents(Composite parent) { Control contents= super.createContents(parent); if (ColoredViewersManager.showColoredLabels()) { if (contents instanceof Composite) { Table listControl= findTableControl((Composite) contents); if (listControl != null) { installOwnerDraw(listControl); } } } return contents; } private void installOwnerDraw(Table tableControl) { new OwnerDrawSupport(tableControl) { // installs the owner draw listeners public ColoredString getColoredLabel(Item item) { String text= item.getText(); ColoredString str= new ColoredString(text); int index= text.indexOf('-'); if (index != -1) { str.colorize(index, str.length() - index, ColoredJavaElementLabels.QUALIFIER_STYLE); } return str; } public Color getColor(String foregroundColorName, Display display) { return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(foregroundColorName); } }; } private Table findTableControl(Composite composite) { Control[] children= composite.getChildren(); for (int i= 0; i < children.length; i++) { Control curr= children[i]; if (curr instanceof Table) { return (Table) curr; } else if (curr instanceof Composite) { Table res= findTableControl((Composite) curr); if (res != null) { return res; } } } return null; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, * org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, * org.eclipse.core.runtime.IProgressMonitor) */ protected void fillContentProvider(AbstractContentProvider provider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException { TypeItemsFilter typeSearchFilter= (TypeItemsFilter) itemsFilter; TypeSearchRequestor requestor= new TypeSearchRequestor(provider, typeSearchFilter); SearchEngine engine= new SearchEngine((WorkingCopyOwner) null); progressMonitor.setTaskName(JavaUIMessages.FilteredTypesSelectionDialog_searchJob_taskName); /* * Setting the filter into match everything mode avoids filtering twice * by the same pattern (the search engine only provides filtered * matches). For the case when the pattern is a camel case pattern with * a terminator, the filter is not set to match everything mode because * jdt.core's SearchPattern does not support that case. */ String prefix= typeSearchFilter.getInitialPattern(); int matchRule= typeSearchFilter.getMatchRule(); if (matchRule == SearchPattern.RULE_CAMELCASE_MATCH) { // If the pattern is empty, the RULE_BLANK_MATCH will be chosen, so we don't have to check the pattern length char lastChar= prefix.charAt(prefix.length() - 1); if (lastChar == '<' || lastChar == ' ') { prefix= prefix.substring(0, prefix.length() - 1); } else { typeSearchFilter.setMatchEverythingMode(true); } matchRule |= SearchPattern.RULE_PREFIX_MATCH; } else { typeSearchFilter.setMatchEverythingMode(true); } try { engine.searchAllTypeNames(prefix.toCharArray(), matchRule, //TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=176017 typeSearchFilter.getElementKind(), typeSearchFilter.getSearchScope(), requestor, IJavaScriptSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, progressMonitor); } finally { typeSearchFilter.setMatchEverythingMode(false); } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator() */ protected Comparator getItemsComparator() { return fTypeItemsComparator; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object) */ public String getElementName(Object item) { TypeNameMatch type= (TypeNameMatch) item; return fTypeInfoUtil.getText(type); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object) */ protected IStatus validateItem(Object item) { if (item == null) return new Status(IStatus.ERROR, JavaScriptPlugin.getPluginId(), IStatus.ERROR, "", null); //$NON-NLS-1$ if (fValidator != null) { IType type= ((TypeNameMatch) item).getType(); if (!type.exists()) return new Status(IStatus.ERROR, JavaScriptPlugin.getPluginId(), IStatus.ERROR, Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_error_type_doesnot_exist, ((TypeNameMatch) item).getFullyQualifiedName()), null); Object[] elements= { type }; return fValidator.validate(elements); } else return new Status(IStatus.OK, JavaScriptPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ } /** * Sets search scope used when searching for types. * * @param scope * the new scope */ private void setSearchScope(IJavaScriptSearchScope scope) { fSearchScope= scope; } /* * We only have to ensure history consistency here since the search engine * takes care of working copies. */ private static class ConsistencyRunnable implements IRunnableWithProgress { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { if (fgFirstTime) { // Join the initialize after load job. IJobManager manager= Job.getJobManager(); manager.join(JavaScriptUI.ID_PLUGIN, monitor); } OpenTypeHistory history= OpenTypeHistory.getInstance(); if (fgFirstTime || history.isEmpty()) { if (history.needConsistencyCheck()) { monitor.beginTask(JavaUIMessages.TypeSelectionDialog_progress_consistency, 100); refreshSearchIndices(new SubProgressMonitor(monitor, 90)); history.checkConsistency(new SubProgressMonitor(monitor, 10)); } else { refreshSearchIndices(monitor); } monitor.done(); fgFirstTime= false; } else { history.checkConsistency(monitor); } } public static boolean needsExecution() { OpenTypeHistory history= OpenTypeHistory.getInstance(); return fgFirstTime || history.isEmpty() || history.needConsistencyCheck(); } private void refreshSearchIndices(IProgressMonitor monitor) throws InvocationTargetException { try { new SearchEngine().searchAllTypeNames( null, 0, // make sure we search a concrete name. This is faster according to Kent "_______________".toCharArray(), //$NON-NLS-1$ SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_CASE_SENSITIVE, IJavaScriptSearchConstants.ENUM, SearchEngine.createWorkspaceScope(), new TypeNameRequestor() {}, IJavaScriptSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor); } catch (JavaScriptModelException e) { throw new InvocationTargetException(e); } } } /* * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#reloadCache(boolean, org.eclipse.core.runtime.IProgressMonitor) */ public void reloadCache(boolean checkDuplicates, IProgressMonitor monitor) { IProgressMonitor remainingMonitor; if (ConsistencyRunnable.needsExecution()) { monitor.beginTask(JavaUIMessages.TypeSelectionDialog_progress_consistency, 10); try { ConsistencyRunnable runnable= new ConsistencyRunnable(); runnable.run(new SubProgressMonitor(monitor, 1)); } catch (InvocationTargetException e) { ExceptionHandler.handle(e, JavaUIMessages.TypeSelectionDialog_error3Title, JavaUIMessages.TypeSelectionDialog_error3Message); close(); return; } catch (InterruptedException e) { // cancelled by user close(); return; } remainingMonitor= new SubProgressMonitor(monitor, 9); } else { remainingMonitor= monitor; } super.reloadCache(checkDuplicates, remainingMonitor); monitor.done(); } /* * @see org.eclipse.wst.jsdt.ui.dialogs.ITypeSelectionComponent#triggerSearch() */ public void triggerSearch() { fTypeFilterVersion++; applyFilter(); } /** * The <code>ShowContainerForDuplicatesAction</code> provides means to * show/hide container information for duplicate elements. */ private class ShowContainerForDuplicatesAction extends Action { /** * Creates a new instance of the class */ public ShowContainerForDuplicatesAction() { super(JavaUIMessages.FilteredTypeSelectionDialog_showContainerForDuplicatesAction, IAction.AS_CHECK_BOX); } /* * (non-Javadoc) * * @see org.eclipse.jface.action.Action#run() */ public void run() { fTypeInfoLabelProvider.setContainerInfo(isChecked()); } } private class TypeFiltersPreferencesAction extends Action { public TypeFiltersPreferencesAction() { super(JavaUIMessages.FilteredTypesSelectionDialog_TypeFiltersPreferencesAction_label); } /* * (non-Javadoc) * * @see org.eclipse.jface.action.Action#run() */ public void run() { String typeFilterID= TypeFilterPreferencePage.TYPE_FILTER_PREF_PAGE_ID; PreferencesUtil.createPreferenceDialogOn(getShell(), typeFilterID, new String[] { typeFilterID }, null).open(); triggerSearch(); } } /** * A <code>LabelProvider</code> for (the table of) types. */ private class TypeItemLabelProvider extends LabelProvider implements ILabelDecorator { private boolean fContainerInfo; /** * Construct a new <code>TypeItemLabelProvider</code>. F */ public TypeItemLabelProvider() { } public void setContainerInfo(boolean containerInfo) { fContainerInfo= containerInfo; fireLabelProviderChanged(new LabelProviderChangedEvent(this)); } private boolean isInnerType(TypeNameMatch match) { return match.getTypeQualifiedName().indexOf('.') != -1; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) */ public Image getImage(Object element) { if (!(element instanceof TypeNameMatch)) { return super.getImage(element); } TypeNameMatch type= (TypeNameMatch) element; ImageDescriptor iD= JavaElementImageProvider.getTypeImageDescriptor(isInnerType(type), false, type.getModifiers(), false); return JavaScriptPlugin.getImageDescriptorRegistry().get(iD); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ public String getText(Object element) { if (!(element instanceof TypeNameMatch)) { return super.getText(element); } if (fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element); } if (!fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element); } return fTypeInfoUtil.getText(element); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image, * java.lang.Object) */ public Image decorateImage(Image image, Object element) { return null; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String, * java.lang.Object) */ public String decorateText(String text, Object element) { if (!(element instanceof TypeNameMatch)) { return null; } if (fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element); } return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element); } } /** * A <code>LabelProvider</code> for the label showing type details. */ private static class TypeItemDetailsLabelProvider extends LabelProvider { private final TypeNameMatchLabelProvider fLabelProvider= new TypeNameMatchLabelProvider(TypeNameMatchLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeNameMatchLabelProvider.SHOW_ROOT_POSTFIX); private final TypeInfoUtil fTypeInfoUtil; public TypeItemDetailsLabelProvider(TypeInfoUtil typeInfoUtil) { fTypeInfoUtil= typeInfoUtil; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) */ public Image getImage(Object element) { if (element instanceof TypeNameMatch) { return fLabelProvider.getImage((element)); } return super.getImage(element); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ public String getText(Object element) { if (element instanceof TypeNameMatch) { return fTypeInfoUtil.getQualificationText((TypeNameMatch) element); } return super.getText(element); } } private static class TypeInfoUtil { private final ITypeInfoImageProvider fProviderExtension; private final TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter(); private final Map fLib2Name= new HashMap(); private final String[] fInstallLocations; private final String[] fVMNames; private boolean fFullyQualifyDuplicates; public TypeInfoUtil(ITypeInfoImageProvider extension) { fProviderExtension= extension; List locations= new ArrayList(); List labels= new ArrayList(); IVMInstallType[] installs= JavaRuntime.getVMInstallTypes(); for (int i= 0; i < installs.length; i++) { processVMInstallType(installs[i], locations, labels); } fInstallLocations= (String[]) locations.toArray(new String[locations.size()]); fVMNames= (String[]) labels.toArray(new String[labels.size()]); } public void setFullyQualifyDuplicates(boolean value) { fFullyQualifyDuplicates= value; } private void processVMInstallType(IVMInstallType installType, List locations, List labels) { if (installType != null) { IVMInstall[] installs= installType.getVMInstalls(); boolean isMac= Platform.OS_MACOSX.equals(Platform.getOS()); final String HOME_SUFFIX= "/Home"; //$NON-NLS-1$ for (int i= 0; i < installs.length; i++) { String label= getFormattedLabel(installs[i].getName()); LibraryLocation[] libLocations= installs[i].getLibraryLocations(); if (libLocations != null) { processLibraryLocation(libLocations, label); } else { String filePath= installs[i].getInstallLocation().getAbsolutePath(); // on MacOS X install locations end in an additional // "/Home" segment; remove it if (isMac && filePath.endsWith(HOME_SUFFIX)) filePath= filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1); locations.add(filePath); labels.add(label); } } } } private void processLibraryLocation(LibraryLocation[] libLocations, String label) { for (int l= 0; l < libLocations.length; l++) { LibraryLocation location= libLocations[l]; fLib2Name.put(location.getSystemLibraryPath().toOSString(), label); } } private String getFormattedLabel(String name) { return Messages.format(JavaUIMessages.FilteredTypesSelectionDialog_library_name_format, name); } public String getText(Object element) { return ((TypeNameMatch) element).getQualifiedName(); } public String getQualifiedText(TypeNameMatch type) { StringBuffer result= new StringBuffer(); result.append(type.getQualifiedName()); String containerName= type.getTypeContainerName(); result.append(JavaScriptElementLabels.CONCAT_STRING); if (containerName.length() > 0) { result.append(containerName); } else { result.append(JavaUIMessages.FilteredTypesSelectionDialog_default_package); } return result.toString(); } public String getFullyQualifiedText(TypeNameMatch type) { StringBuffer result= new StringBuffer(); result.append(type.getSimpleTypeName()); String containerName= type.getTypeContainerName(); if (containerName.length() > 0) { result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(containerName); } result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(getContainerName(type)); return result.toString(); } public String getText(TypeNameMatch last, TypeNameMatch current, TypeNameMatch next) { StringBuffer result= new StringBuffer(); int qualifications= 0; String currentTN= current.getSimpleTypeName(); result.append(currentTN); String currentTCN= getTypeContainerName(current); if (last != null) { String lastTN= last.getSimpleTypeName(); String lastTCN= getTypeContainerName(last); if (currentTCN.equals(lastTCN)) { if (currentTN.equals(lastTN)) { result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(currentTCN); result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(getContainerName(current)); return result.toString(); } } else if (currentTN.equals(lastTN)) { qualifications= 1; } } if (next != null) { String nextTN= next.getSimpleTypeName(); String nextTCN= getTypeContainerName(next); if (currentTCN.equals(nextTCN)) { if (currentTN.equals(nextTN)) { result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(currentTCN); result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(getContainerName(current)); return result.toString(); } } else if (currentTN.equals(nextTN)) { qualifications= 1; } } if (qualifications > 0) { result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(currentTCN); if (fFullyQualifyDuplicates) { result.append(JavaScriptElementLabels.CONCAT_STRING); result.append(getContainerName(current)); } } return result.toString(); } public String getQualificationText(TypeNameMatch type) { StringBuffer result= new StringBuffer(); String containerName= type.getTypeContainerName(); if (containerName.length() > 0) { result.append(containerName); result.append(JavaScriptElementLabels.CONCAT_STRING); } result.append(getContainerName(type)); return result.toString(); } private boolean isInnerType(TypeNameMatch match) { return match.getTypeQualifiedName().indexOf('.') != -1; } public ImageDescriptor getImageDescriptor(Object element) { TypeNameMatch type= (TypeNameMatch) element; if (fProviderExtension != null) { fAdapter.setMatch(type); ImageDescriptor descriptor= fProviderExtension.getImageDescriptor(fAdapter); if (descriptor != null) return descriptor; } return JavaElementImageProvider.getTypeImageDescriptor(isInnerType(type), false, type.getModifiers(), false); } private String getTypeContainerName(TypeNameMatch info) { String result= info.getTypeContainerName(); if (result.length() > 0) return result; return JavaUIMessages.FilteredTypesSelectionDialog_default_package; } private String getContainerName(TypeNameMatch type) { IPackageFragmentRoot root= type.getPackageFragmentRoot(); if (root.isExternal()) { String name= root.getPath().toOSString(); for (int i= 0; i < fInstallLocations.length; i++) { if (name.startsWith(fInstallLocations[i])) { return fVMNames[i]; } } String lib= (String) fLib2Name.get(name); if (lib != null) return lib; } StringBuffer buf= new StringBuffer(); JavaScriptElementLabels.getPackageFragmentRootLabel(root, JavaScriptElementLabels.ROOT_QUALIFIED | JavaScriptElementLabels.ROOT_VARIABLE, buf); return buf.toString(); } } /** * Filters types using pattern, scope, element kind and filter extension. */ private class TypeItemsFilter extends ItemsFilter { private final IJavaScriptSearchScope fScope; private final boolean fIsWorkspaceScope; private final int fElemKind; private final ITypeInfoFilterExtension fFilterExt; private final TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter(); private SearchPattern fPackageMatcher; private boolean fMatchEverything= false; private final int fMyTypeFilterVersion= fTypeFilterVersion; private TypeSearchPattern fInitialPattern; /** * Creates instance of TypeItemsFilter * * @param scope * @param elementKind * @param extension */ public TypeItemsFilter(IJavaScriptSearchScope scope, int elementKind, ITypeInfoFilterExtension extension) { super(new TypeSearchPattern()); fScope= scope; fIsWorkspaceScope= scope == null ? false : scope.equals(SearchEngine.createWorkspaceScope()); fElemKind= elementKind; fFilterExt= extension; String initialString = ((TypeSearchPattern) patternMatcher).getInitialString(); String stringPackage= ((TypeSearchPattern) patternMatcher).getPackagePattern(); fInitialPattern = new TypeSearchPattern(); fInitialPattern.setInitialPattern(initialString); if (stringPackage != null) { fPackageMatcher= new SearchPattern(); fPackageMatcher.setPattern(stringPackage); } else { fPackageMatcher= null; } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isSubFilter(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter) */ public boolean isSubFilter(ItemsFilter filter) { if (!super.isSubFilter(filter)) return false; TypeItemsFilter typeItemsFilter= (TypeItemsFilter) filter; if (fScope != typeItemsFilter.getSearchScope()) return false; if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) return false; return getPattern().indexOf('.', filter.getPattern().length()) == -1; } public boolean equalsFilter(ItemsFilter iFilter) { if (!super.equalsFilter(iFilter)) return false; if (!(iFilter instanceof TypeItemsFilter)) return false; TypeItemsFilter typeItemsFilter= (TypeItemsFilter) iFilter; if (fScope != typeItemsFilter.getSearchScope()) return false; if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) return false; return true; } public int getElementKind() { return fElemKind; } public ITypeInfoFilterExtension getFilterExtension() { return fFilterExt; } public IJavaScriptSearchScope getSearchScope() { return fScope; } public int getMyTypeFilterVersion() { return fMyTypeFilterVersion; } public String getPackagePattern() { if (fPackageMatcher == null) return null; return fPackageMatcher.getPattern(); } public int getPackageFlags() { if (fPackageMatcher == null) return SearchPattern.RULE_PREFIX_MATCH; return fPackageMatcher.getMatchRule(); } public String getInitialPattern() { if (fInitialPattern == null) return null; return fInitialPattern.getPattern(); } public boolean matchesRawNamePattern(TypeNameMatch type) { return Strings.startsWithIgnoreCase(type.getSimpleTypeName(), getPattern()); } public boolean matchesCachedResult(TypeNameMatch type) { if (!(matchesPackage(type) && matchesFilterExtension(type))) return false; return matchesName(type); } public boolean matchesHistoryElement(TypeNameMatch type) { if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type))) return false; return matchesName(type); } public boolean matchesFilterExtension(TypeNameMatch type) { if (fFilterExt == null) return true; fAdapter.setMatch(type); return fFilterExt.select(fAdapter); } private boolean matchesName(TypeNameMatch type) { return matches(type.getSimpleTypeName()); } private boolean matchesPackage(TypeNameMatch type) { if (fPackageMatcher == null) return true; return fPackageMatcher.matches(type.getPackageName()); } private boolean matchesScope(TypeNameMatch type) { if (fIsWorkspaceScope) return true; return fScope.encloses(type.getType()); } private boolean matchesModifiers(TypeNameMatch type) { if (fElemKind == IJavaScriptSearchConstants.TYPE) return true; int modifiers= type.getModifiers(); switch (fElemKind) { case IJavaScriptSearchConstants.CLASS: return modifiers == 0; } return false; } /** * Set filter to "match everything" mode. * * @param matchEverything if <code>true</code>, {@link #matchItem(Object)} always returns true. * If <code>false</code>, the filter is enabled. */ public void setMatchEverythingMode(boolean matchEverything) { this.fMatchEverything= matchEverything; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isConsistentItem(java.lang.Object) */ public boolean isConsistentItem(Object item) { return true; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#matchItem(java.lang.Object) */ public boolean matchItem(Object item) { if (fMatchEverything) return true; TypeNameMatch type= (TypeNameMatch) item; if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type))) return false; return fInitialPattern.matches(type.getPackageName()) || matchesName(type); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#matchesRawNamePattern(java.lang.Object) */ public boolean matchesRawNamePattern(Object item) { TypeNameMatch type= (TypeNameMatch) item; return matchesRawNamePattern(type); } public int getMatchRule() { return fInitialPattern.getMatchRule(); } } /** * Extends functionality of SearchPatterns */ private static class TypeSearchPattern extends SearchPattern { private String packagePattern; private String initialString; /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SearchPattern#setPattern(java.lang.String) */ public void setPattern(String stringPattern) { initialString = stringPattern; String pattern= stringPattern; String packPattern= null; int index= stringPattern.lastIndexOf("."); //$NON-NLS-1$ if (index != -1) { packPattern= evaluatePackagePattern(stringPattern.substring(0, index)); pattern= stringPattern.substring(index + 1); if (pattern.length() == 0) pattern= "**"; //$NON-NLS-1$ } super.setPattern(pattern); packagePattern= packPattern; } public void setInitialPattern(String stringPattern) { super.setPattern(stringPattern); } /* * Transforms o.e.j to o*.e*.j* */ private String evaluatePackagePattern(String s) { StringBuffer buf= new StringBuffer(); boolean hasWildCard= false; for (int i= 0; i < s.length(); i++) { char ch= s.charAt(i); if (ch == '.') { if (!hasWildCard) { buf.append('*'); } hasWildCard= false; } else if (ch == '*' || ch == '?') { hasWildCard= true; } buf.append(ch); } if (!hasWildCard) { buf.append('*'); } return buf.toString(); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SearchPattern#isNameCharAllowed(char) */ protected boolean isNameCharAllowed(char nameChar) { return super.isNameCharAllowed(nameChar); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SearchPattern#isPatternCharAllowed(char) */ protected boolean isPatternCharAllowed(char patternChar) { return super.isPatternCharAllowed(patternChar); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.SearchPattern#isValidCamelCaseChar(char) */ protected boolean isValidCamelCaseChar(char ch) { return ch != '.'; } /** * @return the packagePattern */ public String getPackagePattern() { return packagePattern; } /** * @return the initialPattern */ public String getInitialString() { return initialString; } } /** * A <code>TypeSearchRequestor</code> collects matches filtered using * <code>TypeItemsFilter</code>. The attached content provider is filled * on the basis of the collected entries (instances of * <code>TypeNameMatch</code>). */ private static class TypeSearchRequestor extends TypeNameMatchRequestor { private volatile boolean fStop; private final AbstractContentProvider fContentProvider; private final TypeItemsFilter fTypeItemsFilter; public TypeSearchRequestor(AbstractContentProvider contentProvider, TypeItemsFilter typeItemsFilter) { super(); fContentProvider= contentProvider; fTypeItemsFilter= typeItemsFilter; } public void cancel() { fStop= true; } /* * (non-Javadoc) * * @see org.eclipse.wst.jsdt.core.search.TypeNameMatchRequestor#acceptTypeNameMatch(org.eclipse.wst.jsdt.core.search.TypeNameMatch) */ public void acceptTypeNameMatch(TypeNameMatch match) { if (fStop) return; if (TypeFilter.isFiltered(match)) return; if (CharOperation.indexOf(IInferEngine.ANONYMOUS_PREFIX, match.getSimpleTypeName().toCharArray(), false) == 0) return; if (fTypeItemsFilter.matchesFilterExtension(match)) fContentProvider.add(match, fTypeItemsFilter); } } /** * Compares TypeItems is used during sorting */ private static class TypeItemsComparator implements Comparator { private final Map fLib2Name= new HashMap(); private final String[] fInstallLocations; private final String[] fVMNames; /** * Creates new instance of TypeItemsComparator */ public TypeItemsComparator() { List locations= new ArrayList(); List labels= new ArrayList(); IVMInstallType[] installs= JavaRuntime.getVMInstallTypes(); for (int i= 0; i < installs.length; i++) { processVMInstallType(installs[i], locations, labels); } fInstallLocations= (String[]) locations.toArray(new String[locations.size()]); fVMNames= (String[]) labels.toArray(new String[labels.size()]); } private void processVMInstallType(IVMInstallType installType, List locations, List labels) { if (installType != null) { IVMInstall[] installs= installType.getVMInstalls(); boolean isMac= Platform.OS_MACOSX.equals(Platform.getOS()); final String HOME_SUFFIX= "/Home"; //$NON-NLS-1$ for (int i= 0; i < installs.length; i++) { String label= getFormattedLabel(installs[i].getName()); LibraryLocation[] libLocations= installs[i].getLibraryLocations(); if (libLocations != null) { processLibraryLocation(libLocations, label); } else { String filePath= installs[i].getInstallLocation().getAbsolutePath(); // on MacOS X install locations end in an additional // "/Home" segment; remove it if (isMac && filePath.endsWith(HOME_SUFFIX)) filePath= filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1); locations.add(filePath); labels.add(label); } } } } private void processLibraryLocation(LibraryLocation[] libLocations, String label) { for (int l= 0; l < libLocations.length; l++) { LibraryLocation location= libLocations[l]; fLib2Name.put(location.getSystemLibraryPath().toString(), label); } } private String getFormattedLabel(String name) { return MessageFormat.format(JavaUIMessages.FilteredTypesSelectionDialog_library_name_format, new Object[] { name }); } /* * (non-Javadoc) * * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(Object left, Object right) { TypeNameMatch leftInfo= (TypeNameMatch) left; TypeNameMatch rightInfo= (TypeNameMatch) right; int result= compareName(leftInfo.getSimpleTypeName(), rightInfo.getSimpleTypeName()); if (result != 0) return result; result= compareTypeContainerName(leftInfo.getTypeContainerName(), rightInfo.getTypeContainerName()); if (result != 0) return result; int leftCategory= getElementTypeCategory(leftInfo); int rightCategory= getElementTypeCategory(rightInfo); if (leftCategory < rightCategory) return -1; if (leftCategory > rightCategory) return +1; return compareContainerName(leftInfo, rightInfo); } private int compareName(String leftString, String rightString) { int result= leftString.compareToIgnoreCase(rightString); if (result != 0 || rightString.length() == 0) { return result; } else if (Strings.isLowerCase(leftString.charAt(0)) && !Strings.isLowerCase(rightString.charAt(0))) { return +1; } else if (Strings.isLowerCase(rightString.charAt(0)) && !Strings.isLowerCase(leftString.charAt(0))) { return -1; } else { return leftString.compareTo(rightString); } } private int compareTypeContainerName(String leftString, String rightString) { int leftLength= leftString.length(); int rightLength= rightString.length(); if (leftLength == 0 && rightLength > 0) return -1; if (leftLength == 0 && rightLength == 0) return 0; if (leftLength > 0 && rightLength == 0) return +1; return compareName(leftString, rightString); } private int compareContainerName(TypeNameMatch leftType, TypeNameMatch rightType) { return getContainerName(leftType).compareTo(getContainerName(rightType)); } private String getContainerName(TypeNameMatch type) { IPackageFragmentRoot root= type.getPackageFragmentRoot(); if (root.isExternal()) { String name= root.getPath().toOSString(); for (int i= 0; i < fInstallLocations.length; i++) { if (name.startsWith(fInstallLocations[i])) { return fVMNames[i]; } } String lib= (String) fLib2Name.get(name); if (lib != null) return lib; } StringBuffer buf= new StringBuffer(); JavaScriptElementLabels.getPackageFragmentRootLabel(root, JavaScriptElementLabels.ROOT_QUALIFIED | JavaScriptElementLabels.ROOT_VARIABLE, buf); return buf.toString(); } private int getElementTypeCategory(TypeNameMatch type) { try { if (type.getPackageFragmentRoot().getKind() == IPackageFragmentRoot.K_SOURCE) return 0; } catch (JavaScriptModelException e) { JavaScriptPlugin.log(e); } return 1; } } /** * Extends the <code>SelectionHistory</code>, providing support for * <code>OpenTypeHistory</code>. */ protected class TypeSelectionHistory extends SelectionHistory { /** * Creates new instance of TypeSelectionHistory */ public TypeSelectionHistory() { super(); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#accessed(java.lang.Object) */ public synchronized void accessed(Object object) { super.accessed(object); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#remove(java.lang.Object) */ public synchronized boolean remove(Object element) { OpenTypeHistory.getInstance().remove((TypeNameMatch) element); return super.remove(element); } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#load(org.eclipse.ui.IMemento) */ public void load(IMemento memento) { TypeNameMatch[] types= OpenTypeHistory.getInstance().getTypeInfos(); for (int i= 0; i < types.length; i++) { TypeNameMatch type= types[i]; accessed(type); } } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#save(org.eclipse.ui.IMemento) */ public void save(IMemento memento) { persistHistory(); } /** * Stores contents of the local history into persistent history * container. */ private synchronized void persistHistory() { if (getReturnCode() == OK) { Object[] items= getHistoryItems(); for (int i= 0; i < items.length; i++) { OpenTypeHistory.getInstance().accessed((TypeNameMatch) items[i]); } } } protected Object restoreItemFromMemento(IMemento element) { return null; } /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object, * org.eclipse.ui.IMemento) */ protected void storeItemToMemento(Object item, IMemento element) { } } }