blob: 1d21a03044fc6a2c9030a124d7c61fb5ae38c764 [file] [log] [blame]
package org.eclipse.update.internal.ui.search;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.ui.UpdateUIPlugin;
import org.eclipse.update.internal.ui.model.*;
public class SearchObject extends NamedModelObject {
public static final String P_REFRESH = "p_refresh"; //$NON-NLS-1$
public static final String P_CATEGORY = "p_category"; //$NON-NLS-1$
private static final String KEY_NAME = "Search.name"; //$NON-NLS-1$
private static final String KEY_BEGIN = "Search.begin"; //$NON-NLS-1$
private static final String KEY_MY_COMPUTER = "Search.myComputer"; //$NON-NLS-1$
private static final String KEY_CONTACTING = "Search.contacting"; //$NON-NLS-1$
private static final String KEY_CHECKING = "Search.checking"; //$NON-NLS-1$
protected static final String S_MY_COMPUTER = "searchMyComputer"; //$NON-NLS-1$
protected static final String S_BOOKMARKS = "searchBookmarks"; //$NON-NLS-1$
protected static final String S_DISCOVERY = "searchDiscovery"; //$NON-NLS-1$
protected static final String S_FILTER = "searchFilter"; //$NON-NLS-1$
protected static final String S_DRIVES = "searchDrives"; //$NON-NLS-1$
private Vector result;
transient private boolean searchInProgress;
private BackgroundProgressMonitor backgroundProgress;
transient private BackgroundThread searchThread;
transient private SiteBookmark[] myComputerSites = null;
private String categoryId;
private boolean categoryFixed;
private Hashtable settings = new Hashtable();
private boolean persistent = true;
private boolean instantSearch = false;
class SearchAdapter extends MonitorAdapter implements Serializable {
public void done() {
searchInProgress = false;
}
}
public SearchObject() {
this("", null, false); //$NON-NLS-1$
}
public SearchObject(String name, SearchCategoryDescriptor descriptor) {
this(name, descriptor, false);
}
public SearchObject(
String name,
SearchCategoryDescriptor descriptor,
boolean categoryFixed) {
super(name);
this.categoryId = descriptor.getId();
this.categoryFixed = categoryFixed;
backgroundProgress = new BackgroundProgressMonitor();
backgroundProgress.addProgressMonitor(new SearchAdapter());
result = new Vector();
}
public boolean isCategoryFixed() {
return categoryFixed;
}
public boolean isPersistent() {
return persistent;
}
public void setPersistent(boolean value) {
this.persistent = value;
}
public boolean isInstantSearch() {
return instantSearch;
}
public void setInstantSearch(boolean value) {
this.instantSearch = value;
}
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String id) {
if (categoryId != null && !categoryId.equals(id)) {
settings.clear();
}
this.categoryId = id;
notifyObjectChanged(P_CATEGORY);
}
public void setDisplay(Display display) {
backgroundProgress.setDisplay(display);
}
public Hashtable getSettings() {
return settings;
}
public boolean getSearchMyComputer() {
return getBooleanValue(S_MY_COMPUTER);
}
public void setSearchMyComputer(boolean value) {
settings.put(S_MY_COMPUTER, value ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
}
public void setSearchBookmarks(boolean value) {
setBooleanValue(S_BOOKMARKS, value);
}
public boolean getSearchBookmarks() {
return getBooleanValue(S_BOOKMARKS);
}
public void setSearchDiscovery(boolean value) {
setBooleanValue(S_DISCOVERY, value);
}
public boolean getSearchDiscovery() {
return getBooleanValue(S_DISCOVERY);
}
public String getDriveSettings() {
return (String) settings.get(S_DRIVES);
}
public void setDriveSettings(String drives) {
settings.put(S_DRIVES, drives);
}
public void setFilterEnvironment(boolean value) {
setBooleanValue(S_FILTER, !value);
}
public boolean getFilterEnvironment() {
return !getBooleanValue(S_FILTER);
}
private boolean getBooleanValue(String key) {
String value = (String) settings.get(key);
if (value != null && value.equals("true")) //$NON-NLS-1$
return true;
return false;
}
private void setBooleanValue(String key, boolean value) {
settings.put(key, value ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* @see IWorkbenchAdapter#getChildren(Object)
*/
public Object[] getChildren(Object parent) {
return result.toArray();
}
public boolean hasChildren() {
return result.size() > 0;
}
public void attachProgressMonitor(IProgressMonitor monitor) {
backgroundProgress.addProgressMonitor(monitor);
}
public void detachProgressMonitor(IProgressMonitor monitor) {
backgroundProgress.removeProgressMonitor(monitor);
}
public void startSearch(Display display, ISearchQuery[] queries)
throws InvocationTargetException, InterruptedException {
if (searchInProgress)
return;
backgroundProgress.setDisplay(display);
IRunnableWithProgress operation = getSearchOperation(display, queries);
searchThread =
new BackgroundThread(operation, backgroundProgress, display);
searchInProgress = true;
searchThread.start();
Throwable throwable = searchThread.getThrowable();
if (throwable != null) {
UpdateUIPlugin.logException(throwable);
if (throwable instanceof InvocationTargetException) {
throw (InvocationTargetException) throwable;
} else if (throwable instanceof InterruptedException) {
throw (InterruptedException) throwable;
} else if (throwable instanceof OperationCanceledException) {
// See 1GAN3L5: ITPUI:WIN2000 - ModalContext converts OperationCancelException into InvocationTargetException
throw new InterruptedException(throwable.getMessage());
} else {
throw new InvocationTargetException(throwable);
}
}
}
public boolean isSearchInProgress() {
return searchInProgress;
}
public void stopSearch() {
if (!searchInProgress || searchThread == null)
return;
backgroundProgress.setCanceled(true);
}
public IRunnableWithProgress getSearchOperation(
final Display display,
final ISearchQuery[] queries) {
return new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException {
try {
doSearch(display, queries, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
}
private void doSearch(
Display display,
ISearchQuery[] queries,
IProgressMonitor monitor)
throws CoreException {
result.clear();
asyncFireObjectChanged(display, this, P_REFRESH);
ArrayList candidates = new ArrayList();
monitor.beginTask(
UpdateUIPlugin.getResourceString(KEY_BEGIN),
IProgressMonitor.UNKNOWN);
if (getSearchMyComputer()) {
monitor.setTaskName(
UpdateUIPlugin.getResourceString(KEY_MY_COMPUTER));
initializeMyComputerSites(monitor);
}
ArrayList statusList = new ArrayList();
if (!monitor.isCanceled()) {
computeSearchSources(candidates);
int ntasks = queries.length * (1 + candidates.size());
monitor.beginTask(
UpdateUIPlugin.getResourceString(KEY_BEGIN),
ntasks);
for (int i = 0; i < queries.length; i++) {
ISearchQuery query = queries[i];
ISiteAdapter site = query.getSearchSite();
if (site != null) {
SubProgressMonitor subMonitor =
new SubProgressMonitor(monitor, 1);
UpdateUIPlugin.getResourceString(KEY_CHECKING);
IStatus status =
searchOneSite(display, site, query, subMonitor);
if (status != null)
statusList.add(status);
if (monitor.isCanceled())
break;
}
for (int j = 0; j < candidates.size(); j++) {
if (monitor.isCanceled()) {
break;
}
Object source = candidates.get(j);
SubProgressMonitor subMonitor =
new SubProgressMonitor(monitor, 1);
IStatus status =
searchOneSite(
display,
(ISiteAdapter) source,
query,
subMonitor);
if (status != null)
statusList.add(status);
monitor.worked(1);
}
if (monitor.isCanceled())
break;
}
}
searchInProgress = false;
monitor.done();
asyncFireObjectChanged(display, this, P_REFRESH);
if (statusList.size() > 0) {
IStatus[] children =
(IStatus[]) statusList.toArray(new IStatus[statusList.size()]);
MultiStatus multiStatus = new MultiStatus(UpdateUIPlugin.getPluginId(), ISite.SITE_ACCESS_EXCEPTION, children, UpdateUIPlugin.getResourceString("Search.networkProblems"), //$NON-NLS-1$
null);
throw new CoreException(multiStatus);
}
}
public void computeSearchSources(ArrayList sources) {
addMyComputerSites(sources);
addDiscoverySites(sources);
addBookmarks(sources);
}
private IStatus searchOneSite(
Display display,
ISiteAdapter siteAdapter,
ISearchQuery query,
SubProgressMonitor monitor)
throws CoreException {
String text =
UpdateUIPlugin.getFormattedMessage(KEY_CONTACTING, siteAdapter.getLabel());
monitor.subTask(text);
URL siteURL = siteAdapter.getURL();
ISite site;
try {
site = SiteManager.getSite(siteURL);
} catch (CoreException e) {
// Test the exception. If the exception is
// due to the site connection problems,
// allow the search to move on to
// the next site. Otherwise,
// rethrow the exception, causing the search
// to terminate.
IStatus status = e.getStatus();
if (status == null
|| status.getCode() != ISite.SITE_ACCESS_EXCEPTION)
throw e;
monitor.worked(1);
return status;
}
text = UpdateUIPlugin.getFormattedMessage(KEY_CHECKING,
siteAdapter.getLabel());
monitor.getWrappedProgressMonitor().subTask(text);
monitor.beginTask("", 2); //$NON-NLS-1$
IFeature[] matches =
query.getMatchingFeatures(site, new SubProgressMonitor(monitor, 1));
for (int i = 0; i < matches.length; i++) {
if (monitor.isCanceled())
return null;
if (getFilterEnvironment() && !isValidEnvironment(matches[i]))
continue;
// bingo - add this
SearchResultSite searchSite = findResultSite(site);
if (searchSite == null) {
searchSite =
new SearchResultSite(this, siteAdapter.getLabel(), site);
result.add(searchSite);
asyncFireObjectAdded(display, this, searchSite);
}
SimpleFeatureAdapter featureAdapter =
new SimpleFeatureAdapter(matches[i]);
searchSite.addCandidate(featureAdapter);
asyncFireObjectAdded(display, searchSite, featureAdapter);
}
monitor.worked(1);
return null;
}
private SearchResultSite findResultSite(ISite site) {
for (int i = 0; i < result.size(); i++) {
SearchResultSite resultSite = (SearchResultSite) result.get(i);
if (resultSite.getSite(null).equals(site))
return resultSite;
}
return null;
}
private boolean isValidEnvironment(IFeature candidate) {
return UpdateManagerUtils.isValidEnvironment(candidate);
}
private void asyncFireObjectAdded(
Display display,
final Object parent,
final Object child) {
final UpdateModel model = getModel();
display.asyncExec(new Runnable() {
public void run() {
model.fireObjectsAdded(parent, new Object[] { child });
}
});
}
private void asyncFireObjectChanged(
Display display,
final Object obj,
final String property) {
final UpdateModel model = getModel();
display.asyncExec(new Runnable() {
public void run() {
model.fireObjectChanged(obj, property);
}
});
}
private void initializeMyComputerSites(IProgressMonitor monitor) {
Vector sites = new Vector();
MyComputer myComputer = new MyComputer();
MyComputerSearchSettings settings = new MyComputerSearchSettings(this);
myComputer.collectSites(sites, settings, monitor);
if (sites.size() > 0) {
myComputerSites =
(SiteBookmark[]) sites.toArray(new SiteBookmark[sites.size()]);
} else
myComputerSites = null;
}
private void addMyComputerSites(ArrayList result) {
if (myComputerSites != null && getSearchMyComputer()) {
for (int i = 0; i < myComputerSites.length; i++) {
result.add(myComputerSites[i]);
}
}
}
private void addBookmarks(ArrayList result) {
if (getSearchBookmarks() == false)
return;
UpdateModel model = UpdateUIPlugin.getDefault().getUpdateModel();
SiteBookmark[] bookmarks = model.getBookmarkLeafs();
for (int i = 0; i < bookmarks.length; i++) {
SiteBookmark bookmark = bookmarks[i];
result.add(bookmark);
}
}
private void addDiscoverySites(ArrayList result) {
if (getSearchDiscovery() == false)
return;
DiscoveryFolder dfolder = new DiscoveryFolder();
Object[] children = dfolder.getChildren(dfolder);
for (int i = 0; i < children.length; i++) {
SiteBookmark bookmark = (SiteBookmark) children[i];
result.add(bookmark);
}
}
}