1 /******************************************************************************* 2 * Copyright (c) 2011 LWJGL Project and others 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html, and under the terms of the 7 * BSD license, see http://lwjgl.org/license.php for details. 8 * 9 * Contributors: 10 * Jens von Pilgrim - initial implementation 11 ******************************************************************************/ 12 package org.lwjgl.ant; 13 14 import java.io.File; 15 import java.io.IOException; 16 import java.io.InputStream; 17 import java.util.Date; 18 import java.util.HashSet; 19 import java.util.Iterator; 20 import java.util.Set; 21 import java.util.StringTokenizer; 22 import java.util.TreeMap; 23 import java.util.Vector; 24 25 import org.apache.tools.ant.BuildException; 26 import org.apache.tools.ant.taskdefs.Expand; 27 import org.apache.tools.ant.types.PatternSet; 28 import org.apache.tools.ant.types.selectors.SelectorUtils; 29 import org.apache.tools.ant.util.FileNameMapper; 30 import org.apache.tools.ant.util.FileUtils; 31 32 /** 33 * Ant task extracting package names (or generally directory names) into given 34 * property. 35 * 36 * Parameters: 37 * - just like unzip, except dest can be null and is ignored otherwise 38 * - property - name of property storing the resulting list 39 * - pathsep - path separator, default "," 40 * - dirsep - directory separator, default "." 41 * - includeemptydirs -- whether to include empty directories, default: false 42 * 43 * @author Jens von Pilgrim 44 * @since 12.09.2007 45 */ 46 public class PackageList extends Expand { 47 48 /** 49 * The property to receive the conversion 50 */ 51 private String property = null; 52 53 /** 54 * User override on path sep char 55 */ 56 private String pathSep = ","; 57 58 /** 59 * User override on directory sep char 60 */ 61 private String dirSep = "."; 62 63 64 private boolean includeemptydirs = false; 65 66 class IntegerContainer { 67 int value; 68 inc()69 public void inc() { 70 value++; 71 } 72 }; 73 74 TreeMap<String, IntegerContainer> packagelist = new TreeMap<String, IntegerContainer>(); 75 76 /** 77 * {@inheritDoc} 78 * @see org.apache.tools.ant.taskdefs.Expand#execute() 79 */ 80 @Override execute()81 public void execute() throws BuildException { 82 83 setDest(new File(" no file, files are only listed internaly")); 84 super.execute(); 85 86 StringBuffer strb = new StringBuffer(); 87 for (String name : packagelist.keySet()) { 88 89 // System.out.println("name: " + name + " (" +packagelist.get(name).value + ")" ); 90 91 if (includeemptydirs || packagelist.get(name).value > 0) { 92 if (strb.length() > 0) { 93 strb.append(pathSep); 94 } 95 StringTokenizer stDirectory = new StringTokenizer(name, "/", 96 true); 97 98 while (stDirectory.hasMoreTokens()) { 99 String token = stDirectory.nextToken(); 100 strb.append("/".equals(token) ? dirSep : token); 101 } 102 } 103 } 104 105 if (property != null) { 106 String value = strb.toString(); 107 getProject().setNewProperty(property, value); 108 } 109 110 } 111 112 private Vector<PatternSet> patternsets = new Vector<PatternSet>(); 113 114 /** 115 * Add a patternset. 116 * @param set a pattern set 117 */ addPatternset(PatternSet set)118 public void addPatternset(PatternSet set) { 119 super.addPatternset(set); 120 patternsets.addElement(set); 121 } 122 123 /** 124 * {@inheritDoc} 125 * @see org.apache.tools.ant.taskdefs.Expand#extractFile(org.apache.tools.ant.util.FileUtils, java.io.File, java.io.File, java.io.InputStream, java.lang.String, java.util.Date, boolean, org.apache.tools.ant.util.FileNameMapper) 126 */ 127 @Override extractFile(FileUtils i_fileUtils, File i_srcF, File i_dir, InputStream i_compressedInputStream, String i_entryName, Date i_entryDate, boolean i_isDirectory, FileNameMapper i_mapper)128 protected void extractFile(FileUtils i_fileUtils, File i_srcF, File i_dir, 129 InputStream i_compressedInputStream, String i_entryName, 130 Date i_entryDate, boolean i_isDirectory, FileNameMapper i_mapper) 131 throws IOException { 132 133 if (!matchPatterns(i_entryName)) { 134 //Do not process this file 135 return; 136 } 137 138 String strDir = getDir(i_isDirectory, i_entryName); 139 if (strDir != null && !"META-INF".equals(strDir)) { 140 if (!packagelist.containsKey(strDir)) { 141 packagelist.put(strDir, new IntegerContainer()); 142 } 143 if (!i_isDirectory) { 144 packagelist.get(strDir).inc(); 145 } 146 } 147 148 } 149 150 /** 151 * @param i_entryName 152 */ matchPatterns(String i_entryName)153 private boolean matchPatterns(String i_entryName) { 154 if (patternsets != null && patternsets.size() > 0) { 155 boolean included = false; 156 String name = i_entryName.replace('/', File.separatorChar).replace( 157 '\\', File.separatorChar); 158 159 Set<String> includePatterns = new HashSet<String>(); 160 Set<String> excludePatterns = new HashSet<String>(); 161 for (int v = 0, size = patternsets.size(); v < size; v++) { 162 PatternSet p = (PatternSet) patternsets.elementAt(v); 163 String[] incls = p.getIncludePatterns(getProject()); 164 if (incls == null || incls.length == 0) { 165 // no include pattern implicitly means includes="**" 166 incls = new String[] { "**" }; 167 } 168 169 for (int w = 0; w < incls.length; w++) { 170 String pattern = incls[w].replace('/', File.separatorChar) 171 .replace('\\', File.separatorChar); 172 if (pattern.endsWith(File.separator)) { 173 pattern += "**"; 174 } 175 includePatterns.add(pattern); 176 } 177 178 String[] excls = p.getExcludePatterns(getProject()); 179 if (excls != null) { 180 for (int w = 0; w < excls.length; w++) { 181 String pattern = excls[w].replace('/', 182 File.separatorChar).replace('\\', 183 File.separatorChar); 184 if (pattern.endsWith(File.separator)) { 185 pattern += "**"; 186 } 187 excludePatterns.add(pattern); 188 } 189 } 190 } 191 192 for (Iterator<String> iter = includePatterns.iterator(); !included 193 && iter.hasNext();) { 194 String pattern = iter.next(); 195 included = SelectorUtils.matchPath(pattern, name); 196 } 197 198 for (Iterator<String> iter = excludePatterns.iterator(); included 199 && iter.hasNext();) { 200 String pattern = iter.next(); 201 included = !SelectorUtils.matchPath(pattern, name); 202 } 203 204 return included; 205 } 206 return true; 207 } 208 209 /** 210 * @param i_isDirectory 211 * @param i_entryName 212 * @return 213 */ getDir(boolean i_isDirectory, String i_entryName)214 private String getDir(boolean i_isDirectory, String i_entryName) { 215 216 if (i_entryName == null) 217 return null; 218 int iIndex = i_entryName.lastIndexOf('/'); 219 if (iIndex >= 0) { 220 return i_entryName.substring(0, iIndex); 221 } 222 if (i_isDirectory) { 223 return i_entryName; 224 } 225 return null; 226 } 227 228 /** 229 * Set the name of the property into which the converted path will be placed. 230 * @param p the property name. 231 */ setProperty(String p)232 public void setProperty(String p) { 233 property = p; 234 } 235 236 /** 237 * Set the default path separator string; defaults to current JVM 238 * {@link java.io.File#pathSeparator File.pathSeparator}. 239 * @param sep path separator string. 240 */ setPathSep(String sep)241 public void setPathSep(String sep) { 242 pathSep = sep; 243 } 244 245 /** 246 * Set the default directory separator string; 247 * defaults to current JVM {@link java.io.File#separator File.separator}. 248 * @param sep directory separator string. 249 */ setDirSep(String sep)250 public void setDirSep(String sep) { 251 dirSep = sep; 252 } 253 254 /** 255 * Simple getter for attribute includeemptydirs. 256 * @return the includeemptydirs 257 */ isIncludeemptydirs()258 public boolean isIncludeemptydirs() { 259 return includeemptydirs; 260 } 261 262 /** 263 * Simple setter for attribute includeemptydirs. 264 * @param i_includeemptydirs the includeemptydirs to set 265 */ setIncludeemptydirs(boolean i_includeemptydirs)266 public void setIncludeemptydirs(boolean i_includeemptydirs) { 267 includeemptydirs = i_includeemptydirs; 268 } 269 270 } 271