001    /*
002     * The Apache Software License, Version 1.1
003     *
004     * Copyright (C) 2000-2002 The Apache Software Foundation.  All rights
005     * reserved.
006     * Copyright (C) 2003 jcoverage ltd.
007     * Copyright (C) 2005 Mark Doliner
008     * Copyright (C) 2005 Joakim Erdfelt
009     * Copyright (C) 2005 Grzegorz Lukasik
010     * Copyright (C) 2006 Srivathsan Varadarajan
011     * Copyright (C) 2006 Matt Cordes
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 "Ant" 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    
061    package net.sourceforge.cobertura.ant;
062    
063    import java.io.File;
064    import java.io.IOException;
065    import java.net.URL;
066    import java.net.URLClassLoader;
067    import java.util.Iterator;
068    import java.util.LinkedList;
069    import java.util.List;
070    
071    import net.sourceforge.cobertura.util.CommandLineBuilder;
072    import net.sourceforge.cobertura.util.StringUtil;
073    
074    import org.apache.tools.ant.AntClassLoader;
075    import org.apache.tools.ant.DirectoryScanner;
076    import org.apache.tools.ant.Project;
077    import org.apache.tools.ant.taskdefs.Java;
078    import org.apache.tools.ant.taskdefs.MatchingTask;
079    import org.apache.tools.ant.types.FileSet;
080    import org.apache.tools.ant.types.Path;
081    import org.apache.tools.ant.types.Reference;
082    
083    public abstract class CommonMatchingTask extends MatchingTask
084    {
085    
086            final String className;
087            final List fileSets = new LinkedList();
088    
089            private Java java = null;
090            private String maxMemory = null;
091    
092            public CommonMatchingTask(String className)
093            {
094                    this.className = className;
095            }
096    
097            private String getClassName()
098            {
099                    return className;
100            }
101    
102            protected Java getJava()
103            {
104                    if (java == null)
105                    {
106                            java = (Java)getProject().createTask("java");
107                            java.setTaskName(getTaskName());
108                            java.setClassname(getClassName());
109                            java.setFork(true);
110                            java.setDir(getProject().getBaseDir());
111                            if (maxMemory != null)
112                                    java.setJvmargs("-Xmx" + maxMemory);
113    
114                            /**
115                             * We replace %20 with a space character because, for some
116                             * reason, when we call Cobertura from within CruiseControl,
117                             * the classpath here contains %20's instead of spaces.  I
118                             * don't know if this is our problem, or CruiseControl, or
119                             * ant, but this seems to fix it.  --Mark
120                             */
121                            if (getClass().getClassLoader() instanceof AntClassLoader)
122                            {
123                                    String classpath = ((AntClassLoader)getClass()
124                                                    .getClassLoader()).getClasspath();
125                                    createClasspath().setPath(
126                                                    StringUtil.replaceAll(classpath, "%20", " "));
127                            }
128                            else if (getClass().getClassLoader() instanceof URLClassLoader)
129                            {
130                                    URL[] earls = ((URLClassLoader)getClass().getClassLoader())
131                                                    .getURLs();
132                                    for (int i = 0; i < earls.length; i++)
133                                    {
134                                            String classpath = (new File(earls[i].getFile())).getAbsolutePath();
135                                            createClasspath().setPath(
136                                                            StringUtil.replaceAll(classpath, "%20", " "));
137                                    }
138                            }
139                    }
140    
141                    return java;
142            }
143    
144            protected void createArgumentsForFilesets( CommandLineBuilder builder) throws IOException {
145                    Iterator iter = fileSets.iterator();
146                    while (iter.hasNext())
147                    {
148                            FileSet fileSet = (FileSet)iter.next();
149    
150                            builder.addArg("--basedir", baseDir(fileSet));
151                            createArgumentsForFilenames( builder, getFilenames(fileSet));
152                    }
153            }
154    
155            private void createArgumentsForFilenames( CommandLineBuilder builder, String[] filenames) throws IOException
156            {
157                    for (int i = 0; i < filenames.length; i++)
158                    {
159                            getProject().log("Adding " + filenames[i] + " to list",
160                                            Project.MSG_VERBOSE);
161                            builder.addArg(filenames[i]);
162                    }
163            }
164    
165            public Path createClasspath()
166            {
167                    return getJava().createClasspath().createPath();
168            }
169    
170            public void setClasspath(Path classpath)
171            {
172                    createClasspath().append(classpath);
173            }
174    
175            public void setClasspathRef(Reference r)
176            {
177                    createClasspath().setRefid(r);
178            }
179    
180            DirectoryScanner getDirectoryScanner(FileSet fileSet)
181            {
182                    return fileSet.getDirectoryScanner(getProject());
183            }
184    
185            String[] getIncludedFiles(FileSet fileSet)
186            {
187                    return getDirectoryScanner(fileSet).getIncludedFiles();
188            }
189    
190            String[] getExcludedFiles(FileSet fileSet)
191            {
192                    return getDirectoryScanner(fileSet).getExcludedFiles();
193            }
194    
195            String[] getFilenames(FileSet fileSet)
196            {
197                    String[] filesToReturn = getIncludedFiles(fileSet);
198    
199                    return filesToReturn;
200            }
201    
202            String baseDir(FileSet fileSet)
203            {
204                    return fileSet.getDirectoryScanner(getProject()).getBasedir()
205                                    .toString();
206            }
207    
208            public void addFileset(FileSet fileSet)
209            {
210                    fileSets.add(fileSet);
211            }
212    
213            /**
214             * @param maxMemory Assumed to be something along the lines of
215             *        100M or 50K or 1G.
216             */
217            public void setMaxMemory(String maxMemory)
218            {
219                    this.maxMemory = maxMemory != null ? maxMemory.trim() : null;
220            }
221    }