CCM NG: Revised Import/Export system
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5698 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: ab15c9b980
pull/2/head
parent
9e97b9b187
commit
1e47bc97d8
|
|
@ -18,21 +18,57 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.imexport;
|
package org.libreccm.imexport;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This class implements topological sorting to determine the order in which
|
||||||
|
* entities are imported.
|
||||||
|
*
|
||||||
|
* The class is used by creating an instance with the parameterless constructor.
|
||||||
|
* To create the tree/graph call the null {@link #generateTree(java.util.List)}
|
||||||
|
* method. With the returned list of nodes call the
|
||||||
|
* {@link #orderImExporters(java.util.List)} method. The list returned by
|
||||||
|
* {@link #orderImExporters(java.util.List)} contains all
|
||||||
|
* {@link EntityImExporter} in the order.
|
||||||
|
*
|
||||||
|
* This class is <strong>not</strong> not part of the public API.
|
||||||
|
*
|
||||||
|
** More information about topological sorting:
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/Topological_sorting">https://en.wikipedia.org/wiki/Topological_sorting</a>
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
final class EntityImExporterTreeManager {
|
final class EntityImExporterTreeManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager
|
||||||
|
.getLogger(EntityImExporterTreeManager.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the tree with the provided list of {@link EntityImExporter}s.
|
||||||
|
*
|
||||||
|
* @param imExporters The available {@link EntityImExporter}s.
|
||||||
|
*
|
||||||
|
* @return An ordered list of the tree nodes.
|
||||||
|
*
|
||||||
|
* @throws DependencyException If something is wrong with the dependency
|
||||||
|
* tree. For example if a module on which
|
||||||
|
* another module depends is missing or if a
|
||||||
|
* cycle is detected in the dependency tree.
|
||||||
|
*/
|
||||||
public List<EntityImExporterTreeNode> generateTree(
|
public List<EntityImExporterTreeNode> generateTree(
|
||||||
final List<EntityImExporter<?>> imExporters)
|
final List<EntityImExporter<?>> imExporters)
|
||||||
throws DependencyException {
|
throws DependencyException {
|
||||||
|
|
||||||
|
LOGGER.info("Starting to generate dependency tree...");
|
||||||
|
|
||||||
|
//Create the tree nodes. A HashMap is used to avoid duplicates and
|
||||||
|
//the lookup the nodes based on their name.
|
||||||
final Map<String, EntityImExporterTreeNode> nodes = imExporters
|
final Map<String, EntityImExporterTreeNode> nodes = imExporters
|
||||||
.stream()
|
.stream()
|
||||||
.map(EntityImExporterTreeNode::new)
|
.map(EntityImExporterTreeNode::new)
|
||||||
|
|
@ -46,32 +82,139 @@ final class EntityImExporterTreeManager {
|
||||||
.getName(),
|
.getName(),
|
||||||
node -> node));
|
node -> node));
|
||||||
|
|
||||||
|
//Add the dependency relations to the nodes
|
||||||
for (final EntityImExporter<?> imExporter : imExporters) {
|
for (final EntityImExporter<?> imExporter : imExporters) {
|
||||||
addDependencyRelations(imExporter, nodes);
|
addDependencyRelations(imExporter, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Generate the node list
|
||||||
final List<EntityImExporterTreeNode> nodeList = new ArrayList<>();
|
final List<EntityImExporterTreeNode> nodeList = new ArrayList<>();
|
||||||
for (final Map.Entry<String, EntityImExporterTreeNode> entry
|
for (final Map.Entry<String, EntityImExporterTreeNode> entry
|
||||||
: nodes.entrySet()) {
|
: nodes.entrySet()) {
|
||||||
|
|
||||||
nodeList.add(entry.getValue());
|
nodeList.add(entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Dependency tree generated.");
|
||||||
|
|
||||||
return nodeList;
|
return nodeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an ordered list of the tree nodes which can be used to process
|
||||||
|
* the imports in the correct order.
|
||||||
|
*
|
||||||
|
* In this method the topological sorting happens.
|
||||||
|
*
|
||||||
|
* @param nodes The nodes of the dependency tree.
|
||||||
|
*
|
||||||
|
* @return A ordered list of the tree nodes.
|
||||||
|
*
|
||||||
|
* @throws DependencyException If something is wrong with dependency graph.
|
||||||
|
*/
|
||||||
|
public List<EntityImExporterTreeNode> orderImExporters(
|
||||||
|
final List<EntityImExporterTreeNode> nodes)
|
||||||
|
throws DependencyException {
|
||||||
|
|
||||||
|
LOGGER.info("Creating an ordered list from the dependency tree...");
|
||||||
|
|
||||||
|
//List for the ordered and resolved nodes.
|
||||||
|
final List<EntityImExporterTreeNode> orderedNodes = new ArrayList<>();
|
||||||
|
final List<EntityImExporterTreeNode> resolvedNodes = new ArrayList<>();
|
||||||
|
|
||||||
|
LOGGER.info("Looking for EntityImExporters which do not depend on any "
|
||||||
|
+ "other EntityImExporters.");
|
||||||
|
//Find all nodes which do not depend on any other nodes. These
|
||||||
|
//nodes are used as starting point for the sorting.
|
||||||
|
for (final EntityImExporterTreeNode node : nodes) {
|
||||||
|
|
||||||
|
if (node.getDependsOn().isEmpty()) {
|
||||||
|
LOGGER.info(
|
||||||
|
"\tNode \"{}\" does not depend on any other module",
|
||||||
|
node.getEntityImExporter().getClass().getName());
|
||||||
|
resolvedNodes.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Ordering remaining nodes...");
|
||||||
|
while (!resolvedNodes.isEmpty()) {
|
||||||
|
|
||||||
|
//Remove the first node from the resolved nodes list
|
||||||
|
final EntityImExporterTreeNode current = resolvedNodes.remove(0);
|
||||||
|
LOGGER.info("\tProcessing node for EntityImExporter \"{}\"...",
|
||||||
|
current.getEntityImExporter().getClass().getName());
|
||||||
|
|
||||||
|
//Add the node to the ordered modules list.
|
||||||
|
orderedNodes.add(current);
|
||||||
|
|
||||||
|
//Remove the edges to the current node.
|
||||||
|
for (final EntityImExporterTreeNode dependent
|
||||||
|
: current.getDependentImExporters()) {
|
||||||
|
|
||||||
|
dependent.removeDependsOn(current);
|
||||||
|
|
||||||
|
//If the dependent node has no more dependsOn relations put
|
||||||
|
//the node into the resolved modules list.
|
||||||
|
if (dependent.getDependsOn().isEmpty()) {
|
||||||
|
resolvedNodes.add(dependent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if all nodes have been ordered. If not the tree has at least on
|
||||||
|
//on cycle and can't be processed.
|
||||||
|
if (orderedNodes.size() == nodes.size()) {
|
||||||
|
|
||||||
|
LOGGER.info("EntityImExporter dependency graph processed "
|
||||||
|
+ "successfully. EntityImExporters in order:");
|
||||||
|
for (final EntityImExporterTreeNode node : orderedNodes) {
|
||||||
|
LOGGER.info("\t{}",
|
||||||
|
node.getEntityImExporter().getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderedNodes;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
LOGGER.fatal("The EntityImExporter dependency graph has at least "
|
||||||
|
+ "one cycle.");
|
||||||
|
throw new DependencyException("The EntityImExporter dependency "
|
||||||
|
+ "graph has at least one cycle.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for adding the dependency relations for an
|
||||||
|
* {@link EntityImExporter} to the nodes.
|
||||||
|
*
|
||||||
|
* @param imExporter The current {@link EntityImExporter}.
|
||||||
|
* @param nodes The map of nodes.
|
||||||
|
*
|
||||||
|
* @throws DependencyException If something goes wrong.
|
||||||
|
*/
|
||||||
private void addDependencyRelations(
|
private void addDependencyRelations(
|
||||||
final EntityImExporter<?> imExporter,
|
final EntityImExporter<?> imExporter,
|
||||||
final Map<String, EntityImExporterTreeNode> nodes)
|
final Map<String, EntityImExporterTreeNode> nodes)
|
||||||
throws DependencyException {
|
throws DependencyException {
|
||||||
|
|
||||||
|
//Get the dependencies of the current EntityImExporter
|
||||||
final Processes processes = imExporter
|
final Processes processes = imExporter
|
||||||
.getClass()
|
.getClass()
|
||||||
.getAnnotation(Processes.class);
|
.getAnnotation(Processes.class);
|
||||||
final String className = imExporter.getClass().getName();
|
|
||||||
|
|
||||||
|
//Get the name of the module from the module info.
|
||||||
|
final String className = imExporter.getClass().getName();
|
||||||
|
LOGGER
|
||||||
|
.info("Adding dependency relations for EntityImExporter \"{}\"...",
|
||||||
|
className);
|
||||||
|
|
||||||
|
//Check if the nodes map has an entry for the EntityImExporter.
|
||||||
if (!nodes.containsKey(className)) {
|
if (!nodes.containsKey(className)) {
|
||||||
|
|
||||||
|
LOGGER.fatal("EntityImExporter nodes map does contain an entry for "
|
||||||
|
+ "\"{}\". That should not happen.",
|
||||||
|
className);
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"The nodes map does not contain a node for "
|
"The nodes map does not contain a node for "
|
||||||
+ "EntityImExporter \"%s\"."
|
+ "EntityImExporter \"%s\"."
|
||||||
|
|
@ -79,34 +222,59 @@ final class EntityImExporterTreeManager {
|
||||||
className));
|
className));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Get the node from the map
|
||||||
final EntityImExporterTreeNode node = nodes.get(className);
|
final EntityImExporterTreeNode node = nodes.get(className);
|
||||||
|
LOGGER
|
||||||
|
.info("Processing required modules for EntityImExporter \"{}\"...",
|
||||||
|
className);
|
||||||
|
//Process the EntityImExporter required by the current module and add
|
||||||
|
//the dependency relations.
|
||||||
for (final Class<? extends Exportable> clazz : processes.dependsOn()) {
|
for (final Class<? extends Exportable> clazz : processes.dependsOn()) {
|
||||||
|
|
||||||
addDependencyRelation(nodes, node, clazz);
|
addDependencyRelation(nodes, node, clazz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for adding a single dependency relation.
|
||||||
|
*
|
||||||
|
* @param nodes The map of tree nodes.
|
||||||
|
* @param node The node to which the dependency relations are
|
||||||
|
* added.
|
||||||
|
* @param requiredClass The type which is required by the current
|
||||||
|
* module/node.
|
||||||
|
*
|
||||||
|
* @throws DependencyException
|
||||||
|
*/
|
||||||
private void addDependencyRelation(
|
private void addDependencyRelation(
|
||||||
final Map<String, EntityImExporterTreeNode> nodes,
|
final Map<String, EntityImExporterTreeNode> nodes,
|
||||||
EntityImExporterTreeNode node,
|
EntityImExporterTreeNode node,
|
||||||
Class<? extends Exportable> clazz)
|
Class<? extends Exportable> requiredClass)
|
||||||
throws DependencyException {
|
throws DependencyException {
|
||||||
|
|
||||||
if (!nodes.containsKey(clazz.getName())) {
|
LOGGER.info("\tEntityImExporter for \"{}\" requires "
|
||||||
|
+ "EntityImExporter for \"{}\".",
|
||||||
|
node.getEntityImExporter().getClass().getName(),
|
||||||
|
requiredClass.getName());
|
||||||
|
|
||||||
|
//Check if the nodes list has an entry for the required module.
|
||||||
|
if (!nodes.containsKey(requiredClass.getName())) {
|
||||||
|
|
||||||
|
LOGGER.fatal("Required EntityImExporter for \"{}\" no found.",
|
||||||
|
requiredClass.getName());
|
||||||
throw new DependencyException(String.format(
|
throw new DependencyException(String.format(
|
||||||
"EntityImExporter for type \"%s\" depends on type \"%s\" "
|
"EntityImExporter for type \"%s\" depends on type \"%s\" "
|
||||||
+ "but no EntityImExporter for type \"%s\" is available.",
|
+ "but no EntityImExporter for type \"%s\" is available.",
|
||||||
node.getEntityImExporter().getClass().getAnnotation(
|
node.getEntityImExporter().getClass().getAnnotation(
|
||||||
Processes.class).type().getName(),
|
Processes.class).type().getName(),
|
||||||
clazz.getName(),
|
requiredClass.getName(),
|
||||||
clazz.getName()));
|
requiredClass.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final EntityImExporterTreeNode dependencyNode = nodes
|
final EntityImExporterTreeNode dependencyNode = nodes
|
||||||
.get(clazz.getName());
|
.get(requiredClass.getName());
|
||||||
|
|
||||||
|
//Create the dependencies relations.
|
||||||
node.addDependsOn(dependencyNode);
|
node.addDependsOn(dependencyNode);
|
||||||
dependencyNode.addDependentImExporter(node);
|
dependencyNode.addDependentImExporter(node);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,26 +102,30 @@ public class ImportExport {
|
||||||
importName));
|
importName));
|
||||||
}
|
}
|
||||||
} catch (FileAccessException
|
} catch (FileAccessException
|
||||||
| FileDoesNotExistException
|
| FileDoesNotExistException
|
||||||
| InsufficientPermissionsException ex) {
|
| InsufficientPermissionsException ex) {
|
||||||
|
|
||||||
throw new UnexpectedErrorException(ex);
|
throw new UnexpectedErrorException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String manifestPath = String.format("%s/ccm-export.json",
|
final List<EntityImExporter<?>> imExportersList = new ArrayList<>();
|
||||||
importsPath);
|
imExporters.forEach(imExporter -> imExportersList.add(imExporter));
|
||||||
try (final InputStream manifestInputStream = ccmFiles
|
|
||||||
.createInputStream(importsPath)) {
|
|
||||||
|
|
||||||
final JsonReader manifestReader = Json
|
try {
|
||||||
.createReader(manifestInputStream);
|
final EntityImExporterTreeManager treeManager
|
||||||
final JsonObject manifest = manifestReader.readObject();
|
= new EntityImExporterTreeManager();
|
||||||
|
final List<EntityImExporterTreeNode> tree = treeManager
|
||||||
|
.generateTree(
|
||||||
|
imExportersList);
|
||||||
|
final List<EntityImExporterTreeNode> orderedNodes = treeManager
|
||||||
|
.orderImExporters(tree);
|
||||||
|
|
||||||
} catch (IOException
|
final ImportManifest manifest = createImportManifest(importName);
|
||||||
| FileDoesNotExistException
|
|
||||||
| FileAccessException
|
|
||||||
| InsufficientPermissionsException ex) {
|
|
||||||
|
|
||||||
|
//ToDo
|
||||||
|
|
||||||
|
} catch (DependencyException ex) {
|
||||||
|
throw new UnexpectedErrorException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
@ -134,8 +138,8 @@ public class ImportExport {
|
||||||
try {
|
try {
|
||||||
importArchivePaths = ccmFiles.listFiles("imports");
|
importArchivePaths = ccmFiles.listFiles("imports");
|
||||||
} catch (FileAccessException
|
} catch (FileAccessException
|
||||||
| FileDoesNotExistException
|
| FileDoesNotExistException
|
||||||
| InsufficientPermissionsException ex) {
|
| InsufficientPermissionsException ex) {
|
||||||
|
|
||||||
throw new UnexpectedErrorException(ex);
|
throw new UnexpectedErrorException(ex);
|
||||||
}
|
}
|
||||||
|
|
@ -168,52 +172,53 @@ public class ImportExport {
|
||||||
final String manifestPath = String.format("imports/%s/ccm-export.json",
|
final String manifestPath = String.format("imports/%s/ccm-export.json",
|
||||||
path);
|
path);
|
||||||
|
|
||||||
final InputStream inputStream;
|
try (final InputStream inputStream = ccmFiles
|
||||||
try {
|
.createInputStream(manifestPath)) {
|
||||||
inputStream = ccmFiles.createInputStream(manifestPath);
|
|
||||||
} catch (FileAccessException
|
final JsonReader reader = Json.createReader(inputStream);
|
||||||
| FileDoesNotExistException
|
final JsonObject manifestJson = reader.readObject();
|
||||||
| InsufficientPermissionsException ex) {
|
|
||||||
|
if (!manifestJson.containsKey("created")) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The manifest file \"%s\" is malformed. "
|
||||||
|
+ "Key \"created\" is missing.",
|
||||||
|
manifestPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!manifestJson.containsKey("onServer")) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The manifest file \"%s\" is malformed. "
|
||||||
|
+ "Key \"onServer\" is missing.",
|
||||||
|
manifestPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!manifestJson.containsKey("types")) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The manifest file \"%s\" is malformed. "
|
||||||
|
+ "Key \"types\" is missing.",
|
||||||
|
manifestPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalDateTime created = LocalDateTime
|
||||||
|
.parse(manifestJson.getString("created"));
|
||||||
|
final String onServer = manifestJson.getString("onServer");
|
||||||
|
final List<String> types = manifestJson.getJsonArray("types")
|
||||||
|
.stream()
|
||||||
|
.map(value -> value.toString())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return new ImportManifest(
|
||||||
|
Date.from(created.atZone(ZoneId.of("UTC")).toInstant()),
|
||||||
|
onServer,
|
||||||
|
types);
|
||||||
|
} catch (IOException
|
||||||
|
| FileAccessException
|
||||||
|
| FileDoesNotExistException
|
||||||
|
| InsufficientPermissionsException ex) {
|
||||||
|
|
||||||
throw new UnexpectedErrorException(ex);
|
throw new UnexpectedErrorException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
final JsonReader reader = Json.createReader(inputStream);
|
|
||||||
final JsonObject manifestJson = reader.readObject();
|
|
||||||
|
|
||||||
if (!manifestJson.containsKey("created")) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"The manifest file \"%s\" is malformed. "
|
|
||||||
+ "Key \"created\" is missing.",
|
|
||||||
manifestPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manifestJson.containsKey("onServer")) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"The manifest file \"%s\" is malformed. "
|
|
||||||
+ "Key \"onServer\" is missing.",
|
|
||||||
manifestPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manifestJson.containsKey("types")) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"The manifest file \"%s\" is malformed. "
|
|
||||||
+ "Key \"types\" is missing.",
|
|
||||||
manifestPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
final LocalDateTime created = LocalDateTime
|
|
||||||
.parse(manifestJson.getString("created"));
|
|
||||||
final String onServer = manifestJson.getString("onServer");
|
|
||||||
final List<String> types = manifestJson.getJsonArray("types")
|
|
||||||
.stream()
|
|
||||||
.map(value -> value.toString())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return new ImportManifest(
|
|
||||||
Date.from(created.atZone(ZoneId.of("UTC")).toInstant()),
|
|
||||||
onServer,
|
|
||||||
types);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import java.util.Map;
|
||||||
* The class is used by creating an instance with the parameterless constructor.
|
* The class is used by creating an instance with the parameterless constructor.
|
||||||
* To create the tree/graph call the
|
* To create the tree/graph call the
|
||||||
* {@link #generateTree(javax.enterprise.inject.Instance)} method. With the
|
* {@link #generateTree(javax.enterprise.inject.Instance)} method. With the
|
||||||
* returned list of nodes call the the {@link #orderModules(java.util.List)}
|
* returned list of nodes call the {@link #orderModules(java.util.List)}
|
||||||
* method. The list returned by {@link #orderModules(java.util.List)} contains
|
* method. The list returned by {@link #orderModules(java.util.List)} contains
|
||||||
* all modules in order.
|
* all modules in order.
|
||||||
*
|
*
|
||||||
|
|
@ -54,11 +54,13 @@ final class DependencyTreeManager {
|
||||||
* Initialises the tree with the provided list of modules.
|
* Initialises the tree with the provided list of modules.
|
||||||
*
|
*
|
||||||
* @param modules The module for which a dependency tree is generated.
|
* @param modules The module for which a dependency tree is generated.
|
||||||
|
*
|
||||||
* @return An ordered list of tree nodes.
|
* @return An ordered list of tree nodes.
|
||||||
*
|
*
|
||||||
* @throws DependencyException If something is wrong with the dependency
|
* @throws DependencyException If something is wrong with the dependency
|
||||||
* tree. For example if a module on which another module depends is missing
|
* tree. For example if a module on which
|
||||||
* or if a cycle is detected in the dependency tree.
|
* another module depends is missing or if a
|
||||||
|
* cycle is detected in the dependency tree.
|
||||||
*/
|
*/
|
||||||
public List<TreeNode> generateTree(final Iterable<CcmModule> modules)
|
public List<TreeNode> generateTree(final Iterable<CcmModule> modules)
|
||||||
throws DependencyException {
|
throws DependencyException {
|
||||||
|
|
@ -95,9 +97,11 @@ final class DependencyTreeManager {
|
||||||
* In this method the topological sorting happens.
|
* In this method the topological sorting happens.
|
||||||
*
|
*
|
||||||
* @param dependencyTree The list of tree nodes of the dependency tree.
|
* @param dependencyTree The list of tree nodes of the dependency tree.
|
||||||
|
*
|
||||||
* @return A ordered list of the tree nodes.
|
* @return A ordered list of the tree nodes.
|
||||||
|
*
|
||||||
* @throws DependencyException If something is wrong with the dependency
|
* @throws DependencyException If something is wrong with the dependency
|
||||||
* tree.
|
* tree.
|
||||||
*/
|
*/
|
||||||
public List<TreeNode> orderModules(final List<TreeNode> dependencyTree)
|
public List<TreeNode> orderModules(final List<TreeNode> dependencyTree)
|
||||||
throws DependencyException {
|
throws DependencyException {
|
||||||
|
|
@ -135,7 +139,7 @@ final class DependencyTreeManager {
|
||||||
for (final TreeNode dependent : current.getDependentModules()) {
|
for (final TreeNode dependent : current.getDependentModules()) {
|
||||||
dependent.removeDependsOn(current);
|
dependent.removeDependsOn(current);
|
||||||
|
|
||||||
//If the dependent node has node more dependsOn relations put
|
//If the dependent node has no more dependsOn relations put
|
||||||
//the node into the resolved modules list.
|
//the node into the resolved modules list.
|
||||||
if (dependent.getDependsOn().isEmpty()) {
|
if (dependent.getDependsOn().isEmpty()) {
|
||||||
resolvedModules.add(dependent);
|
resolvedModules.add(dependent);
|
||||||
|
|
@ -176,9 +180,9 @@ final class DependencyTreeManager {
|
||||||
* nodes.
|
* nodes.
|
||||||
*
|
*
|
||||||
* @param module The module.
|
* @param module The module.
|
||||||
* @param nodes The map of nodes.
|
* @param nodes The map of nodes.
|
||||||
*
|
*
|
||||||
* @throws DependencyException If something goes wrong.
|
* @throws DependencyException If something goes wrong.
|
||||||
*/
|
*/
|
||||||
private void addDependencyRelations(final CcmModule module,
|
private void addDependencyRelations(final CcmModule module,
|
||||||
final Map<String, TreeNode> nodes)
|
final Map<String, TreeNode> nodes)
|
||||||
|
|
@ -221,9 +225,11 @@ final class DependencyTreeManager {
|
||||||
/**
|
/**
|
||||||
* Helper method for adding a single dependency relation.
|
* Helper method for adding a single dependency relation.
|
||||||
*
|
*
|
||||||
* @param nodes The map of tree nodes.
|
* @param nodes The map of tree nodes.
|
||||||
* @param node The node to which the dependency relations are added.
|
* @param node The node to which the dependency relations are
|
||||||
|
* added.
|
||||||
* @param requiredModule The module required by the current module/node.
|
* @param requiredModule The module required by the current module/node.
|
||||||
|
*
|
||||||
* @throws DependencyException
|
* @throws DependencyException
|
||||||
*/
|
*/
|
||||||
private void addDependencyRelation(final Map<String, TreeNode> nodes,
|
private void addDependencyRelation(final Map<String, TreeNode> nodes,
|
||||||
|
|
@ -301,11 +307,11 @@ final class DependencyTreeManager {
|
||||||
|
|
||||||
if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
||||||
&& (maxRequiredVersion == null || maxRequiredVersion.
|
&& (maxRequiredVersion == null || maxRequiredVersion.
|
||||||
isEmpty())) {
|
isEmpty())) {
|
||||||
return true;
|
return true;
|
||||||
} else if ((minRequiredVersion != null && !minRequiredVersion.isEmpty())
|
} else if ((minRequiredVersion != null && !minRequiredVersion.isEmpty())
|
||||||
&& (maxRequiredVersion == null || maxRequiredVersion
|
&& (maxRequiredVersion == null || maxRequiredVersion
|
||||||
.isEmpty())) {
|
.isEmpty())) {
|
||||||
final ComparableVersion minVersion = new ComparableVersion(
|
final ComparableVersion minVersion = new ComparableVersion(
|
||||||
minRequiredVersion);
|
minRequiredVersion);
|
||||||
final ComparableVersion version = new ComparableVersion(
|
final ComparableVersion version = new ComparableVersion(
|
||||||
|
|
@ -314,7 +320,7 @@ final class DependencyTreeManager {
|
||||||
return minVersion.compareTo(version) <= 0;
|
return minVersion.compareTo(version) <= 0;
|
||||||
} else if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
} else if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
||||||
&& (maxRequiredVersion != null && !maxRequiredVersion
|
&& (maxRequiredVersion != null && !maxRequiredVersion
|
||||||
.isEmpty())) {
|
.isEmpty())) {
|
||||||
final ComparableVersion maxVersion = new ComparableVersion(
|
final ComparableVersion maxVersion = new ComparableVersion(
|
||||||
maxRequiredVersion);
|
maxRequiredVersion);
|
||||||
final ComparableVersion version = new ComparableVersion(
|
final ComparableVersion version = new ComparableVersion(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue