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