blob: 8361043b745859c60fa267269c992fb2c3040bd7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.search.internal.ui;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageScoreComputer;
import org.eclipse.search.ui.ISearchResultViewEntry;
import org.eclipse.search.internal.ui.util.ExceptionHandler;
/**
* Proxy that represents a search page.
*/
class SearchPageDescriptor implements Comparable {
public final static String PAGE_TAG= "page"; //$NON-NLS-1$
private final static String ID_ATTRIBUTE= "id"; //$NON-NLS-1$
private final static String ICON_ATTRIBUTE= "icon"; //$NON-NLS-1$
private final static String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
private final static String LABEL_ATTRIBUTE= "label"; //$NON-NLS-1$
private final static String SIZE_ATTRIBUTE= "sizeHint"; //$NON-NLS-1$
private final static String TAB_POSITION_ATTRIBUTE= "tabPosition"; //$NON-NLS-1$
private final static String EXTENSIONS_ATTRIBUTE= "extensions"; //$NON-NLS-1$
private final static String SHOW_SCOPE_SECTION_ATTRIBUTE= "showScopeSection"; //$NON-NLS-1$
private final static String CAN_SEARCH_ENCLOSING_PROJECTS= "canSearchEnclosingProjects"; //$NON-NLS-1$
private final static String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
private final static String SEARCH_VIEW_HELP_CONTEXT_ID_ATTRIBUTE= "searchViewHelpContextId"; //$NON-NLS-1$
public final static Point UNKNOWN_SIZE= new Point(SWT.DEFAULT, SWT.DEFAULT);
// dialog store id constants
private final static String SECTION_ID= "Search"; //$NON-NLS-1$
private final static String STORE_ENABLED_PAGE_IDS= SECTION_ID + ".enabledPageIds"; //$NON-NLS-1$
private final static String STORE_PROCESSED_PAGE_IDS= SECTION_ID + ".processedPageIds"; //$NON-NLS-1$
private static List fgEnabledPageIds;
private static class ExtensionScorePair {
public String extension;
public int score;
public ExtensionScorePair(String extension, int score) {
this.extension= extension;
this.score= score;
}
}
private IConfigurationElement fElement;
private List fExtensionScorePairs;
private int fWildcardScore= ISearchPageScoreComputer.UNKNOWN;
/**
* Creates a new search page node with the given configuration element.
*/
public SearchPageDescriptor(IConfigurationElement element) {
fElement= element;
}
/**
* Creates a new search page from this node.
*/
public ISearchPage createObject() {
ISearchPage result= null;
try {
result= (ISearchPage)fElement.createExecutableExtension(CLASS_ATTRIBUTE);
} catch (CoreException ex) {
ExceptionHandler.handle(ex, SearchMessages.getString("Search.Error.createSearchPage.title"), SearchMessages.getString("Search.Error.createSearchPage.message")); //$NON-NLS-2$ //$NON-NLS-1$
} catch (ClassCastException ex) {
ExceptionHandler.displayMessageDialog(ex, SearchMessages.getString("Search.Error.createSearchPage.title"), SearchMessages.getString("Search.Error.createSearchPage.message")); //$NON-NLS-2$ //$NON-NLS-1$
return null;
}
if (result != null) {
result.setTitle(getLabel());
}
return result;
}
//---- XML Attribute accessors ---------------------------------------------
/**
* Returns the page's id.
*/
public String getId() {
return fElement.getAttribute(ID_ATTRIBUTE);
}
/**
* Returns the page's image
*/
public ImageDescriptor getImage() {
String imageName= fElement.getAttribute(ICON_ATTRIBUTE);
if (imageName == null)
return null;
URL url;
try {
url= new URL(fElement.getDeclaringExtension().getDeclaringPluginDescriptor().getInstallURL(), imageName);
} catch (java.net.MalformedURLException ex) {
ExceptionHandler.log(ex, SearchMessages.getString("Search.Error.createSearchPage.message")); //$NON-NLS-1$
return null;
}
return ImageDescriptor.createFromURL(url);
}
/**
* Returns the page's label.
*/
public String getLabel() {
return fElement.getAttribute(LABEL_ATTRIBUTE);
}
/**
* Returns <code>true</code> if the scope section needs
* to be shown in the dialog.
*/
public boolean showScopeSection() {
return Boolean.valueOf(fElement.getAttribute(SHOW_SCOPE_SECTION_ATTRIBUTE)).booleanValue();
}
/**
* Returns <code>true</code> if the page is initially
* shown in the Search dialog.
*
* This attribute is optional and defaults to <code>true</code>.
*/
public boolean isInitiallyEnabled() {
String strVal= fElement.getAttribute(ENABLED_ATTRIBUTE);
return strVal == null || Boolean.valueOf(strVal).booleanValue();
}
/**
* Returns <code>true</code> if the page can handle
* searches in enclosing projects. The value should be ignored if <code>showScopeSection()</code>
* returns <code>false</code>.
*
* This attribute is optional and defaults to <code>false</code>.
*/
public boolean canSearchInProjects() {
return Boolean.valueOf(fElement.getAttribute(CAN_SEARCH_ENCLOSING_PROJECTS)).booleanValue();
}
/**
* Returns the page's preferred size
*/
public Point getPreferredSize() {
return StringConverter.asPoint(
fElement.getAttribute(SIZE_ATTRIBUTE), UNKNOWN_SIZE);
}
/**
* Returns the page's tab position relative to the other tabs.
* @return the tab position or <code>Integer.MAX_VALUE</code> if not defined in
* the plugins.xml file
*/
public int getTabPosition() {
int position= Integer.MAX_VALUE / 2;
String str= fElement.getAttribute(TAB_POSITION_ATTRIBUTE);
if (str != null)
try {
position= Integer.parseInt(str);
} catch (NumberFormatException ex) {
ExceptionHandler.log(ex, SearchMessages.getString("Search.Error.createSearchPage.message")); //$NON-NLS-1$
// position is Integer.MAX_VALUE;
}
return position;
}
boolean isEnabled() {
return getEnabledPageIds().contains(getId());
}
/**
* Returns the help context for help shown in search view.
*
* @return the help context id or <code>null</code> if not defined
*/
public String getSearchViewHelpContextId() {
return fElement.getAttribute(SEARCH_VIEW_HELP_CONTEXT_ID_ATTRIBUTE);
}
static void setEnabled(Object[] enabledDescriptors) {
fgEnabledPageIds= new ArrayList(5);
for (int i= 0; i < enabledDescriptors.length; i++) {
if (enabledDescriptors[i] instanceof SearchPageDescriptor)
fgEnabledPageIds.add(((SearchPageDescriptor)enabledDescriptors[i]).getId());
}
storeEnabledPageIds();
}
private static List getEnabledPageIds() {
if (fgEnabledPageIds == null) {
List descriptors= SearchPlugin.getDefault().getSearchPageDescriptors();
String[] enabledPageIds= getDialogSettings().getArray(STORE_ENABLED_PAGE_IDS);
if (enabledPageIds == null)
fgEnabledPageIds= new ArrayList(descriptors.size());
else
fgEnabledPageIds= new ArrayList(Arrays.asList(enabledPageIds));
List processedPageIds;
String[] processedPageIdsArr= getDialogSettings().getArray(STORE_PROCESSED_PAGE_IDS);
if (processedPageIdsArr == null)
processedPageIds= new ArrayList(descriptors.size());
else
processedPageIds= new ArrayList(Arrays.asList(processedPageIdsArr));
// Enable pages based on contribution
Iterator iter= descriptors.iterator();
while (iter.hasNext()) {
SearchPageDescriptor desc= (SearchPageDescriptor)iter.next();
if (processedPageIds.contains(desc.getId()))
continue;
processedPageIds.add(desc.getId());
if (desc.isInitiallyEnabled())
fgEnabledPageIds.add(desc.getId());
}
getDialogSettings().put(STORE_PROCESSED_PAGE_IDS, (String[])processedPageIds.toArray(new String[processedPageIds.size()]));
storeEnabledPageIds();
}
return fgEnabledPageIds;
}
private static void storeEnabledPageIds() {
getDialogSettings().put(STORE_ENABLED_PAGE_IDS, (String[])fgEnabledPageIds.toArray(new String[fgEnabledPageIds.size()]));
SearchPlugin.getDefault().savePluginPreferences();
}
private static IDialogSettings getDialogSettings() {
IDialogSettings settings= SearchPlugin.getDefault().getDialogSettings();
IDialogSettings section= settings.getSection(SECTION_ID);
if (section == null)
// create new section
section= settings.addNewSection(SECTION_ID);
return section;
}
/*
* Implements a method from IComparable
*/
public int compareTo(Object o) {
int myPos= getTabPosition();
int objsPos= ((SearchPageDescriptor)o).getTabPosition();
if (myPos == Integer.MAX_VALUE && objsPos == Integer.MAX_VALUE || myPos == objsPos)
return getLabel().compareTo(((SearchPageDescriptor)o).getLabel());
else
return myPos - objsPos;
}
//---- Suitability tests ---------------------------------------------------
/**
* Returns the score for this page with the given input element.
*/
public int computeScore(Object element) {
if (element instanceof IAdaptable) {
IResource resource= (IResource)((IAdaptable)element).getAdapter(IResource.class);
if (resource != null && resource.getType() == IResource.FILE) {
String extension= ((IFile)resource).getFileExtension();
if (extension != null)
return getScoreForFileExtension(extension);
} else {
ISearchPageScoreComputer tester=
(ISearchPageScoreComputer)((IAdaptable)element).getAdapter(ISearchPageScoreComputer.class);
if (tester != null)
return tester.computeScore(getId(), element);
}
} else if (element instanceof ISearchResultViewEntry) {
ISearchResultViewEntry entry= (ISearchResultViewEntry)element;
return computeScore(entry.getSelectedMarker());
}
if (fWildcardScore != ISearchPageScoreComputer.UNKNOWN)
return fWildcardScore;
return ISearchPageScoreComputer.LOWEST;
}
private int getScoreForFileExtension(String extension) {
if (fExtensionScorePairs == null)
readExtensionScorePairs();
int size= fExtensionScorePairs.size();
for (int i= 0; i < size; i++) {
ExtensionScorePair p= (ExtensionScorePair)fExtensionScorePairs.get(i);
if (extension.equals(p.extension))
return p.score;
}
if (fWildcardScore != ISearchPageScoreComputer.UNKNOWN)
return fWildcardScore;
return ISearchPageScoreComputer.LOWEST;
}
private void readExtensionScorePairs() {
fExtensionScorePairs= new ArrayList(3);
String content= fElement.getAttribute(EXTENSIONS_ATTRIBUTE);
if (content == null)
return;
StringTokenizer tokenizer= new StringTokenizer(content, ","); //$NON-NLS-1$
while (tokenizer.hasMoreElements()) {
String token= tokenizer.nextToken().trim();
int pos= token.indexOf(':');
if (pos != -1) {
String extension= token.substring(0, pos);
int score= StringConverter.asInt(token.substring(pos+1), ISearchPageScoreComputer.UNKNOWN);
if (extension.equals("*")) { //$NON-NLS-1$
fWildcardScore= score;
} else {
fExtensionScorePairs.add(new ExtensionScorePair(extension, score));
}
}
}
}
}