001package com.hfg.anttask; 002 003 004import org.apache.tools.ant.BuildException; 005import org.apache.tools.ant.DirectoryScanner; 006import org.apache.tools.ant.FileScanner; 007import org.apache.tools.ant.Task; 008import org.apache.tools.ant.types.PatternSet; 009 010import java.io.File; 011 012import com.hfg.util.BooleanUtil; 013import com.hfg.util.StringUtil; 014 015 016//------------------------------------------------------------------------------ 017/** 018 Ant task for assigning a file to a property. 019 <h3>Description</h3> 020 <p>If the specified file exists, this task sets the properties 021 <code><i><name></i></code>, <code><i><name></i>.name</code>, 022 <code><i><name></i>.wildcard</code>, 023 in the project. Properties are case sensitive.</p> 024 <p>Normally, this task is used with files whose names contain a variable portion, the 025 matching of which is facilitated by a PatternSet which allows '*' and '?' wildcarding 026 (see Ant's documentation). 027 </p> 028 <p> 029 If multiple files are found which match the file pattern, a BuildException is thrown. 030 </p> 031 032 <h3>Parameters</h3> 033 <table border="1" cellpadding="2" cellspacing="0"> 034 <caption>Parameter descriptions</caption> 035 <tr> 036 <td valign="top"><b>Attribute</b></td> 037 <td valign="top"><b>Description</b></td> 038 <td valign="top" align="center"><b>Required</b></td> 039 </tr> 040 <tr> 041 <td valign="top">name</td> 042 <td valign="top">The name (handle) of the property.</td> 043 <td valign="top" align="center">Yes</td> 044 </tr> 045 <tr> 046 <td valign="top">dir</td> 047 <td valign="top">The directory containing the file. If not 048 set, it defaults to the current directory.</td> 049 <td valign="top" align='center' rowspan='2'>Yes</td> 050 </tr> 051 <tr> 052 <td valign="top">file</td> 053 <td valign="top">The name of the file (may contain wildcards). 054 If not set, a directory is searched for in place of a file.</td> 055 </tr> 056 <tr> 057 <td valign="top">if</td> 058 <td valign="top">Only execute if a property of the given name exists in the current project.</td> 059 <td valign="top" align="center">No</td> 060 </tr> 061 <tr> 062 <td valign="top">unless</td> 063 <td valign="top">Only execute if a property of the given name doesn't exist in the current project.</td> 064 <td valign="top" align="center">No</td> 065 </tr> 066 </table> 067 <p> 068 The <code>if</code> and <code>unless</code> attributes make the 069 execution conditional -both probe for the named property being defined. 070 The <code>if</code> tests for the property being defined, the 071 <code>unless</code> for a property being undefined. 072 </p> 073 If both attributes are set, then the task executes only if both tests 074 are true. i.e. 075 <pre>execute := defined(ifProperty) && !defined(unlessProperty)</pre> 076 077 <h3>Examples</h3> 078 If <code>${lib.dir}</code> contained the file <code>commons-net-20040324.jar</code> 079 <pre> 080 <fileproperty name='commons_net' dir='${lib.dir}' file='commons-net-*.jar' /> 081 </pre> 082 would set the <code>commons_net</code> property to <code>${lib.dir}/commons-net-20040324.jar</code>, 083 the <code>commons_net.name</code> property to <code>commons-net-20040324.jar</code>, 084 the <code>commons_net.wildcard</code> property to <code>20040324</code> 085 086 @author J. Alex Taylor, hairyfatguy.com 087 */ 088//------------------------------------------------------------------------------ 089// com.hfg XML/HTML Coding Library 090// 091// This library is free software; you can redistribute it and/or 092// modify it under the terms of the GNU Lesser General Public 093// License as published by the Free Software Foundation; either 094// version 2.1 of the License, or (at your option) any later version. 095// 096// This library is distributed in the hope that it will be useful, 097// but WITHOUT ANY WARRANTY; without even the implied warranty of 098// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 099// Lesser General Public License for more details. 100// 101// You should have received a copy of the GNU Lesser General Public 102// License along with this library; if not, write to the Free Software 103// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 104// 105// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 106// jataylor@hairyfatguy.com 107//------------------------------------------------------------------------------ 108 109 110 111public class FileProperty extends Task 112{ 113 114 private String mName; 115 private PatternSet mPattern; 116 private File mDir = new File("."); 117 private String mIfCondition; 118 private String mUnlessCondition; 119 private boolean mDebug; 120 121 private int mMode = FILE_MODE; 122 123 private static int FILE_MODE = 1; 124 private static int DIR_MODE = 2; 125 126 //-------------------------------------------------------------------------- 127 public void setName(String name) 128 { 129 mName = name; 130 } 131 132 //-------------------------------------------------------------------------- 133 public void setFile(String file) 134 { 135 mPattern = new PatternSet(); 136 mPattern.setIncludes(file); 137 } 138 139 //-------------------------------------------------------------------------- 140 public void setDir(File dir) throws BuildException 141 { 142 mDir = dir; 143 } 144 145 //-------------------------------------------------------------------------- 146 public void setDebug(String inValue) throws BuildException 147 { 148 mDebug = BooleanUtil.valueOf(inValue); 149 } 150 151 152 //--------------------------------------------------------------------------- 153 /** 154 * Only execute if a property of the given name exists in the current project 155 * 156 * @param inPropertyName property name 157 */ 158 public void setIf(String inPropertyName) 159 { 160 mIfCondition = inPropertyName; 161 } 162 163 //--------------------------------------------------------------------------- 164 /** 165 * Only execute if a property of the given name does not exist in the current project 166 * 167 * @param inPropertyName property name 168 */ 169 public void setUnless(String inPropertyName) 170 { 171 mUnlessCondition = inPropertyName; 172 } 173 174 //-------------------------------------------------------------------------- 175 public void execute() 176 throws BuildException 177 { 178 if (TaskUtil.testIfCondition(mIfCondition, getProject()) 179 && TaskUtil.testUnlessCondition(mUnlessCondition, getProject())) 180 { 181 try 182 { 183 if (null == mPattern) 184 { 185 // No file pattern specified. Use the dir as a pattern 186 mPattern = new PatternSet(); 187 mPattern.setIncludes(mDir.getName()); 188 189 mDir = mDir.getParentFile(); 190 mMode = DIR_MODE; 191 } 192 193 if (mDir.exists() 194 && mDir.isDirectory()) 195 { 196 DirectoryScanner ds = getDirectoryScanner(); 197 198 if (mDebug) 199 { 200 System.out.println("Looking for file pattern " + StringUtil.singleQuote(mPattern.toString()) + " ..."); 201 } 202 203 String[] srcFiles = (mMode == FILE_MODE ? ds.getIncludedFiles() : ds.getIncludedDirectories()); 204 205 if (mDebug) 206 { 207 System.out.println(srcFiles.length + " matching files found."); 208 } 209 210 if (srcFiles.length > 1) 211 { 212 throw new BuildException("More than one file matches pattern."); 213 } 214 else if (srcFiles.length == 1) 215 { 216 File file = new File(mDir, srcFiles[0]); 217 getProject().setProperty(mName, file.getAbsolutePath()); 218 getProject().setProperty(mName + ".name", file.getName()); 219 setWildcardProperty(file.getName()); 220 } 221 } 222 else if (mDebug) 223 { 224 System.out.println("Directory " + StringUtil.singleQuote(mDir.getPath()) + " doesn't exist!"); 225 } 226 227 } 228 catch (Exception e) 229 { 230 throw new BuildException(e); 231 } 232 } 233 } 234 235 236 //-------------------------------------------------------------------------- 237 private void setWildcardProperty(String matchedFilename) 238 { 239 String patternString = mPattern.getIncludePatterns(getProject())[0]; 240 int wildcardIndex = patternString.indexOf("*"); 241 if (wildcardIndex >= 0) 242 { 243 String wildcard = ""; 244 if (wildcardIndex > 0) 245 { 246 String leftSide = patternString.substring(0, wildcardIndex); 247 wildcard = matchedFilename.substring(leftSide.length()); 248 } 249 250 String rightSide = patternString.substring(wildcardIndex + 1); 251 if (wildcardIndex < patternString.length() 252 && rightSide.length() < wildcard.length()) 253 { 254 wildcard = wildcard.substring(0, wildcard.length() - rightSide.length()); 255 } 256 257 getProject().setProperty(mName + ".wildcard", wildcard); 258 } 259 else 260 { 261 wildcardIndex = patternString.indexOf("?"); 262 if (wildcardIndex >= 0) 263 { 264 StringBuilder wildcard = new StringBuilder(); 265 while (wildcardIndex < patternString.length()) 266 { 267 if (patternString.charAt(wildcardIndex) == '?') 268 { 269 wildcard.append(matchedFilename.charAt(wildcardIndex)); 270 } 271 else 272 { 273 break; 274 } 275 wildcardIndex++; 276 } 277 278 getProject().setProperty(mName + ".wildcard", wildcard.toString()); 279 } 280 } 281 } 282 283 //-------------------------------------------------------------------------- 284 /** 285 * Returns the directory scanner needed to access the files to process. 286 */ 287 private DirectoryScanner getDirectoryScanner() 288 { 289 DirectoryScanner ds = new DirectoryScanner(); 290 setupDirectoryScanner(ds); 291 ds.scan(); 292 293 return ds; 294 } 295 296 //-------------------------------------------------------------------------- 297 private void setupDirectoryScanner(FileScanner ds) 298 { 299 if (ds == null) 300 { 301 throw new IllegalArgumentException("ds cannot be null"); 302 } 303 304 ds.setBasedir(mDir); 305 ds.setIncludes(mPattern.getIncludePatterns(getProject())); 306 } 307 308}