]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.ui/src/org/simantics/ui/selection/WorkbenchSelectionUtils.java
Provide classifications and datatype for Variable-based drag sources
[simantics/platform.git] / bundles / org.simantics.ui / src / org / simantics / ui / selection / WorkbenchSelectionUtils.java
index ecdda45c24ba654de669a56bf052a9d8255d4e1c..e3e6eeafe9270432ab1a1a1dd984d8f8ea3d2306 100644 (file)
@@ -1,17 +1,29 @@
 package org.simantics.ui.selection;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.ui.handlers.HandlerUtil;
 import org.simantics.Simantics;
+import org.simantics.databoard.type.Datatype;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.common.primitiverequest.IsInstanceOf;
+import org.simantics.db.common.primitiverequest.Supertypes;
+import org.simantics.db.common.primitiverequest.Types;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleGUID;
+import org.simantics.db.layer0.request.PossibleURI;
+import org.simantics.db.layer0.request.PossibleVariableGUID;
+import org.simantics.db.layer0.request.PossibleVariableRepresents;
+import org.simantics.db.layer0.request.VariableRead;
 import org.simantics.db.layer0.request.VariableURI;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.utils.ui.ISelectionUtils;
@@ -92,16 +104,47 @@ public class WorkbenchSelectionUtils {
 
        public static String getPossibleJSON(RequestProcessor processor, Object input) throws DatabaseException {
                Variable var = getPossibleVariable(processor, input);
+               Resource res = getPossibleResource(processor, input);
+               String typesStr = getTypeResourceString(processor, res, var);
                if(var != null) {
                        String uri = processor.syncRequest(new VariableURI(var));
-                       return "{ \"type\":\"Variable\", \"uri\" : \"" + uri + "\" }";
+                       String guid = processor.syncRequest(new PossibleVariableGUID(var));
+                       
+                       Set<String> classifications = processor.syncRequest(new VariableRead<Set<String>>(var) {
+                               @Override
+                               public Set<String> perform(ReadGraph graph) throws DatabaseException {
+                                       return var.getClassifications(graph);
+                               }
+                       });
+                       String classificationsStr = toJSONStringArray(new ArrayList<>(classifications));
+                       
+                       Datatype datatype = processor.syncRequest(new VariableRead<Datatype>(var) {
+                               @Override
+                               public Datatype perform(ReadGraph graph) throws DatabaseException {
+                                       return var.getPossibleDatatype(graph);
+                               }
+                       });
+                       
+                       return toJSONObjectString(
+                                       "type", "\"Variable\"",
+                                       "uri", safeQuotedString(uri),
+                                       "guid", safeQuotedString(guid),
+                                       "resourceId", res == null ? "" : Long.toString(res.getResourceId()),
+                                       "typeResources", typesStr,
+                                       "classifications", classificationsStr,
+                                       "datatype", safeQuotedString(datatype != null ? datatype.getClass().getName() : null));
                }
-               Resource res = getPossibleResource(processor, input);
                if(res != null) {
-                       return "{ type:\"Resource\" }";
+                   String uri = processor.syncRequest(new PossibleURI(res));
+                   String guid = processor.syncRequest(new PossibleGUID(res));
+                       return toJSONObjectString(
+                                       "type", "\"Resource\"",
+                                       "uri", safeQuotedString(uri),
+                                       "guid", safeQuotedString(guid),
+                                       "resourceId", Long.toString(res.getResourceId()),
+                                       "typeResources", typesStr);
                }
-               return "{ type:\"Unknown\" }";
-               
+               return "{ \"type\": \"Unknown\" }";
        }
 
        public static Resource getPossibleResource(RequestProcessor processor, Object input) throws DatabaseException {
@@ -171,4 +214,81 @@ public class WorkbenchSelectionUtils {
                 : ISelectionUtils.filterSingleSelection(selection, clazz);
     }
 
+    private static class PossibleVariableType extends VariableRead<Resource> {
+
+        public PossibleVariableType(Variable var) {
+            super(var);
+        }
+
+        @Override
+        public Resource perform(ReadGraph graph) throws DatabaseException {
+            return variable.getPossibleType(graph);
+        }
+
+    }
+
+       private static String toJSONObjectString(String... keyValuePairs) {
+               int len = keyValuePairs.length;
+               assert (len & 1) == 0;
+               StringBuilder sb = new StringBuilder(128);
+               sb.append("{ ");
+               int entryCount = 0;
+               for (int i = 0; i < len; i += 2) {
+                       String value = keyValuePairs[i+1];
+                       if (value != null && !value.isEmpty()) {
+                               if (entryCount > 0)
+                                       sb.append(", ");
+                               sb.append("\"").append(keyValuePairs[i]).append("\": ").append(value);
+                               ++entryCount;
+                       }
+               }
+               sb.append(" }");
+               return sb.toString();
+       }
+
+       private static String escapeQuotes(String s) {
+               return s.indexOf('"') >= 0 ? s.replaceAll("\"", "\\\\\"") : s;
+       }
+
+       private static String safeQuotedString(String s) {
+               return s != null && !s.isEmpty() ? "\"" + escapeQuotes(s) + "\"" : "";
+       }
+
+       private static String toJSONStringArray(List<String> strings) throws DatabaseException {
+               // Sort the type strings to produce stable results
+               if (strings.isEmpty())
+                       return "";
+               return strings.stream()
+                               .map(WorkbenchSelectionUtils::escapeQuotes)
+                               .sorted()
+                               .collect(Collectors.joining("\", \"", "[\"", "\"]"));
+       }
+
+       private static String getTypeResourceString(RequestProcessor processor, Resource r, Variable v) throws DatabaseException {
+               return toJSONStringArray(
+                               toPossibleURIs(processor,
+                                               getTypes(processor, r, v)));
+       }
+
+       private static Set<Resource> getTypes(RequestProcessor processor, Resource r, Variable v) throws DatabaseException {
+               if (r == null && v != null)
+                       r = processor.syncRequest(new PossibleVariableRepresents(v));
+               if (r != null)
+                       return processor.syncRequest(new Types(r));
+               r = v != null ? processor.syncRequest(new PossibleVariableType(v)) : null;
+               return r != null ? processor.syncRequest(new Supertypes(r)) : Collections.emptySet();
+       }
+
+       private static List<String> toPossibleURIs(RequestProcessor processor, Collection<Resource> resources) throws DatabaseException {
+               if (resources.isEmpty())
+                       return Collections.emptyList();
+               List<String> result = new ArrayList<>(resources.size());
+               for (Resource r : resources) {
+                       String uri = processor.syncRequest(new PossibleURI(r));
+                       if (uri != null)
+                               result.add(uri);
+               }
+               return result;
+       }
+
 }