--- /dev/null
+package org.simantics.document.linking.function;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.Instances;\r
+import org.simantics.document.linking.ontology.DocumentLink;\r
+import org.simantics.document.linking.utils.SourceLinkUtil;\r
+import org.simantics.scl.runtime.function.FunctionImpl5;\r
+import org.simantics.workbench.search.NamedResource;\r
+import org.simantics.workbench.search.SearchQuery;\r
+import org.simantics.workbench.search.SearchResult;\r
+import org.simantics.workbench.search.SearchResultColumn;\r
+import org.simantics.workbench.search.SearchResultRow;\r
+import org.simantics.workbench.search.StringUtil;\r
+\r
+public class SearchFunction extends FunctionImpl5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> {\r
+\r
+ public static List<SearchResultColumn> columns;\r
+ \r
+ static {\r
+ columns = new ArrayList<SearchResultColumn>();\r
+ columns.add(new SearchResultColumn("Name"));\r
+ columns.add(new SearchResultColumn("Comment"));\r
+ columns.add(new SearchResultColumn("Part Of"));\r
+ }\r
+ \r
+ @Override\r
+ public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {\r
+ try {\r
+ DocumentLink sl = DocumentLink.getInstance(graph);\r
+ Instances instancesQuery = graph.adapt(sl.Source, Instances.class);\r
+ Collection<Resource> found = instancesQuery.find(graph, model);\r
+ return generateSearchResults(graph, found,query);\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ \r
+ public static class NameComparator {\r
+ private String name;\r
+ int type = 0;\r
+ \r
+ public NameComparator(String query) {\r
+ String parts[] = query.split(" OR ");\r
+ for (String s : parts) {\r
+ if (s.startsWith("Name:")) {\r
+ name = s.substring(5);\r
+ }\r
+ }\r
+ if (name == null)\r
+ return;\r
+ name = name.trim();\r
+ boolean freeStart = false;\r
+ boolean freeEnd = false;\r
+ if (name.endsWith("*")) {\r
+ name = name.substring(0,name.length()-1);\r
+ freeEnd = true;\r
+ }\r
+ if (name.startsWith("*")) {\r
+ name = name.substring(1,name.length());\r
+ freeStart = true;\r
+ }\r
+ if (freeStart && freeEnd)\r
+ type = 1;\r
+ else if (freeStart)\r
+ type = 2;\r
+ else if (freeEnd)\r
+ type = 3;\r
+ name = name.toLowerCase();\r
+ }\r
+ \r
+ public boolean compare(String s) {\r
+ switch (type) {\r
+ case 0:\r
+ return s.toLowerCase().equals(name);\r
+ case 1:\r
+ return s.toLowerCase().contains(name);\r
+ case 2:\r
+ return s.toLowerCase().endsWith(name);\r
+ case 3:\r
+ return s.toLowerCase().startsWith(name);\r
+ }\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ public static final SearchResult generateSearchResults(ReadGraph graph,\r
+ Collection<Resource> results, SearchQuery query) throws DatabaseException {\r
+ DocumentLink sl = DocumentLink.getInstance(graph);\r
+\r
+ SearchResult result = new SearchResult(columns);\r
+ Set<Resource> processed = new HashSet<Resource>();\r
+\r
+ NameComparator c = new NameComparator(query.getQuery("Name"));\r
+ \r
+ for (Resource source : results) {\r
+ // Prevent index corruption from producing duplicate results.\r
+ if (!processed.add(source))\r
+ continue;\r
+ \r
+ Resource reference = SourceLinkUtil.getReferredDocument(graph, source);\r
+ if (!SourceLinkUtil.isValidReference(graph, reference)) {\r
+ // TODO: searching removed references\r
+ continue;\r
+ }\r
+\r
+ Resource parent = (Resource) graph.getSingleObject(source, sl.hasSource_Inverse);\r
+ String name = NameUtils.getSafeLabel(graph,reference);\r
+ if (name.length() == 0)\r
+ name = NameUtils.getSafeName(graph, reference);\r
+ \r
+ if (!c.compare(name))\r
+ continue;\r
+ \r
+ String parentName = NameUtils.getSafeLabel(graph, parent);\r
+ if (parentName.length() == 0)\r
+ parentName = NameUtils.getSafeName(graph, parent);\r
+ \r
+ if (graph.isInstanceOf(source, sl.FunctionalSource)) {\r
+ Resource relation = graph.getSingleObject(source, sl.consernsRelation);\r
+ String relationName = NameUtils.getSafeLabel(graph, relation);\r
+ if (relationName.length() == 0)\r
+ relationName = NameUtils.getSafeName(graph, relation);\r
+ parentName = parentName +"#"+relationName;\r
+ }\r
+ \r
+ DocumentLinkRow rst = new DocumentLinkRow();\r
+ rst.resource = NamedResource.of(graph, reference, name);\r
+ rst.parent = NamedResource.of(graph, parent,parentName);\r
+ rst.comment = graph.getPossibleRelatedValue(source, sl.hasSourceComment,Bindings.STRING);\r
+\r
+// Collection<Resource> typeResources = graph.getTypes(reference);\r
+// Collection<Resource> principalTypeResources = graph.getPrincipalTypes(reference);\r
+// if (!typeResources.isEmpty()) {\r
+// rst.types = new ArrayList<NamedResource>(typeResources.size());\r
+// rst.principalTypes = new ArrayList<NamedResource>(principalTypeResources.size());\r
+// for (Resource t : typeResources) {\r
+// String oname = NameUtils.getSafeLabel(graph, t);\r
+// NamedResource nr = NamedResource.of(graph, t, oname);\r
+// rst.types.add(nr);\r
+// if (principalTypeResources.contains(t))\r
+// rst.principalTypes.add(nr);\r
+// }\r
+// }\r
+\r
+ result.addRow(rst);\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ private static class DocumentLinkRow implements SearchResultRow {\r
+ public NamedResource resource;\r
+ public NamedResource parent;\r
+ public String comment;\r
+ @Override\r
+ public String getContent(int column) {\r
+ switch (column) {\r
+ case 0:\r
+ return "<a class=\"small\" href=\"resource:"+ resource.getResource() +"\"" + (resource.getUri() == null ? "" : " title=\""+resource.getUri()+"\">")+StringUtil.escape(resource.getName())+"</a>";\r
+ case 1:\r
+ if (comment != null)\r
+ return comment;\r
+ return "";\r
+ case 2:\r
+ if (parent != null)\r
+ return "<a class=\"small\" href=\"resource:"+ parent.getResource() +"\"" + (parent.getUri() == null ? "" : " title=\""+parent.getUri()+"\">")+StringUtil.escape(parent.getName())+"</a>";\r
+ return "";\r
+ default:\r
+ return "";\r
+ }\r
+ }\r
+ }\r
+ \r
+}\r
+\r