X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.debug.ui%2Fsrc%2Forg%2Fsimantics%2Fdebug%2Fui%2FSearchResourceDialog.java;h=29cfd63bd45d9786bed42ad25a04b9e0cdc670a7;hp=ffdc681754940015690d29e92ed7a6f832a4d4b4;hb=304a9422a5d698963db84080645766b1a14f346c;hpb=1f2ae6dca5f4784be8e6287ab4445834061de31f diff --git a/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/SearchResourceDialog.java b/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/SearchResourceDialog.java index ffdc68175..29cfd63bd 100644 --- a/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/SearchResourceDialog.java +++ b/bundles/org.simantics.debug.ui/src/org/simantics/debug/ui/SearchResourceDialog.java @@ -1,461 +1,473 @@ -/******************************************************************************* - * Copyright (c) 2007, 2016 Association for Decentralized Information Management - * in Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - * Semantum Oy - index based searching and graph manipulation (#4255) - *******************************************************************************/ -package org.simantics.debug.ui; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.resource.ResourceManager; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.common.primitiverequest.PossibleAdapter; -import org.simantics.db.common.procedure.adapter.TransientCacheListener; -import org.simantics.db.common.request.BinaryRead; -import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.request.ReadRequest; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.uri.UnescapedChildMapOfResource; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.migration.OntologiesFromLibrary; -import org.simantics.db.layer0.variable.Variables.Role; -import org.simantics.db.request.Read; -import org.simantics.db.service.SerialisationSupport; -import org.simantics.debug.ui.ResourceSearch.IResourceFilter; -import org.simantics.debug.ui.internal.Activator; -import org.simantics.debug.ui.internal.DebugUtils; -import org.simantics.layer0.Layer0; -import org.simantics.operation.Layer0X; -import org.simantics.scl.runtime.function.Function; -import org.simantics.ui.selection.ResourceWorkbenchSelectionElement; -import org.simantics.ui.workbench.dialogs.ResourceLabelProvider; -import org.simantics.utils.Container; -import org.simantics.utils.ui.BundleUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * TODO Add Debugger Composite as preview! - */ -public class SearchResourceDialog extends FilteredItemsSelectionDialog { - - private static final Logger LOGGER = LoggerFactory.getLogger(SearchResourceDialog.class); - - /** - * The default maximum amount of Dependencies index hits to produce as results. - */ - private static final int DEFAULT_MAX_INDEX_HITS = 1000; - - private static final Pattern ID_PATTERN = Pattern.compile("\\$([0-9]+)"); - - private static final String SEARCH_RESOURCE_DIALOG = "SearchResourceDialog"; //$NON-NLS-1$ - - private static final int SHOW_IN_BROWSER_ID = IDialogConstants.CLIENT_ID + 1; - - private static final String SHOW_IN_BROWSER_LABEL = "Show In Browser"; - - private Session session; - @SuppressWarnings("unused") - private IStructuredSelection selection; - private ResourceManager resourceManager; - private IResourceFilter resourceFilter = ResourceSearch.FILTER_ALL; - - LabelProvider detailsLabelProvider = new LabelProvider() { - @Override - public String getText(Object element) { - if (element == null) - return "null"; - // This may happen if multiple choice is enabled - if (element instanceof String) - return (String) element; - @SuppressWarnings("unchecked") - Container rc = (Container) element; - final Resource r = rc.get(); - try { - return session.syncRequest(new Read() { - @Override - public String perform(ReadGraph g) throws DatabaseException { - String name = NameUtils.getSafeName(g, r); - String uri = DebugUtils.getPossibleRootRelativePath(g, r); - return - "[" + r.getResourceId() + "] - " - + name - + (uri != null ? " - " : "") - + (uri != null ? uri : ""); - } - }); - } catch (DatabaseException e) { - Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Resource label provider failed unexpectedly.", e)); - return ""; - } - } - }; - - static class ElementLabelProvider extends ResourceLabelProvider { - public ElementLabelProvider(Display display) { - super(display); - } - @Override - public String getText(Object element) { - if (element==null) - return "null"; - return element.toString(); - } - @Override - public Image getImage(Object element) { - if (element == null) - return null; - @SuppressWarnings("unchecked") - Container rc = (Container) element; - final Resource r = rc.get(); - return super.getImage(r); - } - }; - - ElementLabelProvider labelProvider; - - public SearchResourceDialog(Session s, boolean multi, Shell shell, String title) { - this(s, multi, shell, title, null); - } - - public SearchResourceDialog(Session s, boolean multi, Shell shell, String title, IStructuredSelection selection) { - super(shell, multi); - this.session = s; - this.selection = selection; - this.labelProvider = new ElementLabelProvider(shell.getDisplay()); - setMessage("Enter name, resource URI or ID"); - setListLabelProvider(labelProvider); - setDetailsLabelProvider(detailsLabelProvider); - setTitle(title); - //setInitialPattern("*", FilteredItemsSelectionDialog.FULL_SELECTION); - setSelectionHistory(new ResourceSelectionHistory()); - setSeparatorLabel("Previously selected above, others below"); - } - - @Override - protected void configureShell(Shell shell) { - this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), shell); - setImage((Image) resourceManager.get(BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/cog_blue.png"))); - super.configureShell(shell); - } - - @Override - protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, - true); - createButton(parent, SHOW_IN_BROWSER_ID, SHOW_IN_BROWSER_LABEL, - true); - createButton(parent, IDialogConstants.CANCEL_ID, - IDialogConstants.CANCEL_LABEL, false); - } - - @Override - protected void buttonPressed(int buttonId) { - if (buttonId == SHOW_IN_BROWSER_ID) { - okPressed(); - LabeledResource lr = (LabeledResource) getFirstResult(); - ShowInBrowser.defaultExecute(new StructuredSelection(new ResourceWorkbenchSelectionElement(lr.resource))); - return; - } - super.buttonPressed(buttonId); - } - - class ResourceSelectionHistory extends FilteredItemsSelectionDialog.SelectionHistory { - - @Override - protected Object restoreItemFromMemento(IMemento memento) { - String data = memento.getTextData(); - try { - SerialisationSupport support = Simantics.getSession().getService(SerialisationSupport.class); - Resource r = support.getResource(Long.parseLong(data)); - if (r == null) - return null; - - String name = session.syncRequest(new UniqueRead() { - @Override - public String perform(ReadGraph g) throws DatabaseException { - if (!resourceFilter.acceptResource(g, r)) - return null; - try { - try { - return DebugUtils.getSafeLabel(g, r); - } catch (Exception ex) { - System.out.println("Exception thrown from restoreItemFromMemento"); - } - } catch (Throwable t) {} - return "" + r.getResourceId(); - } - }); - if (name==null) return null; - return new LabeledResource(name, r); - } catch (NumberFormatException | DatabaseException e) { - LOGGER.info("Search memento restoration failed.", e); - return null; - } - } - - @SuppressWarnings("unchecked") - @Override - protected void storeItemToMemento(Object item, IMemento memento) { - if(item instanceof Container) { - try { - SerialisationSupport support = Simantics.getSession().getService(SerialisationSupport.class); - memento.putTextData(String.valueOf(support.getRandomAccessId(((Container)item).get()))); - } catch (DatabaseException e) { - e.printStackTrace(); - } - } - } - }; - - @Override - protected Control createExtendedContentArea(Composite parent) { - return null; - } - - @Override - protected ItemsFilter createFilter() { - // NOTE: filter must be created here. - return new ItemsFilter() { - @Override - public boolean matchItem(Object item) { - //return matches(item.toString()); - return true; - } - - // If this method returns true, it means fillContentProvider will - // not be called again, but the existing results are just re-filtered. - @Override - public boolean isSubFilter(ItemsFilter filter) { - //System.out.println(getPattern() + " vs. " + filter.getPattern()); - return false; - } - - @Override - public boolean isConsistentItem(Object item) { - return true; - } - - @Override - public boolean equalsFilter(ItemsFilter filter) { - return false; - } - }; - } - - @Override - protected void fillContentProvider(final AbstractContentProvider contentProvider, - final ItemsFilter itemsFilter, final IProgressMonitor progressMonitor) - throws CoreException { - final String pattern = itemsFilter.getPattern(); - final boolean findUris = pattern.trim().startsWith("http:/"); - final long referencedResourceId = referencedResourceId(pattern); - final boolean findIds = referencedResourceId != 0; - - //progressMonitor.beginTask("Searching", IProgressMonitor.UNKNOWN); - - try { - session.syncRequest(new ReadRequest() { - @Override - public void run(ReadGraph graph) throws DatabaseException { - // Find by ID first. - if (findIds) { - try { - Resource r = graph.getService(SerialisationSupport.class).getResource(referencedResourceId); - contentProvider.add(new LabeledResource(DebugUtils.getSafeLabel(graph, r), r), itemsFilter); - //contentProvider.add(new LabeledResource(pattern, r), itemsFilter); - } catch (DatabaseException e) { - // No resource for specified id. - } - } - if (findUris) { - String uri = pattern; - if (uri.endsWith(Role.CHILD.getIdentifier())) { - uri = uri.substring(0, uri.length() - 1); - } - Resource r = graph.getPossibleResource(uri); - if (r != null) { - contentProvider.add(new LabeledResource(DebugUtils.getSafeURI(graph, r), r), itemsFilter ); - - Map children = graph.syncRequest(new UnescapedChildMapOfResource(r)); - for (Resource child : children.values()) { - contentProvider.add(new LabeledResource(DebugUtils.getSafeURI(graph, child), child), itemsFilter ); - } - } - } else { - Resource project = Simantics.peekProjectResource(); - if (project != null) { - IResourceFilter rf = resourceFilter; - String filter = getFilterForResourceFilter(rf); - if (!filter.isEmpty()) - filter += " AND "; - filter += "Name:" + pattern + "*"; - - Layer0 L0 = Layer0.getInstance(graph); - - Set indexRoots = new HashSet<>(); - indexRoots.addAll(graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, L0.IndexRoot))); - indexRoots.addAll(graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()))); - for (Resource indexRoot : indexRoots) { - Collection hits = find(graph, indexRoot, filter); - for (Resource r : hits) { - if (rf != null && !rf.acceptResource(graph, r)) - continue; - contentProvider.add(new LabeledResource(DebugUtils.getSafeLabel(graph, r), r), itemsFilter); - } - } - } - } - } - - public Collection find(ReadGraph graph, Resource index, String filter) throws DatabaseException { - //TimeLogger.resetTimeAndLog("find(" + graph.getURI(index) + ", " + filter + ")"); - Collection indexResult = graph.syncRequest(new QueryIndex(index, filter), TransientCacheListener.>instance()); - //TimeLogger.log("found " + indexResult.size()); - return indexResult; - } - - }); - } catch (DatabaseException ex) { - Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)); - } - - progressMonitor.done(); - } - - /** - * A (cacheable) query to optimize single index queries for immutable - * indexes such as ontologies. - */ - static class QueryIndex extends BinaryRead> { - - public QueryIndex(Resource index, String filter) { - super(index, filter); - } - - @Override - public Collection perform(ReadGraph graph) - throws DatabaseException { - Layer0X L0X = Layer0X.getInstance(graph); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - Function dependencies = graph.syncRequest(new PossibleAdapter(L0X.DependencyResources, Function.class), TransientCacheListener.instance()); - if (dependencies == null) - return Collections.emptyList(); - - @SuppressWarnings("unchecked") - List results = (List) dependencies.apply(graph, parameter, parameter2, DEFAULT_MAX_INDEX_HITS); - if (results == null || results.isEmpty()) - return Collections.emptyList(); - - // TreeSet to keep the results in deterministic order and to prevent duplicates. - Set resultSet = new TreeSet<>(); - for (Resource res : results) { - if (res != null && !resultSet.contains(res)) - resultSet.add(res); - } - return new ArrayList(resultSet); - } - - } - - private long referencedResourceId(String pattern) { - Matcher m = ID_PATTERN.matcher(pattern); - if (m.matches()) { - String id = m.group(1); - try { - return Long.parseLong(id); - } catch (NumberFormatException nfe) { - } - } - return 0; - } - - @Override - protected IDialogSettings getDialogSettings() { - IDialogSettings settings = Activator.getDefault().getDialogSettings() - .getSection(SEARCH_RESOURCE_DIALOG); - if (settings == null) { - settings = Activator.getDefault().getDialogSettings() - .addNewSection(SEARCH_RESOURCE_DIALOG); - } - return settings; - } - - @SuppressWarnings("unchecked") - @Override - public String getElementName(Object item) { - return ((Container)item).get().getResourceId()+""; - //return item.toString(); - } - - @Override - protected Comparator getItemsComparator() { - return (arg0, arg1) -> { - return arg0.toString().compareTo(arg1.toString()); - }; - } - - @Override - protected IStatus validateItem(Object item) { - return Status.OK_STATUS; - } - - public IResourceFilter getResourceFilter() { - return resourceFilter; - } - - public void setResourceFilter(IResourceFilter resourceFilter) { - this.resourceFilter = resourceFilter; - } - - private String getFilterForResourceFilter(IResourceFilter filter) { - if (filter == null || filter == ResourceSearch.FILTER_ALL) - return ""; - if (filter == ResourceSearch.FILTER_RELATIONS) - return "Types:Relation"; - if (filter == ResourceSearch.FILTER_TYPES) - return "Types:Type"; - return ""; - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2016 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - index based searching and graph manipulation (#4255) + *******************************************************************************/ +package org.simantics.debug.ui; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.primitiverequest.PossibleAdapter; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.BinaryRead; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.uri.UnescapedChildMapOfResource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.migration.OntologiesFromLibrary; +import org.simantics.db.layer0.variable.Variables.Role; +import org.simantics.db.request.Read; +import org.simantics.db.service.SerialisationSupport; +import org.simantics.debug.ui.ResourceSearch.IResourceFilter; +import org.simantics.debug.ui.internal.Activator; +import org.simantics.debug.ui.internal.DebugUtils; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.scl.runtime.function.Function; +import org.simantics.ui.selection.ResourceWorkbenchSelectionElement; +import org.simantics.ui.workbench.dialogs.ResourceLabelProvider; +import org.simantics.utils.Container; +import org.simantics.utils.ui.BundleUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * TODO Add Debugger Composite as preview! + */ +public class SearchResourceDialog extends FilteredItemsSelectionDialog { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchResourceDialog.class); + + /** + * The default maximum amount of Dependencies index hits to produce as results. + */ + private static final int DEFAULT_MAX_INDEX_HITS = 1000; + + private static final Pattern ID_PATTERN = Pattern.compile("\\$([0-9]+)"); + + private static final String SEARCH_RESOURCE_DIALOG = "SearchResourceDialog"; //$NON-NLS-1$ + + private static final int SHOW_IN_BROWSER_ID = IDialogConstants.CLIENT_ID + 1; + + private static final String SHOW_IN_BROWSER_LABEL = "Show In Browser"; + + private Session session; + @SuppressWarnings("unused") + private IStructuredSelection selection; + private ResourceManager resourceManager; + private IResourceFilter resourceFilter = ResourceSearch.FILTER_ALL; + + LabelProvider detailsLabelProvider = new LabelProvider() { + @Override + public String getText(Object element) { + if (element == null) + return "null"; + // This may happen if multiple choice is enabled + if (element instanceof String) + return (String) element; + @SuppressWarnings("unchecked") + Container rc = (Container) element; + final Resource r = rc.get(); + try { + return session.syncRequest(new Read() { + @Override + public String perform(ReadGraph g) throws DatabaseException { + String name = NameUtils.getSafeName(g, r); + String uri = DebugUtils.getPossibleRootRelativePath(g, r); + return + "[" + r.getResourceId() + "] - " + + name + + (uri != null ? " - " : "") + + (uri != null ? uri : ""); + } + }); + } catch (DatabaseException e) { + Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Resource label provider failed unexpectedly.", e)); + return ""; + } + } + }; + + static class ElementLabelProvider extends ResourceLabelProvider { + public ElementLabelProvider(Display display) { + super(display); + } + @Override + public String getText(Object element) { + if (element==null) + return "null"; + return element.toString(); + } + @Override + public Image getImage(Object element) { + if (element == null) + return null; + @SuppressWarnings("unchecked") + Container rc = (Container) element; + final Resource r = rc.get(); + return super.getImage(r); + } + }; + + ElementLabelProvider labelProvider; + + public SearchResourceDialog(Session s, boolean multi, Shell shell, String title) { + this(s, multi, shell, title, null); + } + + public SearchResourceDialog(Session s, boolean multi, Shell shell, String title, IStructuredSelection selection) { + super(shell, multi); + this.session = s; + this.selection = selection; + this.labelProvider = new ElementLabelProvider(shell.getDisplay()); + setMessage("Enter name, resource URI or ID"); + setListLabelProvider(labelProvider); + setDetailsLabelProvider(detailsLabelProvider); + setTitle(title); + //setInitialPattern("*", FilteredItemsSelectionDialog.FULL_SELECTION); + setSelectionHistory(new ResourceSelectionHistory()); + setSeparatorLabel("Previously selected above, others below"); + } + + @Override + protected void configureShell(Shell shell) { + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), shell); + setImage((Image) resourceManager.get(BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/cog_blue.png"))); + super.configureShell(shell); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, + true); + createButton(parent, SHOW_IN_BROWSER_ID, SHOW_IN_BROWSER_LABEL, + true); + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + @Override + protected void buttonPressed(int buttonId) { + if (buttonId == SHOW_IN_BROWSER_ID) { + okPressed(); + LabeledResource lr = (LabeledResource) getFirstResult(); + ShowInBrowser.defaultExecute(new StructuredSelection(new ResourceWorkbenchSelectionElement(lr.resource))); + return; + } + super.buttonPressed(buttonId); + } + + class ResourceSelectionHistory extends FilteredItemsSelectionDialog.SelectionHistory { + + @Override + protected Object restoreItemFromMemento(IMemento memento) { + String data = memento.getTextData(); + try { + SerialisationSupport support = Simantics.getSession().getService(SerialisationSupport.class); + Resource r = support.getResource(Long.parseLong(data)); + if (r == null) + return null; + + String name = session.syncRequest(new UniqueRead() { + @Override + public String perform(ReadGraph g) throws DatabaseException { + if (!resourceFilter.acceptResource(g, r)) + return null; + try { + try { + return DebugUtils.getSafeLabel(g, r); + } catch (Exception ex) { + System.out.println("Exception thrown from restoreItemFromMemento"); + } + } catch (Throwable t) {} + return "" + r.getResourceId(); + } + }); + if (name==null) return null; + return new LabeledResource(name, r); + } catch (NumberFormatException | DatabaseException e) { + LOGGER.info("Search memento restoration failed.", e); + return null; + } + } + + @SuppressWarnings("unchecked") + @Override + protected void storeItemToMemento(Object item, IMemento memento) { + if(item instanceof Container) { + try { + SerialisationSupport support = Simantics.getSession().getService(SerialisationSupport.class); + memento.putTextData(String.valueOf(support.getRandomAccessId(((Container)item).get()))); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + } + }; + + @Override + protected Control createExtendedContentArea(Composite parent) { + return null; + } + + @Override + protected ItemsFilter createFilter() { + // NOTE: filter must be created here. + return new ItemsFilterWithSearchResults(); + } + + private class ItemsFilterWithSearchResults extends ItemsFilter { + private Set searchResults = new HashSet(); + + public ItemsFilterWithSearchResults() { + + final String pattern = getPattern(); + final boolean findUris = pattern.trim().startsWith("http:/"); + final long referencedResourceId = referencedResourceId(pattern); + final boolean findIds = referencedResourceId != 0; + + searchResults.clear(); + if (pattern.isEmpty()) return; + //progressMonitor.beginTask("Searching", IProgressMonitor.UNKNOWN); + + try { + session.syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + // Find by ID first. + if (findIds) { + try { + Resource r = graph.getService(SerialisationSupport.class).getResource(referencedResourceId); + searchResults.add(new LabeledResource(DebugUtils.getSafeLabel(graph, r), r)); + } catch (DatabaseException e) { + // No resource for specified id. + } + } + if (findUris) { + String uri = pattern; + if (uri.endsWith(Role.CHILD.getIdentifier())) { + uri = uri.substring(0, uri.length() - 1); + } + Resource r = graph.getPossibleResource(uri); + if (r != null) { + searchResults.add(new LabeledResource(DebugUtils.getSafeURI(graph, r), r)); + + Map children = graph.syncRequest(new UnescapedChildMapOfResource(r)); + for (Resource child : children.values()) { + searchResults.add(new LabeledResource(DebugUtils.getSafeURI(graph, child), child)); + } + } + } else { + Resource project = Simantics.peekProjectResource(); + if (project != null) { + IResourceFilter rf = resourceFilter; + String filter = getFilterForResourceFilter(rf); + if (!filter.isEmpty()) + filter += " AND "; + filter += "Name:" + pattern + "*"; + + Layer0 L0 = Layer0.getInstance(graph); + + Set indexRoots = new HashSet<>(); + indexRoots.addAll(graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, L0.IndexRoot))); + indexRoots.addAll(graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()))); + for (Resource indexRoot : indexRoots) { + Collection hits = find(graph, indexRoot, filter); + for (Resource r : hits) { + if (rf != null && !rf.acceptResource(graph, r)) + continue; + searchResults.add(new LabeledResource(DebugUtils.getSafeLabel(graph, r), r)); + } + } + } + } + } + + public Collection find(ReadGraph graph, Resource index, String filter) throws DatabaseException { + //TimeLogger.resetTimeAndLog("find(" + graph.getURI(index) + ", " + filter + ")"); + Collection indexResult = graph.syncRequest(new QueryIndex(index, filter), TransientCacheListener.>instance()); + //TimeLogger.log("found " + indexResult.size()); + return indexResult; + } + + }); + } catch (DatabaseException ex) { + Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)); + } + + } + + @Override + public boolean matchItem(Object item) { + return searchResults.contains(item); + } + + @Override + public boolean isSubFilter(ItemsFilter filter) { + return false; + } + + @Override + public boolean isConsistentItem(Object item) { + return true; + } + + @Override + public boolean equalsFilter(ItemsFilter filter) { + return false; + } + + public void fillContentProvider(final AbstractContentProvider contentProvider) { + for (Object item : searchResults) { + contentProvider.add(item, this); + } + } + } + + @Override + protected void fillContentProvider(final AbstractContentProvider contentProvider, + final ItemsFilter itemsFilter, final IProgressMonitor progressMonitor) + throws CoreException { + ((ItemsFilterWithSearchResults) itemsFilter).fillContentProvider(contentProvider); + progressMonitor.done(); + } + + /** + * A (cacheable) query to optimize single index queries for immutable + * indexes such as ontologies. + */ + static class QueryIndex extends BinaryRead> { + + public QueryIndex(Resource index, String filter) { + super(index, filter); + } + + @Override + public Collection perform(ReadGraph graph) + throws DatabaseException { + Layer0X L0X = Layer0X.getInstance(graph); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + Function dependencies = graph.syncRequest(new PossibleAdapter(L0X.DependencyResources, Function.class), TransientCacheListener.instance()); + if (dependencies == null) + return Collections.emptyList(); + + @SuppressWarnings("unchecked") + List results = (List) dependencies.apply(graph, parameter, parameter2, DEFAULT_MAX_INDEX_HITS); + if (results == null || results.isEmpty()) + return Collections.emptyList(); + + // TreeSet to keep the results in deterministic order and to prevent duplicates. + Set resultSet = new TreeSet<>(); + for (Resource res : results) { + if (res != null && !resultSet.contains(res)) + resultSet.add(res); + } + return new ArrayList(resultSet); + } + + } + + private long referencedResourceId(String pattern) { + Matcher m = ID_PATTERN.matcher(pattern); + if (m.matches()) { + String id = m.group(1); + try { + return Long.parseLong(id); + } catch (NumberFormatException nfe) { + } + } + return 0; + } + + @Override + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = Activator.getDefault().getDialogSettings() + .getSection(SEARCH_RESOURCE_DIALOG); + if (settings == null) { + settings = Activator.getDefault().getDialogSettings() + .addNewSection(SEARCH_RESOURCE_DIALOG); + } + return settings; + } + + @SuppressWarnings("unchecked") + @Override + public String getElementName(Object item) { + return ((Container)item).get().getResourceId()+""; + //return item.toString(); + } + + @Override + protected Comparator getItemsComparator() { + return (arg0, arg1) -> { + return arg0.toString().compareTo(arg1.toString()); + }; + } + + @Override + protected IStatus validateItem(Object item) { + return Status.OK_STATUS; + } + + public IResourceFilter getResourceFilter() { + return resourceFilter; + } + + public void setResourceFilter(IResourceFilter resourceFilter) { + this.resourceFilter = resourceFilter; + } + + private String getFilterForResourceFilter(IResourceFilter filter) { + if (filter == null || filter == ResourceSearch.FILTER_ALL) + return ""; + if (filter == ResourceSearch.FILTER_RELATIONS) + return "Types:Relation"; + if (filter == ResourceSearch.FILTER_TYPES) + return "Types:Type"; + return ""; + } + +}