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) 2008 Matt Cordes
012 * Copyright (C) 2008 John Lewis
013 *
014 * Redistribution and use in source and binary forms, with or without
015 * modification, are permitted provided that the following conditions
016 * are met:
017 *
018 * 1. Redistributions of source code must retain the above copyright
019 * notice, this list of conditions and the following disclaimer.
020 *
021 * 2. Redistributions in binary form must reproduce the above copyright
022 * notice, this list of conditions and the following disclaimer in
023 * the documentation and/or other materials provided with the
024 * distribution.
025 *
026 * 3. The end-user documentation included with the redistribution, if
027 * any, must include the following acknowlegement:
028 * "This product includes software developed by the
029 * Apache Software Foundation (http://www.apache.org/)."
030 * Alternately, this acknowlegement may appear in the software itself,
031 * if and wherever such third-party acknowlegements normally appear.
032 *
033 * 4. The names "Ant" and "Apache Software
034 * Foundation" must not be used to endorse or promote products derived
035 * from this software without prior written permission. For written
036 * permission, please contact apache@apache.org.
037 *
038 * 5. Products derived from this software may not be called "Apache"
039 * nor may "Apache" appear in their names without prior written
040 * permission of the Apache Group.
041 *
042 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
043 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
044 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
045 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
046 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
047 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
048 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
049 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
050 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
051 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
052 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
053 * SUCH DAMAGE.
054 * ====================================================================
055 *
056 * This software consists of voluntary contributions made by many
057 * individuals on behalf of the Apache Software Foundation. For more
058 * information on the Apache Software Foundation, please see
059 * <http://www.apache.org/>.
060 */
061
062 package net.sourceforge.cobertura.ant;
063
064 import java.io.File;
065 import java.io.IOException;
066 import java.net.URL;
067 import java.net.URLClassLoader;
068 import java.util.Iterator;
069 import java.util.LinkedList;
070 import java.util.List;
071
072 import net.sourceforge.cobertura.util.CommandLineBuilder;
073 import net.sourceforge.cobertura.util.StringUtil;
074
075 import org.apache.tools.ant.AntClassLoader;
076 import org.apache.tools.ant.BuildException;
077 import org.apache.tools.ant.DirectoryScanner;
078 import org.apache.tools.ant.Project;
079 import org.apache.tools.ant.taskdefs.Java;
080 import org.apache.tools.ant.taskdefs.MatchingTask;
081 import org.apache.tools.ant.types.FileSet;
082 import org.apache.tools.ant.types.AbstractFileSet;
083 import org.apache.tools.ant.types.DirSet;
084 import org.apache.tools.ant.types.Path;
085 import org.apache.tools.ant.types.Reference;
086
087 public abstract class CommonMatchingTask extends MatchingTask
088 {
089
090 final String className;
091 final List fileSets = new LinkedList();
092
093 private Java java = null;
094 private String maxMemory = null;
095
096 public CommonMatchingTask(String className)
097 {
098 this.className = className;
099 }
100
101 private String getClassName()
102 {
103 return className;
104 }
105
106 protected Java getJava()
107 {
108 if (java == null)
109 {
110 java = (Java)getProject().createTask("java");
111 java.setTaskName(getTaskName());
112 java.setClassname(getClassName());
113 java.setFork(true);
114 java.setDir(getProject().getBaseDir());
115 if (maxMemory != null)
116 java.setJvmargs("-Xmx" + maxMemory);
117
118 /**
119 * We replace %20 with a space character because, for some
120 * reason, when we call Cobertura from within CruiseControl,
121 * the classpath here contains %20's instead of spaces. I
122 * don't know if this is our problem, or CruiseControl, or
123 * ant, but this seems to fix it. --Mark
124 */
125 if (getClass().getClassLoader() instanceof AntClassLoader)
126 {
127 String classpath = ((AntClassLoader)getClass()
128 .getClassLoader()).getClasspath();
129 createClasspath().setPath(
130 StringUtil.replaceAll(classpath, "%20", " "));
131 }
132 else if (getClass().getClassLoader() instanceof URLClassLoader)
133 {
134 URL[] earls = ((URLClassLoader)getClass().getClassLoader())
135 .getURLs();
136 for (int i = 0; i < earls.length; i++)
137 {
138 String classpath = (new File(earls[i].getFile())).getAbsolutePath();
139 createClasspath().setPath(
140 StringUtil.replaceAll(classpath, "%20", " "));
141 }
142 }
143 }
144
145 return java;
146 }
147
148 protected void createArgumentsForFilesets( CommandLineBuilder builder) throws IOException {
149 Iterator iter = fileSets.iterator();
150 boolean filesetFound = false;
151 while (iter.hasNext())
152 {
153 AbstractFileSet fileSet = (AbstractFileSet)iter.next();
154
155 if (fileSet instanceof FileSet)
156 {
157 filesetFound = true;
158 builder.addArg("--basedir", baseDir(fileSet));
159 createArgumentsForFilenames( builder, getFilenames(fileSet));
160 }
161 else
162 {
163 if (filesetFound)
164 {
165 /*
166 * Once --basedir has been used, it cannot be undone without changes to the
167 * Main methods. So, any dirsets have to come before filesets.
168 */
169 throw new BuildException("Dirsets have to come before filesets");
170 }
171 createArgumentsForFilenames( builder, getDirectoryScanner(fileSet).getIncludedDirectories());
172 }
173 }
174 }
175
176 private void createArgumentsForFilenames( CommandLineBuilder builder, String[] filenames) throws IOException
177 {
178 for (int i = 0; i < filenames.length; i++)
179 {
180 getProject().log("Adding " + filenames[i] + " to list",
181 Project.MSG_VERBOSE);
182 builder.addArg(filenames[i]);
183 }
184 }
185
186 public Path createClasspath()
187 {
188 return getJava().createClasspath().createPath();
189 }
190
191 public void setClasspath(Path classpath)
192 {
193 createClasspath().append(classpath);
194 }
195
196 public void setClasspathRef(Reference r)
197 {
198 createClasspath().setRefid(r);
199 }
200
201 DirectoryScanner getDirectoryScanner(AbstractFileSet fileSet)
202 {
203 return fileSet.getDirectoryScanner(getProject());
204 }
205
206 String[] getIncludedFiles(AbstractFileSet fileSet)
207 {
208 return getDirectoryScanner(fileSet).getIncludedFiles();
209 }
210
211 String[] getExcludedFiles(FileSet fileSet)
212 {
213 return getDirectoryScanner(fileSet).getExcludedFiles();
214 }
215
216 String[] getFilenames(AbstractFileSet fileSet)
217 {
218 String[] filesToReturn = getIncludedFiles(fileSet);
219
220 return filesToReturn;
221 }
222
223 String baseDir(AbstractFileSet fileSet)
224 {
225 return fileSet.getDirectoryScanner(getProject()).getBasedir()
226 .toString();
227 }
228
229 public void addDirSet(DirSet dirSet)
230 {
231 fileSets.add(dirSet);
232 }
233
234 public void addFileset(FileSet fileSet)
235 {
236 fileSets.add(fileSet);
237 }
238
239 /**
240 * @param maxMemory Assumed to be something along the lines of
241 * 100M or 50K or 1G.
242 */
243 public void setMaxMemory(String maxMemory)
244 {
245 this.maxMemory = maxMemory != null ? maxMemory.trim() : null;
246 }
247 }