From: Tuukka Lehtonen Date: Tue, 3 Apr 2018 20:48:36 +0000 (+0300) Subject: Support diagram profile activity store/restore in model export/import X-Git-Tag: v1.43.0~136^2~507 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=957ddea830ceb97eab9f358d99a591cafc518d8a;ds=sidebyside Support diagram profile activity store/restore in model export/import 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) --- diff --git a/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/request/ReferencedProfileEntries.java b/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/request/ReferencedProfileEntries.java index ca8ec0973..edc46b622 100644 --- a/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/request/ReferencedProfileEntries.java +++ b/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/request/ReferencedProfileEntries.java @@ -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 index 000000000..f59fba414 --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBean.java @@ -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 activeEntries = new ArrayList<>(); + } + + public TreeMap 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 index 000000000..bb4402f5b --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRepresentation.java @@ -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 getValue(RequestProcessor processor, Map 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 index 000000000..5dc89b581 --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ProfileActivityBeanRequest.java @@ -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 { + + 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; + } + +} diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java index ff0f7b685..03da3b78c 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java @@ -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 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 index 000000000..1f7a7ede7 --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TopLevelProfiles.java @@ -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> { + + protected TopLevelProfiles(Resource root) { + super(root); + } + + @Override + public List perform(ReadGraph graph) throws DatabaseException { + BasicResources BR = BasicResources.getInstance(graph); + ArrayList 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; + } + +}