1 package org.simantics.document.linking.function;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
9 import org.eclipse.core.runtime.IProgressMonitor;
10 import org.simantics.databoard.Bindings;
11 import org.simantics.db.ReadGraph;
12 import org.simantics.db.Resource;
13 import org.simantics.db.common.utils.Logger;
14 import org.simantics.db.common.utils.NameUtils;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.layer0.adapter.Instances;
17 import org.simantics.document.linking.ontology.DocumentLink;
18 import org.simantics.document.linking.utils.SourceLinkUtil;
19 import org.simantics.scl.runtime.function.FunctionImpl5;
20 import org.simantics.workbench.search.NamedResource;
21 import org.simantics.workbench.search.SearchQuery;
22 import org.simantics.workbench.search.SearchResult;
23 import org.simantics.workbench.search.SearchResultColumn;
24 import org.simantics.workbench.search.SearchResultRow;
25 import org.simantics.workbench.search.StringUtil;
27 public class SearchFunction extends FunctionImpl5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> {
29 public static List<SearchResultColumn> columns;
32 columns = new ArrayList<SearchResultColumn>();
33 columns.add(new SearchResultColumn("Name"));
34 columns.add(new SearchResultColumn("Comment"));
35 columns.add(new SearchResultColumn("Part Of"));
39 public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {
41 DocumentLink sl = DocumentLink.getInstance(graph);
42 Instances instancesQuery = graph.adapt(sl.Source, Instances.class);
43 Collection<Resource> found = instancesQuery.find(graph, model);
44 return generateSearchResults(graph, found,query);
45 } catch (DatabaseException e) {
46 Logger.defaultLogError(e);
52 public static class NameComparator {
56 public NameComparator(String query) {
57 String parts[] = query.split(" OR ");
58 for (String s : parts) {
59 if (s.startsWith("Name:")) {
60 name = s.substring(5);
66 boolean freeStart = false;
67 boolean freeEnd = false;
68 if (name.endsWith("*")) {
69 name = name.substring(0,name.length()-1);
72 if (name.startsWith("*")) {
73 name = name.substring(1,name.length());
76 if (freeStart && freeEnd)
82 name = name.toLowerCase();
85 public boolean compare(String s) {
88 return s.toLowerCase().equals(name);
90 return s.toLowerCase().contains(name);
92 return s.toLowerCase().endsWith(name);
94 return s.toLowerCase().startsWith(name);
100 public static final SearchResult generateSearchResults(ReadGraph graph,
101 Collection<Resource> results, SearchQuery query) throws DatabaseException {
102 DocumentLink sl = DocumentLink.getInstance(graph);
104 SearchResult result = new SearchResult(columns);
105 Set<Resource> processed = new HashSet<Resource>();
107 NameComparator c = new NameComparator(query.getQuery("Name"));
109 for (Resource source : results) {
110 // Prevent index corruption from producing duplicate results.
111 if (!processed.add(source))
114 Resource reference = SourceLinkUtil.getReferredDocument(graph, source);
115 if (!SourceLinkUtil.isValidReference(graph, reference)) {
116 // TODO: searching removed references
120 Resource parent = (Resource) graph.getSingleObject(source, sl.hasSource_Inverse);
121 String name = NameUtils.getSafeLabel(graph,reference);
122 if (name.length() == 0)
123 name = NameUtils.getSafeName(graph, reference);
125 if (!c.compare(name))
128 String parentName = NameUtils.getSafeLabel(graph, parent);
129 if (parentName.length() == 0)
130 parentName = NameUtils.getSafeName(graph, parent);
132 if (graph.isInstanceOf(source, sl.FunctionalSource)) {
133 Resource relation = graph.getSingleObject(source, sl.consernsRelation);
134 String relationName = NameUtils.getSafeLabel(graph, relation);
135 if (relationName.length() == 0)
136 relationName = NameUtils.getSafeName(graph, relation);
137 parentName = parentName +"#"+relationName;
140 DocumentLinkRow rst = new DocumentLinkRow();
141 rst.resource = NamedResource.of(graph, reference, name);
142 rst.parent = NamedResource.of(graph, parent,parentName);
143 rst.comment = graph.getPossibleRelatedValue(source, sl.hasSourceComment,Bindings.STRING);
145 // Collection<Resource> typeResources = graph.getTypes(reference);
146 // Collection<Resource> principalTypeResources = graph.getPrincipalTypes(reference);
147 // if (!typeResources.isEmpty()) {
148 // rst.types = new ArrayList<NamedResource>(typeResources.size());
149 // rst.principalTypes = new ArrayList<NamedResource>(principalTypeResources.size());
150 // for (Resource t : typeResources) {
151 // String oname = NameUtils.getSafeLabel(graph, t);
152 // NamedResource nr = NamedResource.of(graph, t, oname);
153 // rst.types.add(nr);
154 // if (principalTypeResources.contains(t))
155 // rst.principalTypes.add(nr);
164 private static class DocumentLinkRow implements SearchResultRow {
165 public NamedResource resource;
166 public NamedResource parent;
167 public String comment;
169 public String getContent(int column) {
172 return "<a class=\"small\" href=\"resource:"+ resource.getResource() +"\"" + (resource.getUri() == null ? "" : " title=\""+resource.getUri()+"\">")+StringUtil.escape(resource.getName())+"</a>";
179 return "<a class=\"small\" href=\"resource:"+ parent.getResource() +"\"" + (parent.getUri() == null ? "" : " title=\""+parent.getUri()+"\">")+StringUtil.escape(parent.getName())+"</a>";