Support diagram profile activity store/restore in model export/import 88/1688/1
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 3 Apr 2018 20:48:36 +0000 (23:48 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 3 Apr 2018 21:06:58 +0000 (23:06 +0200)
Diagram profile selections are stored in the "profiles" workspace
persistent virtual graph. They cannot be done in the persistent database
because we do not want the profile selections to be part of the database
version/undo history. This just doesn't fit the current way of using
diagram profiles.

The code introduced in this commit needs to be put to use in
product-specific custom export/import logic and copy/paste handlers to
take advantage of it.

refs #7854

Change-Id: Ib996144f1afa376a1563e4309fe41421ee4da529
(cherry picked from commit 95e05b3cc3208ec57118e8167a090c9b90edfaf2)

bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/request/ReferencedProfileEntries.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBean.java [new file with mode: 0644]
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRepresentation.java [new file with mode: 0644]
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRequest.java [new file with mode: 0644]
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TopLevelProfiles.java [new file with mode: 0644]

index ca8ec0973947715cb4c76e1a16c3f83428b5e627..edc46b6222aa37431a6596e24b40bad9bd834064 100644 (file)
@@ -6,7 +6,6 @@ import java.util.HashSet;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceRead;
-import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.scenegraph.profile.ProfileUtils;
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBean.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBean.java
new file mode 100644 (file)
index 0000000..f59fba4
--- /dev/null
@@ -0,0 +1,30 @@
+package org.simantics.diagram.profile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.annotations.Optional;
+import org.simantics.databoard.binding.Binding;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.32.0
+ */
+public class ProfileActivityBean {
+
+       public static final String EXTENSION_KEY = ProfileActivityBean.class.getSimpleName();
+       public static final Binding BINDING = Bindings.getBindingUnchecked(ProfileActivityBean.class);
+
+       public static class Profile {
+               public String relativeUri;
+               public List<String> activeEntries = new ArrayList<>();
+       }
+
+       public TreeMap<String, Profile> topLevelProfiles = new TreeMap<>();
+
+       @Optional
+       public String activeProfile;
+
+}
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRepresentation.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRepresentation.java
new file mode 100644 (file)
index 0000000..bb4402f
--- /dev/null
@@ -0,0 +1,51 @@
+package org.simantics.diagram.profile;
+
+import java.util.Map;
+
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 6.08
+ */
+public class ProfileActivityBeanRepresentation implements Representation {
+
+       private static final Logger LOGGER = LoggerFactory.getLogger(ProfileActivityBeanRepresentation.class);
+
+       public static Key KEY = new KeyOf(ProfileActivityBean.class, "PROFILE_ACTIVITY_BEAN");
+
+       private final Resource source;
+       private ProfileActivityBean bean;
+
+       public ProfileActivityBeanRepresentation(Resource source) {
+               this.source = source;
+       }
+
+       @Override
+       public Key getKey() {
+               return KEY;
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public <T> T getValue(RequestProcessor processor, Map<String,Object> hints) {
+               if (bean == null) {
+                       try {
+                               bean = Profiles.readProfileActivity(processor, source);
+                       } catch (DatabaseException e) {
+                               LOGGER.error("Failed to read profile activity information from model " + source, e);
+                               // Prevent the code from attempting further reads from this source
+                               bean = new ProfileActivityBean();
+                       }
+               }
+               return (T) bean;
+       }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRequest.java
new file mode 100644 (file)
index 0000000..5dc89b5
--- /dev/null
@@ -0,0 +1,60 @@
+package org.simantics.diagram.profile;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.profile.ProfileActivityBean.Profile;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.simulation.ontology.SimulationResource;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.32.0
+ */
+class ProfileActivityBeanRequest extends ResourceRead<ProfileActivityBean> {
+
+       public ProfileActivityBeanRequest(Resource root) {
+               super(root);
+       }
+
+       @Override
+       public ProfileActivityBean perform(ReadGraph graph) throws DatabaseException {
+               ProfileActivityBean bean = new ProfileActivityBean();
+               String rootUri = graph.getPossibleURI(resource);
+               if (rootUri == null)
+                       return bean;
+
+               for (NamedResource r : graph.syncRequest(new TopLevelProfiles(resource))) {
+                       Profile prof = readProfile(graph, rootUri, r.getResource());
+                       if (prof != null)
+                               bean.topLevelProfiles.put(prof.relativeUri, prof);
+               }
+
+               DiagramResource DIA = DiagramResource.getInstance(graph);
+               Resource activeProfile = graph.getPossibleObject(resource, DIA.HasActiveProfile);
+               if (activeProfile != null) {
+                       bean.activeProfile = Profiles.possiblyRelativeUri(graph, rootUri, activeProfile);
+               }
+
+               return bean;
+       }
+
+       private static Profile readProfile(ReadGraph graph, String rootUri, Resource profile) throws DatabaseException {
+               Profile prof = new Profile();
+               prof.relativeUri = Profiles.possiblyRelativeUri(graph, rootUri, profile);
+               if (prof.relativeUri == null)
+                       return null;
+
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               for (Resource active : graph.getObjects(profile, SIMU.IsActive)) {
+                       String euri = Profiles.possiblyRelativeUri(graph, rootUri, active);
+                       if (euri != null)
+                               prof.activeEntries.add(euri);
+               }
+
+               return prof;
+       }
+
+}
index ff0f7b685f1d25e751b0a72061b336a47c38f05e..03da3b78ca287da81bd56d2bb9fe2e6bc5a2f454 100644 (file)
@@ -18,8 +18,11 @@ import java.util.Map;
 import java.util.Set;
 
 import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.mutable.Variant;
 import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
+import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.WriteOnlyGraph;
 import org.simantics.db.common.request.WriteRequest;
@@ -33,6 +36,7 @@ import org.simantics.db.layer0.util.SimanticsClipboardImpl;
 import org.simantics.db.layer0.util.SimanticsKeys;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.diagram.profile.ProfileActivityBean.Profile;
 import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.graph.db.TransferableGraphs;
 import org.simantics.graph.representation.Root;
@@ -321,4 +325,89 @@ public class Profiles {
                return instance;
        }
 
+       public static ProfileActivityBean readProfileActivity(
+                       RequestProcessor processor,
+                       Resource root)
+                                       throws DatabaseException
+       {
+               return processor.syncRequest(new ProfileActivityBeanRequest(root));
+       }
+
+       public static ProfileActivityBean readProfileActivity(
+                       RequestProcessor processor,
+                       Resource root,
+                       Map<String, Variant> writeToMap)
+                                       throws DatabaseException
+       {
+               ProfileActivityBean pab = readProfileActivity(processor, root);
+               if (pab != null && writeToMap != null)
+                       writeToMap.put(ProfileActivityBean.EXTENSION_KEY, new Variant(ProfileActivityBean.BINDING, pab));
+               return pab;
+       }
+
+       public static void writeProfileActivity(
+                       RequestProcessor processor,
+                       Resource root,
+                       ProfileActivityBean bean)
+                                       throws DatabaseException
+       {
+               VirtualGraph vg = processor.getService(VirtualGraphSupport.class).getWorkspacePersistent("profiles");
+               processor.syncRequest(new WriteRequest(vg) {
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                               writeProfileActivity(graph, root, bean);
+                       }
+               });
+       }
+
+       private static void writeProfileActivity(
+                       WriteGraph graph,
+                       Resource root,
+                       ProfileActivityBean bean)
+                                       throws DatabaseException
+       {
+               String rootUri = graph.getPossibleURI(root);
+               if (rootUri == null)
+                       return;
+
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               for (Profile p : bean.topLevelProfiles.values()) {
+                       Resource pr = resolveRelativeUri(graph, rootUri, p.relativeUri);
+                       if (pr == null)
+                               continue;
+                       for (String active : p.activeEntries) {
+                               Resource ar = resolveRelativeUri(graph, rootUri, active);
+                               if (ar != null)
+                                       graph.claim(pr, SIMU.IsActive, ar);
+                       }
+               }
+
+               Resource activeProfile = resolveRelativeUri(graph, rootUri, bean.activeProfile);
+               if (activeProfile != null) {
+                       DiagramResource DIA = DiagramResource.getInstance(graph);
+                       graph.claim(root, DIA.HasActiveProfile, DIA.HasActiveProfile_Inverse, activeProfile);
+               }
+       }
+
+       static String possiblyRelativeUri(ReadGraph graph, String rootUri, Resource r) throws DatabaseException {
+               if (r == null)
+                       return null;
+               String uri = graph.getPossibleURI(r);
+               if (rootUri != null && uri != null && uri.startsWith(rootUri))
+                       return uri.substring(rootUri.length());
+               return uri;
+       }
+
+       static Resource resolveRelativeUri(ReadGraph graph, String rootUri, String possiblyRelativeUri) throws DatabaseException {
+               return possiblyRelativeUri != null
+                               ? graph.getPossibleResource( resolveRelativeUri(rootUri, possiblyRelativeUri) )
+                               : null;
+       }
+
+       private static String resolveRelativeUri(String rootUri, String possiblyRelativeUri) {
+               return possiblyRelativeUri.startsWith("http:/")
+                               ? possiblyRelativeUri
+                               : rootUri + possiblyRelativeUri;
+       }
+
 }
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TopLevelProfiles.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TopLevelProfiles.java
new file mode 100644 (file)
index 0000000..1f7a7ed
--- /dev/null
@@ -0,0 +1,43 @@
+package org.simantics.diagram.profile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.diagram.synchronization.graph.BasicResources;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.32.0
+ */
+public class TopLevelProfiles extends ResourceRead<List<NamedResource>> {
+
+       protected TopLevelProfiles(Resource root) {
+               super(root);
+       }
+
+       @Override
+       public List<NamedResource> perform(ReadGraph graph) throws DatabaseException {
+               BasicResources BR = BasicResources.getInstance(graph);
+               ArrayList<NamedResource> result = new ArrayList<>();
+
+               Instances query = graph.adapt(BR.DIA.Profile, Instances.class);
+               for (Resource profile : query.find(graph, resource)) {
+                       if (!graph.hasStatement(profile, BR.L0.Abstract)) {
+                               String name = graph.getPossibleRelatedValue(profile, BR.L0.HasName, Bindings.STRING);
+                               if (name != null) {
+                                       result.add(new NamedResource(name, profile));
+                               }
+                       }
+               }
+
+               return result;
+       }
+
+}