1 package org.simantics.ui.selection;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
8 import java.util.stream.Collectors;
10 import org.eclipse.core.commands.ExecutionEvent;
11 import org.eclipse.jface.viewers.ISelection;
12 import org.eclipse.ui.handlers.HandlerUtil;
13 import org.simantics.Simantics;
14 import org.simantics.databoard.type.Datatype;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.RequestProcessor;
17 import org.simantics.db.Resource;
18 import org.simantics.db.common.primitiverequest.IsInstanceOf;
19 import org.simantics.db.common.primitiverequest.Supertypes;
20 import org.simantics.db.common.primitiverequest.Types;
21 import org.simantics.db.exception.DatabaseException;
22 import org.simantics.db.layer0.request.PossibleGUID;
23 import org.simantics.db.layer0.request.PossibleURI;
24 import org.simantics.db.layer0.request.PossibleVariableGUID;
25 import org.simantics.db.layer0.request.PossibleVariableRepresents;
26 import org.simantics.db.layer0.request.VariableRead;
27 import org.simantics.db.layer0.request.VariableURI;
28 import org.simantics.db.layer0.variable.Variable;
29 import org.simantics.utils.ui.ISelectionUtils;
31 public class WorkbenchSelectionUtils {
33 public static Resource getPossibleResource(ExecutionEvent event) throws DatabaseException {
34 ISelection selection = HandlerUtil.getCurrentSelection(event);
35 return getPossibleResource(selection);
38 public static Variable getPossibleVariable(ExecutionEvent event) throws DatabaseException {
39 ISelection selection = HandlerUtil.getCurrentSelection(event);
40 return getPossibleVariable(selection);
43 public static List<WorkbenchSelectionElement> getWorkbenchSelectionElements(ISelection selection) {
44 return ISelectionUtils.filterSelection(selection, WorkbenchSelectionElement.class);
47 public static String getPossibleJSON(Object selection) throws DatabaseException {
48 WorkbenchSelectionElement element = getPossibleWorkbenchSelectionElement(selection);
49 return element != null ? getPossibleJSON(element) : null;
52 public static Resource getPossibleResource(Object selection) throws DatabaseException {
53 WorkbenchSelectionElement element = getPossibleWorkbenchSelectionElement(selection);
54 return element != null ? getPossibleResource(element) : null;
57 public static Variable getPossibleVariable(Object selection) throws DatabaseException {
58 WorkbenchSelectionElement element = getPossibleWorkbenchSelectionElement(selection);
59 return element != null ? getPossibleVariable(element) : null;
62 public static Resource getPossibleResourceFromSelection(RequestProcessor processor, Object selection) throws DatabaseException {
63 WorkbenchSelectionElement element = getPossibleWorkbenchSelectionElement(selection);
64 return element != null ? getPossibleResource(processor, element) : null;
67 public static Variable getPossibleVariableFromSelection(RequestProcessor processor, Object selection) throws DatabaseException {
68 WorkbenchSelectionElement element = getPossibleWorkbenchSelectionElement(selection);
69 return element != null ? getPossibleVariable(processor, element) : null;
72 public static Variable getPossibleVariable(Object[] selection) throws DatabaseException {
73 if(selection.length != 1) return null;
74 if(!(selection[0] instanceof WorkbenchSelectionElement)) return null;
75 return getPossibleVariable((WorkbenchSelectionElement)selection[0]);
78 public static <T> T getPossibleElement(Object[] selection, WorkbenchSelectionContentType<T> contentType) throws DatabaseException {
79 if(selection.length != 1) return null;
80 if(!(selection[0] instanceof WorkbenchSelectionElement)) return null;
81 WorkbenchSelectionElement wse = (WorkbenchSelectionElement)selection[0];
82 return wse.getContent(contentType);
85 public static String getPossibleJSON(WorkbenchSelectionElement wse) throws DatabaseException {
86 return getPossibleJSON(Simantics.getSession(), wse);
89 public static Resource getPossibleResource(WorkbenchSelectionElement wse) throws DatabaseException {
90 return getPossibleResource(Simantics.getSession(), wse);
93 public static Variable getPossibleVariable(WorkbenchSelectionElement wse) throws DatabaseException {
94 return getPossibleVariable(Simantics.getSession(), wse);
97 public static Variable getPossibleVariableSCL(ReadGraph graph, WorkbenchSelectionElement wse) throws DatabaseException {
98 return getPossibleVariable(graph, wse);
101 public static Resource getPossibleResourceSCL(ReadGraph graph, WorkbenchSelectionElement wse) throws DatabaseException {
102 return getPossibleResource(graph, wse);
105 public static String getPossibleJSON(RequestProcessor processor, Object input) throws DatabaseException {
106 Variable var = getPossibleVariable(processor, input);
107 Resource res = getPossibleResource(processor, input);
108 String typesStr = getTypeResourceString(processor, res, var);
110 String uri = processor.syncRequest(new VariableURI(var));
111 String guid = processor.syncRequest(new PossibleVariableGUID(var));
113 Set<String> classifications = processor.syncRequest(new VariableRead<Set<String>>(var) {
115 public Set<String> perform(ReadGraph graph) throws DatabaseException {
116 return var.getClassifications(graph);
119 String classificationsStr = toJSONStringArray(new ArrayList<>(classifications));
121 Datatype datatype = processor.syncRequest(new VariableRead<Datatype>(var) {
123 public Datatype perform(ReadGraph graph) throws DatabaseException {
124 return var.getPossibleDatatype(graph);
128 return toJSONObjectString(
129 "type", "\"Variable\"",
130 "uri", safeQuotedString(uri),
131 "guid", safeQuotedString(guid),
132 "resourceId", res == null ? "" : Long.toString(res.getResourceId()),
133 "typeResources", typesStr,
134 "classifications", classificationsStr,
135 "datatype", safeQuotedString(datatype != null ? datatype.getClass().getName() : null));
138 String uri = processor.syncRequest(new PossibleURI(res));
139 String guid = processor.syncRequest(new PossibleGUID(res));
140 return toJSONObjectString(
141 "type", "\"Resource\"",
142 "uri", safeQuotedString(uri),
143 "guid", safeQuotedString(guid),
144 "resourceId", Long.toString(res.getResourceId()),
145 "typeResources", typesStr);
147 return "{ \"type\": \"Unknown\" }";
150 public static Resource getPossibleResource(RequestProcessor processor, Object input) throws DatabaseException {
151 return getPossibleResource(processor, input, null);
154 public static Resource getPossibleResource(RequestProcessor processor, Object input, Resource type) throws DatabaseException {
155 if(input instanceof Collection && !((Collection<?>)input).isEmpty()) {
156 Object element = ((Collection<?>)input).iterator().next();
157 if(element instanceof Resource)
158 return (Resource)element;
160 Resource resource = getPossibleElement(input, new AnyResource(processor));
161 if(resource == null) return resource;
163 if(processor.sync(new IsInstanceOf(resource, type))) return resource;
169 public static Variable getPossibleVariable(RequestProcessor processor, Object input) throws DatabaseException {
170 return getPossibleElement(input, new AnyVariable(processor));
173 public static <T> T getPossibleElement(Object input, WorkbenchSelectionContentType<T> contentType) {
174 Object single = getPossibleSingleElement(input);
175 if(single == null) return null;
176 if(single instanceof WorkbenchSelectionElement) {
177 WorkbenchSelectionElement element = (WorkbenchSelectionElement)single;
178 return (T)element.getContent(contentType);
183 public static WorkbenchSelectionElement getPossibleSelectionElement(Object input) {
184 if(input instanceof WorkbenchSelectionElement) return (WorkbenchSelectionElement)input;
185 if(input instanceof Collection) {
186 Collection<?> c = (Collection<?>)input;
188 Object o = c.iterator().next();
189 if(o instanceof WorkbenchSelectionElement) return (WorkbenchSelectionElement)o;
197 private static Object getPossibleSingleElement(Object input) {
198 if(input instanceof WorkbenchSelectionElement) return input;
199 if(input instanceof Collection) {
200 Collection<?> c = (Collection<?>)input;
201 if(c.size() == 1) return c.iterator().next();
206 private static WorkbenchSelectionElement getPossibleWorkbenchSelectionElement(Object selection) {
207 return getPossibleObject(selection, WorkbenchSelectionElement.class);
210 @SuppressWarnings("unchecked")
211 private static <T> T getPossibleObject(Object selection, Class<T> clazz) {
212 return clazz.isInstance(selection)
214 : ISelectionUtils.filterSingleSelection(selection, clazz);
217 private static class PossibleVariableType extends VariableRead<Resource> {
219 public PossibleVariableType(Variable var) {
224 public Resource perform(ReadGraph graph) throws DatabaseException {
225 return variable.getPossibleType(graph);
230 private static String toJSONObjectString(String... keyValuePairs) {
231 int len = keyValuePairs.length;
232 assert (len & 1) == 0;
233 StringBuilder sb = new StringBuilder(128);
236 for (int i = 0; i < len; i += 2) {
237 String value = keyValuePairs[i+1];
238 if (value != null && !value.isEmpty()) {
241 sb.append("\"").append(keyValuePairs[i]).append("\": ").append(value);
246 return sb.toString();
249 private static String escapeQuotes(String s) {
250 return s.indexOf('"') >= 0 ? s.replaceAll("\"", "\\\\\"") : s;
253 private static String safeQuotedString(String s) {
254 return s != null && !s.isEmpty() ? "\"" + escapeQuotes(s) + "\"" : "";
257 private static String toJSONStringArray(List<String> strings) throws DatabaseException {
258 // Sort the type strings to produce stable results
259 if (strings.isEmpty())
261 return strings.stream()
262 .map(WorkbenchSelectionUtils::escapeQuotes)
264 .collect(Collectors.joining("\", \"", "[\"", "\"]"));
267 private static String getTypeResourceString(RequestProcessor processor, Resource r, Variable v) throws DatabaseException {
268 return toJSONStringArray(
269 toPossibleURIs(processor,
270 getTypes(processor, r, v)));
273 private static Set<Resource> getTypes(RequestProcessor processor, Resource r, Variable v) throws DatabaseException {
274 if (r == null && v != null)
275 r = processor.syncRequest(new PossibleVariableRepresents(v));
277 return processor.syncRequest(new Types(r));
278 r = v != null ? processor.syncRequest(new PossibleVariableType(v)) : null;
279 return r != null ? processor.syncRequest(new Supertypes(r)) : Collections.emptySet();
282 private static List<String> toPossibleURIs(RequestProcessor processor, Collection<Resource> resources) throws DatabaseException {
283 if (resources.isEmpty())
284 return Collections.emptyList();
285 List<String> result = new ArrayList<>(resources.size());
286 for (Resource r : resources) {
287 String uri = processor.syncRequest(new PossibleURI(r));