1 /** 2 * The utillib library. 3 * More information is available at http://www.jinchess.com/. 4 * Copyright (C) 2002 Alexander Maryanovsky. 5 * All rights reserved. 6 * 7 * The utillib library is free software; you can redistribute 8 * it and/or modify it under the terms of the GNU Lesser General Public License 9 * as published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * The utillib library is distributed in the hope that it will 13 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with utillib library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 package free.util; 23 24 import java.io.*; 25 26 27 /** 28 * A commandline utility application which adds text taken from a given file, 29 * and adds it to the beginning of all files with the given extension in a given 30 * directory. This is useful for adding license text to source code files. 31 * The modifying process of a single file includes renaming it to a file with 32 * the name of the original file, ".tmp" added to it, then creating a new file 33 * with the name of the original file, writing license information into the new 34 * file, writing the contents of the ".tmp" file into the new file and only then 35 * deleting the ".tmp" file. If at any point an I/O error occurrs, the utility 36 * terminates immediately. This ensures that at all times, either the original 37 * file or the ".tmp" file exist, preventing possible data loss. 38 */ 39 40 public class ApplyLicense{ 41 42 43 /** 44 * The main method, duh. 45 */ 46 main(String [] args)47 public static void main(String [] args){ 48 if (args.length<3){ 49 if (args.length!=0) 50 System.out.println("Not enough arguments."); 51 printUsage(); 52 System.exit(0); 53 } 54 55 boolean recurse = false; 56 boolean undo = false; 57 String backupDirName = null; 58 59 int argIndex = 0; 60 while (argIndex<args.length-3){ 61 String arg = args[argIndex]; 62 if (arg.equals("-r")) 63 recurse = true; 64 else if (arg.equals("-b")) 65 backupDirName = args[++argIndex]; 66 else if (arg.equals("-u")) 67 undo = true; 68 69 argIndex++; 70 } 71 72 if (argIndex>args.length-3){ 73 System.out.println("Not enough arguments"); 74 printUsage(); 75 System.exit(0); 76 } 77 78 String licenseFilename = args[args.length-3]; 79 String extension = args[args.length-2]; 80 String dirName = args[args.length-1]; 81 82 File backupDir = (backupDirName==null ? null : new File(backupDirName)); 83 File licenseFile = new File(licenseFilename); 84 File dir = new File(dirName); 85 86 if (!licenseFile.exists()){ 87 System.out.println("No such file: "+licenseFilename); 88 System.exit(0); 89 } 90 91 if (!dir.exists()){ 92 System.out.println("No such directory: "+dirName); 93 System.exit(0); 94 } 95 96 if (!dir.isDirectory()){ 97 System.out.println(dirName+" is a file, not a directory"); 98 System.exit(0); 99 } 100 101 if (backupDir != null){ 102 if (!backupDir.exists()){ 103 System.out.print("Creating backup directory "+backupDirName+" "); 104 if (!backupDir.mkdirs()){ 105 System.out.println("Unable to create backup directory "+backupDirName); 106 System.exit(0); 107 } 108 System.out.println("done"); 109 } 110 try{ 111 System.out.print("Backing up files in "+backupDir.getCanonicalPath()+" "); 112 IOUtilities.copyDir(dir, backupDir, recurse); 113 System.out.println("done"); 114 } catch (IOException e){ 115 System.out.println("Unable to backup files into "+backupDirName); 116 e.printStackTrace(); 117 System.exit(0); 118 } 119 } 120 121 try{ 122 String license = IOUtilities.loadTextFile(licenseFile); 123 if (undo) 124 removeLicense(license, new ExtensionFilenameFilter("."+extension), dir, recurse); 125 else 126 applyLicense(license, new ExtensionFilenameFilter("."+extension), dir, recurse); 127 } catch (IOException e){ 128 e.printStackTrace(); 129 System.exit(0); 130 } 131 } 132 133 134 135 136 /** 137 * Prints usage information to the standard output stream. 138 * Here is what this method prints: 139 * <PRE> 140 * 141 * ApplyLicense Utility 142 * Copyright (C) 2001 Alexander Maryanovsky 143 * 144 * Use: java free.util.ApplyLicense [-r][-b backupDir] licenseFile extension dir 145 * 146 * -r apply recursively into subdirectories 147 * -b backupDir Backup files into the given directory before applying license 148 * 149 * Version 1.00 - 05 Oct. 2001 150 * </PRE> 151 */ 152 printUsage()153 private static void printUsage(){ 154 System.out.println(); 155 System.out.println("ApplyLicense Utility"); 156 System.out.println("Copyright (C) 2001 Alexander Maryanovsky"); 157 System.out.println(); 158 System.out.println("Use: java free.util.ApplyLicense [-r][-b backupDir] licenseFile extension dir"); 159 System.out.println(); 160 System.out.println("-r Apply recursively into subdirectories"); 161 System.out.println("-u Undo applying the license"); 162 System.out.println("-b backupDir Backup files into the given directory before applying license"); 163 System.out.println(); 164 System.out.println("Version 1.00 - 05 Oct. 2001"); 165 } 166 167 168 169 170 /** 171 * Adds the given license string to the beginning of every file in the given 172 * directory, optionally recursing into subdirectories, which passes the given 173 * FilenameFilter. 174 * 175 * @throws IOException If an I/O error occurs during the processing of the 176 * file(s). 177 */ 178 applyLicense(String license, FilenameFilter filter, File dir, boolean recurse)179 public static void applyLicense(String license, FilenameFilter filter, File dir, boolean recurse) throws IOException{ 180 if (!dir.exists()) 181 throw new IllegalArgumentException("The directory "+dir+" does not exist"); 182 183 if (!dir.isDirectory()) 184 throw new IllegalArgumentException(dir.toString()+" is a file, not a directory"); 185 186 String [] filenames = dir.list(); 187 for (int i = 0; i < filenames.length; i++){ 188 String filename = filenames[i]; 189 File file = new File(dir, filename); 190 if (file.isDirectory()){ 191 if (recurse) 192 applyLicense(license, filter, file, true); 193 } 194 else if (filter.accept(dir, filename)){ 195 System.out.print("Prepending license text to: "+file); 196 prependLicense(license, file); 197 System.out.println(" done"); 198 } 199 } 200 } 201 202 203 204 205 /** 206 * Prepends the given text to the given file. 207 */ 208 prependLicense(String license, File file)209 private static void prependLicense(String license, File file) throws IOException{ 210 File tmpFile = new File(file.getAbsolutePath()+".tmp"); 211 if (!file.renameTo(tmpFile)) 212 throw new IOException("Unable to rename "+file+" into "+tmpFile); 213 214 OutputStream out = null; 215 InputStream in = null; 216 217 try{ 218 out = new FileOutputStream(file); 219 Writer writer = new BufferedWriter(new OutputStreamWriter(out)); 220 writer.write(license); 221 writer.flush(); 222 in = new FileInputStream(tmpFile); 223 IOUtilities.pump(in, out); 224 } finally{ 225 if (in != null) 226 in.close(); 227 if (out != null) 228 out.close(); 229 } 230 if (!tmpFile.delete()) 231 throw new IOException("Unable to delete "+tmpFile); 232 } 233 234 235 236 237 238 /** 239 * Removes the given license string from the beginning of every file in the 240 * given directory, optionally recursing into subdirectories, which passes 241 * the given FilenameFilter. 242 * 243 * @throws IOException If an I/O error occurs during the processing of the 244 * file(s). 245 */ 246 removeLicense(String license, FilenameFilter filter, File dir, boolean recurse)247 public static void removeLicense(String license, FilenameFilter filter, File dir, boolean recurse) throws IOException{ 248 if (!dir.exists()) 249 throw new IllegalArgumentException("The directory "+dir+" does not exist"); 250 251 if (!dir.isDirectory()) 252 throw new IllegalArgumentException(dir.toString()+" is a file, not a directory"); 253 254 String [] filenames = dir.list(); 255 for (int i = 0; i < filenames.length; i++){ 256 String filename = filenames[i]; 257 File file = new File(dir, filename); 258 if (file.isDirectory()){ 259 if (recurse) 260 removeLicense(license, filter, file, true); 261 } 262 else if (filter.accept(dir, filename)){ 263 System.out.print("Removing license text from: "+file); 264 deleteLicense(license, file); 265 System.out.println(" done"); 266 } 267 } 268 } 269 270 271 272 273 /** 274 * Prepends the specified text from the beginning of the given file. Returns 275 * <code>true</code> if the file indeed started with the specified text, 276 * false otherwise. 277 */ 278 deleteLicense(String license, File file)279 private static boolean deleteLicense(String license, File file) throws IOException{ 280 File tmpFile = new File(file.getAbsolutePath()+".tmp"); 281 if (!file.renameTo(tmpFile)) 282 throw new IOException("Unable to rename "+file+" into "+tmpFile); 283 284 OutputStream out = null; 285 InputStream in = null; 286 287 try{ 288 in = new FileInputStream(tmpFile); 289 int i = 0, b; 290 while (i < license.length()){ 291 b = in.read(); 292 if ((b==-1) || ((byte)b != license.charAt(i++))){ 293 in.close(); 294 in = null; 295 if (!tmpFile.renameTo(file)) 296 throw new IOException("Unable to rename "+tmpFile+" into "+file); 297 return false; 298 } 299 } 300 out = new FileOutputStream(file); 301 IOUtilities.pump(in, out); 302 } finally{ 303 if (in != null) 304 in.close(); 305 if (out != null) 306 out.close(); 307 } 308 if (!tmpFile.delete()) 309 throw new IOException("Unable to delete "+tmpFile); 310 311 return true; 312 } 313 314 315 316 } 317