All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reprezen.genflow.common.graph.ResourceSorter Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright © 2013, 2016 Modelsolv, Inc.
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property
 * of ModelSolv, Inc. See the file license.html in the root directory of
 * this project for further information.
 *******************************************************************************/
package com.reprezen.genflow.common.graph;

import static com.reprezen.rapidml.util.RapidmlModelUtils.getZenModel;

import java.util.ArrayList;
import java.util.List;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.reprezen.rapidml.ReferenceLink;
import com.reprezen.rapidml.ResourceDefinition;
import com.reprezen.rapidml.ServiceDataResource;
import com.reprezen.rapidml.ZenModel;

/**
 * Topologically sorts resources to achieve the left-to-right direction of
 * reference links.
 * 
 * @author Tatiana Fesenko 
 * 
 */
public class ResourceSorter {

	private BiMap> resourceToGraph = HashBiMap
			.>create();

	private List> graph = new ArrayList<>();

	/**
	 * Topologically sorts resources to achieve the left-to-right direction of
	 * reference links.
	 * 
	 * @param service data resources
	 * @return a list of service data resources ordered to favor left-to-right
	 *         direction of reference links.
	 */
	public List sort(List resources) {
		DirectedGraph graph = buildResourcesGraph(resources);
		List> sorted = TopologicalSorter.splitAndSort(graph);
		List result = new ArrayList<>();
		BiMap, ServiceDataResource> graphNodeToResource = resourceToGraph.inverse();
		for (DirectedGraphNode node : sorted) {
			ServiceDataResource resource = graphNodeToResource.get(node);
			result.add(resource);
		}
		return result;
	}

	/**
	 * Builds a directed graph consisting of {@link DirectedGraphNode} from the
	 * provided service data resources. Resources are used as vertices, reference
	 * links are used as edges.
	 * 
	 * @param resources
	 * @return a directed graph
	 */
	protected DirectedGraph buildResourcesGraph(List resources) {
		resourceToGraph.clear();
		// build graph nodes first to preserve order
		for (ServiceDataResource next : resources) {
			createNode(next);
		}
		for (ServiceDataResource next : resources) {
			DirectedGraphNode graphNode = getOrCreateNode(next);
			ZenModel model = getZenModel(next);
			for (ReferenceLink link : next.getReferenceLinks()) {
				ResourceDefinition target = link.getTargetResource();
				if (target == null || model != getZenModel(target)) {
					continue;
				}
				DirectedGraphNode linkedResourceGraphNode = getOrCreateNode((ServiceDataResource) target);
				graphNode.addEdgeTo(linkedResourceGraphNode);
			}
		}
		return new DirectedGraph<>(graph);
	}

	private DirectedGraphNode getOrCreateNode(ServiceDataResource resource) {
		DirectedGraphNode graphNode = getNode(resource);
		if (graphNode != null) {
			return graphNode;
		}
		return createNode(resource);
	}

	private DirectedGraphNode getNode(ServiceDataResource resource) {
		DirectedGraphNode graphNode = resourceToGraph.get(resource);
		return graphNode;
	}

	private DirectedGraphNode createNode(ServiceDataResource resource) {
		DirectedGraphNode graphNode = new DirectedGraphNode(resource.getName());
		resourceToGraph.put(resource, graphNode);
		graph.add(graphNode);
		return graphNode;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy