ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vanovc...@logica.com
Subject RE: echo and filesets
Date Mon, 13 Jan 2003 08:02:42 GMT
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package com.logica.ant;

import java.io.File;
import java.util.Enumeration;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.CallTarget;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.PatternSet;

/**
 * Call another target(s) in the same project for each file in a specified
 * fileset. The targets are invoked with nested properties from the
 * <code>&lt;antcall&gt;</code> element; four additional properties are
 * passed: <BR>
 * <code>foreach.file</code>--a full filename from the defined fileset,<BR>
 * <code>foreach.dir</code>--the directory of the file,<BR>
 * <code>foreach.name.ext</code>--the name of the file, without path but
 *   with extension,<BR>
 * <code>foreach.name</code>--the name of the file, without path and without
 * extension
 * <code>foreach.name.withpath</code>--the name of the file with path
 * relative to the current directory
 * <pre>
 * &lt;target name="foo"&gt;
 *   &lt;foreach&gt;
 *     &lt;fileset dir="${server.src}" casesensitive="yes"&gt;
 *       &lt;include name="**\/*.java"/&gt;
 *       &lt;exclude name="**\/*Test*"/&gt;
 *     &lt;/fileset&gt;
 *     &lt;antcall target="bar"&gt;
 *       &lt;param name="property1" value="aaaaa" /&gt;
 *       &lt;param name="foo" value="bar" /&gt;
 *     &lt;/antcall&gt;
 *   &lt;/foreach&gt;
 * &lt;/target&gt;
 *
 * &lt;target name="bar" depends="init"&gt;
 *   &lt;echo message="prop is ${property1} ${foo}" /&gt;
 *   &lt;echo message="foreach.file is ${foreach.file}" /&gt;
 *   &lt;echo message="foreach.dir is ${foreach.dir}" /&gt;
 *   &lt;echo message="foreach.name.ext is ${foreach.name.ext}" /&gt;
 *   &lt;echo message="foreach.name is ${foreach.name}" /&gt;
 * &lt;/target&gt;
 * </pre>
 *
 * <p>This only works as expected if neither property1 nor foo are
 * defined in the project itself.
 *
 * @author  Stefano Mazzocchi
 *         <a href="mailto:stefano@apache.org">stefano@apache.org</a>
 * @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>
 * @author Glenn McAllister
 *         <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
 * @author Jon S. Stevens <a
href="mailto:jon@latchkey.com">jon@latchkey.com</a>
 * @author Jan Vanovcan <a href="mailto:jan.vanovcan@logicacmg.com">
 * jan.vanovcan@logicacmg.com</a>
 *
 * @since Ant 1.5.1
 *
 * @ant.task name="foreach" category="control"
 */
public class ForEach extends MatchingTask {

        protected File file = null;
        protected File dir = null;
        protected Vector filesets = new Vector();
        protected boolean usedMatchingTask = false;
        // by default, process matching empty dirs
        protected boolean includeEmpty = false;

        private int verbosity = Project.MSG_VERBOSE;
        private boolean quiet = false;
        private boolean failonerror = true;

        /*
         * The target(s) we will call
         */
        private Vector callTarget = new Vector();

