/** * Copyright (c) 2015 INRIA. * 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: * - Fawaz PARAISO */ package org.occiware.clouddesigner.occi.docker.connector.dockerjava.graph; import com.google.common.base.Objects; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Set; import org.occiware.clouddesigner.occi.docker.connector.dockerjava.graph.GraphNode; import org.occiware.clouddesigner.occi.docker.connector.dockerjava.graph.NodeValueListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") public class Graph<T extends Object> { private static Logger LOGGER = LoggerFactory.getLogger(Graph.class); /** * Organize the deployment order of the Nodes */ private List<GraphNode<T>> deploymentOrder = new ArrayList<GraphNode<T>>(); /** * These are basically the nodes of the graph */ private HashMap<T, GraphNode<T>> nodes = new HashMap<T, GraphNode<T>>(); /** * The callback interface used to notify of the fact that a node just got * the evaluation */ private NodeValueListener<T> listener; /** * It holds a list of the already evaluated nodes */ private List<GraphNode<T>> evaluatedNodes = new ArrayList<GraphNode<T>>(); /** * The main constructor that has one parameter representing the callback * mechanism used by this class to notify when a node gets the evaluation. * * @param listener * The callback interface implemented by the user classes */ public NodeValueListener<T> Graph(final NodeValueListener<T> listener) { return this.listener = listener; } /** * Allows adding of new dependicies to the graph. "evalFirstValue" needs to * be evaluated before "evalAfterValue" * * @param evalFirstValue * The parameter that needs to be evaluated first * @param evalAfterValue * The parameter that needs to be evaluated after */ public void addDependency(final T evalFirstValue, final T evalAfterValue) { GraphNode<T> firstNode = null; GraphNode<T> afterNode = null; boolean _containsKey = this.nodes.containsKey(evalFirstValue); if (_containsKey) { GraphNode<T> _get = this.nodes.get(evalFirstValue); firstNode = _get; } else { GraphNode<T> _createNode = this.createNode(evalFirstValue); firstNode = _createNode; this.nodes.put(evalFirstValue, firstNode); } boolean _containsKey_1 = this.nodes.containsKey(evalAfterValue); if (_containsKey_1) { GraphNode<T> _get_1 = this.nodes.get(evalAfterValue); afterNode = _get_1; } else { GraphNode<T> _createNode_1 = this.createNode(evalAfterValue); afterNode = _createNode_1; this.nodes.put(evalAfterValue, afterNode); } firstNode.addGoingOutNode(afterNode); afterNode.addComingInNode(firstNode); } /** * Creates a graph node of the <T> generic type * * @param value * The value that is hosted by the node * @return a generic GraphNode object */ private GraphNode<T> createNode(final T value) { GraphNode<T> node = new GraphNode<T>(); node.value = value; return node; } /** * Get the node that has not a parent */ public List<GraphNode<T>> getOrphanNodes() { List<GraphNode<T>> orphanNodes = null; Set<T> keys = this.nodes.keySet(); for (final T key : keys) { { GraphNode<T> node = this.nodes.get(key); if ((Objects.equal(node.getComingInNodes(), null) && Objects.equal(node.getComingInNodes(), null))) { boolean _equals = Objects.equal(orphanNodes, null); if (_equals) { ArrayList<GraphNode<T>> _arrayList = new ArrayList<GraphNode<T>>(); orphanNodes = _arrayList; } orphanNodes.add(node); } } } return orphanNodes; } public List<GraphNode<T>> getLeafNodes() { List<GraphNode<T>> leafNodes = null; Set<T> keys = this.nodes.keySet(); for (final T key : keys) { { GraphNode<T> node = this.nodes.get(key); List<GraphNode<T>> _goingOutNodes = node.getGoingOutNodes(); boolean _equals = Objects.equal(_goingOutNodes, null); if (_equals) { boolean _equals_1 = Objects.equal(leafNodes, null); if (_equals_1) { ArrayList<GraphNode<T>> _arrayList = new ArrayList<GraphNode<T>>(); leafNodes = _arrayList; } leafNodes.add(node); } } } return leafNodes; } public List<GraphNode<T>> deploymentOrder() { List<GraphNode<T>> currentNodes = this.getLeafNodes(); List<GraphNode<T>> orphnanNodes = this.getOrphanNodes(); for (final GraphNode<T> m : orphnanNodes) { Graph.LOGGER.info(("Orphans: " + m.value)); } List<GraphNode<T>> newleafNodes = new ArrayList<GraphNode<T>>(); while ((!currentNodes.isEmpty())) { { for (final GraphNode<T> g : currentNodes) { List<GraphNode<T>> _comingInNodes = g.getComingInNodes(); boolean _notEquals = (!Objects.equal(_comingInNodes, null)); if (_notEquals) { List<GraphNode<T>> realLeafs = g.getComingInNodes(); realLeafs.removeAll(orphnanNodes); ArrayList<GraphNode<T>> _arrayList = new ArrayList<GraphNode<T>>(realLeafs); newleafNodes.addAll(_arrayList); } } final List<GraphNode<T>> linkedGraphs = this.getLinkedGraphs(newleafNodes); ArrayList<GraphNode<T>> _arrayList_1 = new ArrayList<GraphNode<T>>(linkedGraphs); newleafNodes.addAll(_arrayList_1); for (final GraphNode<T> n : currentNodes) { boolean _contains = this.deploymentOrder.contains(n); boolean _not = (!_contains); if (_not) { this.deploymentOrder.add(n); } } ArrayList<GraphNode<T>> _arrayList_2 = new ArrayList<GraphNode<T>>(newleafNodes); currentNodes = _arrayList_2; ArrayList<GraphNode<T>> _arrayList_3 = new ArrayList<GraphNode<T>>(); newleafNodes = _arrayList_3; } } for (final GraphNode<T> n : orphnanNodes) { boolean _contains = this.deploymentOrder.contains(n); boolean _not = (!_contains); if (_not) { this.deploymentOrder.add(n); } } return this.deploymentOrder; } public synchronized List<GraphNode<T>> getLinkedGraphs(final List<GraphNode<T>> graphs) { List<GraphNode<T>> linkedGraphs = new ArrayList<GraphNode<T>>(); for (final GraphNode<T> firstVal : graphs) { for (final GraphNode<T> g : graphs) { List<GraphNode<T>> _comingInNodes = g.getComingInNodes(); boolean _contains = _comingInNodes.contains(firstVal); if (_contains) { linkedGraphs.add(firstVal); } } } graphs.removeAll(linkedGraphs); return linkedGraphs; } public boolean isAlreadyEvaluated(final GraphNode<T> node) { return this.evaluatedNodes.contains(node); } public boolean areAlreadyEvaluated(final List<GraphNode<T>> nodes) { return this.evaluatedNodes.containsAll(nodes); } }