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 }