You are viewing a plain text version of this content. The canonical link for it is here.
Posted to alexandria-dev@jakarta.apache.org by ru...@apache.org on 2001/09/30 16:46:59 UTC

cvs commit: jakarta-alexandria/proposal/gump/java Jenny.java Module.java Project.java Workspace.java

rubys       01/09/30 07:46:59

  Modified:    proposal/gump gen.bat gen.sh
  Added:       proposal/gump/java Jenny.java Module.java Project.java
                        Workspace.java
  Removed:     proposal/gump gen.java
  Log:
  Refactor java code into separate classes
  
  Revision  Changes    Path
  1.9       +6 -3      jakarta-alexandria/proposal/gump/gen.bat
  
  Index: gen.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.bat,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- gen.bat	2001/09/18 19:14:51	1.8
  +++ gen.bat	2001/09/30 14:46:58	1.9
  @@ -6,7 +6,6 @@
   
   SET XALAN=C:\xalan-j_2_2_D8
   SET CLASSPATH=%XALAN%\bin\xalan.jar;%XALAN%\bin\xerces.jar;%CLASSPATH%
  -echo %CLASSPATH%
   
   SET SOURCE=%1
   IF "%1"=="" SET SOURCE=%COMPUTERNAME%.xml
  @@ -17,10 +16,14 @@
   REM ********************************************************************
   
   echo Merging projects into workspace
  -javac -classpath .;%CLASSPATH% gen.java
  +if exist classes rmdir /s /q classes
  +mkdir classes
  +javac -d classes java/*.java
   if errorlevel 1 goto fail
  +jar cf jenny.jar -C classes .
  +if errorlevel 1 goto fail
   echo.
  -java -classpath .;%CLASSPATH% gen %SOURCE%
  +java -classpath jenny.jar;%CLASSPATH% Jenny %SOURCE%
   if not errorlevel 0 goto fail
   
   REM ********************************************************************
  
  
  
  1.13      +6 -3      jakarta-alexandria/proposal/gump/gen.sh
  
  Index: gen.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.sh,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- gen.sh	2001/09/18 19:14:51	1.12
  +++ gen.sh	2001/09/30 14:46:58	1.13
  @@ -19,7 +19,7 @@
     export CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
   else
     export CLASSPATH=.:$XALAN/bin/xerces.jar:$XALAN/bin/xalan.jar:$CLASSPATH
  -  test -z "$1" && export SOURCE=`hostname -s`.xml
  +  test -z "$1" && export SOURCE=`hostname`.xml
   fi
   
   test -d work && rm -rf work
  @@ -28,9 +28,12 @@
   # ********************************************************************
   
   echo Merging projects into workspace
  -javac gen.java || export FAIL=1
  +rm -rf classes
  +mkdir classes
  +javac -d classes java/*.java || export FAIL=1
  +jar cf jenny.jar -C classes . || export FAIL=1
   echo
  -java gen $SOURCE || export FAIL=1
  +java -classpath jenny.jar:$CLASSPATH Jenny $SOURCE || export FAIL=1
   
   # ********************************************************************
   
  
  
  
  1.1                  jakarta-alexandria/proposal/gump/java/Jenny.java
  
  Index: Jenny.java
  ===================================================================
  // TRaX classes
  import javax.xml.transform.dom.DOMResult;
  import javax.xml.transform.dom.DOMSource;
  import javax.xml.transform.OutputKeys;
  import javax.xml.transform.stream.StreamResult;
  import javax.xml.transform.stream.StreamSource;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  
  // Java API for XML Parsing classes
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  
  // DOM classes
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  import org.w3c.dom.traversal.NodeIterator;
  import org.xml.sax.SAXParseException;
  
  // Java classes
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  // Apache xpath
  import org.apache.xpath.XPathAPI;
  
  public class Jenny {
  
      DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
      TransformerFactory tFactory = TransformerFactory.newInstance();
  
      /**
       * Parse an XML source file into an DOM.
       * @param source name of source file
       * @return Node
       */
      private Document parse(String source) throws Exception {
          try {
              DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
              return dBuilder.parse(new java.io.File(source));
          } catch (SAXParseException e) {
              System.err.print("Error parsing file " + source);
              System.err.println(" line " + e.getLineNumber() + ": ");
              throw e;
          }
      }
  
      /**
       * Transform a DOM given a stylesheet.
       * @param dom document to be transformed
       * @param sheet stylesheet to be used
       * @return Node
       */
      private Node transform(Node dom, String sheet) throws Exception {
          StreamSource source = new StreamSource("stylesheet/"+sheet);
          Transformer transformer = tFactory.newTransformer(source);
          DOMResult output = new DOMResult();
          transformer.transform(new DOMSource(dom), output);
          return output.getNode();
      }
  
      /**
       * Copy child nodes (attributes, elements, text, etc).
       * @param source element to copy from
       * @param target element to update
       */
      protected static void copyChildren(Element source, Element target) {
         Node child=source.getFirstChild();
         while (child != null) {
             Node next=child.getNextSibling();
             target.appendChild(child);
             child=next;
         }
  
         NamedNodeMap attrs = source.getAttributes();
         for (int i=0; i<attrs.getLength(); i++) {
             Node a = attrs.item(i);
             if (target.getAttributeNode(a.getNodeName())==null) {
                 target.setAttribute(a.getNodeName(),a.getNodeValue());
             }
         }
      }
  
      /**
       * Expand hrefs in place, recursively.
       * @param node source element
       */
      private void expand(Element node) throws Exception {
         // expand hrefs
         Attr href = node.getAttributeNode("href");
         if (href != null && !node.getNodeName().equals("url")) {
             String source=href.getValue();
             Node sub = parse(source);
  
             if (source.lastIndexOf(".")>0)
                 source=source.substring(0,source.lastIndexOf("."));
  
             if (source.lastIndexOf("/")>0)
                 source=source.substring(source.lastIndexOf("/")+1);
  
             node.removeAttribute("href");
             node.setAttribute("defined-in", source);
  
             Document doc = node.getOwnerDocument();
             Element copy=(Element)doc.importNode(sub.getFirstChild(), true);
             copyChildren(node, copy);
  
             Element parent = (Element)node.getParentNode();
             if (node.getNodeName().equals("profile")) {
                 copy.removeAttribute("defined-in");
                 copyChildren(copy, parent);
             } else {
  
                 parent.replaceChild(copy,node);
             }
         }
  
         // recurse through the children
         Node child=node.getFirstChild();
         while (child != null) {
             Node next=child.getNextSibling();
             if (child.getNodeType()==Node.ELEMENT_NODE) expand((Element)child);
             child=next;
         }
      }
  
      /**
       * Merge the contents of nodes with the same value for the name attribute.
       * Attributes from later definitions get added (or overlay) prior
       * definitions.  Elements get appended.
       * @param type Element localname.  Typically project or repository.
       * @param list Hashtable used for recursion.  Must initially be empty.
       * @param document Starting point for search.
       */
      private void merge(String type, Hashtable list, Node document)
          throws Exception
      {
          NodeIterator nl = XPathAPI.selectNodeIterator(document, "//"+type);
          for (Node child=nl.nextNode(); child!=null; child=nl.nextNode()) {
              Element element = (Element) child;
              String name = element.getAttribute("name");
  
              Element priorDefinition = (Element)list.get(name);
              if (priorDefinition != null && priorDefinition != element) {
                  Element parent  = (Element)priorDefinition.getParentNode();
                  String definedIn = parent.getAttribute("defined-in");
                  if (!definedIn.equals(""))
                      element.setAttribute("defined-in",definedIn);
  
                  copyChildren(priorDefinition, element);
                  parent.removeChild(priorDefinition);
              }
              list.put(name, element);
          }
      }
  
      /**
       * Unnest all elements of a given type by moving them all to become
       * direct children of the specified root node.  In the process, merge
       * all matching nodes which contain the same value for the name attribute.
       * For elements that get "hoisted", an additional "defined-in" attribute
       * is added indicating where the element was originally defined.
       * @param type Element localname.  Typically project or repository.
       * @param root Root (workspace) node
       */
      private Hashtable flatten(String type, Node root)
          throws Exception
      {
          Hashtable list = new Hashtable();
          merge(type, list, root);
          for (Enumeration e=list.keys(); e.hasMoreElements();) {
             Element element = (Element)list.get(e.nextElement());
             Element parent  = (Element)element.getParentNode();
  
             if (parent != root) {
                 String definedIn = parent.getAttribute("defined-in");
                 if (definedIn.equals(""))
                     definedIn = parent.getAttribute("name");
                 element.setAttribute("defined-in",definedIn);
  
                 parent.removeChild(element);
                 root.appendChild(element);
             }
          }
          return list;
      }
  
      /**
       * Serialize a DOM tree to file.
       * @param dom document to be transformed
       * @param dest name of file where the results are to be placed
       */
      private void output(Node dom, String dest) throws Exception {
          DOMSource in = new DOMSource(dom);
          StreamResult out = new StreamResult(dest);
          tFactory.newTransformer().transform(in, out);
      }
  
      /**
       * merge, sort, and insert defaults into a workspace
       * @param source document to be transformed
       */
      private Jenny(String source) throws Exception {
          Document doc = parse(source);
          Element workspace = (Element)doc.getFirstChild();
          Workspace.init(workspace);
  
          expand(workspace);
          Module.load(flatten("module",workspace).elements());
          Project.load(flatten("project",workspace).elements());
          flatten("repository", workspace);
          output (doc, "work/merge.xml");
  
          Node sorted   = transform(doc, "sortdep.xsl");
          output (sorted, "work/sorted.xml");
      }
  
      /**
       * Combine, colasce, and sort the files referenced by a workspace
       * definition into a single XML file.
       */
      public static void main(String[] args) {
          try {
              if (args.length == 1)
                  new Jenny(args[0]);
              else
                  System.out.println("Usage: Jenny workspace.xml");
          } catch (Exception e) {
              e.printStackTrace();
              System.exit(99);
          }
      }
  }
  
  
  
  1.1                  jakarta-alexandria/proposal/gump/java/Module.java
  
  Index: Module.java
  ===================================================================
  // DOM classes
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  
  // Java classes
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  public class Module {
  
      static private Hashtable modules = new Hashtable();
      private Element element;
      private String name;
      private String srcdir;
  
      /**
       * Create a set of Module definitions based on XML nodes.
       * @param moudules list of &lt;module&gt; elements
       */
      public static void load(Enumeration modules) throws Exception {
          while (modules.hasMoreElements()) {
              new Module((Element)modules.nextElement());
          }
      }
  
      /**
       * Find a Module given its name.
       * @param String module name
       * @return Module
       */
      public static Module find(String name) {
          return (Module) modules.get(name);
      }
  
      /**
       * Constructor.
       * @param element &lt;module&gt; element
       */
      public Module(Element element) throws Exception {
          this.element = element;
          name = element.getAttribute("name");
  
          computeSrcDir();
          markProjects();
  
          modules.put(name, this);
      }
  
      /**
       * Property accessor for srcdir attribute.
       * @return Source directory associated with this module
       */
      public String getSrcDir() {
          return srcdir;
      }
  
      /**
       * Resolve the source directory for this module.
       */
      private void computeSrcDir() throws Exception {
          srcdir=element.getAttribute("srcdir");
          if (srcdir.equals("")) srcdir=name;
          srcdir = Workspace.getBaseDir() + "/" + srcdir;
  
          element.setAttribute("srcdir", srcdir);
      }
  
      /**
       * Set module name on any projects contained herein.
       */
      private void markProjects() throws Exception {
          Node child=element.getFirstChild();
          while (child != null) {
              if (child.getNodeName().equals("project")) {
                  Element project = (Element) child;
                  if (project.getAttributeNode("module") == null) {
                      project.setAttribute("module", name);
                  }
              }
              child=child.getNextSibling();
          }
      }
  
  }
  
  
  
  1.1                  jakarta-alexandria/proposal/gump/java/Project.java
  
  Index: Project.java
  ===================================================================
  // DOM classes
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.traversal.NodeIterator;
  
  // Java classes
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  // Apache xpath
  import org.apache.xpath.XPathAPI;
  
  public class Project {
  
      private Document document;
      private Element element;
      private String name;
      private Hashtable depends = new Hashtable();
  
      /**
       * Create a set of Project definitions based on XML nodes.
       * @param project list of &lt;project&gt; elements
       */
      public static void load(Enumeration projects) throws Exception {
          while (projects.hasMoreElements()) {
             new Project((Element)projects.nextElement());
          }
      }
  
      /**
       * Constructor.
       * @param element &lt;project&gt; element
       */
      public Project(Element element) throws Exception {
          this.element = element;
          document = element.getOwnerDocument();
          name = element.getAttribute("name");
  
          Element home = null;
          Element ant = null;
  
          Node child=element.getFirstChild();
          while (child != null) {
              if (child.getNodeName().equals("depend")) {
                  depends.put(((Element)child).getAttribute("project"),child);
              } else if (child.getNodeName().equals("option")) {
                  depends.put(((Element)child).getAttribute("project"),child);
              } else if (child.getNodeName().equals("ant")) {
                  ant = (Element)child;
              } else if (child.getNodeName().equals("home")) {
                  home = (Element)child;
              }
              child=child.getNextSibling();
          }
  
          computeHome(home);
  
          if (ant != null) {
              genProperties(ant);
              genDepends(ant);
          }
      }
  
      /**
       * Replace ant "depend" elements with "property" elements.  This is
       * a convenience "syntatic sugar" that makes for simpler project
       * definitions.  Attribute "property" becomes name.  Attributes
       * reference="jarpath" and classpath="true" are added.
       * @param ant &lt;ant&gt; element to be processed
       */
      private void genProperties(Element ant) throws Exception {
  
          NodeIterator nl = XPathAPI.selectNodeIterator(ant, "depend");
          for (Node depend=nl.nextNode(); depend!=null;) {
              Node next = nl.nextNode();
  
              // create a new element based on existing element
              Element property = document.createElement("property");
              property.setAttribute("reference", "jarpath");
              property.setAttribute("classpath", "add");
              Jenny.copyChildren((Element)depend, property);
  
              // change property attribute to name attribute
              if (property.getAttributeNode("name")==null) {
                 Attr pname = property.getAttributeNode("property");
                 if (pname != null) {
                     property.setAttribute("name",pname.getValue());
                     property.removeAttributeNode(pname);
                 }
              }
  
              // replace existing element with new one
              depend.getParentNode().replaceChild(property, depend);
  
              depend = next;
          }
      }
  
      /**
       * Generate Depend elements from property references to projects.
       * @param ant &lt;ant&gt; element to be processed
       */
      private void genDepends(Element ant) throws Exception {
          NodeIterator nl = XPathAPI.selectNodeIterator(ant, "property");
          for (Node child=nl.nextNode(); child!=null; child=nl.nextNode()) {
              Element property = (Element) child;
  
              String dependency = property.getAttribute("project");
              if (dependency.equals("")) continue;
              if (dependency.equals(name)) continue;
              if (depends.get(dependency) != null) continue;
  
              if (property.getAttribute("reference").equals("srcdir")) continue;
  
              Element depend = document.createElement("depend");
              depend.setAttribute("project", dependency);
              if (property.getAttributeNode("classpath") == null)
                  depend.appendChild(document.createElement("noclasspath"));
  
              element.appendChild(depend);
              depends.put(dependency, depend);
          }
      }
  
      /**
       * Resolve home directory.
       * @param home &lt;ant&gt; element which may contain info
       */
      private void computeHome(Element home) {
          String basedir = Workspace.getBaseDir();
          String pkgdir = Workspace.getPkgDir();
  
          String module = element.getAttribute("module");
          String srcdir = Module.find(module).getSrcDir();
  
          // compute home directory
          String result=element.getAttribute("home");
          if (result.equals("")) {
              if (home != null) {
                  String attr;
                  if (! (attr=home.getAttribute("parent")).equals("")) {
                      result = basedir + "/" + attr;
                  } else if (! (attr=home.getAttribute("nested")).equals("")) {
                      result = srcdir + "/" + attr;
                  } else if (! (attr=home.getAttribute("dir")).equals("")) {
                      result = attr;
                  }
              }
  
              if (result.equals("")) {
                  String pkg = element.getAttribute("package");
                  if (!pkg.equals("")) result = pkgdir + "/" + pkg;
              }
  
              if (result.equals("")) result=srcdir;
              element.setAttribute("home", result);
          }
      }
  }
  
  
  
  1.1                  jakarta-alexandria/proposal/gump/java/Workspace.java
  
  Index: Workspace.java
  ===================================================================
  import org.w3c.dom.Element;
  
  public class Workspace {
  
      static final String GUMP_VERSION = "0.3";
  
      private static Element element;
      private static String basedir;
  
      /**
       * Static property accessor for basedir attribute.
       * @return Base directory associated with this workspace
       */
      public static String getBaseDir() {
          return element.getAttribute("basedir");
      }
  
      /**
       * Static property accessor for pkgdir attribute.
       * @return Package directory associated with this workspace
       */
      public static String getPkgDir() {
          return element.getAttribute("pkgdir");
      }
  
      /**
       * Default and verify various workspace attributes.
       * If not specified:
       *   banner-image="http://jakarta.apache.org/images/jakarta-logo.gif"
       *   banner-link="http://jakarta.apache.org"
       *   cvsdir=basedir+"/cvs"
       *   logdir=basedir+"/log"
       *   pkgdir=basedir
       * @param Workspace element to be updated
       */
      public static void init(Element workspace) throws Exception {
          Workspace.element = workspace;
  
          if (!workspace.getAttribute("version").equals(GUMP_VERSION)) {
              throw new Exception("workspace version " + GUMP_VERSION +
                                  " required.");
          }
  
          basedir = workspace.getAttribute("basedir");
  
          if (workspace.getAttribute("banner-image").equals("")) {
              workspace.setAttribute("banner-image",
                  "http://jakarta.apache.org/images/jakarta-logo.gif");
          }
  
          if (workspace.getAttribute("banner-link").equals("")) {
              workspace.setAttribute("banner-link", "http://jakarta.apache.org");
          }
  
          if (workspace.getAttribute("logdir").equals("")) {
              workspace.setAttribute("logdir", basedir + "/log");
          }
  
          if (workspace.getAttribute("cvsdir").equals("")) {
              workspace.setAttribute("cvsdir", basedir + "/cvs");
          }
  
          if (workspace.getAttribute("pkgdir").equals("")) {
              workspace.setAttribute("pkgdir", basedir);
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: alexandria-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: alexandria-dev-help@jakarta.apache.org


Re: cvs commit: jakarta-alexandria/proposal/gump/java Jenny.java Module.java Project.java Workspace.java

Posted by Shyam Koppikar <vk...@tds.net>.
----- Original Message -----
From: <ru...@apache.org>
To: <ja...@apache.org>
Sent: Sunday, September 30, 2001 7:46 AM
Subject: cvs commit: jakarta-alexandria/proposal/gump/java Jenny.java
Module.java Project.java Workspace.java


> rubys       01/09/30 07:46:59
>
>   Modified:    proposal/gump gen.bat gen.sh
>   Added:       proposal/gump/java Jenny.java Module.java Project.java
>                         Workspace.java
>   Removed:     proposal/gump gen.java
>   Log:
>   Refactor java code into separate classes
>
>   Revision  Changes    Path
>   1.9       +6 -3      jakarta-alexandria/proposal/gump/gen.bat
>
>   Index: gen.bat
>   ===================================================================
>   RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.bat,v
>   retrieving revision 1.8
>   retrieving revision 1.9
>   diff -u -r1.8 -r1.9
>   --- gen.bat 2001/09/18 19:14:51 1.8
>   +++ gen.bat 2001/09/30 14:46:58 1.9
>   @@ -6,7 +6,6 @@
>
>    SET XALAN=C:\xalan-j_2_2_D8
>    SET CLASSPATH=%XALAN%\bin\xalan.jar;%XALAN%\bin\xerces.jar;%CLASSPATH%
>   -echo %CLASSPATH%
>
>    SET SOURCE=%1
>    IF "%1"=="" SET SOURCE=%COMPUTERNAME%.xml
>   @@ -17,10 +16,14 @@
>    REM
********************************************************************
>
>    echo Merging projects into workspace
>   -javac -classpath .;%CLASSPATH% gen.java
>   +if exist classes rmdir /s /q classes
>   +mkdir classes
>   +javac -d classes java/*.java
>    if errorlevel 1 goto fail
>   +jar cf jenny.jar -C classes .
>   +if errorlevel 1 goto fail
>    echo.
>   -java -classpath .;%CLASSPATH% gen %SOURCE%
>   +java -classpath jenny.jar;%CLASSPATH% Jenny %SOURCE%
>    if not errorlevel 0 goto fail
>
>    REM
********************************************************************
>
>
>
>   1.13      +6 -3      jakarta-alexandria/proposal/gump/gen.sh
>
>   Index: gen.sh
>   ===================================================================
>   RCS file: /home/cvs/jakarta-alexandria/proposal/gump/gen.sh,v
>   retrieving revision 1.12
>   retrieving revision 1.13
>   diff -u -r1.12 -r1.13
>   --- gen.sh 2001/09/18 19:14:51 1.12
>   +++ gen.sh 2001/09/30 14:46:58 1.13
>   @@ -19,7 +19,7 @@
>      export CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
>    else
>      export
CLASSPATH=.:$XALAN/bin/xerces.jar:$XALAN/bin/xalan.jar:$CLASSPATH
>   -  test -z "$1" && export SOURCE=`hostname -s`.xml
>   +  test -z "$1" && export SOURCE=`hostname`.xml
>    fi
>
>    test -d work && rm -rf work
>   @@ -28,9 +28,12 @@
>    # ********************************************************************
>
>    echo Merging projects into workspace
>   -javac gen.java || export FAIL=1
>   +rm -rf classes
>   +mkdir classes
>   +javac -d classes java/*.java || export FAIL=1
>   +jar cf jenny.jar -C classes . || export FAIL=1
>    echo
>   -java gen $SOURCE || export FAIL=1
>   +java -classpath jenny.jar:$CLASSPATH Jenny $SOURCE || export FAIL=1
>
>    # ********************************************************************
>
>
>
>
>   1.1                  jakarta-alexandria/proposal/gump/java/Jenny.java
>
>   Index: Jenny.java
>   ===================================================================
>   // TRaX classes
>   import javax.xml.transform.dom.DOMResult;
>   import javax.xml.transform.dom.DOMSource;
>   import javax.xml.transform.OutputKeys;
>   import javax.xml.transform.stream.StreamResult;
>   import javax.xml.transform.stream.StreamSource;
>   import javax.xml.transform.Transformer;
>   import javax.xml.transform.TransformerFactory;
>
>   // Java API for XML Parsing classes
>   import javax.xml.parsers.DocumentBuilder;
>   import javax.xml.parsers.DocumentBuilderFactory;
>
>   // DOM classes
>   import org.w3c.dom.Attr;
>   import org.w3c.dom.Document;
>   import org.w3c.dom.Element;
>   import org.w3c.dom.NamedNodeMap;
>   import org.w3c.dom.Node;
>   import org.w3c.dom.traversal.NodeIterator;
>   import org.xml.sax.SAXParseException;
>
>   // Java classes
>   import java.util.Enumeration;
>   import java.util.Hashtable;
>
>   // Apache xpath
>   import org.apache.xpath.XPathAPI;
>
>   public class Jenny {
>
>       DocumentBuilderFactory dFactory =
DocumentBuilderFactory.newInstance();
>       TransformerFactory tFactory = TransformerFactory.newInstance();
>
>       /**
>        * Parse an XML source file into an DOM.
>        * @param source name of source file
>        * @return Node
>        */
>       private Document parse(String source) throws Exception {
>           try {
>               DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
>               return dBuilder.parse(new java.io.File(source));
>           } catch (SAXParseException e) {
>               System.err.print("Error parsing file " + source);
>               System.err.println(" line " + e.getLineNumber() + ": ");
>               throw e;
>           }
>       }
>
>       /**
>        * Transform a DOM given a stylesheet.
>        * @param dom document to be transformed
>        * @param sheet stylesheet to be used
>        * @return Node
>        */
>       private Node transform(Node dom, String sheet) throws Exception {
>           StreamSource source = new StreamSource("stylesheet/"+sheet);
>           Transformer transformer = tFactory.newTransformer(source);
>           DOMResult output = new DOMResult();
>           transformer.transform(new DOMSource(dom), output);
>           return output.getNode();
>       }
>
>       /**
>        * Copy child nodes (attributes, elements, text, etc).
>        * @param source element to copy from
>        * @param target element to update
>        */
>       protected static void copyChildren(Element source, Element target) {
>          Node child=source.getFirstChild();
>          while (child != null) {
>              Node next=child.getNextSibling();
>              target.appendChild(child);
>              child=next;
>          }
>
>          NamedNodeMap attrs = source.getAttributes();
>          for (int i=0; i<attrs.getLength(); i++) {
>              Node a = attrs.item(i);
>              if (target.getAttributeNode(a.getNodeName())==null) {
>                  target.setAttribute(a.getNodeName(),a.getNodeValue());
>              }
>          }
>       }
>
>       /**
>        * Expand hrefs in place, recursively.
>        * @param node source element
>        */
>       private void expand(Element node) throws Exception {
>          // expand hrefs
>          Attr href = node.getAttributeNode("href");
>          if (href != null && !node.getNodeName().equals("url")) {
>              String source=href.getValue();
>              Node sub = parse(source);
>
>              if (source.lastIndexOf(".")>0)
>                  source=source.substring(0,source.lastIndexOf("."));
>
>              if (source.lastIndexOf("/")>0)
>                  source=source.substring(source.lastIndexOf("/")+1);
>
>              node.removeAttribute("href");
>              node.setAttribute("defined-in", source);
>
>              Document doc = node.getOwnerDocument();
>              Element copy=(Element)doc.importNode(sub.getFirstChild(),
true);
>              copyChildren(node, copy);
>
>              Element parent = (Element)node.getParentNode();
>              if (node.getNodeName().equals("profile")) {
>                  copy.removeAttribute("defined-in");
>                  copyChildren(copy, parent);
>              } else {
>
>                  parent.replaceChild(copy,node);
>              }
>          }
>
>          // recurse through the children
>          Node child=node.getFirstChild();
>          while (child != null) {
>              Node next=child.getNextSibling();
>              if (child.getNodeType()==Node.ELEMENT_NODE)
expand((Element)child);
>              child=next;
>          }
>       }
>
>       /**
>        * Merge the contents of nodes with the same value for the name
attribute.
>        * Attributes from later definitions get added (or overlay) prior
>        * definitions.  Elements get appended.
>        * @param type Element localname.  Typically project or repository.
>        * @param list Hashtable used for recursion.  Must initially be
empty.
>        * @param document Starting point for search.
>        */
>       private void merge(String type, Hashtable list, Node document)
>           throws Exception
>       {
>           NodeIterator nl = XPathAPI.selectNodeIterator(document,
"file://"+type);
>           for (Node child=nl.nextNode(); child!=null; child=nl.nextNode())
{
>               Element element = (Element) child;
>               String name = element.getAttribute("name");
>
>               Element priorDefinition = (Element)list.get(name);
>               if (priorDefinition != null && priorDefinition != element) {
>                   Element parent  =
(Element)priorDefinition.getParentNode();
>                   String definedIn = parent.getAttribute("defined-in");
>                   if (!definedIn.equals(""))
>                       element.setAttribute("defined-in",definedIn);
>
>                   copyChildren(priorDefinition, element);
>                   parent.removeChild(priorDefinition);
>               }
>               list.put(name, element);
>           }
>       }
>
>       /**
>        * Unnest all elements of a given type by moving them all to become
>        * direct children of the specified root node.  In the process,
merge
>        * all matching nodes which contain the same value for the name
attribute.
>        * For elements that get "hoisted", an additional "defined-in"
attribute
>        * is added indicating where the element was originally defined.
>        * @param type Element localname.  Typically project or repository.
>        * @param root Root (workspace) node
>        */
>       private Hashtable flatten(String type, Node root)
>           throws Exception
>       {
>           Hashtable list = new Hashtable();
>           merge(type, list, root);
>           for (Enumeration e=list.keys(); e.hasMoreElements();) {
>              Element element = (Element)list.get(e.nextElement());
>              Element parent  = (Element)element.getParentNode();
>
>              if (parent != root) {
>                  String definedIn = parent.getAttribute("defined-in");
>                  if (definedIn.equals(""))
>                      definedIn = parent.getAttribute("name");
>                  element.setAttribute("defined-in",definedIn);
>
>                  parent.removeChild(element);
>                  root.appendChild(element);
>              }
>           }
>           return list;
>       }
>
>       /**
>        * Serialize a DOM tree to file.
>        * @param dom document to be transformed
>        * @param dest name of file where the results are to be placed
>        */
>       private void output(Node dom, String dest) throws Exception {
>           DOMSource in = new DOMSource(dom);
>           StreamResult out = new StreamResult(dest);
>           tFactory.newTransformer().transform(in, out);
>       }
>
>       /**
>        * merge, sort, and insert defaults into a workspace
>        * @param source document to be transformed
>        */
>       private Jenny(String source) throws Exception {
>           Document doc = parse(source);
>           Element workspace = (Element)doc.getFirstChild();
>           Workspace.init(workspace);
>
>           expand(workspace);
>           Module.load(flatten("module",workspace).elements());
>           Project.load(flatten("project",workspace).elements());
>           flatten("repository", workspace);
>           output (doc, "work/merge.xml");
>
>           Node sorted   = transform(doc, "sortdep.xsl");
>           output (sorted, "work/sorted.xml");
>       }
>
>       /**
>        * Combine, colasce, and sort the files referenced by a workspace
>        * definition into a single XML file.
>        */
>       public static void main(String[] args) {
>           try {
>               if (args.length == 1)
>                   new Jenny(args[0]);
>               else
>                   System.out.println("Usage: Jenny workspace.xml");
>           } catch (Exception e) {
>               e.printStackTrace();
>               System.exit(99);
>           }
>       }
>   }
>
>
>
>   1.1                  jakarta-alexandria/proposal/gump/java/Module.java
>
>   Index: Module.java
>   ===================================================================
>   // DOM classes
>   import org.w3c.dom.Element;
>   import org.w3c.dom.Node;
>
>   // Java classes
>   import java.util.Enumeration;
>   import java.util.Hashtable;
>
>   public class Module {
>
>       static private Hashtable modules = new Hashtable();
>       private Element element;
>       private String name;
>       private String srcdir;
>
>       /**
>        * Create a set of Module definitions based on XML nodes.
>        * @param moudules list of &lt;module&gt; elements
>        */
>       public static void load(Enumeration modules) throws Exception {
>           while (modules.hasMoreElements()) {
>               new Module((Element)modules.nextElement());
>           }
>       }
>
>       /**
>        * Find a Module given its name.
>        * @param String module name
>        * @return Module
>        */
>       public static Module find(String name) {
>           return (Module) modules.get(name);
>       }
>
>       /**
>        * Constructor.
>        * @param element &lt;module&gt; element
>        */
>       public Module(Element element) throws Exception {
>           this.element = element;
>           name = element.getAttribute("name");
>
>           computeSrcDir();
>           markProjects();
>
>           modules.put(name, this);
>       }
>
>       /**
>        * Property accessor for srcdir attribute.
>        * @return Source directory associated with this module
>        */
>       public String getSrcDir() {
>           return srcdir;
>       }
>
>       /**
>        * Resolve the source directory for this module.
>        */
>       private void computeSrcDir() throws Exception {
>           srcdir=element.getAttribute("srcdir");
>           if (srcdir.equals("")) srcdir=name;
>           srcdir = Workspace.getBaseDir() + "/" + srcdir;
>
>           element.setAttribute("srcdir", srcdir);
>       }
>
>       /**
>        * Set module name on any projects contained herein.
>        */
>       private void markProjects() throws Exception {
>           Node child=element.getFirstChild();
>           while (child != null) {
>               if (child.getNodeName().equals("project")) {
>                   Element project = (Element) child;
>                   if (project.getAttributeNode("module") == null) {
>                       project.setAttribute("module", name);
>                   }
>               }
>               child=child.getNextSibling();
>           }
>       }
>
>   }
>
>
>
>   1.1                  jakarta-alexandria/proposal/gump/java/Project.java
>
>   Index: Project.java
>   ===================================================================
>   // DOM classes
>   import org.w3c.dom.Attr;
>   import org.w3c.dom.Document;
>   import org.w3c.dom.Element;
>   import org.w3c.dom.Node;
>   import org.w3c.dom.traversal.NodeIterator;
>
>   // Java classes
>   import java.util.Enumeration;
>   import java.util.Hashtable;
>
>   // Apache xpath
>   import org.apache.xpath.XPathAPI;
>
>   public class Project {
>
>       private Document document;
>       private Element element;
>       private String name;
>       private Hashtable depends = new Hashtable();
>
>       /**
>        * Create a set of Project definitions based on XML nodes.
>        * @param project list of &lt;project&gt; elements
>        */
>       public static void load(Enumeration projects) throws Exception {
>           while (projects.hasMoreElements()) {
>              new Project((Element)projects.nextElement());
>           }
>       }
>
>       /**
>        * Constructor.
>        * @param element &lt;project&gt; element
>        */
>       public Project(Element element) throws Exception {
>           this.element = element;
>           document = element.getOwnerDocument();
>           name = element.getAttribute("name");
>
>           Element home = null;
>           Element ant = null;
>
>           Node child=element.getFirstChild();
>           while (child != null) {
>               if (child.getNodeName().equals("depend")) {
>
depends.put(((Element)child).getAttribute("project"),child);
>               } else if (child.getNodeName().equals("option")) {
>
depends.put(((Element)child).getAttribute("project"),child);
>               } else if (child.getNodeName().equals("ant")) {
>                   ant = (Element)child;
>               } else if (child.getNodeName().equals("home")) {
>                   home = (Element)child;
>               }
>               child=child.getNextSibling();
>           }
>
>           computeHome(home);
>
>           if (ant != null) {
>               genProperties(ant);
>               genDepends(ant);
>           }
>       }
>
>       /**
>        * Replace ant "depend" elements with "property" elements.  This is
>        * a convenience "syntatic sugar" that makes for simpler project
>        * definitions.  Attribute "property" becomes name.  Attributes
>        * reference="jarpath" and classpath="true" are added.
>        * @param ant &lt;ant&gt; element to be processed
>        */
>       private void genProperties(Element ant) throws Exception {
>
>           NodeIterator nl = XPathAPI.selectNodeIterator(ant, "depend");
>           for (Node depend=nl.nextNode(); depend!=null;) {
>               Node next = nl.nextNode();
>
>               // create a new element based on existing element
>               Element property = document.createElement("property");
>               property.setAttribute("reference", "jarpath");
>               property.setAttribute("classpath", "add");
>               Jenny.copyChildren((Element)depend, property);
>
>               // change property attribute to name attribute
>               if (property.getAttributeNode("name")==null) {
>                  Attr pname = property.getAttributeNode("property");
>                  if (pname != null) {
>                      property.setAttribute("name",pname.getValue());
>                      property.removeAttributeNode(pname);
>                  }
>               }
>
>               // replace existing element with new one
>               depend.getParentNode().replaceChild(property, depend);
>
>               depend = next;
>           }
>       }
>
>       /**
>        * Generate Depend elements from property references to projects.
>        * @param ant &lt;ant&gt; element to be processed
>        */
>       private void genDepends(Element ant) throws Exception {
>           NodeIterator nl = XPathAPI.selectNodeIterator(ant, "property");
>           for (Node child=nl.nextNode(); child!=null; child=nl.nextNode())
{
>               Element property = (Element) child;
>
>               String dependency = property.getAttribute("project");
>               if (dependency.equals("")) continue;
>               if (dependency.equals(name)) continue;
>               if (depends.get(dependency) != null) continue;
>
>               if (property.getAttribute("reference").equals("srcdir"))
continue;
>
>               Element depend = document.createElement("depend");
>               depend.setAttribute("project", dependency);
>               if (property.getAttributeNode("classpath") == null)
>
depend.appendChild(document.createElement("noclasspath"));
>
>               element.appendChild(depend);
>               depends.put(dependency, depend);
>           }
>       }
>
>       /**
>        * Resolve home directory.
>        * @param home &lt;ant&gt; element which may contain info
>        */
>       private void computeHome(Element home) {
>           String basedir = Workspace.getBaseDir();
>           String pkgdir = Workspace.getPkgDir();
>
>           String module = element.getAttribute("module");
>           String srcdir = Module.find(module).getSrcDir();
>
>           // compute home directory
>           String result=element.getAttribute("home");
>           if (result.equals("")) {
>               if (home != null) {
>                   String attr;
>                   if (! (attr=home.getAttribute("parent")).equals("")) {
>                       result = basedir + "/" + attr;
>                   } else if (!
(attr=home.getAttribute("nested")).equals("")) {
>                       result = srcdir + "/" + attr;
>                   } else if (! (attr=home.getAttribute("dir")).equals(""))
{
>                       result = attr;
>                   }
>               }
>
>               if (result.equals("")) {
>                   String pkg = element.getAttribute("package");
>                   if (!pkg.equals("")) result = pkgdir + "/" + pkg;
>               }
>
>               if (result.equals("")) result=srcdir;
>               element.setAttribute("home", result);
>           }
>       }
>   }
>
>
>
>   1.1
jakarta-alexandria/proposal/gump/java/Workspace.java
>
>   Index: Workspace.java
>   ===================================================================
>   import org.w3c.dom.Element;
>
>   public class Workspace {
>
>       static final String GUMP_VERSION = "0.3";
>
>       private static Element element;
>       private static String basedir;
>
>       /**
>        * Static property accessor for basedir attribute.
>        * @return Base directory associated with this workspace
>        */
>       public static String getBaseDir() {
>           return element.getAttribute("basedir");
>       }
>
>       /**
>        * Static property accessor for pkgdir attribute.
>        * @return Package directory associated with this workspace
>        */
>       public static String getPkgDir() {
>           return element.getAttribute("pkgdir");
>       }
>
>       /**
>        * Default and verify various workspace attributes.
>        * If not specified:
>        *
banner-image="http://jakarta.apache.org/images/jakarta-logo.gif"
>        *   banner-link="http://jakarta.apache.org"
>        *   cvsdir=basedir+"/cvs"
>        *   logdir=basedir+"/log"
>        *   pkgdir=basedir
>        * @param Workspace element to be updated
>        */
>       public static void init(Element workspace) throws Exception {
>           Workspace.element = workspace;
>
>           if (!workspace.getAttribute("version").equals(GUMP_VERSION)) {
>               throw new Exception("workspace version " + GUMP_VERSION +
>                                   " required.");
>           }
>
>           basedir = workspace.getAttribute("basedir");
>
>           if (workspace.getAttribute("banner-image").equals("")) {
>               workspace.setAttribute("banner-image",
>                   "http://jakarta.apache.org/images/jakarta-logo.gif");
>           }
>
>           if (workspace.getAttribute("banner-link").equals("")) {
>               workspace.setAttribute("banner-link",
"http://jakarta.apache.org");
>           }
>
>           if (workspace.getAttribute("logdir").equals("")) {
>               workspace.setAttribute("logdir", basedir + "/log");
>           }
>
>           if (workspace.getAttribute("cvsdir").equals("")) {
>               workspace.setAttribute("cvsdir", basedir + "/cvs");
>           }
>
>           if (workspace.getAttribute("pkgdir").equals("")) {
>               workspace.setAttribute("pkgdir", basedir);
>           }
>       }
>   }
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: alexandria-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: alexandria-dev-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: alexandria-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: alexandria-dev-help@jakarta.apache.org