1 16 package org.apache.commons.attributes.compiler; 17 18 import java.io.BufferedReader ; 19 import java.io.File ; 20 import java.io.FileReader ; 21 import java.io.FileWriter ; 22 import java.io.PrintWriter ; 23 import java.util.ArrayList ; 24 import java.util.Collection ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.StringTokenizer ; 28 29 import org.apache.tools.ant.BuildException; 30 import org.apache.tools.ant.Project; 31 import org.apache.tools.ant.Task; 32 import org.apache.tools.ant.types.FileSet; 33 import org.apache.tools.ant.types.Path; 34 35 import xjavadoc.SourceClass; 36 import xjavadoc.XClass; 37 import xjavadoc.XConstructor; 38 import xjavadoc.XJavaDoc; 39 import xjavadoc.XField; 40 import xjavadoc.XMethod; 41 import xjavadoc.XParameter; 42 import xjavadoc.XProgramElement; 43 import xjavadoc.XTag; 44 import xjavadoc.ant.XJavadocTask; 45 import xjavadoc.filesystem.AbstractFile; 46 47 67 public class AttributeCompiler extends XJavadocTask { 68 69 private final ArrayList fileSets = new ArrayList (); 70 private Path src; 71 private File destDir; 72 private int numGenerated; 73 private int numIgnored; 74 private String attributePackages = ""; 75 76 public AttributeCompiler () { 77 } 78 79 public void setAttributePackages (String attributePackages) { 80 this.attributePackages = attributePackages; 81 } 82 83 public void addFileset (FileSet set) { 84 super.addFileset (set); 85 fileSets.add (set); 86 } 87 88 public void setDestdir (File destDir) { 89 this.destDir = destDir; 90 } 91 92 public void setSourcepathref (String pathref) { 93 String sourcePaths = project.getReference (pathref).toString (); 94 StringTokenizer tok = new StringTokenizer (sourcePaths, File.pathSeparator); 95 while (tok.hasMoreTokens ()) { 96 FileSet fs = new FileSet (); 97 fs.setDir (new File (tok.nextToken ())); 98 fs.setIncludes ("**/*.java"); 99 fs.setProject (project); 100 addFileset (fs); 101 } 102 } 103 104 protected void copyImports (File source, PrintWriter dest) throws Exception { 105 BufferedReader br = new BufferedReader (new FileReader (source)); 106 try { 107 String line = null; 108 while ((line = br.readLine ()) != null) { 109 if (line.startsWith ("import ")) { 110 dest.println (line); 111 } 112 } 113 } finally { 114 br.close (); 115 } 116 } 117 118 protected void addExpressions (Collection tags, PrintWriter pw, String collectionName, File sourceFile) { 119 addExpressions (tags, null, pw, collectionName, sourceFile); 120 } 121 122 protected void addExpressions (Collection tags, String selector, PrintWriter pw, String collectionName, File sourceFile) { 123 String fileName = sourceFile != null ? sourceFile.getPath ().replace ('\\', '/') : "<unknown>"; 124 Iterator iter = tags.iterator (); 125 while (iter.hasNext ()) { 126 XTag tag = (XTag) iter.next (); 127 128 if (isAttribute (tag)) { 129 String expression = tag.getName () + " " + tag.getValue (); 130 expression = expression.trim (); 131 132 expression = expression.substring (1); 134 135 if (selector != null) { 136 if (expression.startsWith (".")) { 137 String tagSelector = expression.substring (1, expression.indexOf (" ")); 139 expression = expression.substring (expression.indexOf (" ")).trim (); 140 if (!selector.equals (tagSelector)) { 141 continue; 143 } 144 } else { 145 continue; 147 } 148 } else { 149 if (expression.startsWith (".")) { 151 continue; 152 } 153 } 154 155 pw.println (" {"); 156 outputAttributeExpression (pw, expression, fileName, tag.getLineNumber (), "_attr"); 157 pw.println (" Object _oattr = _attr; // Need to erase type information"); 158 pw.println (" if (_oattr instanceof org.apache.commons.attributes.Sealable) {"); 159 pw.println (" ((org.apache.commons.attributes.Sealable) _oattr).seal ();"); 160 pw.println (" }"); 161 pw.println (" " + collectionName + ".add ( _attr );"); 162 pw.println (" }"); 163 } 164 } 165 } 166 167 protected void outputAttributeExpression (PrintWriter pw, String expression, String filename, int line, String tempVariableName) { 168 AttributeExpressionParser.ParseResult result = AttributeExpressionParser.parse (expression, filename, line); 169 pw.print (" " + result.className + " " + tempVariableName + " = new " + result.className + "("); 170 171 boolean first = true; 172 Iterator iter = result.arguments.iterator (); 173 while (iter.hasNext ()) { 174 AttributeExpressionParser.Argument arg = (AttributeExpressionParser.Argument) iter.next (); 175 if (arg.field == null) { 176 if (!first) { 177 pw.print (", "); 178 } 179 first = false; 180 pw.print (arg.text); 181 } 182 } 183 pw.println (" // " + filename + ":" + line); 184 pw.println (");"); 185 186 iter = result.arguments.iterator (); 187 while (iter.hasNext ()) { 188 AttributeExpressionParser.Argument arg = (AttributeExpressionParser.Argument) iter.next (); 189 if (arg.field != null) { 190 String methodName = "set" + arg.field.substring (0, 1).toUpperCase () + arg.field.substring (1); 191 pw.println (" " + tempVariableName + "." + methodName + "(\n" + 192 arg.text + " // " + filename + ":" + line + "\n" + 193 ");"); 194 } 195 } 196 } 197 198 protected boolean elementHasAttributes (Collection xElements) { 199 Iterator iter = xElements.iterator (); 200 while (iter.hasNext ()) { 201 XProgramElement element = (XProgramElement) iter.next (); 202 if (tagHasAttributes (element.getDoc ().getTags ())) { 203 return true; 204 } 205 } 206 return false; 207 } 208 209 214 private void getTransformedQualifiedName (XClass type, StringBuffer sb) { 215 216 if (type.isInner ()) { 217 String packageName = type.getContainingPackage ().getName (); 218 sb.append (packageName); 219 if (packageName.length () > 0) { 220 sb.append ("."); 221 } 222 sb.append (type.getName ().replace ('.','$')); 223 } else { 224 sb.append (type.getQualifiedName ()); 225 } 226 } 227 228 protected String getParameterTypes (Collection parameters) { 229 StringBuffer sb = new StringBuffer (); 230 for (Iterator params = parameters.iterator (); params.hasNext ();) { 231 XParameter parameter = (XParameter) params.next (); 232 getTransformedQualifiedName (parameter.getType (), sb); 233 sb.append (parameter.getDimensionAsString ()); 234 235 if (params.hasNext ()) { 236 sb.append (","); 237 } 238 } 239 return sb.toString (); 240 } 241 242 protected void generateClass (XClass xClass) throws Exception { 243 String name = null; 244 File sourceFile = null; 245 File destFile = null; 246 String packageName = null; 247 String className = null; 248 249 packageName = xClass.getContainingPackage().getName (); 250 251 if (xClass.isInner ()) { 252 name = xClass.getQualifiedName ().substring (packageName.length ()); 253 254 sourceFile = getSourceFile (xClass); 255 256 className = xClass.getName ().replace ('.', '$'); 257 name = packageName + (packageName.length () > 0 ? "." : "") + className; 258 } else { 259 name = xClass.getQualifiedName (); 260 sourceFile = getSourceFile (xClass); 261 className = xClass.getName (); 262 } 263 264 if (sourceFile == null) { 265 log ("Unable to find source file for: " + name); 266 } 267 268 destFile = new File (destDir, name.replace ('.', '/') + "$__attributeRepository.java"); 269 270 if (xClass.isAnonymous ()) { 271 log (xClass.getName () + " is anonymous - ignoring.", Project.MSG_VERBOSE); 272 numIgnored++; 273 return; 274 } 275 276 if (!hasAttributes (xClass)) { 277 if (destFile.exists ()) { 278 destFile.delete (); 279 } 280 return; 281 } 282 283 if (destFile.exists () && sourceFile != null && destFile.lastModified () >= sourceFile.lastModified ()) { 284 return; 285 } 286 287 numGenerated++; 288 289 290 destFile.getParentFile ().mkdirs (); 291 PrintWriter pw = new PrintWriter (new FileWriter (destFile)); 292 try { 293 if (packageName != null && !packageName.equals ("")) { 294 pw.println ("package " + packageName + ";"); 295 } 296 297 if (sourceFile != null) { 298 copyImports (sourceFile, pw); 299 } 300 301 StringTokenizer tok = new StringTokenizer (attributePackages, ";"); 302 while (tok.hasMoreTokens ()) { 303 pw.println ("import " + tok.nextToken () + ".*;"); 304 } 305 306 pw.println ("public class " + className + "$__attributeRepository implements org.apache.commons.attributes.AttributeRepositoryClass {"); 307 { 308 pw.println (" private final java.util.Set classAttributes = new java.util.HashSet ();"); 309 pw.println (" private final java.util.Map fieldAttributes = new java.util.HashMap ();"); 310 pw.println (" private final java.util.Map methodAttributes = new java.util.HashMap ();"); 311 pw.println (" private final java.util.Map constructorAttributes = new java.util.HashMap ();"); 312 pw.println (); 313 314 pw.println (" public " + className + "$__attributeRepository " + "() {"); 315 pw.println (" initClassAttributes ();"); 316 pw.println (" initMethodAttributes ();"); 317 pw.println (" initFieldAttributes ();"); 318 pw.println (" initConstructorAttributes ();"); 319 pw.println (" }"); 320 pw.println (); 321 322 pw.println (" public java.util.Set getClassAttributes () { return classAttributes; }"); 323 pw.println (" public java.util.Map getFieldAttributes () { return fieldAttributes; }"); 324 pw.println (" public java.util.Map getConstructorAttributes () { return constructorAttributes; }"); 325 pw.println (" public java.util.Map getMethodAttributes () { return methodAttributes; }"); 326 pw.println (); 327 328 pw.println (" private void initClassAttributes () {"); 329 addExpressions (xClass.getDoc ().getTags (), pw, "classAttributes", sourceFile); 330 pw.println (" }"); 331 pw.println (); 332 333 335 pw.println (" private void initFieldAttributes () {"); 336 pw.println (" java.util.Set attrs = null;"); 337 for (Iterator iter = xClass.getFields ().iterator (); iter.hasNext ();) { 338 XField member = (XField) iter.next (); 339 if (member.getDoc ().getTags ().size () > 0) { 340 String key = member.getName (); 341 342 pw.println (" attrs = new java.util.HashSet ();"); 343 addExpressions (member.getDoc ().getTags (), pw, "attrs", sourceFile); 344 pw.println (" fieldAttributes.put (\"" + key + "\", attrs);"); 345 pw.println (" attrs = null;"); 346 pw.println (); 347 } 348 } 349 pw.println (" }"); 350 351 353 pw.println (" private void initMethodAttributes () {"); 354 pw.println (" java.util.Set attrs = null;"); 355 pw.println (" java.util.List bundle = null;"); 356 for (Iterator iter = xClass.getMethods ().iterator (); iter.hasNext ();) { 357 XMethod member = (XMethod) iter.next (); 358 if (member.getDoc ().getTags ().size () > 0) { 359 StringBuffer sb = new StringBuffer (); 360 sb.append (member.getName ()).append ("("); 361 sb.append (getParameterTypes (member.getParameters ())); 362 sb.append (")"); 363 String key = sb.toString (); 364 365 pw.println (" bundle = new java.util.ArrayList ();"); 366 pw.println (" attrs = new java.util.HashSet ();"); 367 addExpressions (member.getDoc ().getTags (), null, pw, "attrs", sourceFile); 368 pw.println (" bundle.add (attrs);"); 369 pw.println (" attrs = null;"); 370 371 pw.println (" attrs = new java.util.HashSet ();"); 372 addExpressions (member.getDoc ().getTags (), "return", pw, "attrs", sourceFile); 373 pw.println (" bundle.add (attrs);"); 374 pw.println (" attrs = null;"); 375 376 for (Iterator parameters = member.getParameters ().iterator (); parameters.hasNext ();) { 377 XParameter parameter = (XParameter) parameters.next (); 378 pw.println (" attrs = new java.util.HashSet ();"); 379 addExpressions (member.getDoc ().getTags (), parameter.getName (), pw, "attrs", sourceFile); 380 pw.println (" bundle.add (attrs);"); 381 pw.println (" attrs = null;"); 382 } 383 384 pw.println (" methodAttributes.put (\"" + key + "\", bundle);"); 385 pw.println (" bundle = null;"); 386 pw.println (); 387 } 388 } 389 pw.println (" }"); 390 391 392 394 pw.println (" private void initConstructorAttributes () {"); 395 pw.println (" java.util.Set attrs = null;"); 396 pw.println (" java.util.List bundle = null;"); 397 for (Iterator iter = xClass.getConstructors ().iterator (); iter.hasNext ();) { 398 XConstructor member = (XConstructor) iter.next (); 399 if (member.getDoc ().getTags ().size () > 0) { 400 StringBuffer sb = new StringBuffer (); 401 sb.append ("("); 402 sb.append (getParameterTypes (member.getParameters ())); 403 sb.append (")"); 404 String key = sb.toString (); 405 406 pw.println (" bundle = new java.util.ArrayList ();"); 407 pw.println (" attrs = new java.util.HashSet ();"); 408 addExpressions (member.getDoc ().getTags (), null, pw, "attrs", sourceFile); 409 pw.println (" bundle.add (attrs);"); 410 pw.println (" attrs = null;"); 411 412 for (Iterator parameters = member.getParameters ().iterator (); parameters.hasNext ();) { 413 XParameter parameter = (XParameter) parameters.next (); 414 pw.println (" attrs = new java.util.HashSet ();"); 415 addExpressions (member.getDoc ().getTags (), parameter.getName (), pw, "attrs", sourceFile); 416 pw.println (" bundle.add (attrs);"); 417 pw.println (" attrs = null;"); 418 } 419 420 pw.println (" constructorAttributes.put (\"" + key + "\", bundle);"); 421 pw.println (" bundle = null;"); 422 pw.println (); 423 } 424 } 425 pw.println (" }"); 426 } 427 pw.println ("}"); 428 429 pw.close (); 430 } catch (Exception e) { 431 pw.close (); 432 destFile.delete (); 433 throw e; 434 } 435 } 436 437 444 protected File getSourceFile (XClass xClass) throws BuildException { 445 while (xClass != null && xClass.isInner ()) { 446 xClass = xClass.getContainingClass (); 447 } 448 449 if (xClass != null && xClass instanceof SourceClass) { 450 AbstractFile af = ((SourceClass) xClass).getFile (); 451 return new File (af.getPath ()); 452 } 453 return null; 454 } 455 456 protected boolean hasAttributes (XClass xClass) { 457 if (tagHasAttributes (xClass.getDoc ().getTags ()) || 458 elementHasAttributes (xClass.getFields ()) || 459 elementHasAttributes (xClass.getMethods ()) || 460 elementHasAttributes (xClass.getConstructors ()) ) { 461 return true; 462 } 463 return false; 464 } 465 466 470 protected boolean isAttribute (XTag tag) { 471 return tag.getName ().length () > 0 && tag.getName ().charAt (0) == '@'; 472 } 473 474 protected void start() throws BuildException { 475 destDir.mkdirs (); 476 numGenerated = 0; 477 478 XJavaDoc doc = getXJavaDoc (); 479 Iterator iter = doc.getSourceClasses ().iterator (); 480 try { 481 while (iter.hasNext ()) { 482 XClass xClass = (XClass) iter.next (); 483 generateClass (xClass); 484 } 485 } catch (Exception e) { 486 throw new BuildException (e.toString (), e); 487 } 488 log ("Generated attribute information for " + numGenerated + " classes. Ignored " + numIgnored + " classes."); 489 } 490 491 494 protected boolean tagHasAttributes (Collection tags) { 495 Iterator iter = tags.iterator (); 496 while (iter.hasNext ()) { 497 XTag tag = (XTag) iter.next (); 498 if (isAttribute (tag)) { 499 return true; 500 } 501 } 502 return false; 503 } 504 } | Popular Tags |