| /******************************************************************************* |
| * Copyright (c) 2016, 2019 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 v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation |
| * Chalmers | University of Gothenburg - additional features, updated API |
| *******************************************************************************/ |
| package org.eclipse.capra.core.adapters; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.capra.core.handlers.IArtifactHandler; |
| import org.eclipse.capra.core.helpers.ArtifactHelper; |
| import org.eclipse.capra.core.helpers.ExtensionPointHelper; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| |
| /** |
| * Implements standard functionality for the methods defined in the |
| * {@link TraceMetaModelAdapter}. |
| */ |
| public abstract class AbstractMetaModelAdapter implements TraceMetaModelAdapter { |
| |
| private List<Connection> getInternalElementsTransitive(EObject element, EObject traceModel, |
| List<Object> accumulator, List<String> selectedRelationshipTypes, int currentDepth, int maximumDepth, |
| List<Connection> existingTraces) { |
| List<Connection> directElements = getInternalElements(element, traceModel, selectedRelationshipTypes, true, |
| maximumDepth, existingTraces); |
| List<Connection> allElements = new ArrayList<>(); |
| int currDepth = currentDepth + 1; |
| for (Connection connection : directElements) { |
| if (!accumulator.contains(connection.getTlink())) { |
| allElements.add(connection); |
| accumulator.add(connection.getTlink()); |
| for (EObject e : connection.getTargets()) { |
| if (maximumDepth == 0 || currDepth < (maximumDepth + 2)) { |
| allElements.addAll(getInternalElementsTransitive(e, traceModel, accumulator, |
| selectedRelationshipTypes, currDepth, maximumDepth, existingTraces)); |
| } |
| } |
| } |
| } |
| |
| return allElements; |
| } |
| |
| /** |
| * Used to get internal links connected to a selected element. |
| * |
| * @param element |
| * the selected element |
| * @param traceModel |
| * the current trace model |
| * @param selectedRelationshipTypes |
| * the selected relationship types from the filter, if the user |
| * has selected any |
| * @param maximumDepth |
| * The maximum depth the transitivity should go. 0 means show all |
| * the links |
| * @param existingTraces |
| * The trace links that have been created manually by the user, |
| * these are obtained from the trace model |
| */ |
| public List<Connection> getInternalElementsTransitive(EObject element, EObject traceModel, |
| List<String> selectedRelationshipTypes, int maximumDepth, List<Connection> existingTraces) { |
| List<Object> accumulator = new ArrayList<>(); |
| return getInternalElementsTransitive(element, traceModel, accumulator, selectedRelationshipTypes, 0, |
| maximumDepth, existingTraces); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<Connection> getInternalElements(EObject element, EObject traceModel, |
| List<String> selectedRelationshipTypes, boolean traceLinksTransitive, int transitivityDepth, |
| List<Connection> existingTraces) { |
| List<Connection> allElements = new ArrayList<>(); |
| List<Connection> directElements; |
| if (traceLinksTransitive) { |
| directElements = getTransitivelyConnectedElements(element, traceModel, selectedRelationshipTypes, |
| transitivityDepth); |
| } else { |
| directElements = getConnectedElements(element, traceModel, selectedRelationshipTypes); |
| } |
| List<Integer> hashCodes = new ArrayList<>(); |
| |
| for (Connection conn : existingTraces) { |
| int connectionHash = conn.getOrigin().hashCode() + conn.getTlink().hashCode(); |
| for (EObject targ : conn.getTargets()) { |
| connectionHash += targ.hashCode(); |
| } |
| hashCodes.add(connectionHash); |
| } |
| |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get(); |
| EObject artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet); |
| ArtifactHelper artifactHelper = new ArtifactHelper(artifactModel); |
| |
| ArtifactMetaModelAdapter artifactMetaModelAdapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter() |
| .get(); |
| for (Connection conn : directElements) { |
| int connectionHash = conn.getOrigin().hashCode() + conn.getTlink().hashCode(); |
| for (EObject targ : conn.getTargets()) { |
| connectionHash += targ.hashCode(); |
| } |
| if (!hashCodes.contains(connectionHash)) { |
| allElements.add(conn); |
| } |
| for (EObject o : conn.getTargets()) { |
| // assume that the object is an artifact wrapper and get its |
| // handler |
| IArtifactHandler<Object> handler = (IArtifactHandler<Object>) artifactMetaModelAdapter |
| .getArtifactHandlerInstance(o); |
| if (handler == null) { |
| // object is not an artifact handler |
| handler = (IArtifactHandler<Object>) artifactHelper.getHandler(o).orElse(null); |
| } |
| if (handler != null) { |
| allElements.addAll(handler.addInternalLinks(o, selectedRelationshipTypes)); |
| } |
| |
| } |
| } |
| |
| if (element.getClass().getPackage().toString().contains("org.eclipse.eatop")) { |
| IArtifactHandler<Object> handler = (IArtifactHandler<Object>) artifactHelper.getHandler(element) |
| .orElse(null); |
| allElements.addAll(handler.addInternalLinks(element, selectedRelationshipTypes)); |
| } |
| return allElements; |
| } |
| |
| @Override |
| public boolean isThereAnInternalTraceBetween(EObject first, EObject second) { |
| |
| ResourceSet resourceSet = new ResourceSetImpl(); |
| TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get(); |
| EObject artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet); |
| ArtifactHelper artifactHelper = new ArtifactHelper(artifactModel); |
| IArtifactHandler<?> handlerFirstElement = artifactHelper.getHandler(first).orElse(null); |
| IArtifactHandler<?> handlerSecondElement = artifactHelper.getHandler(second).orElse(null); |
| |
| return handlerFirstElement.isThereAnInternalTraceBetween(first, second) |
| || handlerSecondElement.isThereAnInternalTraceBetween(first, second); |
| } |
| } |