/****************************************************************************** * Copyright (c) 2016 Oracle * 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: * Shenxue Zhou - initial implementation and ongoing maintenance * Konstantin Komissarchik - [341856] NPE when a diagram connection doesn't define a label * Konstantin Komissarchik - [342897] Integrate with properties view * Konstantin Komissarchik - [342775] Support EL in MasterDetailsTreeNodeDef.ImagePath * Konstantin Komissarchik - [378756] Convert ModelElementListener and ModelPropertyListener to common listener infrastructure ******************************************************************************/ package org.eclipse.sapphire.ui.diagram.internal; import java.util.List; import org.eclipse.sapphire.Element; import org.eclipse.sapphire.Event; import org.eclipse.sapphire.FilteredListener; import org.eclipse.sapphire.Listener; import org.eclipse.sapphire.PropertyDef; import org.eclipse.sapphire.PropertyEvent; import org.eclipse.sapphire.ReferenceValue; import org.eclipse.sapphire.modeling.ModelPath; import org.eclipse.sapphire.services.ReferenceService; import org.eclipse.sapphire.ui.diagram.def.IDiagramConnectionEndpointBindingDef; import org.eclipse.sapphire.ui.diagram.def.IDiagramExplicitConnectionBindingDef; import org.eclipse.sapphire.ui.diagram.editor.DiagramNodePart; import org.eclipse.sapphire.ui.diagram.editor.SapphireDiagramEditorPagePart; /** * @author <a href="mailto:shenxue.zhou@oracle.com">Shenxue Zhou</a> * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a> */ public class StandardEmbeddedConnectionPart extends StandardDiagramConnectionPart { private Element srcNodeModel; private Element endpointModel; private ModelPath endpointPath; private Listener referenceServiceListener; private ReferenceValue<?, ?> endpointReferenceValue; private IDiagramConnectionEndpointBindingDef endpointDef; public StandardEmbeddedConnectionPart(IDiagramExplicitConnectionBindingDef connBindingDef, Element srcNodeModel, ModelPath endpointPath) { this.bindingDef = connBindingDef; this.srcNodeModel = srcNodeModel; this.endpointPath = endpointPath; } @Override protected void init() { initLabelId(); this.endpointDef = this.bindingDef.getEndpoint2().content(); this.endpointModel = resolveEndpoint(this.modelElement, this.endpointPath); // Add model property listener this.modelPropertyListener = new FilteredListener<PropertyEvent>() { @Override protected void handleTypedEvent( final PropertyEvent event ) { handleModelPropertyChange( event ); } }; addModelListener(); addReferenceServiceListeners(); } @Override public Element getEndpoint1() { return this.srcNodeModel; } @Override public Element getEndpoint2() { return this.endpointModel; } @Override public void resetEndpoint1(DiagramNodePart newSrcNode) { } public DiagramNodePart getSourceNodePart() { SapphireDiagramEditorPagePart diagramPart = (SapphireDiagramEditorPagePart)parent().parent().parent(); return diagramPart.getDiagramNodePart(this.srcNodeModel); } public String getId() { StringBuffer buffer = new StringBuffer(getConnectionTypeId()); buffer.append(CONNECTION_ID_SEPARATOR); String instanceId = getInstanceId(); if (instanceId != null && instanceId.length() > 0) { buffer.append(getInstanceId()); buffer.append(CONNECTION_ID_SEPARATOR); } Element srcNodeElement = getSourceNodePart().getLocalModelElement(); List<StandardDiagramConnectionPart> connParts = getDiagramConnectionTemplate().getDiagramConnections(srcNodeElement); int index = connParts.indexOf(this); buffer.append(index); return buffer.toString(); } @Override public void addModelListener() { this.modelElement.attach(this.modelPropertyListener, this.endpointDef.getProperty().content()); } @Override public void addReferenceServiceListeners() { this.endpointReferenceValue = resolveEndpointReferenceValue(modelElement, endpointPath); if (endpointReferenceValue != null) { ReferenceService<?> refService = endpointReferenceValue.service(ReferenceService.class); this.referenceServiceListener = new Listener() { @Override public void handle( Event event ) { handleEndpointReferenceChange(); } }; if (refService != null) { refService.attach(this.referenceServiceListener); } } } @Override public void removeModelListener() { this.modelElement.detach(this.modelPropertyListener, this.endpointDef.getProperty().content()); } @Override protected void handleModelPropertyChange(final PropertyEvent event) { final PropertyDef property = event.property().definition(); if (property.name().equals(this.endpointDef.getProperty().content())) { this.endpointModel = resolveEndpoint(this.modelElement, this.endpointPath); notifyConnectionEndpointUpdate(); } } protected void handleEndpointReferenceChange() { Element newTargetModel = resolveEndpoint(this.modelElement, this.endpointPath); if (newTargetModel != this.endpointModel) { this.endpointModel = newTargetModel; notifyConnectionEndpointUpdate(); } } }