1 package org.simantics.workbench.internal.contributions.search;
\r
4 import java.io.IOException;
\r
5 import java.net.MalformedURLException;
\r
7 import java.net.URISyntaxException;
\r
9 import java.util.ArrayList;
\r
10 import java.util.Collection;
\r
11 import java.util.Collections;
\r
12 import java.util.HashMap;
\r
13 import java.util.HashSet;
\r
14 import java.util.List;
\r
15 import java.util.Map;
\r
16 import java.util.Set;
\r
18 import org.eclipse.core.runtime.IProgressMonitor;
\r
19 import org.eclipse.core.runtime.IStatus;
\r
20 import org.eclipse.core.runtime.NullProgressMonitor;
\r
21 import org.eclipse.core.runtime.Status;
\r
22 import org.eclipse.core.runtime.SubMonitor;
\r
23 import org.eclipse.core.runtime.jobs.Job;
\r
24 import org.eclipse.jface.viewers.ISelection;
\r
25 import org.eclipse.jface.viewers.StructuredSelection;
\r
26 import org.eclipse.swt.SWT;
\r
27 import org.eclipse.swt.browser.LocationEvent;
\r
28 import org.eclipse.swt.browser.LocationListener;
\r
29 import org.eclipse.swt.events.DisposeEvent;
\r
30 import org.eclipse.swt.events.DisposeListener;
\r
31 import org.eclipse.swt.widgets.Control;
\r
32 import org.eclipse.swt.widgets.Display;
\r
33 import org.eclipse.swt.widgets.Shell;
\r
34 import org.eclipse.ui.IViewPart;
\r
35 import org.eclipse.ui.IViewReference;
\r
36 import org.eclipse.ui.IWorkbenchPage;
\r
37 import org.eclipse.ui.IWorkbenchWindow;
\r
38 import org.eclipse.ui.PartInitException;
\r
39 import org.eclipse.ui.PlatformUI;
\r
40 import org.simantics.ObjectIdentitySchedulingRule;
\r
41 import org.simantics.Simantics;
\r
42 import org.simantics.databoard.Bindings;
\r
43 import org.simantics.db.ReadGraph;
\r
44 import org.simantics.db.Resource;
\r
45 import org.simantics.db.Session;
\r
46 import org.simantics.db.exception.DatabaseException;
\r
47 import org.simantics.db.layer0.adapter.Instances;
\r
48 import org.simantics.db.layer0.request.ActiveModels;
\r
49 import org.simantics.db.request.Read;
\r
50 import org.simantics.db.service.SerialisationSupport;
\r
51 import org.simantics.editors.Browser;
\r
52 import org.simantics.editors.BrowserInput;
\r
53 import org.simantics.layer0.Layer0;
\r
54 import org.simantics.scl.runtime.function.Function;
\r
55 import org.simantics.scl.runtime.function.Function5;
\r
56 import org.simantics.ui.workbench.action.ChooseActionRequest;
\r
57 import org.simantics.utils.FileUtils;
\r
58 import org.simantics.utils.datastructures.MapList;
\r
59 import org.simantics.utils.datastructures.Pair;
\r
60 import org.simantics.utils.ui.ErrorLogger;
\r
61 import org.simantics.utils.ui.ExceptionUtils;
\r
62 import org.simantics.utils.ui.workbench.WorkbenchUtils;
\r
63 import org.simantics.workbench.internal.Activator;
\r
64 import org.simantics.workbench.ontology.WorkbenchResource;
\r
65 import org.simantics.workbench.search.ISearchService;
\r
66 import org.simantics.workbench.search.QueryResult;
\r
67 import org.simantics.workbench.search.SearchEngine;
\r
68 import org.simantics.workbench.search.SearchQuery;
\r
69 import org.simantics.workbench.search.SearchResult;
\r
70 import org.simantics.workbench.search.Searching;
\r
72 import freemarker.template.TemplateException;
\r
75 * @author Tuukka Lehtonen
\r
76 * @author Marko Luukkainen
\r
78 public class SearchServiceImpl implements ISearchService{
\r
80 private static final String SEARCH_TEMP_FILE_SUFFIX = "search.html";
\r
81 private static final String SEARCH_TEMP_DIR = "search";
\r
82 private static final String BROWSER_VIEW = BrowserView.ID;
\r
83 private static final Integer MAX_RESULTS = 1000;
\r
86 public void performQuery(SearchQuery query, ResultBrowser browserType, boolean activateResultBrowser) {
\r
88 Set<SearchEngine> searchEngines = getSearchEngines();
\r
90 // if query does not define used engines, use all available engines.
\r
91 boolean containsEngines = false;
\r
92 for (SearchEngine e : searchEngines) {
\r
93 if (query.getSearchFlags().containsKey(e.getId())) {
\r
94 containsEngines = true;
\r
98 if (!containsEngines) {
\r
99 for (SearchEngine e : searchEngines)
\r
100 if (e.isEnabledByDefault())
\r
101 query.setSearchFlag(e.getId(), "on");
\r
103 } catch (DatabaseException e) {
\r
104 ExceptionUtils.logError(e);
\r
106 switch (browserType) {
\r
108 performEditorQuery(query);
\r
111 performViewQuery(query, activateResultBrowser);
\r
117 private void performViewQuery(SearchQuery query, boolean activateResultBrowser) {
\r
119 browserView = (BrowserView) showLocalView(
\r
121 activateResultBrowser ? IWorkbenchPage.VIEW_ACTIVATE : IWorkbenchPage.VIEW_CREATE);
\r
122 if (browserView.getBrowser() != browserViewBrowser) {
\r
123 browserViewBrowser = browserView.getBrowser();
\r
124 browserViewTemporaryFiles = new ArrayList<File>();
\r
125 browserViewTemporaryFiles.add(getNewTemporaryFile());
\r
126 browserView.getBrowser().addLocationListener(browserViewLocationListener);
\r
127 browserView.getBrowser().addDisposeListener(new DisposeListener() {
\r
129 public void widgetDisposed(DisposeEvent e) {
\r
130 browserViewBrowser = null;
\r
134 browserView.setPartProperty(BrowserView.LAST_QUERY_PROPERTY, query.getOriginalQuery());
\r
135 updateViewQuery(browserView, browserViewTemporaryFiles, query);
\r
136 } catch (IOException e1) {
\r
137 ErrorLogger.defaultLogError(e1);
\r
138 } catch (PartInitException e1) {
\r
139 ErrorLogger.defaultLogError(e1);
\r
143 private IViewPart showLocalView(String id, int mode) throws PartInitException {
\r
144 final IWorkbenchWindow wb = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
\r
148 // Is view already created in the currently active workbench window?
\r
149 IViewPart vp = findViewFromWindow(wb, id, false);
\r
151 if (mode == IWorkbenchPage.VIEW_CREATE)
\r
153 IWorkbenchPage page = vp.getViewSite().getPage();
\r
154 if (mode == IWorkbenchPage.VIEW_VISIBLE) {
\r
155 page.bringToTop(vp);
\r
156 } else if (mode == IWorkbenchPage.VIEW_ACTIVATE) {
\r
162 // Create the view on the active window's active page
\r
163 IWorkbenchPage page = wb.getActivePage();
\r
164 if (page == null) {
\r
165 IWorkbenchPage pages[] = wb.getPages();
\r
166 if (pages.length == 0) return null;
\r
169 return page.showView(id, null, mode);
\r
172 private static IViewPart findViewFromWindow(IWorkbenchWindow wb, String viewId, boolean restore) {
\r
173 for (IWorkbenchPage page : wb.getPages()) {
\r
174 IViewReference vr = page.findViewReference(viewId);
\r
176 IViewPart vp = vr.getView(restore);
\r
185 * There's always only one of these around.
\r
187 BrowserView browserView = null;
\r
189 org.eclipse.swt.browser.Browser browserViewBrowser = null;
\r
191 List<File> browserViewTemporaryFiles = null;
\r
193 LocationListener browserViewLocationListener = new LocationListener() {
\r
195 public void changing(LocationEvent event) {
\r
196 //System.out.println("changing: " + event);
\r
198 URI newUri = new URI(event.location);
\r
200 // Handle resource links by opening an editor for them
\r
201 if ("resource".equals(newUri.getScheme())) {
\r
202 event.doit = false;
\r
203 openResource(getShell(event), newUri.getSchemeSpecificPart());
\r
206 } catch (URISyntaxException e) {
\r
207 // This URI was not needed anyway, resource: URIs will always parse properly so let
\r
208 // it go without logging.
\r
209 } catch (DatabaseException e) {
\r
210 ErrorLogger.defaultLogError(e);
\r
215 public void changed(LocationEvent event) {
\r
216 // System.out.println("changed: " + event);
\r
218 URL newUrl = new URL(event.location);
\r
219 String query = newUrl.getQuery();
\r
220 if (query != null) {
\r
221 SearchQuery searchQuery = SearchQuery.decode(newUrl);
\r
222 if (searchQuery.getOriginalQuery() != null) {
\r
223 event.doit = updateViewQuery(
\r
225 browserViewTemporaryFiles,
\r
230 } catch (IOException e) {
\r
231 ErrorLogger.defaultLogError(e);
\r
236 class ViewQueryJob extends Job {
\r
240 List<File> temporaryFiles;
\r
242 BrowserView browserView;
\r
246 public ViewQueryJob(SearchQuery query, List<File> temporaryFiles, BrowserView browserView) {
\r
247 super("Search...");
\r
248 this.query = query;
\r
249 this.temporaryFiles = temporaryFiles;
\r
250 this.browserView = browserView;
\r
251 this.display = browserView.getBrowser().getDisplay();
\r
255 protected IStatus run(IProgressMonitor monitor) {
\r
257 SubMonitor mon = SubMonitor.convert(monitor);
\r
258 monitor.beginTask("Performing search '" + query + "'", 10);
\r
259 monitor.subTask("Querying index");
\r
260 final List<QueryResult> result = createResultPage(mon.newChild(8), query, MAX_RESULTS);
\r
261 if (result == null) {
\r
262 return Status.CANCEL_STATUS;
\r
265 monitor.subTask("Generating results");
\r
266 updatePages(result, temporaryFiles);
\r
268 updateBrowser(browserView, result.get(0));
\r
269 return Status.OK_STATUS;
\r
270 } catch (DatabaseException e1) {
\r
271 return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
\r
272 "Unexpected database problems during search result processing, see exception.", e1);
\r
273 } catch (IOException e1) {
\r
274 return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
\r
275 "Unexpected I/O problems during search result processing, see exception.", e1);
\r
281 void updateBrowser(final BrowserView browserView, final QueryResult result) {
\r
282 if (display.isDisposed())
\r
284 display.asyncExec(new Runnable() {
\r
286 public void run() {
\r
287 if (browserView.isDisposed())
\r
291 long t1 = System.currentTimeMillis();
\r
292 browserView.setUrl(temporaryFiles.get(0).toURI().toURL());
\r
293 //browserView.setContentDescription("'" + query + "' - " + result.getHitCount() + " matches in active model");
\r
294 long t2 = System.currentTimeMillis();
\r
295 System.out.println("Updating UI " + (t2-t1) + " ms");
\r
296 } catch (MalformedURLException e) {
\r
297 ErrorLogger.defaultLogError(e);
\r
304 protected boolean updateViewQuery(BrowserView browserView, List<File> temporaryFiles, SearchQuery query) {
\r
305 ViewQueryJob job = new ViewQueryJob(query, temporaryFiles, browserView);
\r
306 job.setRule(new ObjectIdentitySchedulingRule(browserView));
\r
311 protected Shell getShell(LocationEvent event) {
\r
312 if (event.widget instanceof Control) {
\r
313 Control c = (Control) event.widget;
\r
314 if (c.isDisposed())
\r
316 return c.getShell();
\r
324 protected void performEditorQuery(final SearchQuery query) {
\r
326 final List<File> temporaryFiles = new ArrayList<File>();
\r
327 temporaryFiles.add(getNewTemporaryFile());
\r
328 final BrowserInput input = createBrowserInput(temporaryFiles.get(0), query);
\r
329 updateInput(input, temporaryFiles.get(0), query);
\r
331 final Browser browser = (Browser) WorkbenchUtils.openEditor("org.simantics.editors.browser", input);
\r
333 browser.getBrowser().addLocationListener(new LocationListener() {
\r
335 public void changing(LocationEvent event) {
\r
336 // System.out.println("changing: " + event);
\r
338 // TODO : is there a better way to escape location?
\r
339 URI newUri = new URI(event.location.replaceAll(" ", "%20"));
\r
340 // Handle resource links by opening an editor for them
\r
341 if ("resource".equals(newUri.getScheme())) {
\r
342 event.doit = false;
\r
343 openResource(getShell(event), newUri.getSchemeSpecificPart());
\r
346 } catch (URISyntaxException e) {
\r
347 ErrorLogger.defaultLogError(e);
\r
348 } catch (DatabaseException e) {
\r
349 ErrorLogger.defaultLogError(e);
\r
354 public void changed(LocationEvent event) {
\r
355 if (query != null) {
\r
356 // OpenEditor does not seem to pass any parameters (anything after '?' character)
\r
357 SearchQuery searchQuery = query;
\r
358 if (searchQuery.getOriginalQuery() != null) {
\r
359 event.doit = updateQuery(browser, input, temporaryFiles, searchQuery);
\r
364 } catch (IOException e1) {
\r
365 ErrorLogger.defaultLogError(e1);
\r
366 } catch (PartInitException e1) {
\r
367 ErrorLogger.defaultLogError(e1);
\r
371 protected void openResource(Shell shell, String link) throws DatabaseException {
\r
373 Session session = Simantics.getSession();
\r
374 final long id = Long.parseLong(link);
\r
376 Resource resource = session.syncRequest(new Read<Resource>() {
\r
378 public Resource perform(ReadGraph graph) throws DatabaseException {
\r
379 SerialisationSupport ss = graph.getService(SerialisationSupport.class);
\r
380 return ss.getResource(id);
\r
384 ISelection input = new StructuredSelection(resource);
\r
385 String perspectiveId = WorkbenchUtils.getCurrentPerspectiveId();
\r
387 // Try the doubleClick-extensions
\r
388 session.asyncRequest(new ChooseActionRequest(shell, input, perspectiveId, false, true));
\r
389 } catch (NumberFormatException e) {
\r
397 protected static boolean updateQuery(Browser browser, BrowserInput input, List<File> temporaryFiles, final SearchQuery query) {
\r
399 String url = browser.getBrowser().getUrl();
\r
400 String inputUrl = input.getUrl().toString();
\r
401 if (url.equals(inputUrl))
\r
404 List<QueryResult> result = createResultPage(new NullProgressMonitor(), query, MAX_RESULTS);
\r
405 updateInput(input, temporaryFiles.get(0), query);
\r
406 updatePages(result,temporaryFiles);
\r
407 // browser.getBrowser().setUrl(inputUrl);
\r
408 browser.getBrowser().refresh();
\r
409 // temporaryFile.delete();
\r
410 for (File temporaryFile : temporaryFiles)
\r
411 temporaryFile.deleteOnExit();
\r
413 } catch (DatabaseException e1) {
\r
414 ErrorLogger.defaultLogError(e1);
\r
415 } catch (IOException e1) {
\r
416 ErrorLogger.defaultLogError(e1);
\r
421 private static File ensureTemporaryDirectoryExists() throws IOException {
\r
422 return Simantics.getTemporaryDirectory(SEARCH_TEMP_DIR);
\r
428 * @throws IOException
\r
430 private static File getNewTemporaryFile() throws IOException {
\r
431 return Simantics.getTempfile(SEARCH_TEMP_DIR, SEARCH_TEMP_FILE_SUFFIX);
\r
438 * @throws IOException
\r
440 private static BrowserInput createBrowserInput(File file, SearchQuery query) throws IOException {
\r
441 // new BrowserInput(file.toURI().toURL()
\r
442 return new BrowserInput(SearchQuery.encode(file, query), query.getOriginalQuery(), false, false, SWT.NONE);
\r
445 private static void updatePages(List<QueryResult> result, List<File> temporaryFiles) throws IOException{
\r
446 ensureTemporaryDirectoryExists();
\r
447 for (int i = temporaryFiles.size(); i < result.size(); i++) {
\r
448 temporaryFiles.add(getNewTemporaryFile());
\r
450 if (result.size() > 1) {
\r
451 createPageControls(result,temporaryFiles);
\r
453 if (result.size() > 0) {
\r
454 for (int i = 0; i < result.size(); i++) {
\r
455 updatePage(temporaryFiles.get(i), result.get(i).getHtml());
\r
458 updatePage(temporaryFiles.get(0), "");
\r
465 * @throws IOException
\r
467 private static void updatePage(File file, String html) throws IOException {
\r
468 long t1 = System.currentTimeMillis();
\r
469 FileUtils.writeFile(file, html.getBytes("UTF-8"));
\r
470 long t2 = System.currentTimeMillis();
\r
471 System.out.println("Writing html page took " + (t2-t1) + " ms");
\r
474 private static void createPageControls(List<QueryResult> result, List<File> temporaryFiles) throws IOException{
\r
475 if (result.size() == 1)
\r
477 for (int i = 0; i < result.size(); i++) {
\r
478 boolean first = i == 0;
\r
479 boolean last = i == result.size() -1;
\r
480 QueryResult current = result.get(i);
\r
481 String pageContrtol = "<div class=\"resultInfo\">";
\r
482 pageContrtol += "Page " + (i+1) + " of "+ + result.size() + " ";
\r
484 pageContrtol += "First";
\r
485 pageContrtol += " Previous";
\r
486 pageContrtol += " <a href=\"" + temporaryFiles.get(i+1).toURI().toURL().toString() + "\">Next</a>";
\r
487 pageContrtol += " <a href=\"" + temporaryFiles.get(result.size()-1).toURI().toURL().toString() + "\">Last</a>";
\r
489 pageContrtol += "<a href=\"" + temporaryFiles.get(0).toURI().toURL().toString() + "\">First</a>";
\r
490 pageContrtol += " <a href=\"" + temporaryFiles.get(i-1).toURI().toURL().toString() + "\">Previous</a>";
\r
491 pageContrtol += " Next";
\r
492 pageContrtol += " Last";
\r
494 pageContrtol += "<a href=\"" + temporaryFiles.get(0).toURI().toURL().toString() + "\">First</a>";
\r
495 pageContrtol += " <a href=\"" + temporaryFiles.get(i-1).toURI().toURL().toString() + "\">Previous</a>";
\r
496 pageContrtol += " <a href=\"" + temporaryFiles.get(i+1).toURI().toURL().toString() + "\">Next</a>";
\r
497 pageContrtol += " <a href=\"" + temporaryFiles.get(result.size()-1).toURI().toURL().toString() + "\">Last</a>";
\r
499 pageContrtol += "</div><br>";
\r
501 result.set(i, new QueryResult(current.getHeader(), pageContrtol+current.getContent()+pageContrtol,current.getFooter(),current.getHitCount()));
\r
511 * @throws IOException
\r
513 private static void updateInput(BrowserInput input, File file, SearchQuery query) throws IOException {
\r
514 URL url = SearchQuery.encode(file, query);
\r
516 input.setName(query.getOriginalQuery());
\r
517 // System.out.println("update input: " + url + " - " + query + " - " + input);
\r
520 private static Set<SearchEngine> getSearchEngines() throws DatabaseException{
\r
521 return Simantics.getSession().syncRequest(new Read<Set<SearchEngine>>() {
\r
523 public Set<SearchEngine> perform(ReadGraph graph)
\r
524 throws DatabaseException {
\r
525 Resource project = Simantics.peekProjectResource();
\r
526 if (project == null)
\r
527 return Collections.emptySet();
\r
528 return getSearchEngines(graph, project);
\r
533 private static Set<SearchEngine> getSearchEngines(ReadGraph graph, Resource project) throws DatabaseException{
\r
534 Set<SearchEngine> searchEngines = new HashSet<SearchEngine>();
\r
535 Map<Resource, Set<SearchEngine>> result = getSearchEnginesByModel(graph, project);
\r
536 for (Set<SearchEngine> set : result.values())
\r
537 searchEngines.addAll(set);
\r
538 return searchEngines;
\r
542 private static Map<Resource,Set<SearchEngine>> getSearchEnginesByModel(ReadGraph graph, Resource project) throws DatabaseException{
\r
543 WorkbenchResource WB = WorkbenchResource.getInstance(graph);
\r
544 Layer0 L0 = Layer0.getInstance(graph);
\r
545 Map<Resource, Set<SearchEngine>> result = new HashMap<Resource, Set<SearchEngine>>();
\r
546 Collection<Resource> activeModels = graph.syncRequest(new ActiveModels(project));
\r
547 for (Resource model : activeModels) {
\r
548 Set<SearchEngine> searchEngines = new HashSet<SearchEngine>();
\r
550 List<Resource> searchFunctions = new ArrayList<Resource>();
\r
551 searchFunctions.addAll(graph.getObjects(model, WB.HasWorkbenchSearchFunction));
\r
552 if (searchFunctions.size() == 0) {
\r
553 searchEngines.addAll(findSearchContributions(graph, model));
\r
555 if (searchFunctions.isEmpty() && searchEngines.isEmpty()) {
\r
556 // TODO : backwards compatibility, to be removed.
\r
557 searchFunctions.addAll(graph.getObjects(project, WB.HasWorkbenchSearchFunction));
\r
559 if (searchFunctions.isEmpty() && searchEngines.isEmpty())
\r
560 searchFunctions.add( WB.DependenciesSearchFunction);
\r
562 for (Resource searchFunction : searchFunctions) {
\r
563 @SuppressWarnings("rawtypes")
\r
564 Function f = graph.adapt(searchFunction, Function.class);
\r
565 String id = graph.getURI(searchFunction);
\r
566 String name = graph.getPossibleRelatedValue2(searchFunction, L0.HasLabel);
\r
567 @SuppressWarnings("unchecked")
\r
568 SearchEngine engine = new SearchEngine(id,name,(Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult>)f, true);
\r
570 engine.addSupportedParam("Name");
\r
571 engine.addSupportedParam("Types");
\r
573 searchEngines.add(engine);
\r
575 result.put(model, searchEngines);
\r
582 * @param subMonitor
\r
584 * @param maxResults
\r
586 * @throws DatabaseException
\r
588 private static List<QueryResult> createResultPage(final IProgressMonitor monitor, final SearchQuery query, final int maxResults) throws DatabaseException {
\r
589 return Simantics.getSession().syncRequest(new Read<List<QueryResult>>() {
\r
591 public List<QueryResult> perform(ReadGraph graph) throws DatabaseException {
\r
592 Resource project = Simantics.peekProjectResource();
\r
593 if (project == null)
\r
596 Collection<Resource> activeModels = graph.syncRequest(new ActiveModels(project));
\r
597 //if (activeModels.isEmpty())
\r
599 long t1 = System.currentTimeMillis();
\r
600 Set<SearchEngine> searchEngines = new HashSet<SearchEngine>();
\r
601 MapList<Resource, Pair<SearchEngine,SearchResult>> searchResults = new MapList<Resource, Pair<SearchEngine,SearchResult>>();
\r
602 Map<Resource,Set<SearchEngine>> searchEngineMap = getSearchEnginesByModel(graph, project);
\r
604 for (Resource model : activeModels) {
\r
605 for (SearchEngine engine : searchEngineMap.get(model)) {
\r
607 if (query.getBooleanFlag(engine.getId())) {
\r
608 SearchResult result = engine.getSearchFunction().apply(monitor, graph, model, query, maxResults);
\r
609 if (!result.isEmpty()) {
\r
610 searchResults.add(model, new Pair<SearchEngine,SearchResult>(engine, result));
\r
613 searchEngines.add(engine);
\r
615 // searchResults.put(model, result);
\r
617 long t2 = System.currentTimeMillis();
\r
618 System.out.println("Running search queries took " + (t2-t1) + " ms for query '" + query + "'");
\r
621 return Searching.generatePage(graph, searchEngines,query, maxResults, searchResults);
\r
622 } catch (IOException e) {
\r
623 Activator.logError("I/O problem while generating search result page.", e);
\r
624 } catch (TemplateException e) {
\r
625 Activator.logError("Template definition problem in search result page generation. Please inform the developers.", e);
\r
632 private static Collection<SearchEngine> findSearchContributions(ReadGraph graph, Resource model) throws DatabaseException {
\r
633 WorkbenchResource WB = WorkbenchResource.getInstance(graph);
\r
634 Instances contributionFinder = graph.adapt(WB.SearchContribution, Instances.class);
\r
635 Resource index = model;
\r
636 List<SearchEngine> result = new ArrayList<SearchEngine>();
\r
637 for (Resource r : contributionFinder.find(graph, index)) {
\r
638 SearchEngine engine = contributionToEngine(graph, r);
\r
639 if (engine != null)
\r
640 result.add(engine);
\r
645 private static SearchEngine contributionToEngine(ReadGraph graph, Resource searchContribution) throws DatabaseException {
\r
646 Layer0 L0 = Layer0.getInstance(graph);
\r
647 WorkbenchResource WB = WorkbenchResource.getInstance(graph);
\r
649 Resource searchFunction = graph.getPossibleObject(searchContribution, WB.hasSearchFunction);
\r
650 if (searchFunction == null)
\r
653 @SuppressWarnings("rawtypes")
\r
654 Function f = graph.adapt(searchFunction, Function.class);
\r
655 String id = graph.getURI(searchFunction);
\r
656 String name = graph.getPossibleRelatedValue2(searchFunction, L0.HasLabel);
\r
658 Boolean enabledByDefault = graph.getPossibleRelatedValue2(searchContribution, WB.SearchContribution_isEnabledByDefault, Bindings.BOOLEAN);
\r
659 boolean enabled = !Boolean.FALSE.equals(enabledByDefault);
\r
661 @SuppressWarnings("unchecked")
\r
662 SearchEngine engine = new SearchEngine(id,name,(Function5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult>)f, enabled);
\r
664 engine.addSupportedParam("Name");
\r
665 engine.addSupportedParam("Types");
\r