X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fdiagram%2Fmonitor%2FMonitorClassFactory2.java;h=75d3050b9cd91689c5d136ed82868bd20808fd5f;hb=90a52d58489b6c518b13dde238923125c8f63eec;hp=2dfa0598d1e0a2233f2fcb833869efe49fbe8949;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java index 2dfa0598d..75d3050b9 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/MonitorClassFactory2.java @@ -1,286 +1,282 @@ -/******************************************************************************* - * 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.Callback; -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"); - - private static final String CLASS_ID = "Monitor"; - - 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 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 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 substitutions = new HashMap(); - substitutions.put("#v1", ""); - - 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> validator = new AtomicReference>(); - MonitorVariable monitorVariable = graph.syncRequest(new ResolveMonitorVariable(diagramRuntime, element)); - boolean readOnly = true; - if (monitorVariable != null) { - Function1 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( - new EvaluatingListener.Criterion() { - @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), new Callback() { - @Override - public void run(DatabaseException e) { - if (e != null) - ErrorLogger.defaultLogError(e); - } - }); - } - @Override - public void exception(Throwable t) { - ErrorLogger.defaultLogError(t); - } - }); - } - - }); - } - - IElement mappedElement = 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.asyncRequest(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; - } - +/******************************************************************************* + * 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 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 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 substitutions = new HashMap(); + 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> validator = new AtomicReference>(); + MonitorVariable monitorVariable = graph.syncRequest(new ResolveMonitorVariable(diagramRuntime, element)); + boolean readOnly = true; + if (monitorVariable != null) { + Function1 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( + new EvaluatingListener.Criterion() { + @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