001    /*
002     * $Header: /home/projects/groovy/scm/groovy/groovy-core/src/main/org/codehaus/groovy/ant/FileIterator.java,v 1.1 2003/12/10 18:08:17 jstrachan Exp $
003     * $Revision: 1.1 $
004     * $Date: 2003/12/10 18:08:17 $
005     *
006     * ====================================================================
007     *
008     * The Apache Software License, Version 1.1
009     *
010     * Copyright (c) 2002 The Apache Software Foundation.  All rights
011     * reserved.
012     *
013     * Redistribution and use in source and binary forms, with or without
014     * modification, are permitted provided that the following conditions
015     * are met:
016     *
017     * 1. Redistributions of source code must retain the above copyright
018     *    notice, this list of conditions and the following disclaimer.
019     *
020     * 2. Redistributions in binary form must reproduce the above copyright
021     *    notice, this list of conditions and the following disclaimer in
022     *    the documentation and/or other materials provided with the
023     *    distribution.
024     *
025     * 3. The end-user documentation included with the redistribution, if
026     *    any, must include the following acknowlegement:
027     *       "This product includes software developed by the
028     *        Apache Software Foundation (http://www.apache.org/)."
029     *    Alternately, this acknowlegement may appear in the software itself,
030     *    if and wherever such third-party acknowlegements normally appear.
031     *
032     * 4. The names "The Jakarta Project", "Commons", and "Apache Software
033     *    Foundation" must not be used to endorse or promote products derived
034     *    from this software without prior written permission. For written
035     *    permission, please contact apache@apache.org.
036     *
037     * 5. Products derived from this software may not be called "Apache"
038     *    nor may "Apache" appear in their names without prior written
039     *    permission of the Apache Group.
040     *
041     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044     * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052     * SUCH DAMAGE.
053     * ====================================================================
054     *
055     * This software consists of voluntary contributions made by many
056     * individuals on behalf of the Apache Software Foundation.  For more
057     * information on the Apache Software Foundation, please see
058     * <http://www.apache.org/>.
059     * 
060     * $Id: FileIterator.java,v 1.1 2003/12/10 18:08:17 jstrachan Exp $
061     */
062    package org.codehaus.groovy.ant;
063    
064    import java.io.File;
065    import java.util.Iterator;
066    import java.util.NoSuchElementException;
067    
068    import org.apache.tools.ant.DirectoryScanner;
069    import org.apache.tools.ant.Project;
070    import org.apache.tools.ant.types.FileSet;
071    
072    /** 
073     * <p><code>FileIterator</code> is an iterator over a 
074     * over a number of files from a colleciton of FileSet instances.
075     *
076     * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
077     * @version $Revision: 1.1 $
078     */
079    public class FileIterator implements Iterator {
080    
081        /** The iterator over the FileSet objects */
082        private Iterator fileSetIterator;
083        
084        /** The Ant project */
085        private Project project;
086        
087        /** The directory scanner */
088        private DirectoryScanner ds;
089        
090        /** The file names in the current FileSet scan */
091        private String[] files;
092        
093        /** The current index into the file name array */
094        private int fileIndex = -1;
095        
096        /** The next File object we'll iterate over */
097        private File nextFile;
098    
099        /** Have we set a next object? */
100        private boolean nextObjectSet = false;
101    
102        /** Return only directories? */
103        private boolean iterateDirectories = false;
104    
105        public FileIterator(Project project,
106                            Iterator fileSetIterator) {
107            this( project, fileSetIterator, false);
108        }
109    
110        public FileIterator(Project project,
111                            Iterator fileSetIterator,
112                            boolean iterateDirectories) {
113            this.project = project;
114            this.fileSetIterator = fileSetIterator;
115            this.iterateDirectories = iterateDirectories;
116        }
117        
118        // Iterator interface
119        //-------------------------------------------------------------------------
120        
121        /** @return true if there is another object that matches the given predicate */
122        public boolean hasNext() {
123            if ( nextObjectSet ) {
124                return true;
125            } 
126            else {
127                return setNextObject();
128            }
129        }
130    
131        /** @return the next object which matches the given predicate */
132        public Object next() {
133            if ( !nextObjectSet ) {
134                if (!setNextObject()) {
135                    throw new NoSuchElementException();
136                }
137            }
138            nextObjectSet = false;
139            return nextFile;
140        }
141        
142        /**
143         * throws UnsupportedOperationException 
144         */
145        public void remove() {
146            throw new UnsupportedOperationException();
147        }
148    
149        // Implementation methods
150        //-------------------------------------------------------------------------
151    
152        /**
153         * Set nextObject to the next object. If there are no more 
154         * objects then return false. Otherwise, return true.
155         */
156        private boolean setNextObject() {
157            while (true) {
158                while (ds == null) {
159                    if ( ! fileSetIterator.hasNext() ) {
160                        return false;
161                    }
162                    FileSet fs = (FileSet) fileSetIterator.next();
163                    ds = fs.getDirectoryScanner(project);
164                    ds.scan();
165                    if (iterateDirectories) {
166                        files = ds.getIncludedDirectories();
167                    } 
168                    else {
169                        files = ds.getIncludedFiles();
170                    }
171                    if ( files.length > 0 ) {
172                        fileIndex = -1;
173                        break;
174                    }
175                    else {
176                        ds = null;
177                    }
178                }
179            
180                if ( ds != null && files != null ) {
181                    if ( ++fileIndex < files.length ) {
182                        nextFile = new File( ds.getBasedir(), files[fileIndex] );
183                        nextObjectSet = true;
184                        return true;
185                    }
186                    else {
187                        ds = null;
188                    }
189                }
190            }
191        }
192    }
193    
194