1 18 19 package org.objectweb.jac.ide; 20 21 import com.sun.tools.javac.Main; 22 import gnu.regexp.RE; 23 import gnu.regexp.REException; 24 import gnu.regexp.REMatch; 25 import java.io.BufferedReader; 26 import java.io.ByteArrayInputStream; 27 import java.io.ByteArrayOutputStream; 28 import java.io.FileInputStream; 29 import java.io.FileNotFoundException; 30 import java.io.FileOutputStream; 31 import java.io.FileWriter; 32 import java.io.FilenameFilter; 33 import java.io.IOException; 34 import java.io.InputStreamReader; 35 import java.io.PrintStream; 36 import java.io.Writer; 37 import java.util.Arrays; 38 import java.util.Collection; 39 import java.util.HashSet; 40 import java.util.Hashtable; 41 import java.util.Iterator; 42 import java.util.List; 43 import java.util.Map; 44 import java.util.Set; 45 import java.util.Vector; 46 import java.util.jar.JarEntry; 47 import java.util.jar.JarOutputStream; 48 import java.util.jar.Manifest; 49 import org.apache.log4j.Logger; 50 import org.objectweb.jac.core.rtti.MethodItem; 51 import org.objectweb.jac.core.rtti.NamingConventions; 52 import org.objectweb.jac.lib.Attachment; 53 import org.objectweb.jac.util.Classes; 54 import org.objectweb.jac.util.File; 55 import org.objectweb.jac.util.Files; 56 import org.objectweb.jac.util.LineNumberWriter; 57 import org.objectweb.jac.util.Streams; 58 import org.objectweb.jac.util.Strings; 59 60 public class CodeGeneration { 61 static Logger logger = Logger.getLogger("ide.compile"); 62 63 69 public static void createProjectCode(Project project, String baseDir) 70 throws CannotGenerateException, IOException 71 { 72 createJavaCode(project,baseDir); 73 Iterator it = project.getApplications().iterator(); 74 while(it.hasNext()) { 75 Application cur = (Application)it.next(); 76 createApplicationCode(project, cur, new File(baseDir,cur.getGenerationName())); 77 } 78 print("generation completed for "+project.getName()+"."); 79 } 80 81 86 public static void createJavaCode(Project project, String baseDir) 87 throws CannotGenerateException, IOException, FileNotFoundException 88 { 89 Iterator it = Projects.types.getEnumeratedTypes().iterator(); 90 while(it.hasNext()) { 91 EnumeratedType enum = (EnumeratedType)it.next(); 92 createEnumCode(enum, new File(baseDir,enum.getPackagePath())); 93 } 94 it = project.getPackages().iterator(); 95 while(it.hasNext()) { 96 Package cur = (Package)it.next(); 97 createPackageCode(project, cur, 98 new File(baseDir,cur.getGenerationName()), 99 cur.getGenerationName()); 100 } 101 } 102 103 109 public static void createEnumCode(EnumeratedType enum, File dir) throws IOException { 110 print("Generating code for enum "+enum.getName()+"."); 111 dir.mkdirs(); 112 String enumName = Strings.toUSAscii(enum.getName()); 113 FileWriter out = new FileWriter(new File(dir, enumName+".java")); 114 try { 115 out.write("package "+enum.getPackagePath()+";\n"); 116 out.write("public interface "+enumName+" {\n"); 117 int value = enum.getStartValue(); 118 int step = enum.getStep(); 119 Iterator it = enum.getNames().iterator(); 120 while (it.hasNext()) { 121 StringBuffer nameBuf = new StringBuffer((String)it.next()); 122 Strings.toUSAscii(nameBuf); 123 Strings.toUpperCase(nameBuf); 124 Strings.replace(" '-/+",'_',nameBuf); 125 Strings.deleteChars("()[]",nameBuf); 126 String name = nameBuf.toString(); 127 StringBuffer buffer = new StringBuffer(name.length()); 129 for (int i=0; i<name.length(); i++) { 130 char c = name.charAt(i); 131 if (c != '.') 132 buffer.append(c); 133 } 134 name = buffer.toString(); 135 out.write(" int "+(Character.isDigit(name.charAt(0))?"_":"")+name+" = "+value+";\n"); 136 value += step; 137 } 138 out.write("}\n"); 139 } finally { 140 out.close(); 141 } 142 } 143 144 152 public static void createApplicationCode(Project prj, 153 Application app, 154 File baseDir) 155 throws CannotGenerateException, IOException 156 { 157 Iterator it = app.getAspectConfigurations().iterator(); 158 while (it.hasNext()) { 159 AspectConfiguration ac = (AspectConfiguration) it.next(); 160 createACFile(prj,ac,baseDir); 161 } 163 createJACFile(prj,app,baseDir); 164 } 165 166 171 static void writeWarning(Writer fw) { 172 try { 173 fw.write("//\n"+ 174 "// WARNING: this file has been automatically generated by JAC\n"+ 175 "// DO NOT MODIFY unless you know what you are doing\n"+ 176 "//\n"); 177 } catch(Exception e) { 178 e.printStackTrace(); 179 } 180 } 181 182 static transient Map aspectPlugins = new Hashtable(); 184 static { 185 aspectPlugins.put("rtti", new RttiPlugin()); 186 aspectPlugins.put("gui", new GuiPlugin()); 188 aspectPlugins.put("persistence", new PersistencePlugin()); 189 } 190 191 198 static void createACFile(Project project, 199 AspectConfiguration ac, File dir) { 200 try { 201 File f = new File(dir,ac.getGenerationName()+".acc"); 202 if (f.exists()) 203 f.delete(); 204 f.getParentFile().mkdirs(); 205 f.createNewFile(); 206 FileWriter fw = new FileWriter(f); 207 208 if (aspectPlugins.containsKey(ac.getName())) { 210 AspectPlugin plugin = 211 (AspectPlugin)aspectPlugins.get(ac.getName()); 212 plugin.genConfig(fw,project); 213 } 214 215 if (ac.getDefaultConfigurationCode()!=null && 217 !ac.getDefaultConfigurationCode().equals("")) { 218 Collection classes = createClassesList(project); 219 Iterator itClasses = classes.iterator(); 220 while(itClasses.hasNext()) { 221 String classname = (String)itClasses.next(); 222 fw.write("class "+classname+" {\n"); 223 fw.write(ac.getDefaultConfigurationCode()); 224 fw.write("\n}\n"); 225 } 226 } 227 228 List configItems = project.getConfigItems(); 231 Iterator ite = configItems.iterator(); 232 fw.write("//CodeGeneration : generate Project code\n"); 233 while (ite.hasNext()){ 234 ConfigItem configItem = (ConfigItem)ite.next(); 235 if (configItem.getAspectConfiguration()==ac){ 236 fw.write(configItem.getMethod()+" "+translateParam(configItem)); 237 } 238 } 239 fw.write("//CodeGeneration : end of Project code\n\n"); 240 ite = project.getPackages().iterator(); 242 fw.write("//CodeGeneration : generate Package code\n"); 243 while(ite.hasNext()){ 244 Package pack = (Package)ite.next(); 245 generateConfigItemPackageCode(pack,ac,fw); 246 } 247 fw.write("//CodeGeneration : end of Package code\n\n"); 248 fw.write(ac.getConfigurationCode()); 250 fw.close(); 251 } catch(Exception e) { 252 e.printStackTrace(); 253 } 254 } 255 256 264 static Collection createClassesList(Project project) { 265 Vector result = new Vector(); 266 Iterator it = project.getPackages().iterator(); 267 while(it.hasNext()) { 268 Package cur = (Package)it.next(); 269 result.addAll(createClassesList(cur,cur.getGenerationName())); 270 } 271 return result; 272 } 273 274 282 static Collection createClassesList(Package project,String baseDir) { 283 Vector result = new Vector(); 284 Iterator it = project.getSubPackages().iterator(); 285 while(it.hasNext()) { 286 Package cur = (Package)it.next(); 287 result.addAll(createClassesList(cur,baseDir+"."+cur.getGenerationName())); 288 } 289 it = project.getClasses().iterator(); 290 while(it.hasNext()) { 291 Class cur = (Class)it.next(); 292 result.add(baseDir+"."+cur.getGenerationName()); 293 } 294 return result; 295 } 296 297 304 305 static void createJACFile(Project prj, Application app, File baseDir) 306 throws CannotGenerateException, IOException 307 { 308 File f = app.getJacFile(); 309 if (f.exists()) 310 f.delete(); 311 f.getParentFile().mkdirs(); 312 f.createNewFile(); 313 FileWriter fw = new FileWriter(f); 314 315 if (app.getMainClass()==null) { 316 throw new CannotGenerateException("No main class defined."); 317 } 318 fw.write("applicationName: "+app.getName()+"\n"+ 319 "launchingClass: "+app.getMainClass().getGenerationFullName()+"\n"); 320 321 if (app.getAspectConfigurations()!=null && 322 app.getAspectConfigurations().size()>0) { 323 fw.write( "aspects: "); 324 if (app.getAspectConfigurations().size()>0 && 325 !((AspectConfiguration)app.getAspectConfigurations().get(0)) 326 .getName().equals("rtti")) 327 { 328 fw.write( "rtti" 329 + " \"" + app.getGenerationName() 330 + "/" + "null.acc\"" 331 + " true "); 332 } 333 Iterator it = app.getAspectConfigurations().iterator(); 334 while(it.hasNext()) { 335 AspectConfiguration cur = (AspectConfiguration)it.next(); 336 if( ((org.objectweb.jac.core.ACManager)org.objectweb.jac.core.ACManager.get()) 337 .isACDeclared(cur.getName()) ) { 338 fw.write( cur.getName() 339 + " \"" + app.getGenerationName() 340 + "/" + cur.getGenerationName() + ".acc\"" 341 + " " + cur.isWoven() + " "); 342 } else { 343 fw.write( cur.getAspect().getGenerationFullName()+"AC" 344 + " \"" + app.getGenerationName() 345 + "/" + cur.getGenerationName() + ".acc\"" 346 + " " + cur.isWoven() + " "); 347 } 348 } 349 fw.write("\n\n"); 350 } 351 352 if (app.getHosts()!=null && app.getHosts().size()>0) { 353 fw.write( "\ntopology: "); 354 Iterator it = app.getHosts().iterator(); 355 while(it.hasNext()) { 356 String cur=(String)it.next(); 357 fw.write(cur+" "); 358 } 359 fw.write("\n\n"); 360 } 361 362 if (!app.getIgnoredClasses().isEmpty()) { 363 fw.write("\njac.toNotAdapt: "); 364 Iterator it = app.getIgnoredClasses().iterator(); 365 while(it.hasNext()) { 366 String expr = (String)it.next(); 367 fw.write(expr+" "); 368 } 369 fw.write("\n\n"); 370 } 371 372 fw.close(); 373 } 374 375 383 public static void createPackageCode(Project prj, 384 Package pkg, 385 File baseDir, 386 String ppath) 387 throws FileNotFoundException, IOException 388 { 389 baseDir.mkdirs(); 390 391 Iterator it = pkg.getSubPackages().iterator(); 392 while (it.hasNext()) { 393 Package cur = (Package)it.next(); 394 createPackageCode(prj, cur, 395 new File(baseDir,cur.getGenerationName()), 396 ppath+"."+cur.getGenerationName()); 397 } 398 it = pkg.getClasses().iterator(); 399 while (it.hasNext()) { 400 Class cur = (Class)it.next(); 401 if (cur instanceof Aspect) { 402 createAspectCode(prj,(Aspect)cur,baseDir,ppath); 403 } else { 404 createClassCode(prj,cur,baseDir,ppath); 405 } 406 } 407 408 it = pkg.getResources().iterator(); 409 while (it.hasNext()) { 410 Attachment res = (Attachment)it.next(); 411 FileOutputStream out = new FileOutputStream(new File(baseDir,res.getName())); 412 try { 413 byte[] data = res.getData(); 414 out.write(data,0,data.length); 415 } finally { 416 out.close(); 417 } 418 } 419 } 420 421 static transient Hashtable classesLineNumbers = new Hashtable(); 423 424 428 public static Map getClassLineNumbers(Class c) { 429 Map map = (Map)classesLineNumbers.get(c); 430 if (map==null) { 431 map = new Hashtable(); 432 classesLineNumbers.put(c,map); 433 } 434 return map; 435 } 436 437 445 public static void createClassCode(Project prj, Class c, 446 File baseDir, String ppath) { 447 try { 448 Map lineNumbers = getClassLineNumbers(c); 449 lineNumbers.clear(); 450 print("generating "+c.getFullName()); 451 File f = new File(baseDir,c.getGenerationName()+".java"); 452 classFiles.put(f.getAbsolutePath(),c); 453 if (f.exists()) 454 f.delete(); 455 f.getParentFile().mkdirs(); 456 f.createNewFile(); 457 String shortName = c.getGenerationName(); 458 LineNumberWriter output = new LineNumberWriter(Files.newFileWriter(f,"UTF-8")); 459 writeWarning(output); 460 output.write("\npackage "+ppath+";\n\n"); 461 String description = c.getDescription(); 462 463 HashSet generatedImports = new HashSet(); 464 Iterator it = c.getFields().iterator(); 466 while(it.hasNext()) { 467 Type type = ((Field)it.next()).getType(); 468 if (!(type instanceof EnumeratedType) && 469 type.getPackagePath()!=null && !type.getPackagePath().equals("") 470 && !generatedImports.contains(type.getGenerationFullName())) { 471 output.write("import "+type.getGenerationFullName()+";\n"); 472 generatedImports.add(type.getGenerationFullName()); 473 } 474 } 475 476 it = c.getImports().iterator(); 478 while(it.hasNext()) { 479 String imp = (String)it.next(); 480 if (!generatedImports.contains(imp)) { 481 output.write("import "+imp+";\n"); 482 generatedImports.add(imp); 483 } 484 } 485 486 if (description!=null && description.length()>0) 487 output.write("\n/**\n"+description+"\n*/\n"); 488 boolean isInterface = c instanceof Interface; 489 output.write("\npublic "+(c.isAbstract()?"abstract ":"")+ 490 (isInterface?"interface ":"class ")+ 491 shortName+ 492 ((c.getSuperClass() == null)?"":" extends "+ 493 c.getSuperClass().getGenerationFullName())); 494 Set interfaces = c.getInterfaces(); 495 if (!interfaces.isEmpty()) { 496 if (isInterface) 497 output.write(" extends "); 498 else 499 output.write(" implements "); 500 joinFullNames(output,interfaces,","); 501 } 502 output.write( " {\n" ); 503 List ms = c.getMethods(); 504 for (int i=0; i < ms.size(); i++) { 505 Method method = (Method)ms.get(i); 506 createMethodCode(output,lineNumbers,method,isInterface); 507 } 508 509 List fs = c.getFields(); 510 for (int i=0; i<fs.size(); i++) { 511 Field field = (Field)fs.get(i); 512 createFieldCode(output,lineNumbers,field,isInterface); 513 } 514 515 List rs = c.getLinks(); 516 for (int i=0; i<rs.size(); i++) { 517 Role role = (Role)rs.get(i); 518 if (role instanceof RelationRole) { 519 RelationRole relRole = (RelationRole)role; 520 RelationLink rel = (RelationLink)role.getLink(); 521 if (relRole.isNavigable()) { 522 createRelationCode(output,lineNumbers,rel,relRole,isInterface); 523 } 524 } 525 } 526 527 output.write("}\n"); 528 output.close(); 529 } catch( Exception e) { 531 e.printStackTrace(); 532 } 533 } 534 535 543 public static void createFieldCode(LineNumberWriter output, 544 Map lineNumbers, 545 Field field, 546 boolean isInterface) 547 throws IOException 548 { 549 String fieldName = field.getGenerationName(); 550 String type = field.getType().getGenerationFullName(); 551 552 if (!(field.isCalculated() || isInterface)) { 553 String description = field.getDescription(); 554 if (description!=null && description.length()>0) 555 output.write("\n/**\n" + description + "\n*/\n"); 556 lineNumbers.put(field,new Integer(output.getLines())); 557 output.write("\n " + field.getPrototype()); 558 String defaultValue = field.getDefaultValue(); 559 if (defaultValue!=null && !defaultValue.equals("")) { 560 output.write(" = "+defaultValue); 561 } 562 output.write(";\n"); 563 } 564 565 boolean isStatic = field.isStatic(); 566 if (!field.isReadOnly()) { 567 Setter setter = field.getSetter(); 568 if (setter==null) { 569 output.write("\n /**\n"+ 570 " * Sets the value of field "+fieldName+".\n"+ 571 " * @param "+fieldName+" value of field "+fieldName+ 572 "\n */\n"); 573 lineNumbers.put(field,new Integer(output.getLines())); 574 createSetter( 575 output,fieldName,type, isStatic, 576 field.isStatic()?field.getParent().getGenerationFullName():null, 577 isInterface); 578 } else { 579 createMethodCode(output,lineNumbers,setter,isInterface); 580 } 581 } 582 583 Getter getter = field.getGetter(); 584 if (getter==null) { 585 if (!field.isCalculated()) { 586 output.write("\n /**\n"+ 587 " * Gets the value of field "+fieldName+".\n"+ 588 " * @return value of field "+fieldName+ 589 "\n */\n"); 590 lineNumbers.put(field,new Integer(output.getLines())); 591 createGetter( 592 output,fieldName,type,isStatic, 593 field.isStatic()?field.getParent().getGenerationFullName():null, 594 isInterface); 595 } 596 } else { 597 createMethodCode(output,lineNumbers,field.getGetter(),isInterface); 598 } 599 } 600 601 public static void createRelationCode(LineNumberWriter output, 602 Map lineNumbers, 603 RelationLink rel, 604 RelationRole role, 605 boolean isInterface) 606 throws IOException 607 { 608 String roleGen = role.getGenerationName(); 609 String type = role.getAbstractType().getGenerationFullName(); 610 boolean isCalculated = rel.isCalculated(); 611 if (!isCalculated) { 612 output.write("\n " + role.getPrototype()+";\n"); 613 createSetter(output,roleGen,type,false,null,isInterface); 614 } 615 Method getter = role.getGetter(); 616 if (getter==null && !isCalculated) { 617 createGetter(output,roleGen,type,false,null,isInterface); 618 } else if (getter!=null) { 619 createMethodCode(output,lineNumbers,getter,isInterface); 620 } 621 622 if (role.isMultiple() && !isCalculated) { 623 Typed primaryKey = role.getPrimaryKey(); 624 type = role.getEnd().getGenerationFullName(); 625 626 Method adder = role.getAdder(); 627 if (adder==null) { 628 createAdder(output,roleGen,type,primaryKey); 629 } else { 630 createMethodCode(output,lineNumbers,adder,isInterface); 631 } 632 633 Method remover = role.getRemover(); 634 if (remover==null) { 635 createRemover(output,roleGen,type,primaryKey); 636 } else { 637 createMethodCode(output,lineNumbers,remover,isInterface); 638 } 639 640 Method clearer = role.getClearer(); 641 if (clearer==null) { 642 createClearer(output,roleGen); 643 } else { 644 createMethodCode(output,lineNumbers,clearer,isInterface); 645 } 646 if (primaryKey!=null) { 647 createIndexGetter(output,role); 648 } 649 } 650 } 651 652 659 public static void createMethodCode(LineNumberWriter output, 660 Map lineNumbers, 661 Method method, 662 boolean isInterface) 663 throws IOException 664 { 665 output.write("\n/**\n"); 666 String description = method.getDescription(); 667 if (description!=null) { 668 output.write(description); 669 } 670 Iterator params = method.getParameters().iterator(); 671 while (params.hasNext()) { 672 Parameter param = (Parameter)params.next(); 673 output.write("\n@param "+param.getGenerationName()+" "+ 674 param.getDescription()); 675 } 676 output.write("\n*/\n"); 677 lineNumbers.put(method,new Integer(output.getLines())); 678 output.write("\n "+method.getModifiers()+" "+ 681 method.getPrototype()); 682 if (method.isAbstract() || isInterface) { 683 output.write(";\n"); 684 } else { 685 output.write(" {"); 686 String body = method.getBody(); 687 if (body!=null) 688 output.write( "\n "+body); 689 output.write("\n }\n"); 690 } 691 } 692 693 701 public static void createAspectCode(Project prj,Aspect a, 702 File baseDir,String ppath) { 703 try { 704 print("generating "+a.getName()); 705 File f = new File(baseDir,a.getGenerationName() + "AC.java"); 706 if (f.exists()) 707 f.delete(); 708 f.getParentFile().mkdirs(); 709 f.createNewFile(); 710 String shortName = a.getGenerationName(); 711 FileWriter fw = new FileWriter(f); 712 writeWarning(fw); 713 fw.write( "\npackage "+ppath+";\n" ); 714 fw.write( "import org.objectweb.jac.core.*;\n" ); 715 fw.write( "import org.objectweb.jac.core.rtti.*;\n" ); 716 fw.write( "import org.objectweb.jac.util.*;\n" ); 717 fw.write( "\npublic class "+shortName+ 718 "AC extends org.objectweb.jac.core.AspectComponent"); 719 fw.write( " {\n" ); 720 fw.write( "\n public "+shortName+"AC() {"); 721 Iterator it = a.getPointcutLinks().iterator(); 722 while(it.hasNext()) { 723 PointcutLink pc = (PointcutLink)it.next(); 724 if(pc.getEnd() instanceof org.objectweb.jac.ide.Class) { 725 fw.write("\n pointcut(\""+ 726 "ALL\",\""+ 727 ((org.objectweb.jac.ide.Class)pc.getEnd()).getGenerationFullName()+"\",\""+ 728 pc.getMethodPCD()+"\","+ 729 "new "+shortName+"Wrapper(this)"+",\""+ 730 pc.getAspectRole()+"\",\""+ 731 pc.getHostPCD()+"\",null);"); 732 } else if (pc.getEnd() instanceof Instance) { 733 fw.write("\n pointcut(\""+ 734 ((Instance)pc.getEnd()).getGenerationName()+"\",\""+ 735 ((org.objectweb.jac.ide.Class)((Instance)pc.getEnd()).getType()).getGenerationName()+"\",\""+ 736 pc.getMethodPCD()+"\","+ 737 "new "+shortName+"Wrapper()"+",\""+ 738 pc.getAspectRole()+"\",\""+ 739 pc.getHostPCD()+"\");"); 740 } 741 } 742 fw.write("\n }"); 743 744 fw.write( "\n public class "+shortName+ 745 "Wrapper extends org.objectweb.jac.core.Wrapper {"); 746 747 fw.write( "\n public "+shortName+"Wrapper(AspectComponent ac) {"); 748 fw.write( "\n super(ac);"); 749 fw.write( "\n }"); 750 751 List ms = a.getMethods(); 752 for (int i=0; i<ms.size(); i++) { 753 Method method = (Method)ms.get(i); 754 fw.write("\n "+method.getModifiers()+" "+method.getPrototype()+" {" ); 755 fw.write("\n "+method.getBody()); 756 fw.write("\n }\n"); 757 } 758 759 List fs = a.getFields(); 760 for ( int i = 0; i < fs.size(); i++ ) { 761 Field field=(Field)fs.get(i); 762 fw.write( "\n " + field.getPrototype()+";\n" ); 763 } 766 767 778 779 fw.write("\n }"); 780 fw.write( "}\n" ); 781 fw.close(); 782 } catch( Exception e) { 784 e.printStackTrace(); 785 } 786 } 787 788 795 static void createGetter(Writer output, String name, String type, 796 boolean isStatic,String className, 797 boolean isInterface) 798 throws IOException 799 { 800 output.write("\n "+(isInterface?"":"public ")+ 801 (isStatic?"static ":"")+type+" get"+ 802 NamingConventions.capitalize(name)+"()"); 803 if (isInterface) { 804 output.write(";\n"); 805 } else { 806 output.write(" {\n"); 807 output.write(" return "+name+";\n"); 808 output.write(" }\n"); 809 } 810 } 811 812 819 static void createSetter(Writer output, String name, String type, 820 boolean isStatic, String className, 821 boolean isInterface) 822 throws IOException 823 { 824 output.write("\n "+(isInterface?"":"public")+ 825 (isStatic?" static":"")+" void "+getSetterName(name)+"("+ 826 type+" value)"); 827 if (isInterface) { 828 output.write(";\n"); 829 } else { 830 output.write(" {\n"); 831 if(className==null) { 832 output.write(" this."+name+"=value;\n"); 833 } else { 834 output.write(" "+className+"."+name+"=value;\n"); 835 } 836 output.write(" }\n"); 837 } 838 } 839 840 843 844 public static String getSetterName(String fieldName) { 845 return "set"+NamingConventions.capitalize(fieldName); 846 } 847 848 851 852 public static String getGetterName(String fieldName) { 853 return "get"+NamingConventions.capitalize(fieldName); 854 } 855 856 859 860 public static String getAdderName(String fieldName) { 861 String fn = NamingConventions.getNormalizedString(fieldName); 862 fn = Projects.plurals.getSingular(fn); 863 return "add"+fn; 864 } 865 866 869 870 public static String getClearerName(String fieldName) { 871 String fn = NamingConventions.getNormalizedString(fieldName); 872 fn = Projects.plurals.getSingular(fn); 873 return "clear"+fn; 874 } 875 876 879 880 public static String getRemoverName(String fieldName) { 881 String fn = NamingConventions.getNormalizedString(fieldName); 882 fn = Projects.plurals.getSingular(fn); 883 return "remove"+fn; 884 } 885 886 public static String keyWrapper(Typed keyField, String value) { 887 if (keyField.getType().isPrimitive()) { 888 return "new "+Classes.getPrimitiveTypeWrapper(keyField.getType().getName())+"("+value+")"; 889 } else { 890 return value; 891 } 892 } 893 894 901 static void createAdder(Writer output, String name, String type, 902 Typed primaryKey) 903 throws IOException 904 { 905 output.write("\n public void "+getAdderName(name)+"("+type+" value) {\n"); 906 if (primaryKey==null) 907 output.write(" "+name+".add(value);\n"); 908 else 909 output.write(" "+name+".put("+ 910 keyWrapper(primaryKey,"value."+getGetterName(primaryKey.getGenerationName())+"()")+ 911 ",value);\n"); 912 output.write(" }\n"); 913 } 914 915 916 923 static void createIndexGetter(Writer output, RelationRole role) 924 throws IOException 925 { 926 Typed primaryKey = role.getPrimaryKey(); 927 String keyName = primaryKey.getGenerationName(); 928 String returnType = role.getEnd().getGenerationName(); 929 output.write("\n public "+returnType+ 930 " get"+Projects.plurals.getSingular(NamingConventions.getNormalizedString(role.getGenerationName()))+"("+ 931 role.getPrimaryKey().getType().getGenerationName()+" "+ 932 keyName+") {\n"); 933 output.write(" return ("+returnType+")"+role.getGenerationName()+".get("+ 934 keyWrapper(primaryKey,keyName)+ 935 ");\n"); 936 output.write(" }\n"); 937 } 938 939 945 static void createRemover(Writer output, String name, String type, Typed primaryKey) 946 throws IOException 947 { 948 output.write("\n public void "+getRemoverName(name)+"("+type+" value) {\n"); 949 if (primaryKey==null) { 950 output.write(" "+name+".remove(value);\n"); 951 } else { 952 output.write(" "+name+".remove("+ 953 keyWrapper(primaryKey,"value."+getGetterName(primaryKey.getGenerationName())+"()")+ 954 ");\n"); 955 } 956 output.write(" }\n"); 957 } 958 959 966 static void createClearer(Writer output, String name) 967 throws IOException 968 { 969 String fn = NamingConventions.getNormalizedString(name); 970 output.write("\n public void clear"+ 971 fn+"() {\n"); 972 output.write(" "+name+".clear();\n"); 973 output.write(" }\n"); 974 } 975 976 983 static void createJavaFilesList(Project project, File baseDir, List list) { 984 Iterator it = Projects.types.getEnumeratedTypes().iterator(); 985 while(it.hasNext()) { 986 EnumeratedType enum = (EnumeratedType)it.next(); 987 list.add(new File(baseDir,enum.getPackagePath()+ 988 System.getProperty("file.separator")+ 989 Strings.toUSAscii(enum.getName())+".java").getPath()); 990 } 991 992 993 it = project.getPackages().iterator(); 994 while(it.hasNext()) { 995 Package cur = (Package)it.next(); 996 createJavaFilesList(cur, 997 new File(baseDir,cur.getGenerationName()), 998 list); 999 } 1000 } 1001 1002 1009 static void createJavaFilesList(Package pkg, File baseDir, List list) { 1010 Iterator it = pkg.getSubPackages().iterator(); 1011 while(it.hasNext()) { 1012 Package cur = (Package)it.next(); 1013 createJavaFilesList(cur, 1014 new File(baseDir,cur.getGenerationName()), 1015 list); 1016 } 1017 it = pkg.getClasses().iterator(); 1018 while(it.hasNext()) { 1019 Class cl = (Class)it.next(); 1020 if (cl instanceof Aspect) { 1021 list.add(new File(baseDir,cl.getGenerationName()+"AC.java").getPath()); 1022 } else { 1023 list.add(new File(baseDir,cl.getGenerationName()+".java").getPath()); 1024 } 1025 } 1026 1027 it = pkg.getResources().iterator(); 1028 while(it.hasNext()) { 1029 Attachment res = (Attachment)it.next(); 1030 if ("text/x-java".equals(res.getMimeType())) { 1031 list.add(new File(baseDir,res.getName()).getPath()); 1032 } 1033 } 1034 } 1035 1036 1044 static String createPackageFilesList(Project project,String baseDir) { 1045 StringBuffer result = 1046 new StringBuffer((baseDir.length()+10)*project.getPackages().size()); 1047 Iterator it = project.getPackages().iterator(); 1048 while(it.hasNext()) { 1049 Package cur = (Package)it.next(); 1050 result.append(baseDir + System.getProperty("file.separator") 1051 + cur.getGenerationName() + " "); 1052 } 1053 return result.toString(); 1054 } 1055 1056 static transient Hashtable classFiles = new Hashtable(); 1058 1059 1062 static Class filenameToClass(String filename) { 1063 Class cl = null; 1064 if ((cl = (Class)classFiles.get(filename))!=null) { 1065 return cl; 1066 } else { 1067 logger.error("Cannot find Class for filename "+filename); 1068 return null; 1069 } 1070 } 1071 1072 public static Errors generateAndCompileProjectCode(Project project, String baseDir) 1073 throws CannotGenerateException, CannotCompileException, IOException, InterruptedException 1074 { 1075 createProjectCode(project,baseDir); 1076 return compileProjectCode(project); 1077 } 1078 1079 1085 public static Errors compileProjectCode(Project project) 1086 throws CannotCompileException, IOException, InterruptedException 1087 { 1088 File baseDir = project.getGenerationPath(); 1089 Vector cmdList = new Vector(); 1090 if (!project.getUseToolsJavac()) 1091 cmdList.add(project.getCompilerCommand().toString()); 1092 String[] options = Strings.split(project.getCompilerOptions()," "); 1093 for (int i=0; i<options.length; i++) { 1094 cmdList.add(options[i]); 1095 } 1096 1097 File classesDir = project.getClassesDir(); 1098 cmdList.add("-d"); 1099 cmdList.add(classesDir.getPath()); 1100 1101 cmdList.add("-encoding"); 1103 cmdList.add("UTF-8"); 1104 1105 String classpathString = null; 1106 Collection classpath = new Vector(); 1107 classpath.addAll(project.getClasspath()); 1108 if (!classpath.contains(baseDir)) { 1109 classpath.add(baseDir); 1110 } 1111 if (!classpath.contains(classesDir)) { 1112 classpath.add(classesDir); 1113 } 1114 1115 String jacRoot = org.objectweb.jac.core.Jac.getJacRoot(); 1116 File jacClasses = new File(jacRoot,"classes"); 1117 if (jacClasses.exists() && !classpath.contains(jacClasses)) { 1118 classpath.add(jacClasses); 1119 } 1120 1121 File jacJar = new File(jacRoot+"jac.jar"); 1122 if (jacJar.exists() && !classpath.contains(jacJar)) { 1123 classpath.add(jacJar); 1124 } 1125 1126 File jacDir = new File(jacRoot,"lib"); 1127 java.io.File jars[] = jacDir.listFiles( 1128 new FilenameFilter() { 1129 public boolean accept(java.io.File file, String name) { 1130 return name.endsWith(".jar"); 1131 } 1132 } 1133 ); 1134 if (jars!=null) 1135 classpath.addAll(Arrays.asList(jars)); 1136 String sep = System.getProperty("file.separator"); 1137 classpath.add(new File(jacRoot+sep+"lib"+sep+"opt","jasperreports.jar")); 1138 1139 classpathString = Strings.createPathString(classpath); 1140 1141 logger.info("Classpath = "+classpathString); 1142 if (classpathString!=null) { 1143 cmdList.add("-classpath"); 1144 cmdList.add(classpathString); 1145 } 1146 1147 createJavaFilesList(project,baseDir,cmdList); 1148 1149 File f = new File(baseDir, "classes"); 1150 if (!f.exists()) 1151 f.mkdir(); 1152 1153 logger.info("CMD = "+cmdList); 1154 print("compiling project "+project.getName()+"..."); 1155 1156 BufferedReader reader = null; 1157 final String[] args = (String[])cmdList.toArray(new String[] {}); 1158 if (project.getUseToolsJavac()) { 1159 PrintStream oldErr = System.err; 1160 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1161 System.setErr(new PrintStream(out)); 1162 int res = Main.compile(args); 1163 System.setErr(oldErr); 1164 reader = new BufferedReader( 1165 new InputStreamReader( 1166 new ByteArrayInputStream(out.toByteArray()))); 1167 } else { 1168 Process comp; 1169 try { 1170 comp = Runtime.getRuntime().exec(args); 1171 } catch (IOException e) { 1172 throw new CannotCompileException( 1173 "Failed to start compilation process, is `"+ 1174 project.getCompilerCommand()+"' in your path?"); 1175 } 1176 reader = new BufferedReader( 1177 new InputStreamReader(comp.getErrorStream())); 1178 logger.debug("waiting for compilation to finish "+comp); 1179 } 1180 1181 Vector errors = new Vector(); 1182 String line; 1183 try { 1184 RE re = new RE("^([^:]+):([0-9]+)"); 1185 RE emptyLineRE = new RE("^[ ]*$"); 1186 while ((line=reader.readLine())!=null) { 1187 REMatch match; 1189 if ((match=re.getMatch(line))!=null) { 1190 errors.add(new Error(match.toString(1), 1193 Integer.parseInt(match.toString(2)), 1194 line, 1195 filenameToClass(match.toString(1)))); 1196 } else if (emptyLineRE.getMatch(line)==null) { 1197 errors.add(new Error(line)); 1198 } 1199 } 1200 } catch (REException e) { 1201 throw new CannotCompileException(e.getMessage()); 1202 } 1203 1205 print("compilation done."); 1206 return errors.isEmpty()?null:new Errors(errors); 1207 } 1208 1209 1212 public static void documentProjectCode(Project project,String baseDir) { 1213 String list = createPackageFilesList(project,baseDir); 1214 File f = new File(project.getGenerationPath(),"doc"); 1215 if (!f.exists()) 1216 f.mkdir(); 1217 String cmd = "javadoc -d "+new File(project.getGenerationPath(),"classes")+" "+list; 1218 } 1221 1222 1225 static void print(String msg) { 1226 org.objectweb.jac.aspects.gui.Actions.showStatus(msg); 1227 } 1228 1229 1236 static void generateConfigItemPackageCode(Package pack, AspectConfiguration ac, 1237 Writer fw) 1238 throws IOException 1239 { 1240 AccGenState state = new AccGenState(fw); 1241 Iterator iteClass = pack.getClasses().iterator(); 1242 while (iteClass.hasNext()) { 1244 Class c = (Class)iteClass.next(); 1245 1246 Iterator iteClassConfig = c.getConfigItems().iterator(); 1248 while (iteClassConfig.hasNext()) { 1249 ConfigItem configItem = (ConfigItem)iteClassConfig.next(); 1250 if (configItem.getAspectConfiguration()==ac){ 1251 state.openClass(c); 1252 state.write(translateParam(configItem)); 1253 } 1254 } 1255 1257 Iterator iteField = c.getFields().iterator(); 1259 while (iteField.hasNext()) { 1260 Field field = (Field)iteField.next(); 1261 Iterator iteFieldConfig = field.getConfigItems().iterator(); 1263 while (iteFieldConfig.hasNext()) { 1264 ConfigItem configItem = (ConfigItem)iteFieldConfig.next(); 1265 if (configItem.getAspectConfiguration()==ac){ 1266 state.openField(c,field); 1267 state.write(translateParam(configItem)); 1268 } 1269 } 1270 state.closeMember(); 1271 } 1272 1274 Iterator iteMethod = c.getMethods().iterator(); 1276 while (iteMethod.hasNext()) { 1277 Method method = (Method)iteMethod.next(); 1278 Iterator iteMethodConfig = method.getConfigItems().iterator(); 1280 while (iteMethodConfig.hasNext()) { 1281 ConfigItem configItem = (ConfigItem)iteMethodConfig.next(); 1282 if (configItem.getAspectConfiguration()==ac){ 1283 state.openMethod(c,method); 1284 state.write(translateParam(configItem)); 1285 } 1286 } 1287 state.closeMember(); 1288 } 1289 1291 1307 state.closeClass(); 1309 1310 } 1311 1312 Iterator itePackage = pack.getSubPackages().iterator(); 1314 while (itePackage.hasNext()) { 1315 Package apack = (Package)itePackage.next(); 1316 generateConfigItemPackageCode(apack, ac, fw); 1317 } 1318 } 1319 1320 1325 public final static String translateParam(ConfigItem config){ 1326 MethodItem method=config.getMethod(); 1327 if (method==null || "".equals(method.getName())) 1328 return ""; 1329 StringBuffer result=new StringBuffer(); 1330 result.append(method.getName()+" "); 1331 Iterator params = config.getParam().iterator(); 1332 while (params.hasNext()) { 1333 String s = (String)params.next(); 1334 int posBefore = 0, posAfter = 0; 1336 result.append("\""); 1337 while (posBefore!=-1){ 1338 posAfter=s.indexOf('\"',posBefore); 1339 if (posAfter==-1){ 1340 result.append(s.substring(posBefore)); 1341 posBefore = -1; 1342 }else{ 1343 result.append(s.substring(posBefore,posAfter)+"\\\""); 1344 if (posAfter==s.length()-1){ 1345 posBefore = -1; 1346 }else{ 1347 posBefore = posAfter+1; 1348 } 1349 } 1350 } 1351 result.append("\" "); 1352 } 1353 result.append(";\n"); 1354 return result.toString(); 1355 } 1356 1357 1364 public static void joinFullNames(Writer out, Collection items, String separator) 1365 throws IOException 1366 { 1367 Iterator it = items.iterator(); 1368 while (it.hasNext()) { 1369 out.write(((ModelElement)it.next()).getGenerationFullName()); 1370 if (it.hasNext()) 1371 out.write(separator); 1372 } 1373 } 1374 1375 1377 public static void generateCode(Projects projects) throws Exception { 1378 Iterator it = projects.getProjects().iterator(); 1379 while (it.hasNext()) { 1380 Project p = (Project)it.next(); 1381 generateCode(p); 1382 } 1383 } 1384 1385 public static Errors compile(Projects projects) throws Exception { 1386 Iterator it = projects.getProjects().iterator(); 1387 while (it.hasNext()) { 1388 Project p = (Project)it.next(); 1389 Errors errors = null; 1390 errors = compile(p); 1391 if (errors!=null) { 1392 return errors; 1393 } 1394 } 1395 return null; 1396 } 1397 1398 public static Errors generateAndCompile(Projects projects) throws Exception { 1399 Iterator it = projects.getProjects().iterator(); 1400 while (it.hasNext()) { 1401 Project p = (Project)it.next(); 1402 Errors errors = null; 1403 errors = generateAndCompile(p); 1404 if (errors!=null) { 1405 return errors; 1406 } 1407 } 1408 return null; 1409 } 1410 1411 1413 public static void generateCode(Package pkg) throws Exception { 1414 Project project = pkg.getProject(); 1415 project.checkGenerationPath(); 1416 createPackageCode( 1417 project, 1418 pkg, 1419 new File(project.getGenerationPath().getPath(),pkg.getPath()), 1420 pkg.getPPath()); 1421 } 1422 1423 1425 public static void generateCode(Class cl) throws Exception { 1426 Package pkg = cl.getContainer(); 1427 Project project = pkg.getProject(); 1428 project.checkGenerationPath(); 1429 createClassCode( 1430 project, 1431 cl, 1432 new File(project.getGenerationPath().getPath(),pkg.getPath()), 1433 pkg.getPPath()); 1434 } 1435 1436 1438 public static void generateCode(Project project) throws Exception { 1439 File generationPath = project.getGenerationPath(); 1440 if (generationPath!=null) { 1441 createProjectCode(project,generationPath.getPath()); 1442 } else { 1443 throw new CannotGenerateException( 1444 "Project \""+project.getName()+"\" does not have a generation path"); 1445 } 1446 } 1447 1448 public static void generateJavaCode(Project project) throws Exception { 1449 File generationPath = project.getGenerationPath(); 1450 if (generationPath!=null) { 1451 createJavaCode(project,generationPath.getPath()); 1452 } else { 1453 throw new CannotGenerateException( 1454 "Project \""+project.getName()+"\" does not have a generation path"); 1455 } 1456 } 1457 1458 public static Errors compile(Project project) 1459 throws CannotCompileException, IOException, InterruptedException 1460 { 1461 File generationPath = project.getGenerationPath(); 1462 if (generationPath!=null) { 1463 return compileProjectCode(project); 1464 } else { 1465 throw new CannotCompileException( 1466 "Project \""+project.getName()+"\" does not have a generation path"); 1467 } 1468 } 1469 1470 public static Errors generateAndCompile(Project project) 1471 throws CannotGenerateException, CannotCompileException, 1472 IOException, InterruptedException, Exception 1473 { 1474 generateJavaCode(project); 1475 return compile(project); 1476 } 1477 1478 1479 1482 public static void createJAR(Project project) throws IOException { 1483 createManifest(project); 1484 File generationPath = project.getGenerationPath(); 1485 JarOutputStream out = 1486 new JarOutputStream( 1487 new FileOutputStream( 1488 new File( 1489 generationPath, 1490 project.getGenerationName()+".jar")), 1491 new Manifest( 1492 new FileInputStream( 1493 new File(project.getManifestDir(), "MANIFEST.MF" ))) 1494 ); 1495 1496 File classesDir = project.getClassesDir(); 1498 Iterator it = 1499 project.getClassesDir().listFilesRecursively( 1500 new FilenameFilter() { 1501 public boolean accept(java.io.File file, String name) { 1502 return name.endsWith(".class"); 1503 } 1504 } 1505 ).iterator(); 1506 while (it.hasNext()) { 1507 File classFile = (File)it.next(); 1508 JarEntry entry = new JarEntry(classFile.getRelativePath(classesDir).replace('\\','/')); 1509 out.putNextEntry(entry); 1510 FileInputStream input = new FileInputStream(classFile); 1511 Streams.copy(input,out); 1512 out.closeEntry(); 1513 } 1514 1515 it = project.getApplications().iterator(); 1517 while (it.hasNext()) { 1518 Application application = (Application)it.next(); 1519 Iterator j = application.getAspectConfigurations().iterator(); 1520 File appDir = new File(generationPath,application.getGenerationName()); 1521 while (j.hasNext()) { 1522 AspectConfiguration ac = (AspectConfiguration)j.next(); 1523 File accFile = new File(appDir,ac.getGenerationName()+".acc"); 1524 JarEntry entry = 1525 new JarEntry( 1526 accFile.getRelativePath(generationPath).replace('\\','/')); 1527 out.putNextEntry(entry); 1528 FileInputStream input = new FileInputStream(accFile); 1529 Streams.copy(input,out); 1530 out.closeEntry(); 1531 } 1532 File jacFile = application.getJacFile(); 1533 JarEntry entry = new JarEntry(jacFile.getRelativePath(generationPath)); 1534 out.putNextEntry(entry); 1535 FileInputStream input = new FileInputStream(jacFile); 1536 Streams.copy(input,out); 1537 out.closeEntry(); 1538 } 1539 1540 it = project.getExternalFiles().entrySet().iterator(); 1542 while (it.hasNext()) { 1543 Map.Entry entry = (Map.Entry)it.next(); 1544 JarEntry jarEntry = new JarEntry((String)entry.getKey()); 1545 out.putNextEntry(jarEntry); 1546 FileInputStream input = new FileInputStream((File)entry.getValue()); 1547 Streams.copy(input,out); 1548 out.closeEntry(); 1549 } 1550 1551 it = project.getAllResources().entrySet().iterator(); 1553 while (it.hasNext()) { 1554 Map.Entry entry = (Map.Entry)it.next(); 1555 Package pkg = (Package)entry.getKey(); 1556 Attachment res = (Attachment)entry.getValue(); 1557 JarEntry jarEntry = 1558 new JarEntry( 1559 pkg.getGenerationName()+'/'+res.getName()); 1560 out.putNextEntry(jarEntry); 1561 ByteArrayInputStream input = new ByteArrayInputStream(res.getData()); 1562 Streams.copy(input,out); 1563 out.closeEntry(); 1564 } 1565 out.close(); 1566 } 1567 1568 public static void createManifest(Project project) throws IOException { 1569 File file = project.getManifestDir(); 1570 file.mkdir(); 1571 if (!file.exists()) 1572 new IOException("Could not create META-INF directory"); 1573 1574 FileWriter out = 1575 new FileWriter(new File(project.getManifestDir(), "MANIFEST.MF")); 1576 out.write("Manifest-Version: 1.0\n\n\n\n"); 1577 1578 File classesDir = project.getClassesDir(); 1580 Iterator it = 1581 project.getClassesDir().listFilesRecursively( 1582 new FilenameFilter() { 1583 public boolean accept(java.io.File file, String name) { 1584 return name.endsWith(".class"); 1585 } 1586 } 1587 ).iterator(); 1588 while (it.hasNext()) { 1589 File classFile = (File)it.next(); 1590 out.write("Name: "); 1591 out.write(classFile.getRelativePath(classesDir).replace('\\','/') ); 1592 out.write("\nJava-Bean: True\n\n"); 1593 } 1594 1595 out.close(); 1596 } 1597 1598 1600 public static void generateCode(AspectConfiguration ac) throws Exception { 1601 Project project = ac.getApplication().getProject(); 1602 project.checkGenerationPath(); 1603 CodeGeneration.createACFile( 1604 project,ac, 1605 new File(project.getGenerationPath().getPath(),ac.getApplication().getGenerationName())); 1606 } 1607 1608 public static void generateAndReload(AspectConfiguration ac) throws Throwable { 1609 generateCode(ac); 1610 ac.reload(); 1611 } 1612} 1613 | Popular Tags |