]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeDiagramManager.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / runtime / RuntimeDiagramManager.java
index ef117ee8a8359f0cba338f6f4b69b9bd2c50c449..10c2d89040b1fe2a800091cda84767be54982f09 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2010, 2013 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *     Semantum Oy - issue #4384\r
- *******************************************************************************/\r
-package org.simantics.diagram.runtime;\r
-\r
-import java.util.concurrent.atomic.AtomicReference;\r
-\r
-import org.eclipse.ui.IEditorInput;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.RequestProcessor;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.VirtualGraph;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.procedure.adapter.ListenerSupport;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.request.WriteResultRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.util.RemoverUtil;\r
-import org.simantics.db.layer0.variable.RVI;\r
-import org.simantics.db.procedure.AsyncListener;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.ui.workbench.IResourceEditorInput2;\r
-import org.simantics.utils.datastructures.Callback;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-/**\r
- * A helper class for managing the life-cycle of a diagram runtime realization.\r
- * \r
- * <p>\r
- * The diagram runtime resource is a virtual (transient) graph database resource\r
- * that specifies the active runtime properties of the diagram as follows:\r
- * \r
- * <pre>\r
- *    RUNTIME RESOURCE\r
- *    |---[DIAGRAM.RuntimeDiagram.HasConfiguration]---> :DIAGRAM.Diagram (directed link, no inverse relation)\r
- *    |---[DIAGRAM.RuntimeDiagram.HasRuntimeProfile]---> :DIAGRAM.Profile (directed link, no inverse relation)\r
- *    |---[DIAGRAM.HasModelURI]------------ "Model URI" : L0.String\r
- *    |---[DIAGRAM.HasVariable]------------ "Variable URI" : L0.String\r
- *    `---[DIAGRAM.HasRVI]----------------- "RVI" : L0.String\r
- * </pre>\r
- * \r
- * The runtime resource itself is not attached anywhere in the graph, it only\r
- * contains a directed link back to its diagram.\r
- * \r
- * <p>\r
- * For example diagram profiles require the runtime diagram to have the\r
- * DIAGRAM.HasVariable property. This in turn requires that the model has a\r
- * proper {@link Layer0X#HasBaseRealization} relation in order to be resolved\r
- * (see {@link RuntimeVariable}).\r
- * \r
- * <p>\r
- * To get started using this class, see\r
- * {@link #track(Session, Resource, IEditorInput, ListenerSupport)} and\r
- * {@link #create(Session, Resource, String, String)}.\r
- * \r
- * <p>\r
- * Instances of this class are not thread-safe.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class RuntimeDiagramManager {\r
-\r
-    private boolean                   disposed;\r
-\r
-    private Session                   session;\r
-    private IEditorInput              editorInput;\r
-    private ListenerSupport           support;\r
-\r
-    private AtomicReference<Resource> runtimeDiagram = new AtomicReference<Resource>();\r
-\r
-    /**\r
-     * Constructs a new RuntimeDiagramManager, creates a new runtime diagram\r
-     * based on the specified editor input if it is an\r
-     * {@link IResourceEditorInput2} and starts tracking (listening) to changes\r
-     * in editor input which specifies the ModelURI and RVI needed for the\r
-     * runtime diagram. The tracking aspect comes to play in that editor inputs\r
-     * are basically allowed to change and therefore this manager tries to\r
-     * listen to changes in both the Model URI and RVI. If the input changes,\r
-     * the manager will automatically update the properties of the runtime\r
-     * diagram to match the input.\r
-     * \r
-     * <p>\r
-     * Invoking this method is equal to calling:\r
-     * \r
-     * <pre>\r
-     * RuntimeDiagramManager manager = new RuntimeDiagramManager(session);\r
-     * manager.track(diagram, editorInput, listenerSupport);\r
-     * </pre>\r
-     * \r
-     * @param session\r
-     * @param diagram\r
-     * @param editorInput\r
-     * @param listenerSupport\r
-     * @return\r
-     * @throws DatabaseException\r
-     */\r
-    public static RuntimeDiagramManager track(\r
-            Session session,\r
-            final Resource diagram,\r
-            IEditorInput editorInput,\r
-            ListenerSupport listenerSupport)\r
-    throws DatabaseException\r
-    {\r
-        RuntimeDiagramManager manager = new RuntimeDiagramManager(session);\r
-        manager.track(diagram, editorInput, listenerSupport);\r
-        return manager;\r
-    }\r
-\r
-    /**\r
-     * Just as {@link #track(Session, Resource, IEditorInput, ListenerSupport)}\r
-     * this method will construct a RuntimeDiagramManager and create a runtime\r
-     * diagram resource, but contrary to\r
-     * {@link #track(Session, Resource, IEditorInput, ListenerSupport)} it will\r
-     * not listen to changes nor update the runtime diagram properties.\r
-     * \r
-     * <p>\r
-     * Invoking this method is equal to calling:\r
-     * <pre>\r
-     * RuntimeDiagramManager manager = new RuntimeDiagramManager(session);\r
-     * manager.createRuntimeDiagram(diagram, modelURI, RVI);\r
-     * </pre>\r
-     * \r
-     * @param session\r
-     * @param diagram\r
-     * @param modelURI\r
-     * @param RVI\r
-     * @return\r
-     * @throws DatabaseException\r
-     * \r
-     * @see {@link #track(Session, Resource, IEditorInput, ListenerSupport)}\r
-     */\r
-    public static RuntimeDiagramManager create(\r
-            Session session,\r
-            Resource diagram,\r
-            String modelURI,\r
-            String RVI)\r
-    throws DatabaseException\r
-    {\r
-        RuntimeDiagramManager manager = new RuntimeDiagramManager(session);\r
-        manager.createRuntimeDiagram(diagram, modelURI, RVI);\r
-        return manager;\r
-    }\r
-\r
-    public RuntimeDiagramManager(Session session) {\r
-        this.session = session;\r
-    }\r
-\r
-    public Resource getRuntimeDiagram() {\r
-        return runtimeDiagram.get();\r
-    }\r
-\r
-    public void dispose() {\r
-        synchronized (this) {\r
-            assertNotDisposed();\r
-            disposed = true;\r
-        }\r
-\r
-        destroy();\r
-\r
-        this.session = null;\r
-        this.editorInput = null;\r
-        this.support = null;\r
-    }\r
-\r
-    private void assertNotDisposed() {\r
-        if (disposed)\r
-            throw new IllegalStateException(this + " is disposed");\r
-    }\r
-\r
-    private static IResourceEditorInput2 getResourceInput(Object input) {\r
-        if (input instanceof IResourceEditorInput2)\r
-            return (IResourceEditorInput2) input;\r
-        return null;\r
-    }\r
-\r
-    private IResourceEditorInput2 getResourceInput() {\r
-        return getResourceInput(editorInput);\r
-    }\r
-\r
-    /**\r
-     * Does nothing if already tracking a diagram runtime resource.\r
-     * \r
-     * @param diagram\r
-     * @param editorInput\r
-     * @param listenerSupport\r
-     * @return the current tracked diagram runtime resource\r
-     * @throws DatabaseException\r
-     * \r
-     * @see {@link #track(Session, Resource, IEditorInput, ListenerSupport)}\r
-     */\r
-    public Resource track(final Resource diagram, IEditorInput editorInput, ListenerSupport listenerSupport) throws DatabaseException {\r
-        Resource runtime = runtimeDiagram.get();\r
-        if (runtime != null)\r
-            return runtime;\r
-\r
-        if (editorInput == null)\r
-            throw new NullPointerException("null editorInput");\r
-        if (listenerSupport == null)\r
-            throw new NullPointerException("null listenerSupport");\r
-\r
-        final IResourceEditorInput2 input = getResourceInput(editorInput);\r
-        if (input == null)\r
-            return null;\r
-\r
-        this.editorInput = editorInput;\r
-        this.support = listenerSupport;\r
-\r
-        runtime = session.syncRequest(new WriteResultRequest<Resource>(session.getService(VirtualGraph.class)) {\r
-            @Override\r
-            public Resource perform(WriteGraph graph) throws DatabaseException {\r
-                RuntimeDiagramDesc variable = graph.syncRequest(new RuntimeVariableForInput(input));\r
-                if (variable == null)\r
-                    return null;\r
-\r
-                final Resource runtime = createRuntimeDiagram(graph, diagram, variable);\r
-                listenRequest(graph, diagram);\r
-                return runtime;\r
-            }\r
-        });\r
-\r
-        runtimeDiagram.set(runtime);\r
-        return runtime;\r
-    }\r
-\r
-    /**\r
-     * @param diagram\r
-     * @param modelURI\r
-     * @param RVI\r
-     * @return\r
-     * @throws DatabaseException\r
-     * \r
-     * @see {@link #create(Session, Resource, String, String)\r
-     */\r
-    public Resource createRuntimeDiagram(final Resource diagram, final String modelURI, final String RVI) throws DatabaseException {\r
-        Resource runtime = runtimeDiagram.get();\r
-        if (runtime != null)\r
-            return runtime;\r
-\r
-        runtime = session.syncRequest(new WriteResultRequest<Resource>(session.getService(VirtualGraph.class)) {\r
-            @Override\r
-            public Resource perform(WriteGraph graph) throws DatabaseException {\r
-                Resource model = graph.getPossibleResource(modelURI);\r
-                return createRuntimeDiagram(graph, diagram, model, RVI);\r
-            }\r
-        });\r
-\r
-        runtimeDiagram.set(runtime);\r
-        return runtime;\r
-    }\r
-\r
-    /**\r
-     * @param graph\r
-     * @param diagram\r
-     * @param modelURI\r
-     * @param RVI\r
-     * @return\r
-     * @throws DatabaseException\r
-     */\r
-    public Resource createRuntimeDiagram(WriteGraph graph, final Resource diagram, final Resource model, final String rvis) throws DatabaseException {\r
-        RVI rvi = rvis != null ? RVI.fromResourceFormat(graph, rvis) : null;\r
-        RuntimeDiagramDesc desc = graph.syncRequest(new RuntimeVariable(model, rvi, diagram));\r
-        if (desc == null)\r
-            return null;\r
-        return createRuntimeDiagram(graph, diagram, desc);\r
-    }\r
-\r
-    private void listenRequest(RequestProcessor processor, final Resource diagram) {\r
-        processor.asyncRequest(new RuntimeVariableForInput(getResourceInput()), new AsyncListener<RuntimeDiagramDesc>() {\r
-\r
-            @Override\r
-            public void exception(AsyncReadGraph graph, Throwable throwable) {\r
-                ListenerSupport s = support;\r
-                if (s != null)\r
-                    s.exception(throwable);\r
-            }\r
-\r
-            @Override\r
-            public void execute(AsyncReadGraph graph, final RuntimeDiagramDesc desc) {\r
-                if (desc == null)\r
-                    return;\r
-\r
-                Session session = graph.getSession();\r
-                session.asyncRequest(new WriteRequest(session.getService(VirtualGraph.class)) {\r
-                    @Override\r
-                    public void perform(WriteGraph graph) throws DatabaseException {\r
-                        Resource runtime = getRuntimeDiagram();\r
-                        if (runtime != null)\r
-                            writeConfig(graph, runtime, diagram, desc);\r
-                    }\r
-                }, new Callback<DatabaseException>() {\r
-                    @Override\r
-                    public void run(DatabaseException e) {\r
-                        ListenerSupport s = support;\r
-                        if (e != null && s != null)\r
-                            s.exception(e);\r
-                    }\r
-                });\r
-            }\r
-\r
-            @Override\r
-            public boolean isDisposed() {\r
-               if(disposed) return true;\r
-               else return support != null && support.isDisposed();\r
-            }\r
-        });\r
-    }\r
-\r
-    private Resource createRuntimeDiagram(WriteGraph graph, Resource diagram, RuntimeDiagramDesc desc) throws DatabaseException {\r
-\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        final DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
-        // Create the new runtime diagram instance!\r
-        final Resource runtime = graph.newResource();\r
-        graph.claim(runtime, L0.InstanceOf, null, DIA.RuntimeDiagram);\r
-        graph.claim(runtime, DIA.RuntimeDiagram_HasConfiguration, null, diagram);\r
-\r
-        writeConfig(graph, runtime, diagram, desc);\r
-\r
-        return runtime;\r
-    }\r
-\r
-    private void writeConfig(WriteGraph graph, final Resource runtime, final Resource diagram, RuntimeDiagramDesc desc) throws DatabaseException {\r
-        final DiagramResource DIA = DiagramResource.getInstance(graph);\r
-        if (desc.getVariableURI() != null)\r
-            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasVariable, desc.getVariableURI(), Bindings.STRING);\r
-        if (desc.getRVI() != null)\r
-            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasRVI, desc.getRVI(), Bindings.STRING);\r
-        if (desc.getModelURI() != null)\r
-            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasModelURI, desc.getModelURI(), Bindings.STRING);\r
-        if (desc.getActiveProfileURI() != null) {\r
-            Resource activeProfile = graph.getPossibleResource(desc.getActiveProfileURI());\r
-            if (activeProfile != null) {\r
-                graph.deny(runtime, DIA.RuntimeDiagram_HasRuntimeProfile);\r
-                graph.claim(runtime, DIA.RuntimeDiagram_HasRuntimeProfile, null, activeProfile);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void destroy() {\r
-        final Resource rd = runtimeDiagram.getAndSet(null);\r
-        if (rd != null) {\r
-            try {\r
-                session.syncRequest(new WriteRequest(session.getService(VirtualGraph.class)) {\r
-                    @Override\r
-                    public void perform(WriteGraph graph) throws DatabaseException {\r
-                        RemoverUtil.remove(graph, rd);\r
-                    }\r
-                });\r
-            } catch (DatabaseException e) {\r
-                ListenerSupport s = support;\r
-                if (s != null)\r
-                    s.exception(e);\r
-                else\r
-                    ErrorLogger.defaultLogError(e);\r
-            }\r
-        }\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2010, 2013 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - issue #4384
+ *******************************************************************************/
+package org.simantics.diagram.runtime;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.ui.IEditorInput;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.procedure.adapter.ListenerSupport;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.procedure.AsyncListener;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.ui.workbench.IResourceEditorInput2;
+import org.simantics.utils.datastructures.Callback;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * A helper class for managing the life-cycle of a diagram runtime realization.
+ * 
+ * <p>
+ * The diagram runtime resource is a virtual (transient) graph database resource
+ * that specifies the active runtime properties of the diagram as follows:
+ * 
+ * <pre>
+ *    RUNTIME RESOURCE
+ *    |---[DIAGRAM.RuntimeDiagram.HasConfiguration]---> :DIAGRAM.Diagram (directed link, no inverse relation)
+ *    |---[DIAGRAM.RuntimeDiagram.HasRuntimeProfile]---> :DIAGRAM.Profile (directed link, no inverse relation)
+ *    |---[DIAGRAM.HasModelURI]------------ "Model URI" : L0.String
+ *    |---[DIAGRAM.HasVariable]------------ "Variable URI" : L0.String
+ *    `---[DIAGRAM.HasRVI]----------------- "RVI" : L0.String
+ * </pre>
+ * 
+ * The runtime resource itself is not attached anywhere in the graph, it only
+ * contains a directed link back to its diagram.
+ * 
+ * <p>
+ * For example diagram profiles require the runtime diagram to have the
+ * DIAGRAM.HasVariable property. This in turn requires that the model has a
+ * proper {@link Layer0X#HasBaseRealization} relation in order to be resolved
+ * (see {@link RuntimeVariable}).
+ * 
+ * <p>
+ * To get started using this class, see
+ * {@link #track(Session, Resource, IEditorInput, ListenerSupport)} and
+ * {@link #create(Session, Resource, String, String)}.
+ * 
+ * <p>
+ * Instances of this class are not thread-safe.
+ * 
+ * @author Tuukka Lehtonen
+ */
+public class RuntimeDiagramManager {
+
+    private boolean                   disposed;
+
+    private Session                   session;
+    private IEditorInput              editorInput;
+    private ListenerSupport           support;
+
+    private AtomicReference<Resource> runtimeDiagram = new AtomicReference<Resource>();
+
+    /**
+     * Constructs a new RuntimeDiagramManager, creates a new runtime diagram
+     * based on the specified editor input if it is an
+     * {@link IResourceEditorInput2} and starts tracking (listening) to changes
+     * in editor input which specifies the ModelURI and RVI needed for the
+     * runtime diagram. The tracking aspect comes to play in that editor inputs
+     * are basically allowed to change and therefore this manager tries to
+     * listen to changes in both the Model URI and RVI. If the input changes,
+     * the manager will automatically update the properties of the runtime
+     * diagram to match the input.
+     * 
+     * <p>
+     * Invoking this method is equal to calling:
+     * 
+     * <pre>
+     * RuntimeDiagramManager manager = new RuntimeDiagramManager(session);
+     * manager.track(diagram, editorInput, listenerSupport);
+     * </pre>
+     * 
+     * @param session
+     * @param diagram
+     * @param editorInput
+     * @param listenerSupport
+     * @return
+     * @throws DatabaseException
+     */
+    public static RuntimeDiagramManager track(
+            Session session,
+            final Resource diagram,
+            IEditorInput editorInput,
+            ListenerSupport listenerSupport)
+    throws DatabaseException
+    {
+        RuntimeDiagramManager manager = new RuntimeDiagramManager(session);
+        manager.track(diagram, editorInput, listenerSupport);
+        return manager;
+    }
+
+    /**
+     * Just as {@link #track(Session, Resource, IEditorInput, ListenerSupport)}
+     * this method will construct a RuntimeDiagramManager and create a runtime
+     * diagram resource, but contrary to
+     * {@link #track(Session, Resource, IEditorInput, ListenerSupport)} it will
+     * not listen to changes nor update the runtime diagram properties.
+     * 
+     * <p>
+     * Invoking this method is equal to calling:
+     * <pre>
+     * RuntimeDiagramManager manager = new RuntimeDiagramManager(session);
+     * manager.createRuntimeDiagram(diagram, modelURI, RVI);
+     * </pre>
+     * 
+     * @param session
+     * @param diagram
+     * @param modelURI
+     * @param RVI
+     * @return
+     * @throws DatabaseException
+     * 
+     * @see {@link #track(Session, Resource, IEditorInput, ListenerSupport)}
+     */
+    public static RuntimeDiagramManager create(
+            Session session,
+            Resource diagram,
+            String modelURI,
+            String RVI)
+    throws DatabaseException
+    {
+        RuntimeDiagramManager manager = new RuntimeDiagramManager(session);
+        manager.createRuntimeDiagram(diagram, modelURI, RVI);
+        return manager;
+    }
+
+    public RuntimeDiagramManager(Session session) {
+        this.session = session;
+    }
+
+    public Resource getRuntimeDiagram() {
+        return runtimeDiagram.get();
+    }
+
+    public void dispose() {
+        synchronized (this) {
+            assertNotDisposed();
+            disposed = true;
+        }
+
+        destroy();
+
+        this.session = null;
+        this.editorInput = null;
+        this.support = null;
+    }
+
+    private void assertNotDisposed() {
+        if (disposed)
+            throw new IllegalStateException(this + " is disposed");
+    }
+
+    private static IResourceEditorInput2 getResourceInput(Object input) {
+        if (input instanceof IResourceEditorInput2)
+            return (IResourceEditorInput2) input;
+        return null;
+    }
+
+    private IResourceEditorInput2 getResourceInput() {
+        return getResourceInput(editorInput);
+    }
+
+    /**
+     * Does nothing if already tracking a diagram runtime resource.
+     * 
+     * @param diagram
+     * @param editorInput
+     * @param listenerSupport
+     * @return the current tracked diagram runtime resource
+     * @throws DatabaseException
+     * 
+     * @see {@link #track(Session, Resource, IEditorInput, ListenerSupport)}
+     */
+    public Resource track(final Resource diagram, IEditorInput editorInput, ListenerSupport listenerSupport) throws DatabaseException {
+        Resource runtime = runtimeDiagram.get();
+        if (runtime != null)
+            return runtime;
+
+        if (editorInput == null)
+            throw new NullPointerException("null editorInput");
+        if (listenerSupport == null)
+            throw new NullPointerException("null listenerSupport");
+
+        final IResourceEditorInput2 input = getResourceInput(editorInput);
+        if (input == null)
+            return null;
+
+        this.editorInput = editorInput;
+        this.support = listenerSupport;
+
+        runtime = session.syncRequest(new WriteResultRequest<Resource>(session.getService(VirtualGraph.class)) {
+            @Override
+            public Resource perform(WriteGraph graph) throws DatabaseException {
+                RuntimeDiagramDesc variable = graph.syncRequest(new RuntimeVariableForInput(input));
+                if (variable == null)
+                    return null;
+
+                final Resource runtime = createRuntimeDiagram(graph, diagram, variable);
+                listenRequest(graph, diagram);
+                return runtime;
+            }
+        });
+
+        runtimeDiagram.set(runtime);
+        return runtime;
+    }
+
+    /**
+     * @param diagram
+     * @param modelURI
+     * @param RVI
+     * @return
+     * @throws DatabaseException
+     * 
+     * @see {@link #create(Session, Resource, String, String)
+     */
+    public Resource createRuntimeDiagram(final Resource diagram, final String modelURI, final String RVI) throws DatabaseException {
+        Resource runtime = runtimeDiagram.get();
+        if (runtime != null)
+            return runtime;
+
+        runtime = session.syncRequest(new WriteResultRequest<Resource>(session.getService(VirtualGraph.class)) {
+            @Override
+            public Resource perform(WriteGraph graph) throws DatabaseException {
+                Resource model = graph.getPossibleResource(modelURI);
+                return createRuntimeDiagram(graph, diagram, model, RVI);
+            }
+        });
+
+        runtimeDiagram.set(runtime);
+        return runtime;
+    }
+
+    /**
+     * @param graph
+     * @param diagram
+     * @param modelURI
+     * @param RVI
+     * @return
+     * @throws DatabaseException
+     */
+    public Resource createRuntimeDiagram(WriteGraph graph, final Resource diagram, final Resource model, final String rvis) throws DatabaseException {
+        RVI rvi = rvis != null ? RVI.fromResourceFormat(graph, rvis) : null;
+        RuntimeDiagramDesc desc = graph.syncRequest(new RuntimeVariable(model, rvi, diagram));
+        if (desc == null)
+            return null;
+        return createRuntimeDiagram(graph, diagram, desc);
+    }
+
+    private void listenRequest(RequestProcessor processor, final Resource diagram) {
+        processor.asyncRequest(new RuntimeVariableForInput(getResourceInput()), new AsyncListener<RuntimeDiagramDesc>() {
+
+            @Override
+            public void exception(AsyncReadGraph graph, Throwable throwable) {
+                ListenerSupport s = support;
+                if (s != null)
+                    s.exception(throwable);
+            }
+
+            @Override
+            public void execute(AsyncReadGraph graph, final RuntimeDiagramDesc desc) {
+                if (desc == null)
+                    return;
+
+                Session session = graph.getSession();
+                session.asyncRequest(new WriteRequest(session.getService(VirtualGraph.class)) {
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        Resource runtime = getRuntimeDiagram();
+                        if (runtime != null)
+                            writeConfig(graph, runtime, diagram, desc);
+                    }
+                }, new Callback<DatabaseException>() {
+                    @Override
+                    public void run(DatabaseException e) {
+                        ListenerSupport s = support;
+                        if (e != null && s != null)
+                            s.exception(e);
+                    }
+                });
+            }
+
+            @Override
+            public boolean isDisposed() {
+               if(disposed) return true;
+               else return support != null && support.isDisposed();
+            }
+        });
+    }
+
+    private Resource createRuntimeDiagram(WriteGraph graph, Resource diagram, RuntimeDiagramDesc desc) throws DatabaseException {
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        final DiagramResource DIA = DiagramResource.getInstance(graph);
+
+        // Create the new runtime diagram instance!
+        final Resource runtime = graph.newResource();
+        graph.claim(runtime, L0.InstanceOf, null, DIA.RuntimeDiagram);
+        graph.claim(runtime, DIA.RuntimeDiagram_HasConfiguration, null, diagram);
+
+        writeConfig(graph, runtime, diagram, desc);
+
+        return runtime;
+    }
+
+    private void writeConfig(WriteGraph graph, final Resource runtime, final Resource diagram, RuntimeDiagramDesc desc) throws DatabaseException {
+        final DiagramResource DIA = DiagramResource.getInstance(graph);
+        if (desc.getVariableURI() != null)
+            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasVariable, desc.getVariableURI(), Bindings.STRING);
+        if (desc.getRVI() != null)
+            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasRVI, desc.getRVI(), Bindings.STRING);
+        if (desc.getModelURI() != null)
+            graph.claimLiteral(runtime, DIA.RuntimeDiagram_HasModelURI, desc.getModelURI(), Bindings.STRING);
+        if (desc.getActiveProfileURI() != null) {
+            Resource activeProfile = graph.getPossibleResource(desc.getActiveProfileURI());
+            if (activeProfile != null) {
+                graph.deny(runtime, DIA.RuntimeDiagram_HasRuntimeProfile);
+                graph.claim(runtime, DIA.RuntimeDiagram_HasRuntimeProfile, null, activeProfile);
+            }
+        }
+    }
+
+    private void destroy() {
+        final Resource rd = runtimeDiagram.getAndSet(null);
+        if (rd != null) {
+            try {
+                session.syncRequest(new WriteRequest(session.getService(VirtualGraph.class)) {
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        RemoverUtil.remove(graph, rd);
+                    }
+                });
+            } catch (DatabaseException e) {
+                ListenerSupport s = support;
+                if (s != null)
+                    s.exception(e);
+                else
+                    ErrorLogger.defaultLogError(e);
+            }
+        }
+    }
+
+}