/******************************************************************************* * Copyright (c) 2000, 2011 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 * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.search; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.search.ui.IQueryListener; import org.eclipse.search.ui.ISearchQuery; import org.eclipse.search.ui.ISearchResultViewPart; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Iterator; public class InternalSearchUI { //The shared instance. private static InternalSearchUI fgInstance; // contains all running jobs private HashMap fSearchJobs; private QueryManager fSearchResultsManager; // private PositionTracker fPositionTracker; // // private SearchViewManager fSearchViewManager; public static final Object FAMILY_SEARCH = new Object(); private class SearchJobRecord { public ISearchQuery query; public Job job; public boolean isRunning; public SearchJobRecord(ISearchQuery job) { this.query = job; this.isRunning = false; this.job = null; } } private class InternalSearchJob extends Job { private SearchJobRecord fSearchJobRecord; public InternalSearchJob(SearchJobRecord sjr) { super(sjr.query.getLabel()); fSearchJobRecord = sjr; } protected IStatus run(IProgressMonitor monitor) { fSearchJobRecord.job = this; searchJobStarted(fSearchJobRecord); IStatus status = null; int origPriority = Thread.currentThread().getPriority(); try { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); } catch (SecurityException e) { } try { status = fSearchJobRecord.query.run(monitor); } finally { try { Thread.currentThread().setPriority(origPriority); } catch (SecurityException e) { } searchJobFinished(fSearchJobRecord); } fSearchJobRecord.job = null; return status; } public boolean belongsTo(Object family) { return family == org.eclipse.search2.internal.ui.InternalSearchUI.FAMILY_SEARCH; } } private void searchJobStarted(SearchJobRecord record) { record.isRunning = true; getSearchManager().queryStarting(record.query); } private void searchJobFinished(SearchJobRecord record) { record.isRunning = false; fSearchJobs.remove(record); getSearchManager().queryFinished(record.query); } /** * The constructor. */ public InternalSearchUI() { fgInstance = this; fSearchJobs = new HashMap(); fSearchResultsManager = new QueryManager(); // fPositionTracker = new PositionTracker(); // fSearchViewManager = new SearchViewManager(fSearchResultsManager); // PlatformUI.getWorkbench().getProgressService().registerIconForFamily(SearchPluginImages.DESC_VIEW_SEARCHRES, FAMILY_SEARCH); } /** * @return returns the shared instance. */ public static InternalSearchUI getInstance() { if (fgInstance == null) fgInstance = new InternalSearchUI(); return fgInstance; } // public ISearchResultViewPart getSearchView() { // return getSearchViewManager().getActiveSearchView(); // } // private IWorkbenchSiteProgressService getProgressService() { // ISearchResultViewPart view = getSearchView(); // if (view != null) { // IWorkbenchPartSite site = view.getSite(); // if (site != null) // return (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class); // } // return null; // } public boolean runSearchInBackground(ISearchQuery query, ISearchResultViewPart view) { if (isQueryRunning(query)) return false; // // prepare view // if (view == null) { // getSearchViewManager().activateSearchView(true); // } else { // getSearchViewManager().activateSearchView(view); // } addQuery(query); SearchJobRecord sjr = new SearchJobRecord(query); fSearchJobs.put(query, sjr); Job job = new InternalSearchJob(sjr); job.setPriority(Job.BUILD); job.setUser(true); // IWorkbenchSiteProgressService service= getProgressService(); // if (service != null) { // service.schedule(job, 0, true); // } else { job.schedule(); // } return true; } public boolean isQueryRunning(ISearchQuery query) { SearchJobRecord sjr = (SearchJobRecord)fSearchJobs.get(query); return sjr != null && sjr.isRunning; } public IStatus runSearchInForeground(IRunnableContext context, final ISearchQuery query, ISearchResultViewPart view) { if (isQueryRunning(query)) { return Status.CANCEL_STATUS; } // // prepare view // if (view == null) { // getSearchViewManager().activateSearchView(true); // } else { // getSearchViewManager().activateSearchView(view); // } addQuery(query); SearchJobRecord sjr = new SearchJobRecord(query); fSearchJobs.put(query, sjr); // // if (context == null) // context= new ProgressMonitorDialog(null); return doRunSearchInForeground(sjr, context); } /** * Run a runnable. Convert all thrown exceptions to either * InterruptedException or InvocationTargetException */ private static void runInCurrentThread(IRunnableWithProgress runnable, IProgressMonitor progressMonitor) throws InterruptedException, InvocationTargetException { try { if (runnable != null) { runnable.run(progressMonitor); } } catch (InvocationTargetException e) { throw e; } catch (InterruptedException e) { throw e; } catch (OperationCanceledException e) { throw new InterruptedException(); } catch (ThreadDeath e) { // Make sure to propagate ThreadDeath, or threads will never fully // terminate throw e; } catch (RuntimeException e) { throw new InvocationTargetException(e); } catch (Error e) { throw new InvocationTargetException(e); } } private IStatus doRunSearchInForeground(final SearchJobRecord rec, IRunnableContext context) { try { runInCurrentThread(new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { searchJobStarted(rec); try { IStatus status = rec.query.run(monitor); if (status.matches(IStatus.CANCEL)) { throw new InterruptedException(); } if (!status.isOK()) { throw new InvocationTargetException(new CoreException(status)); } } catch (OperationCanceledException e) { throw new InterruptedException(); } finally { searchJobFinished(rec); } } }, new NullProgressMonitor()); } catch (InvocationTargetException e) { Throwable innerException = e.getTargetException(); if (innerException instanceof CoreException) { return ((CoreException)innerException).getStatus(); } return new Status(IStatus.ERROR, "SearchPlugin.getID()", 0, "An unexpected exception occurred during search", innerException); } catch (InterruptedException e) { return Status.CANCEL_STATUS; } return Status.OK_STATUS; } public static void shutdown() { InternalSearchUI instance = fgInstance; if (instance != null) instance.doShutdown(); } private void doShutdown() { Iterator jobRecs = fSearchJobs.values().iterator(); while (jobRecs.hasNext()) { SearchJobRecord element = (SearchJobRecord)jobRecs.next(); if (element.job != null) element.job.cancel(); } // fPositionTracker.dispose(); // fSearchViewManager.dispose(fSearchResultsManager); } public void cancelSearch(ISearchQuery job) { SearchJobRecord rec = (SearchJobRecord)fSearchJobs.get(job); if (rec != null && rec.job != null) rec.job.cancel(); } public QueryManager getSearchManager() { return fSearchResultsManager; } // public SearchViewManager getSearchViewManager() { // return fSearchViewManager; // } // // public PositionTracker getPositionTracker() { // return fPositionTracker; // } public void addQueryListener(IQueryListener l) { getSearchManager().addQueryListener(l); } public ISearchQuery[] getQueries() { return getSearchManager().getQueries(); } public void removeQueryListener(IQueryListener l) { getSearchManager().removeQueryListener(l); } public void removeQuery(ISearchQuery query) { if (query == null) { throw new IllegalArgumentException(); } cancelSearch(query); getSearchManager().removeQuery(query); fSearchJobs.remove(query); } public void addQuery(ISearchQuery query) { if (query == null) { throw new IllegalArgumentException(); } establishHistoryLimit(); getSearchManager().addQuery(query); } private void establishHistoryLimit() { // int historyLimit= SearchPreferencePage.getHistoryLimit(); // QueryManager searchManager= getSearchManager(); // if (historyLimit >= searchManager.getSize()) { // return; // } // int numberQueriesNotShown= 0; // SearchViewManager searchViewManager= getSearchViewManager(); // ISearchQuery[] queries= searchManager.getQueries(); // for (int i= 0; i < queries.length; i++) { // ISearchQuery query= queries[i]; // if (!searchViewManager.isShown(query)) { // if (++numberQueriesNotShown >= historyLimit) { // removeQuery(query); // } // } // } } public void removeAllQueries() { for (Iterator queries = fSearchJobs.keySet().iterator(); queries.hasNext(); ) { ISearchQuery query = (ISearchQuery)queries.next(); cancelSearch(query); } fSearchJobs.clear(); getSearchManager().removeAll(); } // public void showSearchResult(SearchView searchView, ISearchResult result, boolean openInNew) { // if (openInNew) // searchView= (SearchView)getSearchViewManager().activateSearchView(true, openInNew); // showSearchResult(searchView, result); // } // // private void showSearchResult(SearchView searchView, ISearchResult result) { // getSearchManager().touch(result.getQuery()); // searchView.showSearchResult(result); // } }