| /******************************************************************************* |
| * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others. |
| * 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: |
| * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.capra.handler.uml; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.capra.core.adapters.Connection; |
| import org.eclipse.capra.core.handlers.AbstractArtifactHandler; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.ecore.EModelElement; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.uml2.uml.ActivityEdge; |
| import org.eclipse.uml2.uml.Connector; |
| import org.eclipse.uml2.uml.ConnectorEnd; |
| import org.eclipse.uml2.uml.Element; |
| import org.eclipse.uml2.uml.Interface; |
| import org.eclipse.uml2.uml.Message; |
| import org.eclipse.uml2.uml.MessageOccurrenceSpecification; |
| import org.eclipse.uml2.uml.Port; |
| import org.eclipse.uml2.uml.Relationship; |
| import org.eclipse.uml2.uml.Transition; |
| |
| /** |
| * Handler to allow tracing to and from arbitrary UML model elements. |
| * |
| * @author Dominik Einkemmer |
| */ |
| public class UMLHandler extends AbstractArtifactHandler<EModelElement> { |
| |
| @Override |
| public EObject createWrapper(EModelElement artifact, EObject artifactModel) { |
| return artifact; |
| } |
| |
| @Override |
| public EModelElement resolveWrapper(EObject wrapper) { |
| return (EModelElement) wrapper; |
| } |
| |
| @Override |
| public String getDisplayName(EModelElement artifact) { |
| return artifact.eClass().getName(); |
| } |
| |
| @Override |
| public List<Connection> addInternalLinks(EObject investigatedElement, List<String> selectedRelationshipTypes) { |
| List<Integer> duplicationCheck = new ArrayList<>(); |
| List<Connection> allElements = new ArrayList<>(); |
| if (Relationship.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| Relationship rel = Relationship.class.cast(investigatedElement); |
| List<EObject> relatedElements = new ArrayList<>(); |
| int connectionHash = investigatedElement.hashCode() + rel.hashCode(); |
| for (Element element : rel.getRelatedElements()) { |
| relatedElements.add(element); |
| connectionHash += element.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, rel); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (ActivityEdge.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| ActivityEdge activityEdge = ActivityEdge.class.cast(investigatedElement); |
| List<EObject> relatedElements = new ArrayList<>(); |
| relatedElements.add(activityEdge.getTarget()); |
| relatedElements.add(activityEdge.getSource()); |
| int connectionHash = investigatedElement.hashCode() + activityEdge.hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, activityEdge); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Transition.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| Transition transition = Transition.class.cast(investigatedElement); |
| List<EObject> relatedElements = new ArrayList<>(); |
| relatedElements.add(transition.getSource()); |
| relatedElements.add(transition.getTarget()); |
| int connectionHash = investigatedElement.hashCode() + transition.hashCode() |
| + transition.getTarget().hashCode() + transition.getSource().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, transition); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Message.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| Message msg = Message.class.cast(investigatedElement); |
| MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent(); |
| MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent(); |
| List<EObject> relatedElements = new ArrayList<>(); |
| relatedElements.add(sender.getCovered()); |
| relatedElements.add(receiver.getCovered()); |
| if (receiver != null) { |
| int connectionHash = investigatedElement.hashCode() + msg.hashCode() |
| + msg.getMessageSort().hashCode() + sender.getCovered().hashCode() |
| + receiver.getCovered().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, msg); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } |
| } else if (Port.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| Port port = Port.class.cast(investigatedElement); |
| EList<Interface> provideds = port.getProvideds(); |
| EList<Interface> requireds = port.getRequireds(); |
| List<EObject> relatedElements = new ArrayList<>(); |
| relatedElements.addAll(requireds); |
| relatedElements.addAll(provideds); |
| int connectionHash = investigatedElement.hashCode() + port.hashCode(); |
| for (EObject el : relatedElements) { |
| connectionHash += el.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, port); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Connector.class.isAssignableFrom(investigatedElement.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(investigatedElement.eClass().getName())) { |
| Connector connector = Connector.class.cast(investigatedElement); |
| EList<ConnectorEnd> connectedEnds = connector.getEnds(); |
| List<EObject> relatedElements = new ArrayList<>(); |
| connectedEnds.forEach(connectedEnd -> { |
| if (connectedEnd.getPartWithPort() != null) { |
| relatedElements.add(connectedEnd.getPartWithPort()); |
| } else { |
| relatedElements.add(connectedEnd); |
| } |
| }); |
| int connectionHash = investigatedElement.hashCode() + connector.hashCode(); |
| for (EObject el : relatedElements) { |
| connectionHash += el.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, connector); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else { |
| EObject root = EcoreUtil.getRootContainer(investigatedElement); |
| TreeIterator<EObject> modelContents = root.eAllContents(); |
| while (modelContents.hasNext()) { |
| EObject content = modelContents.next(); |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(content.eClass().getName())) { |
| if (Relationship.class.isAssignableFrom(content.getClass())) { |
| Relationship relation = Relationship.class.cast(content); |
| boolean isRelatedToElement = false; |
| List<EObject> relatedElements = new ArrayList<>(); |
| for (Element relatedElement : relation.getRelatedElements()) { |
| if (relatedElement.hashCode() == investigatedElement.hashCode()) { |
| isRelatedToElement = true; |
| } else { |
| relatedElements.add(relatedElement); |
| } |
| } |
| if (isRelatedToElement) { |
| int connectionHash = investigatedElement.hashCode() + relation.hashCode(); |
| for (EObject element : relatedElements) { |
| connectionHash += element.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, relation); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (ActivityEdge.class.isAssignableFrom(content.getClass())) { |
| if (selectedRelationshipTypes.size() == 0 |
| || selectedRelationshipTypes.contains(content.eClass().getName())) { |
| ActivityEdge activityEdge = ActivityEdge.class.cast(content); |
| List<EObject> relatedElements = new ArrayList<>(); |
| if (activityEdge.getTarget().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(activityEdge.getSource()); |
| } else if (activityEdge.getSource().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(activityEdge.getTarget()); |
| } |
| int connectionHash = investigatedElement.hashCode() + activityEdge.hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, activityEdge); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Transition.class.isAssignableFrom(content.getClass())) { |
| Transition transition = Transition.class.cast(content); |
| List<EObject> relatedElements = new ArrayList<>(); |
| if (transition.getSource().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(transition.getTarget()); |
| int connectionHash = investigatedElement.hashCode() + transition.hashCode() |
| + transition.getTarget().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, transition); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } else if (transition.getTarget().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(transition.getSource()); |
| int connectionHash = investigatedElement.hashCode() + transition.hashCode() |
| + transition.getSource().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, transition); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Message.class.isAssignableFrom(content.getClass())) { |
| Message msg = Message.class.cast(content); |
| MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg |
| .getReceiveEvent(); |
| MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent(); |
| List<EObject> relatedElements = new ArrayList<>(); |
| if (receiver != null && receiver.getCovered() != null) { |
| if (receiver.getCovered().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(sender.getCovered()); |
| int connectionHash = investigatedElement.hashCode() + msg.hashCode() |
| + msg.getMessageSort().hashCode() + sender.getCovered().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, msg); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } else if (sender.getCovered().hashCode() == investigatedElement.hashCode()) { |
| relatedElements.add(receiver.getCovered()); |
| int connectionHash = investigatedElement.hashCode() + msg.hashCode() |
| + msg.getMessageSort().hashCode() + receiver.getCovered().hashCode(); |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, msg); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } |
| } else if (Port.class.isAssignableFrom(content.getClass())) { |
| Port port = Port.class.cast(content); |
| EList<Interface> provideds = port.getProvideds(); |
| boolean investigatedIsProvided = false; |
| for (Interface provided : provideds) { |
| if (provided.hashCode() == investigatedElement.hashCode()) { |
| investigatedIsProvided = true; |
| } |
| } |
| EList<Interface> requireds = port.getRequireds(); |
| boolean investigatedIsRequired = false; |
| for (Interface required : requireds) { |
| if (required.hashCode() == investigatedElement.hashCode()) { |
| investigatedIsRequired = true; |
| } |
| |
| } |
| List<EObject> relatedElements = new ArrayList<>(); |
| |
| if (investigatedIsProvided) { |
| relatedElements.addAll(requireds); |
| } else if (investigatedIsRequired) { |
| relatedElements.addAll(provideds); |
| } |
| if (investigatedIsProvided || investigatedIsRequired) { |
| int connectionHash = investigatedElement.hashCode() + port.hashCode(); |
| for (EObject el : relatedElements) { |
| connectionHash += el.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, port); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } else if (Connector.class.isAssignableFrom(content.getClass())) { |
| Connector connector = Connector.class.cast(content); |
| EList<ConnectorEnd> connectedEnds = connector.getEnds(); |
| List<EObject> relatedElements = new ArrayList<>(); |
| boolean isConnected = false; |
| for (ConnectorEnd connectedEnd : connectedEnds) { |
| if (connectedEnd.getPartWithPort() != null) { |
| relatedElements.add(connectedEnd.getPartWithPort()); |
| if (connectedEnd.getPartWithPort().hashCode() == investigatedElement.hashCode()) { |
| isConnected = true; |
| relatedElements.remove(connectedEnd.getPartWithPort()); |
| } |
| } else { |
| relatedElements.add(connectedEnd); |
| if (connectedEnd.hashCode() == investigatedElement.hashCode()) { |
| isConnected = true; |
| relatedElements.remove(connectedEnd); |
| } |
| } |
| } |
| if (isConnected) { |
| int connectionHash = investigatedElement.hashCode() + connector.hashCode(); |
| for (EObject el : relatedElements) { |
| connectionHash += el.hashCode(); |
| } |
| if (!duplicationCheck.contains(connectionHash)) { |
| Connection conn = new Connection(investigatedElement, relatedElements, connector); |
| allElements.add(conn); |
| duplicationCheck.add(connectionHash); |
| } |
| } |
| } |
| } |
| } |
| } |
| return allElements; |
| } |
| |
| @Override |
| public boolean isThereAnInternalTraceBetween(EObject first, EObject second) { |
| if (first.equals(second)) { |
| return false; |
| } |
| if (Relationship.class.isAssignableFrom(first.getClass()) |
| || Relationship.class.isAssignableFrom(second.getClass())) { |
| Relationship rel; |
| if (Relationship.class.isAssignableFrom(first.getClass())) { |
| rel = Relationship.class.cast(first); |
| } else { |
| rel = Relationship.class.cast(second); |
| } |
| boolean isRelated = false; |
| for (Element relatedElement : rel.getRelatedElements()) { |
| if (relatedElement.hashCode() == first.hashCode() || relatedElement.hashCode() == second.hashCode()) { |
| isRelated = true; |
| } |
| } |
| |
| return isRelated; |
| |
| } else if (ActivityEdge.class.isAssignableFrom(first.getClass()) |
| || ActivityEdge.class.isAssignableFrom(second.getClass())) { |
| ActivityEdge activityEdge; |
| if (ActivityEdge.class.isAssignableFrom(first.getClass())) { |
| activityEdge = ActivityEdge.class.cast(first); |
| } else { |
| activityEdge = ActivityEdge.class.cast(second); |
| } |
| int sourceHash = activityEdge.getSource().hashCode(); |
| int targetHash = activityEdge.getTarget().hashCode(); |
| |
| boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| boolean relationContainsSecondElement = sourceHash == second.hashCode() || sourceHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| return true; |
| } |
| } else if (Transition.class.isAssignableFrom(first.getClass()) |
| || Transition.class.isAssignableFrom(second.getClass())) { |
| Transition transition; |
| if (Transition.class.isAssignableFrom(first.getClass())) { |
| transition = Transition.class.cast(first); |
| } else { |
| transition = Transition.class.cast(second); |
| } |
| int sourceHash = transition.getSource().hashCode(); |
| int targetHash = transition.getTarget().hashCode(); |
| boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| boolean relationContainsSecondElement = sourceHash == second.hashCode() || sourceHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| return true; |
| } |
| } else if (Message.class.isAssignableFrom(first.getClass()) |
| || Message.class.isAssignableFrom(second.getClass())) { |
| Message msg; |
| if (Message.class.isAssignableFrom(first.getClass())) { |
| msg = Message.class.cast(first); |
| } else { |
| msg = Message.class.cast(second); |
| } |
| MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent(); |
| MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent(); |
| if (receiver != null) { |
| int sourceHash = sender.getCovered().hashCode(); |
| int targetHash = receiver.getCovered().hashCode(); |
| boolean relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| boolean relationContainsSecondElement = sourceHash == second.hashCode() |
| || targetHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| return true; |
| } |
| } |
| } else if (Connector.class.isAssignableFrom(first.getClass()) |
| || Connector.class.isAssignableFrom(second.getClass())) { |
| Connector connector; |
| if (Connector.class.isAssignableFrom(first.getClass())) { |
| connector = Connector.class.cast(first); |
| } else { |
| connector = Connector.class.cast(second); |
| } |
| EList<ConnectorEnd> connectedEnds = connector.getEnds(); |
| boolean isRelated = false; |
| for (ConnectorEnd connectedEnd : connectedEnds) { |
| if (connectedEnd.getPartWithPort() != null |
| && (connectedEnd.getPartWithPort().hashCode() == first.hashCode() |
| || connectedEnd.getPartWithPort().hashCode() == second.hashCode())) { |
| isRelated = true; |
| } else if (connectedEnd.hashCode() == first.hashCode() |
| || connectedEnd.hashCode() == second.hashCode()) { |
| isRelated = true; |
| } |
| } |
| if (isRelated) { |
| return true; |
| } |
| } else { |
| boolean relationContainsFirstElement = false; |
| boolean relationContainsSecondElement = false; |
| int numberofInternalLinks = 0; |
| EObject root = EcoreUtil.getRootContainer(first); |
| TreeIterator<EObject> modelContents = root.eAllContents(); |
| while (modelContents.hasNext()) { |
| EObject content = modelContents.next(); |
| if (Relationship.class.isAssignableFrom(content.getClass())) { |
| Relationship relation = Relationship.class.cast(content); |
| for (Element relatedElement : relation.getRelatedElements()) { |
| if (relatedElement.hashCode() == first.hashCode()) { |
| relationContainsFirstElement = true; |
| } else if (relatedElement.hashCode() == second.hashCode()) { |
| relationContainsSecondElement = true; |
| } |
| } |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| numberofInternalLinks++; |
| } |
| } else if (ActivityEdge.class.isAssignableFrom(content.getClass())) { |
| ActivityEdge activityEdge = ActivityEdge.class.cast(content); |
| int sourceHash = activityEdge.getSource().hashCode(); |
| int targetHash = activityEdge.getTarget().hashCode(); |
| |
| relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| relationContainsSecondElement = sourceHash == second.hashCode() || targetHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| numberofInternalLinks++; |
| } |
| } else if (Transition.class.isAssignableFrom(content.getClass())) { |
| Transition transition = Transition.class.cast(content); |
| int sourceHash = transition.getSource().hashCode(); |
| int targetHash = transition.getTarget().hashCode(); |
| relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| relationContainsSecondElement = sourceHash == second.hashCode() || targetHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| numberofInternalLinks++; |
| } |
| } else if (Message.class.isAssignableFrom(content.getClass())) { |
| Message msg = Message.class.cast(content); |
| MessageOccurrenceSpecification receiver = (MessageOccurrenceSpecification) msg.getReceiveEvent(); |
| MessageOccurrenceSpecification sender = (MessageOccurrenceSpecification) msg.getSendEvent(); |
| if (receiver != null) { |
| int sourceHash = sender.getCovered().hashCode(); |
| int targetHash = receiver.getCovered().hashCode(); |
| relationContainsFirstElement = sourceHash == first.hashCode() || targetHash == first.hashCode(); |
| relationContainsSecondElement = sourceHash == second.hashCode() |
| || targetHash == second.hashCode(); |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| numberofInternalLinks++; |
| } |
| } else if (Connector.class.isAssignableFrom(content.getClass())) { |
| Connector connector = Connector.class.cast(content); |
| EList<ConnectorEnd> connectedEnds = connector.getEnds(); |
| for (ConnectorEnd connectedEnd : connectedEnds) { |
| if (connectedEnd.getPartWithPort() != null |
| && (connectedEnd.getPartWithPort().hashCode() == first.hashCode() |
| || connectedEnd.getPartWithPort().hashCode() == second.hashCode())) { |
| relationContainsFirstElement = true; |
| } else if (connectedEnd.hashCode() == first.hashCode() |
| || connectedEnd.hashCode() == second.hashCode()) { |
| relationContainsSecondElement = true; |
| } |
| } |
| if (relationContainsFirstElement && relationContainsSecondElement) { |
| numberofInternalLinks++; |
| } |
| } |
| } |
| } |
| if (numberofInternalLinks > 0) { |
| return true; |
| } |
| } |
| return false; |
| |
| } |
| |
| @Override |
| public String generateMarkerMessage(IResourceDelta delta, String wrapperUri) { |
| return null; |
| } |
| } |