        /**
         * Set the call target tha should be invoked
         *
         * @param task the call target to be invoked
         */
        public void addConfiguredAntcall(CallTarget task) {
                if (task == null)
                        throw new BuildException("Tried to add a NULL
<antcall>");
                callTarget.addElement(task);
                log("Added call target...", Project.MSG_DEBUG);
        }

        /*
         * From this point on the source code is copied from the Ant's
Delete task.
         * The only difference is in replacing word 'Delete/Remove' by
'Process'. Of
         * course the private methods are replaced.
         */

        /**
         * Set the name of a single file to be processed.
         *
         * @param file the file to be processed
         */
        public void setFile(File file) {
                this.file = file;
        }

        /**
         * Set the directory from which files are to be processed
         *
         * @param dir the directory path.
         */
        public void setDir(File dir) {
                this.dir = dir;
        }

        /**
         * If true, list all names of processed files.
         *
         * @param verbose "true" or "on"
         */
        public void setVerbose(boolean verbose) {
                if (verbose) {
                        this.verbosity = Project.MSG_INFO;
                } else {
                        this.verbosity = Project.MSG_VERBOSE;
                }
        }

        /**
         * If true and the file does not exist, do not display a diagnostic
         * message or modify the exit status to reflect an error.
         * This means that if a file or directory cannot be processed, then
no
         * error is reported. Default is false meaning things are &quot;
         * noisy&quot;
         * @param quiet "true" or "on"
         */
        public void setQuiet(boolean quiet) {
                this.quiet = quiet;
                if (quiet) {
                        this.failonerror = false;
                }
        }

        /**
         * If false, note errors but continue.
         *
         * @param failonerror true or false
         */
        public void setFailOnError(boolean failonerror) {
                this.failonerror = failonerror;
        }

        /**
         * If true, process empty directories.
         */
        public void setIncludeEmptyDirs(boolean includeEmpty) {
                this.includeEmpty = includeEmpty;
        }

        /**
          * Adds a set of files to be processed.
          */
        public void addFileset(FileSet set) {
                filesets.addElement(set);
        }

        /**
         * add a name entry on the include list
         */
        public PatternSet.NameEntry createInclude() {
                usedMatchingTask = true;
                return super.createInclude();
        }

        /**
         * add a name entry on the include files list
         */
        public PatternSet.NameEntry createIncludesFile() {
                usedMatchingTask = true;
                return super.createIncludesFile();
        }

        /**
         * add a name entry on the exclude list
         */
        public PatternSet.NameEntry createExclude() {
                usedMatchingTask = true;
                return super.createExclude();
        }

        /**
         * add a name entry on the include files list
         */
        public PatternSet.NameEntry createExcludesFile() {
                usedMatchingTask = true;
                return super.createExcludesFile();
        }

        /**
         * add a set of patterns
         */
        public PatternSet createPatternSet() {
                usedMatchingTask = true;
                return super.createPatternSet();
        }

        /**
         * Sets the set of include patterns. Patterns may be separated by a
comma
         * or a space.
         *
         * @param includes the string containing the include patterns
         */
        public void setIncludes(String includes) {
                usedMatchingTask = true;
                super.setIncludes(includes);
        }

        /**
         * Sets the set of exclude patterns. Patterns may be separated by a
comma
         * or a space.
         *
         * @param excludes the string containing the exclude patterns
         */
        public void setExcludes(String excludes) {
                usedMatchingTask = true;
                super.setExcludes(excludes);
        }

        /**
         * Sets whether default exclusions should be used or not.
         *
         * @param useDefaultExcludes "true"|"on"|"yes" when default
exclusions
         *                           should be used, "false"|"off"|"no" when
they
         *                           shouldn't be used.
         */
        public void setDefaultexcludes(boolean useDefaultExcludes) {
                usedMatchingTask = true;
                super.setDefaultexcludes(useDefaultExcludes);
        }

        /**
         * Sets the name of the file containing the includes patterns.
         *
         * @param includesfile A string containing the filename to fetch
         * the include patterns from.
         */
        public void setIncludesfile(File includesfile) {
                usedMatchingTask = true;
                super.setIncludesfile(includesfile);
        }

        /**
         * Sets the name of the file containing the includes patterns.
         *
         * @param excludesfile A string containing the filename to fetch
         * the include patterns from.
         */
        public void setExcludesfile(File excludesfile) {
                usedMatchingTask = true;
                super.setExcludesfile(excludesfile);
        }

        /**
         * Process the file(s).
         */
        public void execute() throws BuildException {
                if (usedMatchingTask) {
                        log(
                                "DEPRECATED - Use of the implicit FileSet is
deprecated.  "
                                        + "Use a nested fileset element
instead.");
                }

                if (file == null && dir == null && filesets.size() == 0) {
                        throw new BuildException(
                                "At least one of the file or dir "
                                        + "attributes, or a fileset element,
"
                                        + "must be set.");
                }

                if (quiet && failonerror) {
                        throw new BuildException(
                                "quiet and failonerror cannot both be " +
"set to true",
                                location);
                }

                // process the single file
                if (file != null) {
                        if (file.exists()) {
                                if (file.isDirectory()) {
                                        log(
                                                "Directory "
                                                        +
file.getAbsolutePath()
                                                        + " cannot be
processed using the file attribute.  "
                                                        + "Use dir
instead.");
                                } else {
                                        log("Processing: " +
file.getAbsolutePath(), Project.MSG_VERBOSE);

                                        if (!process(file)) {
                                                String message =
                                                        "Unable to process
file " + file.getAbsolutePath();
                                                if (failonerror) {
                                                        throw new
BuildException(message);
                                                } else {
                                                        log(
                                                                message,
                                                                quiet ?
Project.MSG_VERBOSE : Project.MSG_WARN);
                                                }
                                        }
                                }
                        } else {
                                log(
                                        "Could not find file "
                                                + file.getAbsolutePath()
                                                + " to process.",
                                        Project.MSG_VERBOSE);
                        }
                }

                // process the directory
                if (dir != null
                        && dir.exists()
                        && dir.isDirectory()
                        && !usedMatchingTask) {

                        if (verbosity == Project.MSG_VERBOSE) {
                                log("Processing directory " +
dir.getAbsolutePath());
                        }
                        processDir(dir);
                }

                // process the files in the filesets
                for (int i = 0; i < filesets.size(); i++) {
                        FileSet fs = (FileSet) filesets.elementAt(i);
                        try {
                                DirectoryScanner ds =
fs.getDirectoryScanner(project);
                                String[] files = ds.getIncludedFiles();
                                String[] dirs = ds.getIncludedDirectories();
                                processFiles(fs.getDir(project), files,
dirs);
                        } catch (BuildException be) {
                                // directory doesn't exist or is not
readable
                                if (failonerror) {
                                        throw be;
                                } else {
                                        log(
                                                be.getMessage(),
                                                quiet ? Project.MSG_VERBOSE
: Project.MSG_WARN);
                                }
                        }
                }

                // process the files from the default fileset
                if (usedMatchingTask && dir != null) {
                        try {
                                DirectoryScanner ds =
super.getDirectoryScanner(dir);
                                String[] files = ds.getIncludedFiles();
                                String[] dirs = ds.getIncludedDirectories();
                                processFiles(dir, files, dirs);
                        } catch (BuildException be) {
                                // directory doesn't exist or is not
readable
                                if (failonerror) {
                                        throw be;
                                } else {
                                        log(
                                                be.getMessage(),
                                                quiet ? Project.MSG_VERBOSE
: Project.MSG_WARN);
                                }
                        }
                }
        }

 
/********************************************************************
         * Private methods
 
********************************************************************/

        /*
         * All processXXX methods finish here ;-)
         */
        private boolean process(File file) {
                /*
                 * Try to set up the environment...
                 */
                
                log("Processing : " + file.getAbsolutePath(),
Project.MSG_VERBOSE);
                String foreachFile = file.getAbsolutePath();
                this.getProject().setProperty("foreach.file", foreachFile);

                String foreachDir = new String("");
                int lastSlash = foreachFile.lastIndexOf(File.separatorChar);
                if (lastSlash > 0)
                        foreachDir = foreachFile.substring(0, lastSlash);
                this.getProject().setProperty("foreach.dir", foreachDir);

                String foreachNameExt = file.getName();
                this.getProject().setProperty("foreach.name.ext",
foreachNameExt);

                String foreachName = file.getName();
                int dotPosition = foreachName.lastIndexOf('.');
                if (dotPosition > 0)
                        foreachName = foreachName.substring(0, dotPosition);
                this.getProject().setProperty("foreach.name", foreachName);
               
                this.getProject().setProperty("foreach.name.withpath",
file.getPath());
               
                /*
                 * For each file in the fileset call the target with the
proper
                 * environment. The environment (properties) is set
according to the
                 * current file. All embedded tasks are executed--the order
is quite
                 * unknown (depends on Ant's insertion order), but should be
the same
                 * for each iteration.
                 */
                for (Enumeration iter = callTarget.elements();
                        iter.hasMoreElements();
                        ) {
                        CallTarget element = (CallTarget)
iter.nextElement();
                        element.perform();
                }
                return true;
        }

        private boolean processDir(File file) {
                String files[] = dir.list();
                if (files == null) {
                        throw new BuildException(
                                "The '" + dir.getAbsolutePath() + "' is not
a directory.",
                                location);
                }
                for (int i = 0; i < files.length; i++) {
                        File f = new File(files[i]);
                        process(f);
                }
                return true;
        }

        private boolean processFiles(File file, String[] s1, String[] s2) {
                for (int i = 0; i < s1.length; i++) {
                        process(new File(s1[i]));
                }
                return true;
        }

}

> -----Original Message-----
> From: Manjunath Rane [mailto:MRane@virtusa.com]
> Sent: Monday, January 13, 2003 8:44 AM
> To: Ant Developers List
> Subject: RE: echo and filesets
>
>
> sure, i would like it...please do forward the same
>
> Cheers,
> Manjunath Rane
>
> -----Original Message-----
> From: VanovcanJ@logica.com [mailto:VanovcanJ@logica.com]
> Sent: Monday, January 13, 2003 1:50 PM
> To: ant-dev@jakarta.apache.org
> Subject: RE: echo and filesets
>
>
> Matthew,
>
> I wrote a task that takes a fileset and calls any ant target
> for each file
> in the fileset. It passes several formats of the currently processed
> filename in properties:
>
> foreach.file--a full filename from the defined fileset,
> foreach.dir--the directory of the file,
> foreach.name.ext--the name of the file, without path but with
> extension,
> foreach.name--the name of the file, without path and without extension
>
> Example:
>
>  <target name="foo">
>    <foreach>
>      <fileset dir="${server.src}" casesensitive="yes">
>        <include name="**/*.java"/>
>        <exclude name="**/*Test*"/>
>      </fileset>
>      <antcall target="bar">
>        <param name="property1" value="aaaaa" />
>        <param name="foo" value="bar" />
>      </antcall>
>    </foreach>
>  </target>
>
>  <target name="bar" depends="init">
>    <echo message="prop is ${property1} ${foo}" />
>    <echo message="foreach.file is ${foreach.file}" />
>    <echo message="foreach.dir is ${foreach.dir}" />
>    <echo message="foreach.name.ext is ${foreach.name.ext}" />
>    <echo message="foreach.name is ${foreach.name}" />
>  </target>
>
> It is based on the core <delete> task.
>
> Are you interested in it? Is there anyone else interested?
> (Wouldn't mind to
> have it included in the Ant's distribution ;-))
> Jan
>
> > -----Original Message-----
> > From: Inger, Matthew [mailto:inger@Synygy.com]
> > Sent: Friday, January 10, 2003 8:25 PM
> > To: 'ant-dev@jakarta.apache.org'
> > Subject: echo and filesets
> >
> >
> > Would it be possible (i would even be willing to write the code) to
> > extend the echo task so that it could take a fileset argument?  And
> > it would either echo the fileset to the standard output area, or to
> > the file specified in the command?
> >
> > ie.
> >
> >
> > <fileset id="myFs" dir="src" includes="**/*.java" />
> >
> > <echo file="fileList.txt">
> >   <fileset refid="myFs" />
> > </echo>
> >
> >
> > Reason i ask is that right now, we are using the exec command
> > and specifying an output file for a "cmd.exe /c dir /s /b
> > *.java" command to
> > get the filelist.  I'd rather do it in a more os independent manner.
> >
> > Once we have the file, we're passing the filename to the <ajc>
> > (aspect java compiler) for processing.  It uses the contents of
> > this file to actually build the project (it needs all java
> file names
> > to completely aspect and produce appropriate class files).
> >
> > http://www.aspectj.org  for more info on aspectj
> >
> >
> >
>
> This e-mail and any attachment is for authorised use by the intended
> recipient(s) only.  It may contain proprietary material, confidential
> information and/or be subject to legal privilege.  It should
> not be copied,
> disclosed to, retained or used by, any other party.  If you are not an
> intended recipient then please promptly delete this e-mail and any
> attachment and all copies and inform the sender.  Thank you.
>
> --
> To unsubscribe, e-mail:  
<mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>

This e-mail and any attachment is for authorised use by the intended recipient(s) only.  It
may contain proprietary material, confidential information and/or be subject to legal privilege.
 It should not be copied, disclosed to, retained or used by, any other party.  If you are
not an intended recipient then please promptly delete this e-mail and any attachment and all
copies and inform the sender.  Thank you.

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message