ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@locus.apache.org
Subject cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/types PathTest.java
Date Tue, 05 Sep 2000 14:15:57 GMT
bodewig     00/09/05 07:15:52

  Modified:    docs     index.html
               src/main/org/apache/tools/ant/types Path.java Reference.java
               src/testcases/org/apache/tools/ant/types PathTest.java
  Log:
  Add a nested <path> element to <path>. This means one path can include
  another path (by reference as well as literally, although I doubt the
  latter is of any use). Circular references should be caught.
  Suggested by:	Barrie Treloar <Barrie.Treloar@camtech.com.au>
  
  Revision  Changes    Path
  1.90      +17 -0     jakarta-ant/docs/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/docs/index.html,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -u -r1.89 -r1.90
  --- index.html	2000/09/05 08:53:29	1.89
  +++ index.html	2000/09/05 14:15:37	1.90
  @@ -465,6 +465,23 @@
   same level as <em>target</em>s and reference them via their
   <em>id</em> attribute - see <a href="#references">References</a>
for an
   example.</p>
  +<p>A PATH like structure can include a reference to another PATH like
  +structure via a nested <code>&lt;path&gt;</code> elements.</p>
  +<pre>
  +    &lt;path id=&quot;base.path&quot;&gt;
  +      &lt;pathelement path=&quot;${classpath}&quot; /&gt;
  +      &lt;fileset dir=&quot;lib&quot;&gt;
  +        &lt;include name=&quot;**/*.jar&quot; /&gt;
  +      &lt;/fileset;&gt;
  +      &lt;pathelement location=&quot;classes&quot; /&gt;
  +    &lt;/path&gt;
  +
  +    &lt;path id=&quot;tests.path&quot;&gt;
  +      &lt;path refid=&quot;base.path&quot; /&gt;
  +      &lt;pathelement location=&quot;testclasses&quot; /&gt;
  +    &lt;/path&gt;
  +</pre>
  +
   <h3><a name="arg">Command line arguments</a></h3>
   
   <p>Several tasks take arguments that shall be passed to another
  
  
  
  1.7       +104 -11   jakarta-ant/src/main/org/apache/tools/ant/types/Path.java
  
  Index: Path.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/types/Path.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Path.java	2000/08/09 14:09:37	1.6
  +++ Path.java	2000/09/05 14:15:43	1.7
  @@ -60,8 +60,10 @@
   import org.apache.tools.ant.PathTokenizer;
   
   import java.io.File;
  -import java.util.Vector;
  +import java.util.Enumeration;
   import java.util.StringTokenizer;
  +import java.util.Stack;
  +import java.util.Vector;
   import java.text.CharacterIterator;
   import java.text.StringCharacterIterator;
   
  @@ -97,6 +99,11 @@
   
       private Vector elements;
       private Project project;
  +    private boolean isReference = false;
  +    /**
  +     * Are we sure we don't hold circular references?
  +     */
  +    private boolean checked = true;
   
       public static Path systemClasspath = 
           new Path(null, System.getProperty("java.class.path"));
  @@ -140,7 +147,10 @@
        * @param location the location of the element to add (must not be
        * <code>null</code> nor empty.
        */
  -    public void setLocation(File location) {
  +    public void setLocation(File location) throws BuildException {
  +        if (isReference) {
  +            throw tooManyAttributes();
  +        }
           createPathElement().setLocation(location);
       }
   
  @@ -149,15 +159,35 @@
        * Parses a path definition and creates single PathElements.
        * @param path the path definition.
        */
  -    public void setPath(String path) {
  +    public void setPath(String path) throws BuildException {
  +        if (isReference) {
  +            throw tooManyAttributes();
  +        }
           createPathElement().setPath(path);
       }
   
  +    /**
  +     * Makes this instance in effect a reference too another Path instance.
  +     *
  +     * <p>You must not set another attribute or nest elements inside
  +     * this element if you make it a reference.  
  +     */
  +    public void setRefid(Reference r) throws BuildException {
  +        isReference = true;
  +        if (!elements.isEmpty()) {
  +            throw tooManyAttributes();
  +        }
  +        elements.addElement(r);
  +        checked = false;
  +    }
   
       /**
  -     * Created the nested <pathelement> element.
  +     * Creates the nested <pathelement> element.
        */
  -    public PathElement createPathElement() {
  +    public PathElement createPathElement() throws BuildException {
  +        if (isReference) {
  +            throw noChildrenAllowed();
  +        }
           PathElement pe = new PathElement();
           elements.addElement(pe);
           return pe;
  @@ -166,18 +196,37 @@
       /**
        * Adds a nested <fileset> element.
        */
  -    public void addFileset(FileSet fs) {
  +    public void addFileset(FileSet fs) throws BuildException {
  +        if (isReference) {
  +            throw noChildrenAllowed();
  +        }
           elements.addElement(fs);
       }
   
       /**
        * Adds a nested <filesetref> element.
        */
  -    public void addFilesetRef(Reference r) {
  +    public void addFilesetRef(Reference r) throws BuildException {
  +        if (isReference) {
  +            throw noChildrenAllowed();
  +        }
           elements.addElement(r);
       }
   
       /**
  +     * Creates a nested <path> element.
  +     */
  +    public Path createPath() throws BuildException {
  +        if (isReference) {
  +            throw noChildrenAllowed();
  +        }
  +        Path p = new Path(project);
  +        elements.add(p);
  +        checked = false;
  +        return p;
  +    }
  +
  +    /**
        * Append the contents of the other Path instance to this.
        */
       public void append(Path other) {
  @@ -214,19 +263,26 @@
       }
   
       /**
  -     * Returns all path elements defined by this and netsed path objects.
  +     * Returns all path elements defined by this and nested path objects.
        * @return list of path elements.
        */
       public String[] list() {
  +        if (!checked) {
  +            // make sure we don't have a circular reference here
  +            Stack stk = new Stack();
  +            stk.push(this);
  +            bailOnCircularReference(stk);
  +        }
  +
           Vector result = new Vector(2*elements.size());
           for (int i=0; i<elements.size(); i++) {
               Object o = elements.elementAt(i);
               if (o instanceof Reference) {
                   Reference r = (Reference) o;
                   o = r.getReferencedObject(project);
  -                // we only support references to filesets right now
  -                if (o == null || !(o instanceof FileSet)) {
  -                    String msg = r.getRefId()+" doesn\'t denote a fileset";
  +                // we only support references to filesets and paths right now
  +                if (!(o instanceof FileSet) && !(o instanceof Path)) {
  +                    String msg = r.getRefId()+" doesn\'t denote a fileset or path";
                       throw new BuildException(msg);
                   }
               }
  @@ -242,6 +298,11 @@
                   for (int j=0; j<parts.length; j++) {
                       addUnlessPresent(result, parts[j]);
                   }
  +            } else if (o instanceof Path) {
  +                String[] parts = ((Path) o).list();
  +                for (int j=0; j<parts.length; j++) {
  +                    addUnlessPresent(result, parts[j]);
  +                }
               } else if (o instanceof FileSet) {
                   FileSet fs = (FileSet) o;
                   DirectoryScanner ds = fs.getDirectoryScanner(project);
  @@ -338,6 +399,27 @@
           return p;
       }
   
  +    protected void bailOnCircularReference(Stack stk) throws BuildException {
  +        Enumeration enum = elements.elements();
  +        while (enum.hasMoreElements()) {
  +            Object o = enum.nextElement();
  +            if (o instanceof Reference) {
  +                o = ((Reference) o).getReferencedObject(project);
  +            }
  +
  +            if (o instanceof Path) {
  +                if (stk.contains(o)) {
  +                    throw circularReference();
  +                } else {
  +                    stk.push(o);
  +                    ((Path) o).bailOnCircularReference(stk);
  +                    stk.pop();
  +                }
  +            }
  +        }
  +        checked = true;
  +    }
  +
       private static String resolveFile(Project project, String relativeName) {
           if (project != null) {
               return project.resolveFile(relativeName).getAbsolutePath();
  @@ -351,4 +433,15 @@
           }
       }
   
  +    private BuildException tooManyAttributes() {
  +        return new BuildException("You must not specify more than one attribute when using
refid");
  +    }
  +
  +    private BuildException noChildrenAllowed() {
  +        return new BuildException("You must not specify nested elements when using refid");
  +    }
  +
  +    private BuildException circularReference() {
  +        return new BuildException("This path contains a circular reference.");
  +    }
   }
  
  
  
  1.3       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/types/Reference.java
  
  Index: Reference.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/types/Reference.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Reference.java	2000/08/30 14:29:39	1.2
  +++ Reference.java	2000/09/05 14:15:45	1.3
  @@ -90,7 +90,7 @@
           
           Object o = project.getReferences().get(refid);
           if (o == null) {
  -            throw new BuildException("Refernce "+refid+" not found.");
  +            throw new BuildException("Reference "+refid+" not found.");
           }
           return o;
       }
  
  
  
  1.4       +127 -0    jakarta-ant/src/testcases/org/apache/tools/ant/types/PathTest.java
  
  Index: PathTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/types/PathTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- PathTest.java	2000/08/10 08:42:30	1.3
  +++ PathTest.java	2000/09/05 14:15:50	1.4
  @@ -171,6 +171,9 @@
           p.append(new Path(project, "\\f"));
           l = p.list();
           assertEquals("6 after append", 6, l.length);
  +        p.createPath().setLocation(new File("/g"));
  +        l = p.list();
  +        assertEquals("7 after append", 7, l.length);
       }
   
       public void testEmpyPath() {
  @@ -183,6 +186,9 @@
           p.append(new Path(project));
           l = p.list();
           assertEquals("0 after append", 0, l.length);
  +        p.createPath();
  +        l = p.list();
  +        assertEquals("0 after append", 0, l.length);
       }
   
       public void testUnique() {
  @@ -198,6 +204,127 @@
           p.append(new Path(project, "/a;\\a:\\a"));
           l = p.list();
           assertEquals("1 after append", 1, l.length);
  +        p.createPath().setPath("\\a:/a");
  +        l = p.list();
  +        assertEquals("1 after append", 1, l.length);
  +    }
  +
  +    public void testEmptyElementIfIsReference() {
  +        Path p = new Path(project, "/a:/a");
  +        try {
  +            p.setRefid(new Reference("dummyref"));
  +            fail("Can add reference to Path with elements from constructor");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify more than one attribute when using refid",
  +                         be.getMessage());
  +        }
  +
  +        p = new Path(project);
  +        p.setLocation(new File("/a"));
  +        try {
  +            p.setRefid(new Reference("dummyref"));
  +            fail("Can add reference to Path with elements from setLocation");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify more than one attribute when using refid",
  +                         be.getMessage());
  +        }
  +
  +        p = new Path(project);
  +        p.setRefid(new Reference("dummyref"));
  +        try {
  +            p.setLocation(new File("/a"));
  +            fail("Can set location in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify more than one attribute when using refid",
  +                         be.getMessage());
  +        }
  +
  +        try {
  +            p.setPath("/a;\\a");
  +            fail("Can set path in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify more than one attribute when using refid",
  +                         be.getMessage());
  +        }
  +
  +        try {
  +            p.createPath();
  +            fail("Can create nested Path in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify nested elements when using refid",
  +                         be.getMessage());
  +        }
  +
  +        try {
  +            p.createPathElement();
  +            fail("Can create nested PathElement in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify nested elements when using refid",
  +                         be.getMessage());
  +        }
  +
  +        try {
  +            p.addFileset(new FileSet());
  +            fail("Can add nested FileSet in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify nested elements when using refid",
  +                         be.getMessage());
  +        }
  +
  +        try {
  +            p.addFilesetRef(new Reference("dummy2"));
  +            fail("Can add nested FileSetRef in Path that is a reference.");
  +        } catch (BuildException be) {
  +            assertEquals("You must not specify nested elements when using refid",
  +                         be.getMessage());
  +        }
  +
  +    }
  +
  +    public void testCircularReferenceCheck() {
  +        Path p = new Path(project);
  +        project.addReference("dummy", p);
  +        p.setRefid(new Reference("dummy"));
  +        try {
  +            p.list();
  +            fail("Can make Path a Reference to itself.");
  +        } catch (BuildException be) {
  +            assertEquals("This path contains a circular reference.",
  +                         be.getMessage());
  +        }
  +
  +        // dummy1 --> dummy2 --> dummy3 --> dummy1
  +        Path p1 = new Path(project);
  +        project.addReference("dummy1", p1);
  +        Path p2 = p1.createPath();
  +        project.addReference("dummy2", p2);
  +        Path p3 = p2.createPath();
  +        project.addReference("dummy3", p3);
  +        p3.setRefid(new Reference("dummy1"));
  +        try {
  +            p1.list();
  +            fail("Can make circular reference.");
  +        } catch (BuildException be) {
  +            assertEquals("This path contains a circular reference.",
  +                         be.getMessage());
  +        }
  +
  +        // dummy1 --> dummy2 --> dummy3 (with Path "/a")
  +        p1 = new Path(project);
  +        project.addReference("dummy1", p1);
  +        p2 = p1.createPath();
  +        project.addReference("dummy2", p2);
  +        p3 = p2.createPath();
  +        project.addReference("dummy3", p3);
  +        p3.setLocation(new File("/a"));
  +        String[] l = p1.list();
  +        assertEquals("One element burried deep inside a nested path structure",
  +                     1, l.length);
  +        if (isUnixStyle) {
  +            assertEquals("/a", l[0]);
  +        } else {
  +            assertEquals("\\a", l[0]);
  +        }
       }
   
   }
  
  
  

Mime
View raw message