rubys       01/11/02 08:16:27

  Modified:    proposal/gump gen.bat gen.sh
               proposal/gump/java Jenny.java Project.java
  Removed:     proposal/gump/stylesheet sortdep.xsl
  Log:
  Move sorting from XSLT to Java.  Also introduce a deterministic sort order
  where the projects most often referenced are done first.
  
  Revision  Changes    Path
  1.16      +2 -2      jakarta-alexandria/proposal/gump/gen.bat
  
  Index: gen.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.bat,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- gen.bat   2001/10/13 00:24:17     1.15
  +++ gen.bat   2001/11/02 16:16:27     1.16
  @@ -34,7 +34,7 @@
   REM ********************************************************************
   
   echo Generating checkout instructions
  -java org.apache.xalan.xslt.Process -xml -in work\sorted.xml -xsl 
stylesheet\update.xsl -out work\update.xml
  +java org.apache.xalan.xslt.Process -xml -in work\merge.xml -xsl 
stylesheet\update.xsl -out work\update.xml
   if not errorlevel 0 goto fail
   
   echo Applying web site stylesheet
  @@ -48,7 +48,7 @@
   REM ********************************************************************
   
   echo Generating build definition
  -java org.apache.xalan.xslt.Process -EDUMP -indent 2 -xml -in work\sorted.xml -xsl 
stylesheet\build.xsl -out work\build.xml
  +java org.apache.xalan.xslt.Process -EDUMP -indent 2 -xml -in work\merge.xml -xsl 
stylesheet\build.xsl -out work\build.xml
   if not errorlevel 0 goto fail
   
   echo Applying web site stylesheet
  
  
  
  1.24      +4 -4      jakarta-alexandria/proposal/gump/gen.sh
  
  Index: gen.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.sh,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- gen.sh    2001/11/01 16:45:03     1.23
  +++ gen.sh    2001/11/02 16:16:27     1.24
  @@ -39,7 +39,7 @@
   
   echo Generate checkout instructions
   test -n "$FAIL" || \
  -java org.apache.xalan.xslt.Process -xml -in work/sorted.xml -xsl 
stylesheet/update.xsl -out work/update.xml || \
  +java org.apache.xalan.xslt.Process -xml -in work/merge.xml -xsl 
stylesheet/update.xsl -out work/update.xml || \
   export FAIL=1
   
   echo Applying web site stylesheet
  @@ -56,7 +56,7 @@
   
   echo Generate build instructions
   test -n "$FAIL" || \
  -java org.apache.xalan.xslt.Process -xml -in work/sorted.xml -xsl 
stylesheet/build.xsl -out work/build.xml || \
  +java org.apache.xalan.xslt.Process -xml -in work/merge.xml -xsl 
stylesheet/build.xsl -out work/build.xml || \
   export FAIL=1
   
   echo Applying web site stylesheet
  @@ -73,7 +73,7 @@
   
   echo Generate crossreference data
   test -n "$FAIL" || \
  -java org.apache.xalan.xslt.Process -xml -in work/sorted.xml -xsl 
stylesheet/xref.xsl -out work/xref.xml || \
  +java org.apache.xalan.xslt.Process -xml -in work/merge.xml -xsl stylesheet/xref.xsl 
-out work/xref.xml || \
   export FAIL=1
   
   echo Applying web site stylesheet
  @@ -95,7 +95,7 @@
   
   echo Generate template for publishing an xml source file
   test -n "$FAIL" || \
  -java org.apache.xalan.xslt.Process -xml -in work/sorted.xml -xsl 
stylesheet/publish.xsl -out work/publish.xml || \
  +java org.apache.xalan.xslt.Process -xml -in work/merge.xml -xsl 
