Added Variable/Resource type information for DnD'd entities to JSON 70/1370/3
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 12 Jan 2018 09:16:46 +0000 (11:16 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 12 Jan 2018 10:25:27 +0000 (12:25 +0200)
refs #7715

Change-Id: I238e9b036a9c781ef8910bd5d6125b220e32f41e

bundles/org.simantics.ui/src/org/simantics/ui/selection/WorkbenchSelectionUtils.java

index ecdda45c24ba654de669a56bf052a9d8255d4e1c..47e866d0f61a651d7df83d53c93e6041740cdd09 100644 (file)
@@ -1,7 +1,11 @@
 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;
@@ -11,7 +15,12 @@ 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.PossibleURI;
+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 +101,23 @@ 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 + "\" }";
+                       return toJSONObjectString(
+                                       "type", "\"Variable\"",
+                                       "uri", safeQuotedString(uri),
+                                       "typeResources", typesStr);
                }
-               Resource res = getPossibleResource(processor, input);
                if(res != null) {
-                       return "{ type:\"Resource\" }";
+                       String uri = processor.syncRequest(new PossibleURI(res));
+                       return toJSONObjectString(
+                                       "type", "\"Resource\"",
+                                       "uri", safeQuotedString(uri),
+                                       "typeResources", typesStr);
                }
-               return "{ type:\"Unknown\" }";
-               
+               return "{ \"type\": \"Unknown\" }";
        }
 
        public static Resource getPossibleResource(RequestProcessor processor, Object input) throws DatabaseException {
@@ -171,4 +187,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;
+       }
+
 }