| 1 17 18 19 package org.apache.catalina.startup; 20 21 22 import java.io.BufferedOutputStream ; 23 import java.io.File ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.util.ArrayList ; 28 import java.util.HashMap ; 29 import java.util.LinkedHashMap ; 30 import java.util.jar.JarEntry ; 31 import java.util.jar.JarFile ; 32 33 import javax.management.ObjectName ; 34 35 import org.apache.catalina.Container; 36 import org.apache.catalina.Context; 37 import org.apache.catalina.Engine; 38 import org.apache.catalina.Host; 39 import org.apache.catalina.Lifecycle; 40 import org.apache.catalina.LifecycleEvent; 41 import org.apache.catalina.LifecycleListener; 42 import org.apache.catalina.core.ContainerBase; 43 import org.apache.catalina.core.StandardHost; 44 import org.apache.catalina.util.StringManager; 45 import org.apache.tomcat.util.digester.Digester; 46 import org.apache.tomcat.util.modeler.Registry; 47 48 49 57 public class HostConfig 58 implements LifecycleListener { 59 60 protected static org.apache.commons.logging.Log log= 61 org.apache.commons.logging.LogFactory.getLog( HostConfig.class ); 62 63 65 66 69 protected File appBase = null; 70 71 72 75 protected File configBase = null; 76 77 78 81 protected String configClass = "org.apache.catalina.startup.ContextConfig"; 82 83 84 87 protected String contextClass = "org.apache.catalina.core.StandardContext"; 88 89 90 93 protected Host host = null; 94 95 96 99 protected ObjectName oname = null; 100 101 102 105 protected static final StringManager sm = 106 StringManager.getManager(Constants.Package); 107 108 109 112 protected boolean deployXML = false; 113 114 115 119 protected boolean unpackWARs = false; 120 121 122 125 protected HashMap deployed = new HashMap (); 126 127 128 132 protected ArrayList serviced = new ArrayList (); 133 134 135 138 protected boolean xmlValidation = false; 139 140 141 144 protected boolean xmlNamespaceAware = false; 145 146 147 150 protected static Digester digester = createDigester(); 151 152 153 155 156 159 public String getConfigClass() { 160 161 return (this.configClass); 162 163 } 164 165 166 171 public void setConfigClass(String configClass) { 172 173 this.configClass = configClass; 174 175 } 176 177 178 181 public String getContextClass() { 182 183 return (this.contextClass); 184 185 } 186 187 188 193 public void setContextClass(String contextClass) { 194 195 this.contextClass = contextClass; 196 197 } 198 199 200 203 public boolean isDeployXML() { 204 205 return (this.deployXML); 206 207 } 208 209 210 215 public void setDeployXML(boolean deployXML) { 216 217 this.deployXML= deployXML; 218 219 } 220 221 222 225 public boolean isUnpackWARs() { 226 227 return (this.unpackWARs); 228 229 } 230 231 232 237 public void setUnpackWARs(boolean unpackWARs) { 238 239 this.unpackWARs = unpackWARs; 240 241 } 242 243 244 249 public void setXmlValidation(boolean xmlValidation){ 250 this.xmlValidation = xmlValidation; 251 } 252 253 258 public boolean getXmlValidation(){ 259 return xmlValidation; 260 } 261 262 267 public boolean getXmlNamespaceAware(){ 268 return xmlNamespaceAware; 269 } 270 271 272 277 public void setXmlNamespaceAware(boolean xmlNamespaceAware){ 278 this.xmlNamespaceAware=xmlNamespaceAware; 279 } 280 281 282 284 285 290 public void lifecycleEvent(LifecycleEvent event) { 291 292 if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) 293 check(); 294 295 try { 297 host = (Host) event.getLifecycle(); 298 if (host instanceof StandardHost) { 299 setDeployXML(((StandardHost) host).isDeployXML()); 300 setUnpackWARs(((StandardHost) host).isUnpackWARs()); 301 setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware()); 302 setXmlValidation(((StandardHost) host).getXmlValidation()); 303 } 304 } catch (ClassCastException e) { 305 log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e); 306 return; 307 } 308 309 if (event.getType().equals(Lifecycle.START_EVENT)) 311 start(); 312 else if (event.getType().equals(Lifecycle.STOP_EVENT)) 313 stop(); 314 315 } 316 317 318 321 public synchronized void addServiced(String name) { 322 serviced.add(name); 323 } 324 325 326 330 public synchronized boolean isServiced(String name) { 331 return (serviced.contains(name)); 332 } 333 334 335 338 public synchronized void removeServiced(String name) { 339 serviced.remove(name); 340 } 341 342 343 348 public long getDeploymentTime(String name) { 349 DeployedApplication app = (DeployedApplication) deployed.get(name); 350 if (app == null) { 351 return 0L; 352 } else { 353 return app.timestamp; 354 } 355 } 356 357 358 365 public boolean isDeployed(String name) { 366 DeployedApplication app = (DeployedApplication) deployed.get(name); 367 if (app == null) { 368 return false; 369 } else { 370 return true; 371 } 372 } 373 374 375 377 378 381 protected static Digester createDigester() { 382 Digester digester = new Digester(); 383 digester.setValidating(false); 384 digester.addObjectCreate("Context", "org.apache.catalina.core.StandardContext", 386 "className"); 387 digester.addSetProperties("Context"); 390 return (digester); 391 } 392 393 394 398 protected File appBase() { 399 400 if (appBase != null) { 401 return appBase; 402 } 403 404 File file = new File (host.getAppBase()); 405 if (!file.isAbsolute()) 406 file = new File (System.getProperty("catalina.base"), 407 host.getAppBase()); 408 try { 409 appBase = file.getCanonicalFile(); 410 } catch (IOException e) { 411 appBase = file; 412 } 413 return (appBase); 414 415 } 416 417 418 422 protected File configBase() { 423 424 if (configBase != null) { 425 return configBase; 426 } 427 428 File file = new File (System.getProperty("catalina.base"), "conf"); 429 Container parent = host.getParent(); 430 if ((parent != null) && (parent instanceof Engine)) { 431 file = new File (file, parent.getName()); 432 } 433 file = new File (file, host.getName()); 434 try { 435 configBase = file.getCanonicalFile(); 436 } catch (IOException e) { 437 configBase = file; 438 } 439 return (configBase); 440 441 } 442 443 447 public String getConfigBaseName() { 448 return configBase().getAbsolutePath(); 449 } 450 451 454 protected String getConfigFile(String path) { 455 String basename = null; 456 if (path.equals("")) { 457 basename = "ROOT"; 458 } else { 459 basename = path.substring(1).replace('/', '#'); 460 } 461 return (basename); 462 } 463 464 465 468 protected String getDocBase(String path) { 469 String basename = null; 470 if (path.equals("")) { 471 basename = "ROOT"; 472 } else { 473 basename = path.substring(1); 474 } 475 return (basename); 476 } 477 478 479 483 protected void deployApps() { 484 485 File appBase = appBase(); 486 File configBase = configBase(); 487 deployDescriptors(configBase, configBase.list()); 489 deployWARs(appBase, appBase.list()); 491 deployDirectories(appBase, appBase.list()); 493 494 } 495 496 497 501 protected void deployApps(String name) { 502 503 File appBase = appBase(); 504 File configBase = configBase(); 505 String baseName = getConfigFile(name); 506 String docBase = getConfigFile(name); 507 508 File xml = new File (configBase, baseName + ".xml"); 510 if (xml.exists()) 511 deployDescriptor(name, xml, baseName + ".xml"); 512 File war = new File (appBase, docBase + ".war"); 514 if (war.exists()) 515 deployWAR(name, war, docBase + ".war"); 516 File dir = new File (appBase, docBase); 518 if (dir.exists()) 519 deployDirectory(name, dir, docBase); 520 521 } 522 523 524 527 protected void deployDescriptors(File configBase, String [] files) { 528 529 if (files == null) 530 return; 531 532 for (int i = 0; i < files.length; i++) { 533 534 if (files[i].equalsIgnoreCase("META-INF")) 535 continue; 536 if (files[i].equalsIgnoreCase("WEB-INF")) 537 continue; 538 File contextXml = new File (configBase, files[i]); 539 if (files[i].toLowerCase().endsWith(".xml")) { 540 541 String nameTmp = files[i].substring(0, files[i].length() - 4); 543 String contextPath = "/" + nameTmp.replace('#', '/'); 544 if (nameTmp.equals("ROOT")) { 545 contextPath = ""; 546 } 547 548 if (isServiced(contextPath)) 549 continue; 550 551 String file = files[i]; 552 553 deployDescriptor(contextPath, contextXml, file); 554 555 } 556 557 } 558 559 } 560 561 562 567 protected void deployDescriptor(String contextPath, File contextXml, String file) { 568 if (deploymentExists(contextPath)) { 569 return; 570 } 571 572 DeployedApplication deployedApp = new DeployedApplication(contextPath); 573 574 if(log.isDebugEnabled()) { 576 log.debug(sm.getString("hostConfig.deployDescriptor", file)); 577 } 578 579 Context context = null; 580 try { 581 synchronized (digester) { 582 try { 583 context = (Context) digester.parse(contextXml); 584 if (context == null) { 585 log.error(sm.getString("hostConfig.deployDescriptor.error", 586 file)); 587 return; 588 } 589 } finally { 590 digester.reset(); 591 } 592 } 593 if (context instanceof Lifecycle) { 594 Class clazz = Class.forName(host.getConfigClass()); 595 LifecycleListener listener = 596 (LifecycleListener) clazz.newInstance(); 597 ((Lifecycle) context).addLifecycleListener(listener); 598 } 599 context.setConfigFile(contextXml.getAbsolutePath()); 600 context.setPath(contextPath); 601 boolean isWar = false; 603 boolean isExternal = false; 604 if (context.getDocBase() != null) { 605 File docBase = new File (context.getDocBase()); 606 if (!docBase.isAbsolute()) { 607 docBase = new File (appBase(), context.getDocBase()); 608 } 609 if (!docBase.getCanonicalPath().startsWith(appBase().getAbsolutePath())) { 611 isExternal = true; 612 deployedApp.redeployResources.put 613 (contextXml.getAbsolutePath(), new Long (contextXml.lastModified())); 614 deployedApp.redeployResources.put(docBase.getAbsolutePath(), 615 new Long (docBase.lastModified())); 616 if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) { 617 isWar = true; 618 } 619 } else { 620 log.warn(sm.getString("hostConfig.deployDescriptor.localDocBaseSpecified", 621 docBase)); 622 context.setDocBase(null); 624 } 625 } 626 host.addChild(context); 627 String name = null; 629 String path = context.getPath(); 630 if (path.equals("")) { 631 name = "ROOT"; 632 } else { 633 if (path.startsWith("/")) { 634 name = path.substring(1); 635 } else { 636 name = path; 637 } 638 } 639 File expandedDocBase = new File (name); 640 File warDocBase = new File (name + ".war"); 641 if (!expandedDocBase.isAbsolute()) { 642 expandedDocBase = new File (appBase(), name); 643 warDocBase = new File (appBase(), name + ".war"); 644 } 645 if (isWar && unpackWARs) { 648 deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(), 649 new Long (expandedDocBase.lastModified())); 650 deployedApp.redeployResources.put 651 (contextXml.getAbsolutePath(), new Long (contextXml.lastModified())); 652 addWatchedResources(deployedApp, expandedDocBase.getAbsolutePath(), context); 653 } else { 654 if (warDocBase.exists()) { 656 deployedApp.redeployResources.put(warDocBase.getAbsolutePath(), 657 new Long (warDocBase.lastModified())); 658 } 659 if (expandedDocBase.exists()) { 660 deployedApp.redeployResources.put(expandedDocBase.getAbsolutePath(), 661 new Long (expandedDocBase.lastModified())); 662 addWatchedResources(deployedApp, 663 expandedDocBase.getAbsolutePath(), context); 664 } else { 665 addWatchedResources(deployedApp, null, context); 666 } 667 if (!isExternal) { 669 deployedApp.redeployResources.put 670 (contextXml.getAbsolutePath(), new Long (contextXml.lastModified())); 671 } 672 } 673 } catch (Throwable t) { 674 log.error(sm.getString("hostConfig.deployDescriptor.error", 675 file), t); 676 } 677 678 if (context != null && host.findChild(context.getName()) != null) { 679 deployed.put(contextPath, deployedApp); 680 } 681 } 682 683 684 687 protected void deployWARs(File appBase, String [] files) { 688 689 if (files == null) 690 return; 691 692 for (int i = 0; i < files.length; i++) { 693 694 if (files[i].equalsIgnoreCase("META-INF")) 695 continue; 696 if (files[i].equalsIgnoreCase("WEB-INF")) 697 continue; 698 File dir = new File (appBase, files[i]); 699 if (files[i].toLowerCase().endsWith(".war")) { 700 701 String contextPath = "/" + files[i]; 703 int period = contextPath.lastIndexOf("."); 704 if (period >= 0) 705 contextPath = contextPath.substring(0, period); 706 if (contextPath.equals("/ROOT")) 707 contextPath = ""; 708 709 if (isServiced(contextPath)) 710 continue; 711 712 String file = files[i]; 713 714 deployWAR(contextPath, dir, file); 715 716 } 717 718 } 719 720 } 721 722 723 728 protected void deployWAR(String contextPath, File dir, String file) { 729 730 if (deploymentExists(contextPath)) 731 return; 732 733 JarFile jar = null; 735 JarEntry entry = null; 736 InputStream istream = null; 737 BufferedOutputStream ostream = null; 738 File xml = new File  739 (configBase, file.substring(0, file.lastIndexOf(".")) + ".xml"); 740 if (deployXML && !xml.exists()) { 741 try { 742 jar = new JarFile (dir); 743 entry = jar.getJarEntry(Constants.ApplicationContextXml); 744 if (entry != null) { 745 istream = jar.getInputStream(entry); 746 747 configBase.mkdirs(); 748 749 ostream = 750 new BufferedOutputStream  751 (new FileOutputStream (xml), 1024); 752 byte buffer[] = new byte[1024]; 753 while (true) { 754 int n = istream.read(buffer); 755 if (n < 0) { 756 break; 757 } 758 ostream.write(buffer, 0, n); 759 } 760 ostream.flush(); 761 ostream.close(); 762 ostream = null; 763 istream.close(); 764 istream = null; 765 entry = null; 766 jar.close(); 767 jar = null; 768 } 769 } catch (Exception e) { 770 if (ostream != null) { 772 try { 773 ostream.close(); 774 } catch (Throwable t) { 775 ; 776 } 777 ostream = null; 778 } 779 if (istream != null) { 780 try { 781 istream.close(); 782 } catch (Throwable t) { 783 ; 784 } 785 istream = null; 786 } 787 } finally { 788 entry = null; 789 if (jar != null) { 790 try { 791 jar.close(); 792 } catch (Throwable t) { 793 ; 794 } 795 jar = null; 796 } 797 } 798 } 799 800 DeployedApplication deployedApp = new DeployedApplication(contextPath); 801 802 if(log.isInfoEnabled()) 804 log.info(sm.getString("hostConfig.deployJar", file)); 805 806 deployedApp.redeployResources.put 808 (dir.getAbsolutePath(), new Long (dir.lastModified())); 809 810 try { 811 Context context = (Context) Class.forName(contextClass).newInstance(); 812 if (context instanceof Lifecycle) { 813 Class clazz = Class.forName(host.getConfigClass()); 814 LifecycleListener listener = 815 (LifecycleListener) clazz.newInstance(); 816 ((Lifecycle) context).addLifecycleListener(listener); 817 } 818 context.setPath(contextPath); 819 context.setDocBase(file); 820 if (xml.exists()) { 821 context.setConfigFile(xml.getAbsolutePath()); 822 deployedApp.redeployResources.put 823 (xml.getAbsolutePath(), new Long (xml.lastModified())); 824 } 825  
|