stylesheet/publish.xsl -out work/publish.xml || \
   export FAIL=1
   
   echo Applying web site stylesheet
  
  
  
  1.4       +0 -3      jakarta-alexandria/proposal/gump/java/Jenny.java
  
  Index: Jenny.java
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/java/Jenny.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Jenny.java        2001/10/06 21:22:16     1.3
  +++ Jenny.java        2001/11/02 16:16:27     1.4
  @@ -183,9 +183,6 @@
           Module.load(merge("module",workspace).elements());
           Project.load(merge("project",workspace).elements());
           output (doc, "work/merge.xml");
  -
  -        Node sorted   = transform(doc, "sortdep.xsl");
  -        output (sorted, "work/sorted.xml");
       }
   
       /**
  
  
  
  1.17      +115 -8    jakarta-alexandria/proposal/gump/java/Project.java
  
  Index: Project.java
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/java/Project.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- Project.java      2001/10/29 16:16:46     1.16
  +++ Project.java      2001/11/02 16:16:27     1.17
  @@ -5,8 +5,12 @@
   import org.w3c.dom.Node;
   
   // Java classes
  +import java.util.Comparator;
   import java.util.Enumeration;
   import java.util.Hashtable;
  +import java.util.Iterator;
  +import java.util.Set;
  +import java.util.TreeSet;
   
   public class Project {
   
  @@ -15,7 +19,8 @@
       private Element element;
       private String name;
       private Element ant = null;
  -    private Hashtable depends = new Hashtable();
  +    private Hashtable dependsOn = new Hashtable();
  +    private Hashtable referencedBy = new Hashtable();
       private Hashtable jars = new Hashtable();
       private Element description;
       private Element url;
  @@ -36,6 +41,8 @@
               p.expandDepends();
               p.resolveProperties();
           }
  +
  +        sort();
       }
   
       /**
  @@ -62,9 +69,9 @@
           Node child=element.getFirstChild();
           for (; child != null; child=child.getNextSibling()) {
               if (child.getNodeName().equals("depend")) {
  -                depends.put(((Element)child).getAttribute("project"), child);
  +                dependsOn.put(((Element)child).getAttribute("project"), child);
               } else if (child.getNodeName().equals("option")) {
  -                depends.put(((Element)child).getAttribute("project"), child);
  +                dependsOn.put(((Element)child).getAttribute("project"), child);
               } else if (child.getNodeName().equals("ant")) {
                   ant = (Element)child;
               } else if (child.getNodeName().equals("home")) {
  @@ -150,7 +157,7 @@
               String dependency = property.getAttribute("project");
               if (dependency.equals("")) continue;
               if (dependency.equals(name)) continue;
  -            if (depends.get(dependency) != null) continue;
  +            if (dependsOn.get(dependency) != null) continue;
   
               if (property.getAttribute("reference").equals("srcdir")) continue;
   
  @@ -160,7 +167,7 @@
                   depend.appendChild(document.createElement("noclasspath"));
   
               element.appendChild(depend);
  -            depends.put(dependency, depend);
  +            dependsOn.put(dependency, depend);
           }
       }
   
  @@ -223,13 +230,17 @@
        * simplifies generation by essentially making project definitions
        * self contained.
        */
  -    private void expandDepends() {
  -        for (Enumeration e=depends.keys(); e.hasMoreElements(); ) {
  +    private void expandDepends() throws Exception {
  +        for (Enumeration e=dependsOn.keys(); e.hasMoreElements(); ) {
               String name = (String)e.nextElement();
               Project target = (Project)projects.get(name);
  +
  +            Element depend = (Element) dependsOn.get(name);
  +            if (!depend.getNodeName().equals("option"))
  +                require(target, "project", name);
               if (target == null) continue;
   
  -            Element depend = (Element) depends.get(name);
  +            target.referencedBy.put(this, depend);
               depend.setAttribute("home",target.get("home"));
               depend.setAttribute("defined-in",target.get("defined-in"));
   
  @@ -244,6 +255,102 @@
                   }
               }
           }
  +    }
  +
  +    /**
  +     * Determine if this project has any unsatisfied dependencies left
  +     * on the todo list.
  +     * @param todo the list of projects yet to be done (includes this one).
  +     * @return true if this project is ready to go
  +     */
  +    private boolean isReady(Set todo) {
  +        for (Enumeration e=dependsOn.keys(); e.hasMoreElements();) {
  +            if (todo.contains(e.nextElement())) return false;
  +        }
  +        return true;
  +    }
  +
  +    /**
  +     * Determine if this project is referenced by anything on the todo list.
  +     * @param todo the list of projects yet to be done (includes this one).
  +     * @return true if this project is holding up progress
  +     */
  +    private boolean isPrereq(Set todo) {
  +        for (Enumeration e=referencedBy.keys(); e.hasMoreElements();) {
  +            if (todo.contains(e.nextElement())) return true;
  +        }
  +        return false;
  +    }
  +
  +    /**
  +     * Move this element to the end of the parents set of children.
  +     */
  +    private void moveToLast() {
  +        Element parent = (Element) element.getParentNode();
  +        parent.removeChild(element);
  +        parent.appendChild(element);
  +    }
  +
  +    /**
  +     * Implement a deterministing sort order.  Projects which are most
  +     * referenced get priority.  After that, order is determined alphabetically.
  +     */
  +    private static class Ranker implements Comparator {
  +        public int compare(Object o1, Object o2) {
  +            Project p1 = (Project) projects.get(o1);
  +            Project p2 = (Project) projects.get(o2);
  +            if (p1 == p2) return 0;
  +            if (p1 == null) return -1;
  +            if (p2 == null) return 1;
  +
  +            int diff = p2.referencedBy.size() - p1.referencedBy.size();
  +            if (diff != 0) return diff;
  +
  +            return ((String)o1).compareTo((String)o2);
  +        }
  +    }
  +
  +    /**
  +     * Sort all projects in an order that respects the dependencies.  If such
  +     * an order can not be determined, print out the ones that form a loop.
  +     */
  +    private static void sort() throws Exception {
  +        TreeSet todo = new TreeSet(new Ranker());
  +        todo.addAll(projects.keySet());
  +
  +        // As long as there are projects which are ready, put the next
  +        // available one at the end of the list.
  +        for (Iterator i=todo.iterator(); i.hasNext();) {
  +            Project p = (Project) projects.get(i.next());
  +            if (p.isReady(todo)) {
  +                p.moveToLast();
  +                todo.remove(p.name);
  +                i=todo.iterator();
  +            }
  +        }
  +            
  +        // Did we succeed?
  +        if (todo.isEmpty()) return;
  +
  +        // Remove all elements which are not prereqed by any projects
  +        // remaining
  +        if (todo.isEmpty()) return;
  +        for (Iterator i=todo.iterator(); i.hasNext();) {
  +            Project p = (Project) projects.get(i.next());
  +            if (!p.isPrereq(todo)) {
  +                todo.remove(p.name);
  +                i=todo.iterator();
  +            }
  +        }
  +
  +
  +        // Construct a list of the rest, and throw an exception
  +        String message="Circular dependency loop involving:";
  +        for (Iterator i=todo.iterator(); i.hasNext();) {
  +            Project p = ((Project)(i.next()));
  +            message += "\n  " + p.name;
  +        }
  +        throw new Exception(message);
       }
   
       /**
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to