1 23 24 25 package com.sun.jdo.api.persistence.enhancer.impl; 26 27 import java.io.*; 28 29 import java.util.Map ; 30 import java.util.Hashtable ; 31 import java.util.Iterator ; 32 33 import com.sun.jdo.api.persistence.enhancer.classfile.ClassFile; 34 import com.sun.jdo.api.persistence.enhancer.classfile.ClassField; 35 import com.sun.jdo.api.persistence.enhancer.classfile.ClassMethod; 36 import com.sun.jdo.api.persistence.enhancer.classfile.ConstClass; 37 38 import com.sun.jdo.api.persistence.enhancer.util.Support; 39 import com.sun.jdo.api.persistence.enhancer.util.UserException; 40 import com.sun.jdo.api.persistence.enhancer.util.ClassFileSource; 41 42 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaData; 44 45 46 64 65 70 public final class ClassControl 71 extends Support { 72 73 74 75 77 static public final int TransientOnly = -1; 79 80 81 static public final int PersistUnknown = 0; 82 83 85 static public final int PersistAware = 1; 87 88 91 static public final int PersistCapable = 2; 93 94 97 static public final int UpdateNotNeeded = -1; 99 100 103 static public final int UpdateUnknown = 0; 104 105 107 static public final int UpdateNew = 1; 108 109 112 static public final int UpdateNewer = 2; 113 114 115 private final Environment env; 118 119 120 private final ClassFileSource theClassSource; 122 123 124 private ClassFile theClass; 125 126 127 private int persistenceType = PersistUnknown; 128 129 130 134 135 136 140 141 142 146 147 148 private int updateType = UpdateUnknown; 149 150 151 private final ClassAction classAction; 153 154 155 private boolean classUpdated; 156 157 158 162 163 165 168 public boolean updated() { 169 return classUpdated; 170 } 171 172 175 181 182 185 public void noteUpdate() { 186 classUpdated = true; 187 } 188 189 192 public ClassFile classFile() { 193 return theClass; 194 } 195 196 199 public int persistType() { 200 return persistenceType; 201 } 202 203 206 212 213 217 227 228 231 239 240 245 public boolean filterRequired() { 246 if (updateType == UpdateUnknown) 247 checkUpdateType(); 248 return (updateType > UpdateUnknown || env.forceOverwrite()); 250 255 } 256 257 260 public void requireUpdate() { 261 updateType = UpdateNew; 262 } 263 264 268 public boolean annotateable() { 269 275 return (persistenceType >= PersistUnknown); 277 } 278 279 282 288 289 292 299 300 303 309 310 313 319 320 323 329 330 334 340 341 344 public ClassAction action() { 345 return classAction; 346 } 347 348 351 public ClassControl(ClassFileSource theSource, 353 Environment env) { 354 theClassSource = theSource; 355 buildTheClass(true ); 356 theClassSource.setExpectedClassName(className()); 357 classAction = new ClassAction(this, env); 358 this.env = env; 359 360 if (false) { 361 System.out.println("ClassControl(): new class = " + className()); } 363 } 364 365 368 public ClassControl(ClassFileSource theSource, 370 ClassFile theFile, 371 Environment env) { 372 theClassSource = theSource; 373 theClass = theFile; 374 theClassSource.setExpectedClassName(className()); 375 classAction = new ClassAction(this, env); 376 this.env = env; 377 378 if (false) { 379 System.out.println("ClassControl(): new class = " + className()); } 381 } 382 383 384 387 private void setPersistenceType() { 389 final JDOMetaData meta = env.getJDOMetaData(); 390 391 if (persistenceType != PersistUnknown) { 393 return; 394 } 395 396 if (classFile().isInterface()) { 398 persistenceType = TransientOnly; 399 return; 400 } 401 402 final String className = className(); 404 if (meta.isTransientClass(className)) { 405 persistenceType = TransientOnly; 406 return; 407 } 408 409 if (meta.isPersistenceCapableClass(className)) { 411 persistenceType = PersistCapable; 412 413 affirm(meta.isPersistenceCapableRootClass(className), 415 ("Sorry, not supported yet: the persistent-capable class " + userClassName() 417 + "cannot extend a persistent-capable super-class.")); } 419 } 420 421 424 public void scan1() { 425 try{ 427 if (env.doTimingStatistics()) { 428 Support.timer.push("ClassControl.scan1()"); } 430 setPersistenceType(); 432 433 437 438 if (annotateable()) { 439 if (filterRequired()) { 442 classAction.scan1(); 443 } else { 444 env.message("skipping " + userClassName() + " because it is already up to date."); } 448 } 449 } finally { 450 if (env.doTimingStatistics()) { 451 Support.timer.pop(); 452 } 453 } 454 } 455 456 459 468 469 472 public void augment() { 474 try{ 476 if (env.doTimingStatistics()) { 477 Support.timer.push("ClassControl.augment()"); } 479 if (annotateable()) { 480 if (filterRequired()) { 483 classAction.augment(); 484 } else { 485 env.message("skipping " + userClassName() + " because it is already up to date."); } 489 } 490 } finally { 491 if (env.doTimingStatistics()) { 492 Support.timer.pop(); 493 } 494 } 495 } 496 497 500 519 520 523 public void annotate() { 524 try{ 526 if (env.doTimingStatistics()) { 527 Support.timer.push("ClassControl.annotate()"); } 529 if (annotateable()) { 530 if (filterRequired()) { 531 classAction.annotate(); 532 } else { 533 env.message("skipping " + userClassName() + " because it is already up to date."); } 536 } 537 } finally { 538 if (env.doTimingStatistics()) { 539 Support.timer.pop(); 540 } 541 } 542 } 543 544 546 549 public String className() { 550 ConstClass cname = theClass.className(); 551 return (cname == null) ? null : cname.asString(); 552 } 553 554 557 public String userClassName() { 558 return userClassFromVMClass(className()); 559 } 560 561 564 static public String userClassFromVMClass(String vmName) { 566 return vmName.replace('/', '.'); 567 } 568 569 572 static public String vmClassFromUserClass(String userName) { 574 return userName.replace('.', '/'); 575 } 576 577 580 public String pkg() { 581 return packageOf(className()); 582 } 583 584 587 static public String packageOf(String vmName) { 588 int last = vmName.lastIndexOf('/'); 589 if (last < 0) 590 return ""; return vmName.substring(0, last); 592 } 593 594 597 603 604 607 616 617 620 public String sourceName() { 621 return theClassSource.containingFilePath(); 622 } 623 624 627 public ClassFileSource source() { 628 return theClassSource; 629 } 630 631 635 642 643 649 650 655 667 668 679 720 721 725 750 751 757 785 786 813 814 819 public void write(File destFile) 821 throws IOException, FileNotFoundException { 822 DataOutputStream dos = 823 theClassSource.getOutputStream(destFile); 824 theClass.write(dos); 825 dos.close(); 826 } 827 828 830 834 868 869 874 private void checkUpdateType() { 875 if (updateType == UpdateUnknown) { 876 String lookupName; 877 878 lookupName = className(); 880 894 895 ClassFileSource annotatedSource; 896 if (env.updateInPlace() && !theClassSource.isZipped()) 897 annotatedSource = theClassSource; 898 else 899 annotatedSource = env.lookupDestClass(lookupName); 900 901 if (annotatedSource == null) { 902 updateType = UpdateNew; 904 } else { 905 try { 906 long annModDate = annotatedSource.modificationDate(); 907 long srcModDate = source().modificationDate(); 908 if (annModDate < srcModDate) { 909 updateType = UpdateNewer; 912 } else { 913 if (annotatedSource == theClassSource 914 && !action().hasAnnotatedAttribute()) { 915 if (persistenceType == PersistCapable 918 || persistenceType == PersistAware) 919 updateType = UpdateNewer; 920 else 921 updateType = UpdateNotNeeded; 922 } else { 923 updateType = UpdateNotNeeded; 926 } 927 } 928 } catch (FileNotFoundException e) { 929 updateType = UpdateNew; 931 } 932 } 933 } 934 } 935 936 939 private void buildTheClass(boolean allowJDK12ClassFiles) { 940 if (false) { 941 System.out.println("Reading class " + theClassSource.expectedClassName()); 943 } 944 945 try { 953 DataInputStream dis = theClassSource.classFileContents(); 954 theClass = new ClassFile(dis); 955 dis.close(); 956 } catch (FileNotFoundException e) { 957 throw new UserException( 960 getI18N("enhancer.file_not_found", sourceName()), 962 e); 963 } catch (IOException e) { 964 throw new UserException( 966 getI18N("enhancer.io_error_while_reading_file", sourceName()), 968 e); 969 } 970 } 971 } 972 | Popular Tags |