package org.eclipse.uml2.diagram.common.commands; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.uml2.diagram.common.links.PortOperationsExt; import org.eclipse.uml2.diagram.common.links.ProvidedInterfaceLink; import org.eclipse.uml2.diagram.common.links.RefreshComplementaryLinksHelper; import org.eclipse.uml2.diagram.common.preferences.UMLPreferencesConstants; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.Interface; import org.eclipse.uml2.uml.InterfaceRealization; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.Port; import org.eclipse.uml2.uml.Realization; import org.eclipse.uml2.uml.Type; import org.eclipse.uml2.uml.UMLFactory; import org.eclipse.uml2.uml.UMLPackage; public class ProvidedPortLinkHelper { private final EObject mySource; private final EObject myTarget; private final IPreferenceStore myStore; public ProvidedPortLinkHelper(AdapterFactoryEditingDomain editingDomain, EObject source, EObject target, IPreferenceStore store) { mySource = source; myTarget = target; myStore = store; } public void create() { Port port = getSource(); Interface targetInterface = getTarget(); if (port == null || targetInterface == null) { return; } //we can not modify derived Port#getProvideds() directly, //so we will mimic the logic from the PortOperations#getProvideds() Type portType = port.getType(); if (portType == null) { port.setType(targetInterface); RefreshComplementaryLinksHelper.getInstance().addNotificationDescription(port, NotationPackage.eINSTANCE.getView_SourceEdges(), RefreshComplementaryLinksHelper.PORT_PROVIDED_INTERFACES_AFTER_PORT_EVENT); return; } if (portType instanceof Classifier) { //then it is new Realization for this classifier createRealization(port, targetInterface, (Classifier) portType); RefreshComplementaryLinksHelper.getInstance().addNotificationDescription(targetInterface, NotationPackage.eINSTANCE.getView_TargetEdges(), RefreshComplementaryLinksHelper.INTERFACE_TARGET_INTERFACE_REALIZATIONS_AFTER_PORT_PROVIDED_TARGET_CHANGED); } return; } public boolean canCreate() { if (myStore.getBoolean(UMLPreferencesConstants.PREF_MANAGE_LINKS_HIDE_PROVIDED_INTERFACE_LINKS)) { return false; } return true; } public void reorientSource(Port newSource) { ProvidedInterfaceLink realization; //delete the old link if (getTarget().equals(getSource().getType())) { getSource().setType(null); realization = null; RefreshComplementaryLinksHelper.getInstance().addNotificationDescription(getSource(), NotationPackage.eINSTANCE.getView_SourceEdges(), RefreshComplementaryLinksHelper.PORT_PROVIDED_INTERFACES_AFTER_PORT_EVENT); } else { realization = PortOperationsExt.getProvideds(getSource(), getTarget()); realization.getRealization().getClients().remove(realization.getSource()); // if we will not create a link, but just set type, we remove obsolete link Type portType = newSource.getType(); if (portType == null) { realization.getRealization().getSuppliers().remove(getTarget()); if (realization.getRealization().getSuppliers().isEmpty() && realization.getRealization().getClients().isEmpty()) { realization.getRealization().destroy(); } } else { RefreshComplementaryLinksHelper.getInstance().addNotificationDescription(newSource, NotationPackage.eINSTANCE.getView_SourceEdges(), RefreshComplementaryLinksHelper.PORT_PROVIDED_INTERFACE_AFTER_PORT_PROVIDED_SOURCE_CHANGED); } } //create a new link Type portType = newSource.getType(); if (portType == null) { newSource.setType(getTarget()); RefreshComplementaryLinksHelper.getInstance().addNotificationDescription(newSource, NotationPackage.eINSTANCE.getView_SourceEdges(), RefreshComplementaryLinksHelper.PORT_PROVIDED_INTERFACES_AFTER_PORT_EVENT); return; } if (portType instanceof Classifier) { //create new Realization for the classifier if (realization == null) { createRealization(newSource, getTarget(), (Classifier) portType); } else { realization.getRealization().getClients().add((Classifier) portType); } } } public boolean canReorientSource(Port newSource) { return true; } public void reorientTarget(Interface newTarget) { Port port = getSource(); RefreshComplementaryLinksHelper helper = RefreshComplementaryLinksHelper.getInstance(); // if old provided interface was described by port type, then we change port type Classifier portType = (Classifier) port.getType(); if (getTarget().equals(portType)) { port.setType(newTarget); helper.addNotificationDescription(port, UMLPackage.eINSTANCE.getTypedElement_Type(), RefreshComplementaryLinksHelper.PORT_PROVIDED_INTERFACES_AFTER_PORT_EVENT); return; } else { helper.addNotificationDescription(getTarget(), NotationPackage.eINSTANCE.getView_TargetEdges(), RefreshComplementaryLinksHelper.INTERFACE_TARGET_INTERFACE_REALIZATIONS_AFTER_PORT_PROVIDED_TARGET_CHANGED); helper.addNotificationDescription(newTarget, NotationPackage.eINSTANCE.getView_TargetEdges(), RefreshComplementaryLinksHelper.INTERFACE_TARGET_INTERFACE_REALIZATIONS_AFTER_PORT_PROVIDED_TARGET_CHANGED); } // if old provided interface was described by realization link, then we change target of the link InterfaceRealization dependency = PortOperationsExt.getProvideds(port, getTarget()).getRealization(); dependency.getSuppliers().remove(getTarget()); dependency.getSuppliers().add(newTarget); } public boolean canReorientTarget(Interface newTarget) { return true; } private Realization createRealization(Port port, Interface targetInterface, Classifier portType) { Package realizationContainer = null; for (EObject element = getSource(); element != null; element = element.eContainer()) { if (element instanceof Package) { realizationContainer = (Package) element; break; } } if (realizationContainer == null) { return null; } InterfaceRealization realization = UMLFactory.eINSTANCE.createInterfaceRealization(); realizationContainer.getPackagedElements().add(realization); realization.getClients().add(portType); realization.getSuppliers().add(targetInterface); realization.setContract(targetInterface); return realization; } private Port getSource() { return (Port) mySource; } private Interface getTarget() { return (Interface) myTarget; } }