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.db.layer0.genericrelation.Dependencies;
18 import org.simantics.document.linking.ontology.DocumentLink;
19 import org.simantics.document.linking.utils.SourceLinkUtil;
20 import org.simantics.scl.runtime.function.FunctionImpl5;
21 import org.simantics.workbench.search.NamedResource;
22 import org.simantics.workbench.search.SearchQuery;
23 import org.simantics.workbench.search.SearchResult;
24 import org.simantics.workbench.search.SearchResultColumn;
25 import org.simantics.workbench.search.SearchResultRow;
26 import org.simantics.workbench.search.StringUtil;
28 public class SearchFunction extends FunctionImpl5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> {
30 public static List<SearchResultColumn> columns;
33 columns = new ArrayList<SearchResultColumn>();
34 columns.add(new SearchResultColumn("Name")); //$NON-NLS-1$
35 columns.add(new SearchResultColumn("Comment")); //$NON-NLS-1$
36 columns.add(new SearchResultColumn("Part Of")); //$NON-NLS-1$
40 public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {
42 DocumentLink sl = DocumentLink.getInstance(graph);
43 Instances instancesQuery = graph.adapt(sl.Source, Instances.class);
44 Collection<Resource> found = instancesQuery.find(graph, model);
45 return generateSearchResults(graph, found,query);
46 } catch (DatabaseException e) {
47 Logger.defaultLogError(e);
53 public static class NameComparator {
57 public NameComparator(String query) {
58 String parts[] = query.split(" OR "); //$NON-NLS-1$
59 for (String s : parts) {
60 if (s.startsWith("Name:")) { //$NON-NLS-1$
61 name = s.substring(5);
67 boolean freeStart = false;
68 boolean freeEnd = false;
69 if (name.endsWith("*")) { //$NON-NLS-1$
70 name = name.substring(0,name.length()-1);
73 if (name.startsWith("*")) { //$NON-NLS-1$
74 name = name.substring(1,name.length());
77 if (freeStart && freeEnd)
83 name = name.toLowerCase();
86 public boolean compare(String s) {
89 return s.toLowerCase().equals(name);
91 return s.toLowerCase().contains(name);
93 return s.toLowerCase().endsWith(name);
95 return s.toLowerCase().startsWith(name);
101 public static final SearchResult generateSearchResults(ReadGraph graph,
102 Collection<Resource> results, SearchQuery query) throws DatabaseException {
103 DocumentLink sl = DocumentLink.getInstance(graph);
105 SearchResult result = new SearchResult(columns);
106 Set<Resource> processed = new HashSet<Resource>();
108 NameComparator c = new NameComparator(query.getQuery(Dependencies.FIELD_NAME_SEARCH));
110 for (Resource source : results) {
111 // Prevent index corruption from producing duplicate results.
112 if (!processed.add(source))
115 Resource reference = SourceLinkUtil.getReferredDocument(graph, source);
116 if (!SourceLinkUtil.isValidReference(graph, reference)) {
117 // TODO: searching removed references
121 Resource parent = (Resource) graph.getSingleObject(source, sl.hasSource_Inverse);
122 String name = NameUtils.getSafeLabel(graph,reference);
123 if (name.length() == 0)
124 name = NameUtils.getSafeName(graph, reference);
126 if (!c.compare(name))
129 String parentName = NameUtils.getSafeLabel(graph, parent);
130 if (parentName.length() == 0)
131 parentName = NameUtils.getSafeName(graph, parent);
133 if (graph.isInstanceOf(source, sl.FunctionalSource)) {
134 Resource relation = graph.getSingleObject(source, sl.consernsRelation);
135 String relationName = NameUtils.getSafeLabel(graph, relation);
136 if (relationName.length() == 0)
137 relationName = NameUtils.getSafeName(graph, relation);
138 parentName = parentName +"#"+relationName; //$NON-NLS-1$
141 DocumentLinkRow rst = new DocumentLinkRow();
142 rst.resource = NamedResource.of(graph, reference, name);
143 rst.parent = NamedResource.of(graph, parent,parentName);
144 rst.comment = graph.getPossibleRelatedValue(source, sl.hasSourceComment,Bindings.STRING);
146 // Collection<Resource> typeResources = graph.getTypes(reference);
147 // Collection<Resource> principalTypeResources = graph.getPrincipalTypes(reference);
148 // if (!typeResources.isEmpty()) {
149 // rst.types = new ArrayList<NamedResource>(typeResources.size());
150 // rst.principalTypes = new ArrayList<NamedResource>(principalTypeResources.size());
151 // for (Resource t : typeResources) {
152 // String oname = NameUtils.getSafeLabel(graph, t);
153 // NamedResource nr = NamedResource.of(graph, t, oname);
154 // rst.types.add(nr);
155 // if (principalTypeResources.contains(t))
156 // rst.principalTypes.add(nr);
165 private static class DocumentLinkRow implements SearchResultRow {
166 public NamedResource resource;
167 public NamedResource parent;
168 public String comment;
170 public String getContent(int column) {
173 return "<a class=\"small\" href=\"resource:"+ resource.getResource() +"\"" + (resource.getUri() == null ? "" : " title=\""+resource.getUri()+"\">")+StringUtil.escape(resource.getName())+"</a>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
177 return ""; //$NON-NLS-1$
180 return "<a class=\"small\" href=\"resource:"+ parent.getResource() +"\"" + (parent.getUri() == null ? "" : " title=\""+parent.getUri()+"\">")+StringUtil.escape(parent.getName())+"</a>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
181 return ""; //$NON-NLS-1$
183 return ""; //$NON-NLS-1$