1 29 30 package com.caucho.jsp; 31 32 import com.caucho.config.Config; 33 import com.caucho.java.JavaCompiler; 34 import com.caucho.jsp.cfg.JspConfig; 35 import com.caucho.jsp.cfg.JspPropertyGroup; 36 import com.caucho.jsp.cfg.JspTaglib; 37 import com.caucho.loader.CompilingLoader; 38 import com.caucho.loader.DirectoryLoader; 39 import com.caucho.loader.DynamicClassLoader; 40 import com.caucho.loader.EnvironmentBean; 41 import com.caucho.loader.EnvironmentClassLoader; 42 import com.caucho.loader.SimpleLoader; 43 import com.caucho.log.Log; 44 import com.caucho.server.util.CauchoSystem; 45 import com.caucho.server.webapp.WebApp; 46 import com.caucho.server.webapp.WebAppController; 47 import com.caucho.util.L10N; 48 import com.caucho.vfs.Path; 49 import com.caucho.vfs.Vfs; 50 51 import javax.servlet.SingleThreadModel ; 52 import javax.servlet.jsp.HttpJspPage ; 53 import javax.servlet.jsp.JspPage ; 54 import java.io.IOException ; 55 import java.io.InputStream ; 56 import java.util.ArrayList ; 57 import java.util.HashSet ; 58 import java.util.logging.Level ; 59 import java.util.logging.Logger ; 60 61 64 public class JspCompiler implements EnvironmentBean { 65 private static final L10N L = new L10N(JspCompiler.class); 66 private static final Logger log = Log.open(JspCompiler.class); 67 68 private ClassLoader _loader; 69 70 private WebApp _app; 71 72 private Path _classDir; 73 private Path _appDir; 74 75 private JspResourceManager _resourceManager; 76 private TaglibManager _taglibManager; 77 private final TagFileManager _tagFileManager; 78 79 private JspPropertyGroup _jspPropertyGroup; 80 81 private boolean _isXml; 82 private ArrayList <String > _preludeList = new ArrayList <String >(); 83 private ArrayList <String > _codaList = new ArrayList <String >(); 84 85 private HashSet <String > _compilingTags = new HashSet <String >(); 86 private boolean _hasRecursiveCompile; 87 88 private ArrayList <JspCompilerInstance> _pending = 89 new ArrayList <JspCompilerInstance>(); 90 91 public JspCompiler() 92 { 93 _loader = new EnvironmentClassLoader(); 94 95 _tagFileManager = new TagFileManager(this); 96 } 97 98 101 public ClassLoader getClassLoader() 102 { 103 return _loader; 104 } 105 106 109 public void setClassDir(Path path) 110 { 111 _classDir = path; 112 } 113 114 117 public void setClassDirectory(Path path) 118 { 119 setClassDir(path); 120 } 121 122 125 public Path getClassDir() 126 { 127 if (_classDir != null) 128 return _classDir; 129 else 130 return CauchoSystem.getWorkPath(); 131 } 132 133 136 public void setAppDir(Path path) 137 { 138 _appDir = path; 139 } 140 141 144 public Path getAppDir() 145 { 146 if (_appDir != null) 147 return _appDir; 148 else if (_app != null) 149 return _app.getAppDir(); 150 else 151 return null; 152 } 153 154 157 public void addPrelude(String prelude) 158 { 159 _preludeList.add(prelude); 160 } 161 162 165 public void addCoda(String coda) 166 { 167 _codaList.add(coda); 168 } 169 170 173 public void setXml(boolean isXml) 174 { 175 _isXml = isXml; 176 } 177 178 181 public boolean isXml() 182 { 183 return _isXml; 184 } 185 186 189 public void setResourceManager(JspResourceManager manager) 190 { 191 _resourceManager = manager; 192 } 193 194 197 public JspResourceManager getResourceManager() 198 { 199 return _resourceManager; 200 } 201 202 205 public TagFileManager getTagFileManager() 206 { 207 return _tagFileManager; 208 } 209 210 public TaglibManager getTaglibManager() 211 throws JspParseException, IOException 212 { 213 synchronized (this) { 214 if (_taglibManager == null) { 215 WebApp app = getWebApp(); 216 217 Path appDir = getAppDir(); 218 if (appDir == null && app != null) 219 appDir = app.getAppDir(); 220 221 JspResourceManager resourceManager = getResourceManager(); 222 if (resourceManager != null) { 223 } 224 else if (app != null) 225 resourceManager = new AppResourceManager(app); 226 else { 227 resourceManager = new AppDirResourceManager(appDir); 228 } 229 230 _taglibManager = new TaglibManager(resourceManager, 231 app, 232 _tagFileManager); 233 _taglibManager.setWebApp(app); 234 235 JspConfig jspConfig = null; 236 237 if (app != null) 238 jspConfig = (JspConfig) app.getExtension("jsp-config"); 239 240 if (jspConfig != null) { 241 ArrayList <JspTaglib> tldMapList = jspConfig.getTaglibList(); 242 for (int i = 0; i < tldMapList.size(); i++) { 243 JspTaglib taglib = tldMapList.get(i); 244 245 _taglibManager.addLocationMap(taglib.getTaglibUri(), 246 taglib.getTaglibLocation()); 247 } 248 } 249 250 if (app != null) { 251 ArrayList <JspTaglib> taglibs = app.getTaglibList(); 252 for (int i = 0; taglibs != null && i < taglibs.size(); i++) { 253 JspTaglib taglib = taglibs.get(i); 254 255 _taglibManager.addLocationMap(taglib.getTaglibUri(), 256 taglib.getTaglibLocation()); 257 } 258 } 259 } 260 } 261 262 return _taglibManager; 263 } 264 265 268 public JspPropertyGroup createJsp() 269 { 270 if (_jspPropertyGroup == null) { 271 _jspPropertyGroup = new JspPropertyGroup(); 272 } 273 274 return _jspPropertyGroup; 275 } 276 277 280 public JspPropertyGroup getJspPropertyGroup() 281 { 282 return _jspPropertyGroup; 283 } 284 285 289 public WebApp createWebApp() 290 { 291 if (_app == null) { 292 WebAppController controller = 293 new WebAppController("", getAppDir(), null); 294 295 _app = controller.getDeployInstance(); 296 } 297 298 return _app; 299 } 300 301 305 public void setWebApp(WebApp app) 306 { 307 _app = app; 308 309 if (_resourceManager == null) 310 _resourceManager = new AppResourceManager(_app); 311 } 312 313 317 public WebApp createApplication() 318 { 319 return createWebApp(); 320 } 321 322 326 public void setApplication(WebApp webApp) 327 { 328 setWebApp(webApp); 329 } 330 331 334 public WebApp getWebApp() 335 { 336 return _app; 337 } 338 339 342 public boolean addTag(String className) 343 { 344 if (_compilingTags.contains(className)) { 345 _hasRecursiveCompile = true; 346 return true; 347 } 348 349 _compilingTags.add(className); 350 351 return false; 352 } 353 354 357 public boolean hasRecursiveCompile() 358 { 359 return _hasRecursiveCompile; 360 } 361 362 365 public static String urlToClassName(String name) 366 { 367 return JavaCompiler.mangleName("jsp/" + name); 368 } 369 370 373 void addPending(JspCompilerInstance pending) 374 { 375 _pending.add(pending); 376 } 377 378 381 void compilePending() 382 throws Exception 383 { 384 if (_pending.size() == 0) 385 return; 386 387 ArrayList <JspCompilerInstance> pendingList; 388 pendingList = new ArrayList <JspCompilerInstance>(_pending); 389 390 for (int i = 0; i < pendingList.size(); i++) { 391 JspCompilerInstance pending = pendingList.get(i); 392 393 pending.completeTag(); 394 } 395 396 _pending.clear(); 397 } 398 399 407 public Page compile(Path jspPath, String uri) 408 throws Exception 409 { 410 return getCompilerInstance(jspPath, uri).compile(); 411 } 412 413 416 public JspCompilerInstance getCompilerInstance(Path jspPath, 417 String uri) 418 throws Exception 419 { 420 return getCompilerInstance(jspPath, uri, null); 421 } 422 423 public void init() 424 throws JspParseException, IOException 425 { 426 getTaglibManager(); 427 } 428 429 432 public JspCompilerInstance getCompilerInstance(Path jspPath, 433 String uri, 434 String className) 435 throws Exception 436 { 437 JspCompilerInstance instance = new JspCompilerInstance(this); 438 439 instance.setJspPath(jspPath); 440 instance.setURI(uri); 441 instance.setClassName(className); 442 443 instance.init(); 444 445 return instance; 446 } 447 448 453 public Page loadPage(String className, boolean isAutoCompile) 454 throws Throwable 455 { 456 JspPage jspPage = (JspPage ) loadClass(className, isAutoCompile); 457 458 Page page; 459 if (jspPage instanceof Page) 460 page = (Page) jspPage; 461 else if (jspPage instanceof SingleThreadModel ) 462 page = new SingleThreadWrapperPage((HttpJspPage ) jspPage); 463 else 464 page = new WrapperPage((HttpJspPage ) jspPage); 465 466 return page; 467 } 468 469 474 public Object loadClass(String className, boolean autoCompile) 475 throws Throwable 476 { 477 ClassLoader parentLoader = Thread.currentThread().getContextClassLoader(); 478 ClassLoader jspLoader = SimpleLoader.create(parentLoader, 479 getClassDir(), null); 480 481 try { 483 Class cl = CauchoSystem.loadClass(className, false, jspLoader); 484 485 readSmap(parentLoader, className); 486 487 return cl.newInstance(); 488 } catch (Throwable e) { 489 if (autoCompile) { 490 try { 491 String pathName = className.replace('.', '/') + ".class"; 492 Path classPath = getClassDir().lookup(pathName); 493 494 classPath.remove(); 495 } catch (IOException e1) { 496 log.log(Level.FINE, e1.toString(), e1); 497 } 498 } 499 500 throw e; 501 } 502 } 503 504 509 public Page loadStatic(String className, boolean isSession) 510 throws Exception 511 { 512 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 513 514 String staticName = className.replace('.', '/') + ".static"; 516 517 Path path = getClassDir().lookup(staticName); 518 519 return new StaticPage(path, isSession); 520 } 521 522 private void readSmap(ClassLoader loader, String className) 523 { 524 if (loader == null) 525 return; 526 527 String smapName = className.replace('.', '/') + ".java.smap"; 528 529 InputStream is = null; 530 try { 531 is = loader.getResourceAsStream(smapName); 532 } catch (Exception e) { 533 log.log(Level.FINE, e.toString(), e); 534 } finally { 535 if (is != null) { 536 try { 537 is.close(); 538 } catch (IOException e) { 539 } 540 } 541 } 542 } 543 544 public static void main(String []args) 545 throws Exception 546 { 547 if (args.length == 0) { 548 System.out.println("usage: com.caucho.jsp.JspCompiler [flags] jsp1 jsp2 ..."); 549 System.out.println(" -app-dir : The directory root of the web-app."); 550 System.out.println(" -class-dir: The working directory to use as output."); 551 System.out.println(" -conf: A configuration file for the compiler."); 552 System.exit(1); 553 } 554 555 Thread thread = Thread.currentThread(); 557 ClassLoader oldLoader = thread.getContextClassLoader(); 558 try { 559 JspCompiler compiler = new JspCompiler(); 560 561 ClassLoader loader = compiler.getClassLoader(); 562 563 thread.setContextClassLoader(loader); 564 565 JspPropertyGroup jsp = compiler.createJsp(); 566 jsp.setRequireSource(false); 567 568 int i = 0; 569 boolean hasConf = false; 570 571 while (i < args.length) { 572 if (args[i].equals("-app-dir")) { 573 Path appDir = Vfs.lookup(args[i + 1]); 574 575 WebApp app = compiler.createWebApp(); 576 app.setDocumentDirectory(appDir); 577 578 compiler.setWebApp(app); 579 compiler.setAppDir(appDir); 580 581 i += 2; 582 } 583 else if (args[i].equals("-class-dir") || args[i].equals("-d")) { 584 compiler.setClassDirectory(Vfs.lookup(args[i + 1])); 585 i += 2; 586 } 587 else if (args[i].equals("-conf")) { 588 Path path = Vfs.lookup(args[i + 1]); 589 590 new Config().configureBean(compiler, path); 591 hasConf = true; 592 593 i += 2; 594 } 595 else 596 break; 597 } 598 599 WebApp app = compiler.getWebApp(); 600 if (app != null && ! hasConf) { 601 Path appDir = app.getAppDir(); 602 603 DynamicClassLoader dynLoader = app.getEnvironmentClassLoader(); 604 dynLoader.addLoader(new CompilingLoader(appDir.lookup("WEB-INF/classes"))); 605 dynLoader.addLoader(new DirectoryLoader(appDir.lookup("WEB-INF/lib"))); 606 607 Path webXml = appDir.lookup("WEB-INF/web.xml"); 608 609 if (webXml.canRead()) { 610 try { 611 new Config().configureBean(app, webXml); 612 } catch (Exception e) { 613 log.log(Level.WARNING, e.toString(), e); 614 } 615 } 616 } 617 618 Path appDir = null; 619 620 if (app == null && compiler.getAppDir() != null) { 621 app = compiler.createWebApp(); 622 623 app.setDocumentDirectory(compiler.getAppDir()); 624 compiler.setWebApp(app); 625 } 626 627 if (app != null) { 628 app.init(); 629 630 appDir = compiler.getWebApp().getAppDir(); 631 loader = compiler.getWebApp().getClassLoader(); 632 } 633 634 if (appDir == null) { 635 appDir = Vfs.lookup(); 636 637 if (compiler.getAppDir() == null && compiler.getWebApp() == null) { 638 System.err.println(L.l("-app-dir must be specified for JspCompiler")); 639 return; 640 } 641 } 642 643 thread.setContextClassLoader(loader); 644 645 ArrayList <String > pendingClasses = new ArrayList <String >(); 646 647 for (; i < args.length; i++) { 648 String uri = args[i]; 649 650 Path path = Vfs.lookup(uri); 651 652 if (path.isDirectory()) 653 compileDirectory(path, appDir, compiler, pendingClasses); 654 else 655 compileJsp(path, appDir, compiler, pendingClasses); 656 } 657 658 JavaCompiler javaCompiler = JavaCompiler.create(loader); 659 javaCompiler.setClassDir(compiler.getClassDir()); 660 661 String files[] = new String [pendingClasses.size()]; 662 pendingClasses.toArray(files); 663 664 javaCompiler.compileBatch(files); 665 } finally { 666 Thread.currentThread().setContextClassLoader(oldLoader); 667 } 668 } 669 670 private static void compileDirectory(Path path, 671 Path appDir, 672 JspCompiler compiler, 673 ArrayList <String > pendingClasses) 674 throws Exception 675 { 676 if (path.isDirectory()) { 677 String []list = path.list(); 678 679 for (int i = 0; i < list.length; i++) { 680 Path subpath = path.lookup(list[i]); 681 682 compileDirectory(subpath, appDir, compiler, pendingClasses); 683 } 684 } 685 else if (path.getPath().endsWith(".jsp") || 686 path.getPath().endsWith(".jsfx") || 687 path.getPath().endsWith(".jspx") || 688 path.getPath().endsWith(".jsfx")) { 689 compileJsp(path, appDir, compiler, pendingClasses); 690 } 691 } 692 693 private static void compileJsp(Path path, 694 Path appDir, 695 JspCompiler compiler, 696 ArrayList <String > pendingClasses) 697 throws Exception 698 { 699 String uri; 700 701 uri = path.getPath().substring(appDir.getPath().length()); 702 703 704 if (uri.endsWith("x")) 705 compiler.setXml(true); 706 else 707 compiler.setXml(false); 708 709 String className = JspCompiler.urlToClassName(uri); 710 JspCompilerInstance compInst; 711 compInst = compiler.getCompilerInstance(path, uri, className); 712 713 JspGenerator gen = compInst.generate(); 714 715 if (! gen.isStatic()) 716 pendingClasses.add(className.replace('.', '/') + ".java"); 717 } 718 } 719 | Popular Tags |