1 22 23 24 package com.mchange.v2.debug; 25 26 import java.io.*; 27 import java.util.*; 28 import com.mchange.v2.cmdline.*; 29 import com.mchange.v2.io.FileIterator; 30 import com.mchange.v2.io.DirectoryDescentUtils; 31 import com.mchange.v1.io.WriterUtils; 32 import com.mchange.v1.lang.BooleanUtils; 33 import com.mchange.v1.util.SetUtils; 34 import com.mchange.v1.util.StringTokenizerUtils; 35 36 public final class DebugGen implements DebugConstants 37 { 38 final static String [] VALID = new String [] 39 { 40 "codebase", 41 "packages" , 42 "trace", 43 "debug", 44 "recursive", 45 "javac", 46 "noclobber", 47 "classname", 48 "skipdirs", 49 "outputbase" 50 }; 51 52 final static String [] REQUIRED = new String [] 53 { "codebase", "packages" , "trace", "debug" }; 54 55 final static String [] ARGS = new String [] 56 { "codebase", "packages" , "trace", "debug", "classname", "outputbase" }; 57 58 final static String EOL; 59 60 static 61 { 62 EOL = System.getProperty("line.separator"); 63 } 64 65 static int trace_level; 66 static boolean debug; 67 static boolean recursive; 68 static String classname; 69 static boolean clobber; 70 static Set skipDirs; 71 72 public synchronized static final void main(String [] argv) 73 { 74 String codebase; 75 String outputbase; 76 File[] srcPkgDirs; 77 78 try 79 { 80 ParsedCommandLine pcl = CommandLineUtils.parse( argv, "--", VALID, REQUIRED, ARGS); 81 82 codebase = pcl.getSwitchArg("codebase"); 84 codebase = platify( codebase ); 85 if (! codebase.endsWith(File.separator)) 86 codebase += File.separator; 87 88 outputbase = pcl.getSwitchArg("outputbase"); 90 if ( outputbase != null ) 91 { 92 outputbase = platify( outputbase ); 93 if (! outputbase.endsWith(File.separator)) 94 outputbase += File.separator; 95 } 96 else 97 outputbase = codebase; 98 99 File outputBaseDir = new File( outputbase ); 100 if (outputBaseDir.exists()) 102 { 103 if (!outputBaseDir.isDirectory()) 104 { 105 System.exit(-1); 107 } 108 else if (!outputBaseDir.canWrite()) 109 { 110 System.err.println("Output Base '" + outputBaseDir.getPath() + "' is not writable!"); 111 System.exit(-1); 112 } 113 } 114 else if (! outputBaseDir.mkdirs() ) 115 { 116 System.err.println("Output Base directory '" + outputBaseDir.getPath() + "' does not exist, and could not be created!"); 117 System.exit(-1); 118 } 119 120 String [] packages = StringTokenizerUtils.tokenizeToArray(pcl.getSwitchArg("packages"),", \t"); 122 srcPkgDirs = new File[ packages.length ]; 123 for(int i = 0, len = packages.length; i < len; ++i) 124 srcPkgDirs[i] = new File(codebase + sepify(packages[i])); 125 126 trace_level = Integer.parseInt( pcl.getSwitchArg("trace") ); 128 129 debug = BooleanUtils.parseBoolean( pcl.getSwitchArg("debug") ); 131 132 classname = pcl.getSwitchArg("classname"); 134 if (classname == null) 135 classname = "Debug"; 136 137 recursive = pcl.includesSwitch("recursive"); 139 140 clobber = !pcl.includesSwitch("noclobber"); 142 143 String skipdirStr = pcl.getSwitchArg("skipdirs"); 145 if (skipdirStr != null) 146 { 147 String [] skipdirArray = StringTokenizerUtils.tokenizeToArray(skipdirStr, ", \t"); 148 skipDirs = SetUtils.setFromArray( skipdirArray ); 149 } 150 else 151 { 152 skipDirs = new HashSet(); 153 skipDirs.add("CVS"); 154 } 155 156 if ( pcl.includesSwitch("javac") ) 157 System.err.println("autorecompilation of packages not yet implemented."); 158 159 for (int i = 0, len = srcPkgDirs.length; i < len; ++i) 160 { 161 if (recursive) 162 { 163 if (! recursivePrecheckPackages( codebase, srcPkgDirs[i], outputbase, outputBaseDir )) 164 { 165 System.err.println("One or more of the specifies packages" + 166 " could not be processed. Aborting." + 167 " No files have been modified."); 168 System.exit(-1); 169 } 170 } 171 else 172 { 173 if (! precheckPackage( codebase, srcPkgDirs[i], outputbase, outputBaseDir )) 174 { 175 System.err.println("One or more of the specifies packages" + 176 " could not be processed. Aborting." + 177 " No files have been modified."); 178 System.exit(-1); 179 } 180 } 181 } 182 183 for (int i = 0, len = srcPkgDirs.length; i < len; ++i) 184 { 185 if (recursive) 186 recursiveWriteDebugFiles( codebase, srcPkgDirs[i], outputbase, outputBaseDir ); 187 else 188 writeDebugFile( outputbase, srcPkgDirs[i] ); 189 } 190 } 191 catch (Exception e) 192 { 193 e.printStackTrace(); 194 System.err.println(); 195 usage(); 196 } 197 } 198 199 private static void usage() 200 { 201 System.err.println("java " + DebugGen.class.getName() + " \\"); 202 System.err.println("\t--codebase=<directory under which packages live> \\ (no default)"); 203 System.err.println("\t--packages=<comma separated list of packages> \\ (no default)"); 204 System.err.println("\t--debug=<true|false> \\ (no default)"); 205 System.err.println("\t--trace=<an int between 0 and 10> \\ (no default)"); 206 System.err.println("\t--outputdir=<directory under which to generate> \\ (defaults to same dir as codebase)"); 207 System.err.println("\t--recursive \\ (no args)"); 208 System.err.println("\t--noclobber \\ (no args)"); 209 System.err.println("\t--classname=<class to generate> \\ (defaults to Debug)"); 210 System.err.println("\t--skipdirs=<directories that should be skipped> \\ (defaults to CVS)"); 211 } 212 213 private static String ify(String str, char fromChar, char toChar) 214 { 215 if ( fromChar == toChar ) return str; 216 217 StringBuffer sb = new StringBuffer (str); 218 for (int i = 0, len = sb.length(); i < len; ++i) 219 if (sb.charAt(i) == fromChar) 220 sb.setCharAt(i, toChar); 221 return sb.toString(); 222 } 223 224 private static String platify( String str ) 225 { 226 String out; 227 out = ify( str, '/', File.separatorChar ); 228 out = ify( out, '\\', File.separatorChar ); 229 out = ify( out, ':', File.separatorChar ); 230 return out; 231 } 232 233 private static String dottify(String str) 234 { return ify(str, File.separatorChar, '.');} 235 236 private static String sepify(String str) 237 { return ify(str, '.', File.separatorChar);} 238 239 private static boolean recursivePrecheckPackages(String codebase, File srcPkgDir, String outputbase, File outputBaseDir) throws IOException 240 { 241 FileIterator fii = DirectoryDescentUtils.depthFirstEagerDescent( srcPkgDir ); 242 while (fii.hasNext()) 243 { 244 File pkgDir = fii.nextFile(); 245 if (! pkgDir.isDirectory() || skipDirs.contains(pkgDir.getName())) 246 continue; 247 248 File outputDir = outputDir( codebase, pkgDir, outputbase, outputBaseDir ); 249 if (! outputDir.exists() && !outputDir.mkdirs() ) 250 { 251 System.err.println( "Required output dir: '" + outputDir + 252 "' does not exist, and could not be created."); 253 return false; 254 } 255 if (!precheckOutputPackageDir( outputDir )) 256 return false; 257 } 258 return true; 259 } 260 261 private static File outputDir( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) 262 { 263 if (codebase.equals(outputbase)) 265 return srcPkgDir; 266 267 String srcPath = srcPkgDir.getPath(); 268 if (! srcPath.startsWith( codebase )) 269 { 270 System.err.println(DebugGen.class.getName() + ": program bug. Source package path '" + srcPath + 271 "' does not begin with codebase '" + codebase + "'."); 272 System.exit(-1); 273 } 274 return new File( outputBaseDir, srcPath.substring( codebase.length() ) ); 275 } 276 277 278 private static boolean precheckPackage( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) throws IOException 279 { return precheckOutputPackageDir( outputDir(codebase, srcPkgDir, outputbase, outputBaseDir) ); } 280 281 private static boolean precheckOutputPackageDir(File dir) throws IOException 282 { 283 File outFile = new File( dir, classname + ".java" ); 284 if (! dir.canWrite()) 285 { 286 System.err.println("File '" + outFile.getPath() + "' is not writable."); 287 return false; 288 } 289 else if (!clobber && outFile.exists()) 290 { 291 System.err.println("File '" + outFile.getPath() + "' exists, and we are in noclobber mode."); 292 return false; 293 } 294 else 295 return true; 296 } 297 298 private static void recursiveWriteDebugFiles( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) throws IOException 299 { 300 FileIterator fii = DirectoryDescentUtils.depthFirstEagerDescent( outputDir( codebase, srcPkgDir, outputbase, outputBaseDir ) ); 301 while (fii.hasNext()) 302 { 303 File pkgDir = fii.nextFile(); 304 if (! pkgDir.isDirectory() || skipDirs.contains(pkgDir.getName())) 306 continue; 307 308 writeDebugFile(outputbase, pkgDir); 309 } 310 } 311 312 private static void writeDebugFile(String outputbase, File pkgDir) throws IOException 313 { 314 316 File outFile = new File( pkgDir, classname + ".java" ); 317 String pkg = dottify( pkgDir.getPath().substring( outputbase.length() ) ); 318 System.err.println("Writing file: " + outFile.getPath()); 319 Writer writer = null; 320 try 321 { 322 writer = new OutputStreamWriter( 323 new BufferedOutputStream( 324 new FileOutputStream( outFile ) ), "UTF8" ); 325 writer.write("/********************************************************************" + EOL); 326 writer.write(" * This class generated by " + DebugGen.class.getName() + EOL); 327 writer.write(" * and will probably be overwritten by the same! Edit at" + EOL); 328 writer.write(" * YOUR PERIL!!! Hahahahaha." + EOL); 329 writer.write(" ********************************************************************/" + EOL); 330 writer.write(EOL); 331 writer.write("package " + pkg + ';' + EOL); 332 writer.write(EOL); 333 writer.write("import com.mchange.v2.debug.DebugConstants;" + EOL); 334 writer.write(EOL); 335 writer.write("final class " + classname + " implements DebugConstants" + EOL); 336 writer.write("{" + EOL); 337 writer.write("\tfinal static boolean DEBUG = " + debug + ';' + EOL); 338 writer.write("\tfinal static int TRACE = " + traceStr( trace_level ) + ';' + EOL); 339 writer.write(EOL); 340 writer.write("\tprivate " + classname + "()" + EOL); 341 writer.write("\t{}" + EOL); 342 writer.write("}" + EOL); 343 writer.write(EOL); 344 writer.flush(); 345 } 346 finally 347 { WriterUtils.attemptClose( writer ); } 348 } 349 350 private static String traceStr( int trace ) 351 { 352 if (trace == TRACE_NONE) 353 return "TRACE_NONE"; 354 else if (trace == TRACE_MED) 355 return "TRACE_MED"; 356 else if (trace == TRACE_MAX) 357 return "TRACE_MAX"; 358 else 359 return String.valueOf(trace); 360 } 361 } 362 363 364 365 366 367 368 369 370 371 372 | Popular Tags |