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