[Lutinutil-commits] r1474 - in lutinpluginutil/trunk: . src/main/java/org/codelutin/util
Author: tchemit Date: 2009-05-08 13:59:08 +0000 (Fri, 08 May 2009) New Revision: 1474 Added: lutinpluginutil/trunk/src/main/java/org/codelutin/util/DependencyUtil.java Modified: lutinpluginutil/trunk/changelog.txt lutinpluginutil/trunk/pom.xml Log: introduce DependencyUtil class to sort artifacts in dependency order Modified: lutinpluginutil/trunk/changelog.txt =================================================================== --- lutinpluginutil/trunk/changelog.txt 2009-05-06 12:03:30 UTC (rev 1473) +++ lutinpluginutil/trunk/changelog.txt 2009-05-08 13:59:08 UTC (rev 1474) @@ -1,3 +1,6 @@ +0.5 chemit + * 20090508 [chemit] - introduce DependencyUtil class to sort artifacts in dependency order + 0.4 chemit 20090420 * 20090417 [chemit] - use lutinproject 3.5.3 - use doxia-module-jrst instead on maven-jrst-plugin Modified: lutinpluginutil/trunk/pom.xml =================================================================== --- lutinpluginutil/trunk/pom.xml 2009-05-06 12:03:30 UTC (rev 1473) +++ lutinpluginutil/trunk/pom.xml 2009-05-08 13:59:08 UTC (rev 1474) @@ -33,6 +33,13 @@ <scope>provided</scope> </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-dependency-tree</artifactId> + <version>1.2</version> + <scope>provided</scope> + </dependency> + </dependencies> Added: lutinpluginutil/trunk/src/main/java/org/codelutin/util/DependencyUtil.java =================================================================== --- lutinpluginutil/trunk/src/main/java/org/codelutin/util/DependencyUtil.java (rev 0) +++ lutinpluginutil/trunk/src/main/java/org/codelutin/util/DependencyUtil.java 2009-05-08 13:59:08 UTC (rev 1474) @@ -0,0 +1,216 @@ +package org.codelutin.util; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.dependency.tree.DependencyNode; + +/** + * Une classe de methodes utiles sur les dependences entre artifacts. + * + * @author chemit + * @since 0.5 + */ +public class DependencyUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(DependencyUtil.class); + + public static void sortArtifacts(DependencyNode rootNode, List<Artifact> i18nArtifacts, boolean verbose) { + + if (i18nArtifacts.size() == 1) { + return; + } + + Map<String, ArtifactDependencyEntry> dico = new java.util.HashMap<String, ArtifactDependencyEntry>(i18nArtifacts.size()); + + for (Artifact a : i18nArtifacts) { + ArtifactDependencyEntry entry = new ArtifactDependencyEntry(a); + dico.put(entry.artifactKey, entry); + } + + // contient les artifacts non encore fixes + Set<String> universe = new java.util.HashSet<String>(dico.keySet()); + + // recupere les noeuds pour chaque artifact en une seule passe + + setNodes(rootNode, dico, universe, verbose); + + // contient les artifacts resouds dans l'ordre de dependances + List<String> parsed = new java.util.ArrayList<String>(); + + // premiere passe pour recuperer l'ensemble des dependances + for (ArtifactDependencyEntry entry : dico.values()) { + List<String> dependencies = getDependencies(rootNode, entry, universe, verbose); + entry.depIds = dependencies; + } + + int level = 0; + do { + if (verbose) { + log.info("run into level " + (level++)); + } + // on parcourt les artifacts pour detecter les nouveau artifacts fixes + List<String> levelFixed = new java.util.ArrayList<String>(); + + for (String key : universe) { + ArtifactDependencyEntry entry = dico.get(key); + // cet artifact n'est pas encore fixe + if (entry.depIds.isEmpty()) { + // plus de dependance pour cet artifact + levelFixed.add(key); + if (verbose) { + log.info("fixed artifact " + key); + } + } + } + + if (levelFixed.isEmpty()) { + // aucune modification, c'est un cycle! + throw new IllegalStateException("cycle detecte ! entre les artifacts " + universe); + } + + // on met a jour les listes + universe.removeAll(levelFixed); + parsed.addAll(levelFixed); + + if (universe.isEmpty()) { + // tout a ete resolu, plus rien a faire + break; + } + + // on supprime les dependances fixees a ce niveau + for (String key : universe) { + ArtifactDependencyEntry entry = dico.get(key); + entry.depIds.removeAll(levelFixed); + } + + levelFixed.clear(); + } while (true); + + i18nArtifacts.clear(); + for (String key : parsed) { + i18nArtifacts.add(dico.get(key).artifact); + } + + } + + protected static String getArtifactId(Artifact artifact) { + return artifact.getArtifactId() + ":" + artifact.getGroupId(); + } + + protected static List<String> getDependencies(DependencyNode rootNode, ArtifactDependencyEntry entry, Set<String> universe, boolean verbose) { + + List<String> order = new java.util.ArrayList<String>(); + Set<String> exclude = new java.util.HashSet<String>(); + + if (verbose) { + log.info("start [" + entry.artifactKey + "]"); + } + DependencyNode node = entry.node; + + getDependencies(rootNode, node, entry.artifactKey, universe, verbose, order, exclude); + + return order; + } + + private static void getDependencies(DependencyNode rootNode, DependencyNode node, String artifactKey, Set<String> universe, boolean verbose, List<String> order, Set<String> exclude) { + + for (Iterator<?> itr = node.preorderIterator(); itr.hasNext();) { + DependencyNode d = (DependencyNode) itr.next(); + Artifact artifact = d.getArtifact(); + String key = getArtifactId(artifact); + if (artifactKey.equals(key)) { + // artifact du noeud en parametre, rien a faire + continue; + } + if (order.contains(key) || exclude.contains(key)) { + // artifact deja rencontree + continue; + } + + if (d.getState() != DependencyNode.INCLUDED) { + // on doit recuperer le noeud complete + if (log.isDebugEnabled()) { + log.debug("!!! doit recuperer le noeud complet pour " + d.getArtifact()); + } + DependencyNode node1 = getNode(rootNode, key, verbose); + getDependencies(rootNode, node1, artifactKey, universe, verbose, order, exclude); + } + + if (log.isDebugEnabled()) { + log.debug("[" + artifactKey + "] ??????? [" + key + "]"); + } + + if (universe.contains(key)) { + // artifact a retenir + if (verbose) { + log.info(" << [" + d.getArtifact() + "]"); + } + order.add(key); + continue; + } + + // cet artifact peut etre marque comme a ne plus etre scanne + exclude.add(key); + } + + } + + protected static void setNodes(DependencyNode rootNode, Map<String, ArtifactDependencyEntry> dico, Set<String> universe, boolean verbose) { + + for (Iterator<?> itr = rootNode.preorderIterator(); itr.hasNext();) { + DependencyNode d = (DependencyNode) itr.next(); + Artifact artifact = d.getArtifact(); + String key = getArtifactId(artifact); + if (log.isDebugEnabled()) { + log.debug("key : " + key); + } + if (universe.contains(key) && d.getState() == DependencyNode.INCLUDED) { + ArtifactDependencyEntry entry = dico.get(key); + entry.node = d; + if (d == null) { + // ce cas ne devrait jamais arrive + throw new IllegalStateException("on a pas trouve le node pour l'artifact " + artifact); + } + if (log.isDebugEnabled()) { + log.debug("detected node : " + d); + } + } + } + } + + protected static DependencyNode getNode(DependencyNode rootNode, String requiredKey, boolean verbose) { + + for (Iterator<?> itr = rootNode.preorderIterator(); itr.hasNext();) { + DependencyNode d = (DependencyNode) itr.next(); + Artifact artifact = d.getArtifact(); + String key = getArtifactId(artifact); + if (log.isDebugEnabled()) { + log.debug("key : " + key); + } + if (requiredKey.equals(key) && d.getState() == DependencyNode.INCLUDED) { + return d; + } + } + + return null; + } + + public static class ArtifactDependencyEntry { + + protected final Artifact artifact; + protected final String artifactKey; + protected DependencyNode node; + protected List<String> depIds; + + public ArtifactDependencyEntry(Artifact artifact) { + this.artifact = artifact; + this.artifactKey = getArtifactId(artifact); + } + } +}
participants (1)
-
tchemit@users.labs.libre-entreprise.org