blob: 94b36c04369c762d3f9653b086db99bdb4269078 [file] [log] [blame]
/*
*
* Copyright (c) 2011 - 2018 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Initial contribution:
* Loetz GmbH & Co. KG
*
*/
package org.eclipse.osbp.xtext.datainterchange.jvmmodel;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* The Class ManageJoins finds all paths of a directed graph.
*
* @param <T> the generic type
*/
public class ManageJoins<T> {
/** The graph. */
private final JoinGraph<T> graph;
/**
* Instantiates a new manage joins.
*
* @param graphFindAllPaths the graph find all paths
*/
public ManageJoins(JoinGraph<T> graphFindAllPaths) {
if (graphFindAllPaths == null) {
throw new NullPointerException("input graph must not be null.");
}
graph = graphFindAllPaths;
}
/**
* Gets the all paths to destination node.
*
* @param source the source
* @param destination the destination
* @return the all paths
*/
public List<List<T>> getAllPathsToDestination(T source, T destination) {
List<List<T>> paths = new ArrayList<>();
recursive(source, destination, paths, new LinkedHashSet<T>());
return paths;
}
/**
* Gets the all join names.
*
* @param source the source
* @param destination the destination
* @return all joins
*/
public List<List<String>> getAllJoinsToDestination(T source, T destination) {
List<List<T>> paths = getAllPathsToDestination(source, destination);
List<List<String>> joins = new ArrayList<>();
for(List<T> outer:paths) {
List<String> list = new ArrayList<>();
joins.add(list);
T previous = null;
for(T inner:outer) {
if(previous != null) {
list.add(graph.joinsFrom(previous).get(inner));
}
previous = inner;
}
}
return joins;
}
/**
* Gets the all join names.
*
* @param source the source
* @return all joins
*/
public List<List<String>> getAllJoins(T source) {
List<List<T>> paths = getAllPathsToDestination(source, null);
List<List<String>> joins = new ArrayList<>();
for(List<T> outer:paths) {
List<String> list = new ArrayList<>();
joins.add(list);
T previous = null;
for(T inner:outer) {
if(previous != null) {
list.add(graph.joinsFrom(previous).get(inner));
}
previous = inner;
}
}
return joins;
}
/**
* Gets the all paths.
*
* @param source the source
* @return the all paths until the end
*/
public List<List<T>> getAllPaths(T source) {
List<List<T>> paths = new ArrayList<>();
recursive(source, null, paths, new LinkedHashSet<T>());
return paths;
}
/**
* Recursive.
*
* @param current the current
* @param paths the paths
* @param path the path
*/
// cycles are ignored
private void recursive (T current, T destination, List<List<T>> paths, LinkedHashSet<T> path) {
path.add(current);
// cut path if destination is reached
if (destination != null && current == destination) {
paths.add(new ArrayList<T>(path));
path.remove(current);
return;
}
Set<T> joins = graph.joinsFrom(current).keySet();
boolean hadRecursion = false;
for (T t : joins) {
if (!path.contains(t)) {
recursive (t, destination, paths, path);
hadRecursion = true;
}
}
// prefer longest paths
if(destination == null && !hadRecursion) {
paths.add(new ArrayList<T>(path));
}
path.remove(current);
}
}