]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java
Multiple readers in db client
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagram / monitor / MonitorClassFactory2.java
index 2dfa0598d1e0a2233f2fcb833869efe49fbe8949..75d3050b9cd91689c5d136ed82868bd20808fd5f 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 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
- *******************************************************************************/\r
-package org.simantics.modeling.ui.diagram.monitor;\r
-\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.concurrent.atomic.AtomicReference;\r
-\r
-import org.simantics.browsing.ui.common.ErrorLogger;\r
-import org.simantics.common.color.Color;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.util.EvaluatingListener;\r
-import org.simantics.db.layer0.util.EvaluatingListener.Evaluation;\r
-import org.simantics.db.layer0.variable.RVI;\r
-import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.db.procedure.AsyncProcedure;\r
-import org.simantics.diagram.adapter.SyncElementFactory;\r
-import org.simantics.diagram.content.ConnectionUtil;\r
-import org.simantics.diagram.elements.MonitorClass;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.stubs.G2DResource;\r
-import org.simantics.diagram.synchronization.CompositeHintSynchronizer;\r
-import org.simantics.diagram.synchronization.IHintSynchronizer;\r
-import org.simantics.diagram.synchronization.SynchronizationHints;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
-import org.simantics.diagram.synchronization.graph.ElementLoader;\r
-import org.simantics.diagram.synchronization.graph.MonitorSynchronizer;\r
-import org.simantics.diagram.synchronization.graph.TransformSynchronizer;\r
-import org.simantics.diagram.ui.DiagramModelHints;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.DataElementMap;\r
-import org.simantics.g2d.diagram.handler.Relationship;\r
-import org.simantics.g2d.diagram.handler.RelationshipHandler;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.TextEditor;\r
-import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.ui.colors.Colors;\r
-import org.simantics.ui.fonts.FontDescriptor;\r
-import org.simantics.ui.fonts.Fonts;\r
-import org.simantics.utils.datastructures.Callback;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
-\r
-/**\r
- * TODO: recognize experiment disposal and reset monitor contents at that point\r
- * FIXME: monitor does not handle editing properly, and tries to include physical unit as part of numeric value\r
- */\r
-public class MonitorClassFactory2 extends SyncElementFactory {\r
-\r
-    private static final Key               KEY_VARIABLE_LISTENER = new KeyOf(MonitorListener.class,\r
-                                                                         "MONITOR_VARIABLE_LISTENER");\r
-\r
-    private static final String            CLASS_ID          = "Monitor";\r
-\r
-    private static final IHintSynchronizer HINT_SYNCHRONIZER = new CompositeHintSynchronizer(\r
-            MonitorSynchronizer.INSTANCE,\r
-            TransformSynchronizer.INSTANCE);\r
-\r
-    public static ElementClass createMonitorClass(Resource elementType) {\r
-        // set "default scale" to no scaling, 1.0, 1.0\r
-        return MonitorClass.create(1.0, 1.0, new StaticObjectAdapter(elementType)).setId(CLASS_ID);\r
-    }\r
-\r
-    // staticScale{X,Y} define the scale of the static monitor image\r
-    public static ElementClass createMonitorClass(Resource elementType, IElement parentElement, HashMap<String, String> substitutions, Object component, String suffix, double staticScaleX, double staticScaleY) {\r
-        return MonitorClass.create(parentElement, substitutions, component, suffix, staticScaleX, staticScaleY, new StaticObjectAdapter(elementType)).setId(CLASS_ID);\r
-    }\r
-\r
-    @Override\r
-    public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
-            AsyncProcedure<ElementClass> procedure) {\r
-        procedure.execute(graph, createMonitorClass(elementType));\r
-    }\r
-\r
-    @Override\r
-    public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
-        if (!graph.hasStatement(element))\r
-            return;\r
-\r
-        final Layer0 L0 = Layer0.getInstance(graph);\r
-        final G2DResource G2D = G2DResource.getInstance(graph);\r
-        final DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
-        // Must be done here to allow for the relationship manager to work properly.\r
-        e.setHint(ElementHints.KEY_OBJECT, element);\r
-        e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, HINT_SYNCHRONIZER);\r
-\r
-        AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element);\r
-        ElementUtils.setTransform(e, at);\r
-\r
-        // Load alignments\r
-        Resource hAlign = graph.getPossibleObject(element, G2D.HasHorizontalAlignment);\r
-        Resource vAlign = graph.getPossibleObject(element, G2D.HasVerticalAlignment);\r
-\r
-        final Double borderWidth = graph.getPossibleRelatedValue(element, G2D.HasStrokeWidth);\r
-        Double direction = graph.getPossibleRelatedValue(element, DIA.HasDirection);\r
-        double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(graph, element, G2D.HasBounds);\r
-        if (bounds != null) {\r
-            e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3]));\r
-        }\r
-\r
-        if (hAlign != null)\r
-            e.setHint(ElementHints.KEY_HORIZONTAL_ALIGN, DiagramGraphUtil.toAlignment(hAlign, G2D, MonitorClass.DEFAULT_HORIZONTAL_ALIGN));\r
-        if (vAlign != null)\r
-            e.setHint(ElementHints.KEY_VERTICAL_ALIGN, DiagramGraphUtil.toVerticalAlignment(vAlign, G2D, MonitorClass.DEFAULT_VERTICAL_ALIGN));\r
-        if (direction != null)\r
-            e.setHint(MonitorClass.KEY_DIRECTION, direction);\r
-        if (borderWidth != null)\r
-            e.setHint(MonitorClass.KEY_BORDER_WIDTH, borderWidth);\r
-\r
-        String suffix = graph.getPossibleRelatedValue(element, DIA.HasMonitorSuffix, Bindings.STRING);\r
-        if (suffix != null) e.setHint(MonitorClass.KEY_MONITOR_SUFFIX, suffix);\r
-\r
-        String label = graph.getPossibleRelatedValue(element, L0.HasLabel);\r
-        ElementUtils.setText(e, label);\r
-\r
-        FontDescriptor fd = graph.getPossibleRelatedAdapter(element, DIA.HasFont, FontDescriptor.class);\r
-        if(fd != null) ElementUtils.setTextFont(e, Fonts.awt(fd));\r
-        Color color = graph.getPossibleRelatedAdapter(element, DIA.HasColor, Color.class);\r
-        if(color != null) ElementUtils.setTextColor(e, Colors.awt(color));\r
-\r
-        loadParentRelationships(graph, element, e);\r
-\r
-        final Map<String, String> substitutions = new HashMap<String, String>();\r
-        substitutions.put("#v1", "");\r
-\r
-        final Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
-        if (diagramRuntime != null) {\r
-            final Session session = graph.getSession();\r
-\r
-            // Resolve validator for monitor input if possible.\r
-            final AtomicReference<Function1<String, String>> validator = new AtomicReference<Function1<String, String>>();\r
-            MonitorVariable monitorVariable = graph.syncRequest(new ResolveMonitorVariable(diagramRuntime, element));\r
-            boolean readOnly = true;\r
-            if (monitorVariable != null) {\r
-                Function1<String, String> func = monitorVariable.getVariable().getPossiblePropertyValue(graph, Variables.INPUT_VALIDATOR); \r
-                validator.set( func );\r
-                if (func != null)\r
-                    e.setHint(MonitorClass.KEY_INPUT_VALIDATOR, func);\r
-                RVI rvi = monitorVariable.getRVI();\r
-                if (rvi != null)\r
-                    e.setHint(MonitorClass.KEY_RVI, rvi);\r
-                readOnly = Boolean.TRUE.equals(\r
-                        monitorVariable.getVariable().getPossiblePropertyValue(graph, Variables.READONLY, Bindings.BOOLEAN));\r
-            }\r
-\r
-            TextEditor ed = null;\r
-            if (!readOnly &&\r
-                    (ed = e.getElementClass().getAtMostOneItemOfClass(TextEditor.class)) != null) {\r
-                ed.setModifier(e, new TextEditor.Modifier() {\r
-                    @Override\r
-                    public String getValue(IElement e) {\r
-                        return MonitorClass.editText(e);\r
-                    }\r
-\r
-                    @Override\r
-                    public String isValid(IElement e, String text) {\r
-                        if (validator.get() != null)\r
-                            return validator.get().apply(text);\r
-                        return null;\r
-                    }\r
-\r
-                    @Override\r
-                    public void modify(final IElement e, final String text) {\r
-                        session.asyncRequest(new ResolveMonitorVariable(diagramRuntime, element),\r
-                                new EvaluatingListener<MonitorVariable>(\r
-                                        new EvaluatingListener.Criterion<MonitorVariable>() {\r
-                            @Override\r
-                            public Evaluation evaluate(MonitorVariable result) {\r
-                                return result != null ? Evaluation.ACCEPT : Evaluation.IGNORE;\r
-                            }\r
-                        }) {\r
-                            @Override\r
-                            public void accepted(MonitorVariable var) {\r
-                                session.asyncRequest(new MonitorVariableWrite(var.getVariable(), text), new Callback<DatabaseException>() {\r
-                                    @Override\r
-                                    public void run(DatabaseException e) {\r
-                                        if (e != null)\r
-                                            ErrorLogger.defaultLogError(e);\r
-                                    }\r
-                                });\r
-                            }\r
-                            @Override\r
-                            public void exception(Throwable t) {\r
-                                ErrorLogger.defaultLogError(t);\r
-                            }\r
-                        });\r
-                    }\r
-\r
-                });\r
-            }\r
-\r
-            IElement mappedElement = diagram.getDiagramClass().getSingleItem(DataElementMap.class).getElement(diagram, element);\r
-            MonitorListener monitorListener = new MonitorListener(element, canvas, diagram, substitutions);\r
-            if (mappedElement != null) {\r
-                MonitorListener oldListener = mappedElement.getHint(KEY_VARIABLE_LISTENER);\r
-                if (oldListener != null)\r
-                    oldListener.dispose();\r
-                mappedElement.setHint(KEY_VARIABLE_LISTENER, monitorListener);\r
-            }\r
-\r
-            if(monitorVariable != null)\r
-               graph.asyncRequest(new MonitorVariableValueRequest(diagramRuntime, element), monitorListener);\r
-            \r
-        }\r
-    }\r
-\r
-    private void loadParentRelationships(ReadGraph graph, Resource element, IElement e) throws DatabaseException {\r
-        DiagramResource DIA = DiagramResource.getInstance(graph);\r
-        ModelingResources MOD = ModelingResources.getInstance(graph);\r
-\r
-        Resource monitorComponent = graph.getPossibleObject(element, DIA.HasMonitorComponent);\r
-        Resource parentDiagramElement = null;\r
-        if (monitorComponent != null)\r
-            parentDiagramElement = graph.getPossibleObject(monitorComponent, MOD.ComponentToElement);\r
-\r
-        // Load parent relationship after all elements have been loaded.\r
-        if (parentDiagramElement != null) {\r
-            final Resource pde = parentDiagramElement;\r
-            e.setHint(DiagramModelHints.KEY_ELEMENT_LOADER, new ElementLoader() {\r
-                @Override\r
-                public void load(ReadGraph g, IDiagram diagram, IElement element) throws DatabaseException {\r
-                    loadParentRelationship(g, diagram, element, pde);\r
-                }\r
-            });\r
-        }\r
-    }\r
-\r
-    boolean loadParentRelationship(ReadGraph g, IDiagram diagram, IElement element, Resource parentElementResource)\r
-            throws DatabaseException {\r
-        // If no relationship handler is available, stop loading.\r
-        RelationshipHandler rh = diagram.getDiagramClass().getAtMostOneItemOfClass(RelationshipHandler.class);\r
-        if (rh == null)\r
-            return true;\r
-\r
-        DiagramResource DIA = DiagramResource.getInstance(g);\r
-        DataElementMap map = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
-        IElement parentElement = map.getElement(diagram, parentElementResource);\r
-\r
-        if (parentElement != null) {\r
-            element.setHint(ElementHints.KEY_PARENT_ELEMENT, parentElement);\r
-            rh.claim(diagram, element, Relationship.CHILD_OF, parentElement);\r
-\r
-            Resource tailNode = null;\r
-            if (g.isInstanceOf(parentElementResource, DIA.Connection)) {\r
-                tailNode = ConnectionUtil.getConnectionTailNode(g, parentElementResource);\r
-            }\r
-\r
-            if (tailNode != null) {\r
-                IElement tailNodeElement = map.getElement(diagram, tailNode);\r
-                if (parentElement != null) {\r
-                    element.setHint(ElementHints.KEY_PARENT_ELEMENT, tailNodeElement);\r
-                    rh.claim(diagram, element, Relationship.CHILD_OF, tailNodeElement);\r
-                }\r
-            }\r
-\r
-            return true;\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagram.monitor;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.simantics.browsing.ui.common.ErrorLogger;
+import org.simantics.common.color.Color;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.EvaluatingListener;
+import org.simantics.db.layer0.util.EvaluatingListener.Evaluation;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.diagram.adapter.SyncElementFactory;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.elements.MonitorClass;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.stubs.G2DResource;
+import org.simantics.diagram.synchronization.CompositeHintSynchronizer;
+import org.simantics.diagram.synchronization.IHintSynchronizer;
+import org.simantics.diagram.synchronization.SynchronizationHints;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.diagram.synchronization.graph.ElementLoader;
+import org.simantics.diagram.synchronization.graph.MonitorSynchronizer;
+import org.simantics.diagram.synchronization.graph.TransformSynchronizer;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.DataElementMap;
+import org.simantics.g2d.diagram.handler.Relationship;
+import org.simantics.g2d.diagram.handler.RelationshipHandler;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.TextEditor;
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.ui.colors.Colors;
+import org.simantics.ui.fonts.FontDescriptor;
+import org.simantics.ui.fonts.Fonts;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+
+/**
+ * TODO: recognize experiment disposal and reset monitor contents at that point
+ * FIXME: monitor does not handle editing properly, and tries to include physical unit as part of numeric value
+ */
+public class MonitorClassFactory2 extends SyncElementFactory {
+
+    private static final Key               KEY_VARIABLE_LISTENER = new KeyOf(MonitorListener.class,
+                                                                         "MONITOR_VARIABLE_LISTENER"); //$NON-NLS-1$
+
+    private static final String            CLASS_ID          = "Monitor"; //$NON-NLS-1$
+
+    private static final IHintSynchronizer HINT_SYNCHRONIZER = new CompositeHintSynchronizer(
+            MonitorSynchronizer.INSTANCE,
+            TransformSynchronizer.INSTANCE);
+
+    public static ElementClass createMonitorClass(Resource elementType) {
+        // set "default scale" to no scaling, 1.0, 1.0
+        return MonitorClass.create(1.0, 1.0, new StaticObjectAdapter(elementType)).setId(CLASS_ID);
+    }
+
+    // staticScale{X,Y} define the scale of the static monitor image
+    public static ElementClass createMonitorClass(Resource elementType, IElement parentElement, HashMap<String, String> substitutions, Object component, String suffix, double staticScaleX, double staticScaleY) {
+        return MonitorClass.create(parentElement, substitutions, component, suffix, staticScaleX, staticScaleY, new StaticObjectAdapter(elementType)).setId(CLASS_ID);
+    }
+
+    @Override
+    public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,
+            AsyncProcedure<ElementClass> procedure) {
+        procedure.execute(graph, createMonitorClass(elementType));
+    }
+
+    @Override
+    public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {
+        if (!graph.hasStatement(element))
+            return;
+
+        final Layer0 L0 = Layer0.getInstance(graph);
+        final G2DResource G2D = G2DResource.getInstance(graph);
+        final DiagramResource DIA = DiagramResource.getInstance(graph);
+
+        // Must be done here to allow for the relationship manager to work properly.
+        e.setHint(ElementHints.KEY_OBJECT, element);
+        e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, HINT_SYNCHRONIZER);
+
+        AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element);
+        ElementUtils.setTransform(e, at);
+
+        // Load alignments
+        Resource hAlign = graph.getPossibleObject(element, G2D.HasHorizontalAlignment);
+        Resource vAlign = graph.getPossibleObject(element, G2D.HasVerticalAlignment);
+
+        final Double borderWidth = graph.getPossibleRelatedValue(element, G2D.HasStrokeWidth);
+        Double direction = graph.getPossibleRelatedValue(element, DIA.HasDirection);
+        double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(graph, element, G2D.HasBounds);
+        if (bounds != null) {
+            e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3]));
+        }
+
+        if (hAlign != null)
+            e.setHint(ElementHints.KEY_HORIZONTAL_ALIGN, DiagramGraphUtil.toAlignment(hAlign, G2D, MonitorClass.DEFAULT_HORIZONTAL_ALIGN));
+        if (vAlign != null)
+            e.setHint(ElementHints.KEY_VERTICAL_ALIGN, DiagramGraphUtil.toVerticalAlignment(vAlign, G2D, MonitorClass.DEFAULT_VERTICAL_ALIGN));
+        if (direction != null)
+            e.setHint(MonitorClass.KEY_DIRECTION, direction);
+        if (borderWidth != null)
+            e.setHint(MonitorClass.KEY_BORDER_WIDTH, borderWidth);
+
+        String suffix = graph.getPossibleRelatedValue(element, DIA.HasMonitorSuffix, Bindings.STRING);
+        if (suffix != null) e.setHint(MonitorClass.KEY_MONITOR_SUFFIX, suffix);
+
+        String label = graph.getPossibleRelatedValue(element, L0.HasLabel);
+        ElementUtils.setText(e, label);
+
+        FontDescriptor fd = graph.getPossibleRelatedAdapter(element, DIA.HasFont, FontDescriptor.class);
+        if(fd != null) ElementUtils.setTextFont(e, Fonts.awt(fd));
+        Color color = graph.getPossibleRelatedAdapter(element, DIA.HasColor, Color.class);
+        if(color != null) ElementUtils.setTextColor(e, Colors.awt(color));
+
+        loadParentRelationships(graph, element, e);
+
+        final Map<String, String> substitutions = new HashMap<String, String>();
+        substitutions.put("#v1", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+        final Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
+        if (diagramRuntime != null) {
+            final Session session = graph.getSession();
+
+            // Resolve validator for monitor input if possible.
+            final AtomicReference<Function1<String, String>> validator = new AtomicReference<Function1<String, String>>();
+            MonitorVariable monitorVariable = graph.syncRequest(new ResolveMonitorVariable(diagramRuntime, element));
+            boolean readOnly = true;
+            if (monitorVariable != null) {
+                Function1<String, String> func = monitorVariable.getVariable().getPossiblePropertyValue(graph, Variables.INPUT_VALIDATOR); 
+                validator.set( func );
+                if (func != null)
+                    e.setHint(MonitorClass.KEY_INPUT_VALIDATOR, func);
+                RVI rvi = monitorVariable.getRVI();
+                if (rvi != null)
+                    e.setHint(MonitorClass.KEY_RVI, rvi);
+                readOnly = Boolean.TRUE.equals(
+                        monitorVariable.getVariable().getPossiblePropertyValue(graph, Variables.READONLY, Bindings.BOOLEAN));
+            }
+
+            TextEditor ed = null;
+            if (!readOnly &&
+                    (ed = e.getElementClass().getAtMostOneItemOfClass(TextEditor.class)) != null) {
+                ed.setModifier(e, new TextEditor.Modifier() {
+                    @Override
+                    public String getValue(IElement e) {
+                        return MonitorClass.editText(e);
+                    }
+
+                    @Override
+                    public String isValid(IElement e, String text) {
+                        if (validator.get() != null)
+                            return validator.get().apply(text);
+                        return null;
+                    }
+
+                    @Override
+                    public void modify(final IElement e, final String text) {
+                        session.asyncRequest(new ResolveMonitorVariable(diagramRuntime, element),
+                                new EvaluatingListener<MonitorVariable>(
+                                        new EvaluatingListener.Criterion<MonitorVariable>() {
+                            @Override
+                            public Evaluation evaluate(MonitorVariable result) {
+                                return result != null ? Evaluation.ACCEPT : Evaluation.IGNORE;
+                            }
+                        }) {
+                            @Override
+                            public void accepted(MonitorVariable var) {
+                                session.asyncRequest(new MonitorVariableWrite(var.getVariable(), text), e -> {
+                                    if (e != null)
+                                        ErrorLogger.defaultLogError(e);
+                                });
+                            }
+                            @Override
+                            public void exception(Throwable t) {
+                                ErrorLogger.defaultLogError(t);
+                            }
+                        });
+                    }
+
+                });
+            }
+
+            IElement mappedElement = e;//diagram.getDiagramClass().getSingleItem(DataElementMap.class).getElement(diagram, element);
+            MonitorListener monitorListener = new MonitorListener(element, canvas, diagram, substitutions);
+            if (mappedElement != null) {
+                MonitorListener oldListener = mappedElement.getHint(KEY_VARIABLE_LISTENER);
+                if (oldListener != null)
+                    oldListener.dispose();
+                mappedElement.setHint(KEY_VARIABLE_LISTENER, monitorListener);
+            }
+
+            if(monitorVariable != null)
+               graph.syncRequest(new MonitorVariableValueRequest(diagramRuntime, element), monitorListener);
+            
+        }
+    }
+
+    private void loadParentRelationships(ReadGraph graph, Resource element, IElement e) throws DatabaseException {
+        DiagramResource DIA = DiagramResource.getInstance(graph);
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+
+        Resource monitorComponent = graph.getPossibleObject(element, DIA.HasMonitorComponent);
+        Resource parentDiagramElement = null;
+        if (monitorComponent != null)
+            parentDiagramElement = graph.getPossibleObject(monitorComponent, MOD.ComponentToElement);
+
+        // Load parent relationship after all elements have been loaded.
+        if (parentDiagramElement != null) {
+            final Resource pde = parentDiagramElement;
+            e.setHint(DiagramModelHints.KEY_ELEMENT_LOADER, new ElementLoader() {
+                @Override
+                public void load(ReadGraph g, IDiagram diagram, IElement element) throws DatabaseException {
+                    loadParentRelationship(g, diagram, element, pde);
+                }
+            });
+        }
+    }
+
+    boolean loadParentRelationship(ReadGraph g, IDiagram diagram, IElement element, Resource parentElementResource)
+            throws DatabaseException {
+        // If no relationship handler is available, stop loading.
+        RelationshipHandler rh = diagram.getDiagramClass().getAtMostOneItemOfClass(RelationshipHandler.class);
+        if (rh == null)
+            return true;
+
+        DiagramResource DIA = DiagramResource.getInstance(g);
+        DataElementMap map = diagram.getDiagramClass().getSingleItem(DataElementMap.class);
+        IElement parentElement = map.getElement(diagram, parentElementResource);
+
+        if (parentElement != null) {
+            element.setHint(ElementHints.KEY_PARENT_ELEMENT, parentElement);
+            rh.claim(diagram, element, Relationship.CHILD_OF, parentElement);
+
+            Resource tailNode = null;
+            if (g.isInstanceOf(parentElementResource, DIA.Connection)) {
+                tailNode = ConnectionUtil.getConnectionTailNode(g, parentElementResource);
+            }
+
+            if (tailNode != null) {
+                IElement tailNodeElement = map.getElement(diagram, tailNode);
+                if (parentElement != null) {
+                    element.setHint(ElementHints.KEY_PARENT_ELEMENT, tailNodeElement);
+                    rh.claim(diagram, element, Relationship.CHILD_OF, tailNodeElement);
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
 }
\ No newline at end of file