1 package org.apache.turbine; 2 3 56 57 import java.io.BufferedReader ; 58 import java.io.File ; 59 import java.io.FileInputStream ; 60 import java.io.FileNotFoundException ; 61 import java.io.FileReader ; 62 import java.io.InputStream ; 63 import java.io.InputStreamReader ; 64 import java.io.IOException ; 65 import java.io.Reader ; 66 import java.util.Date ; 67 import java.util.Iterator ; 68 import java.util.Properties ; 69 70 import javax.servlet.ServletConfig ; 71 import javax.servlet.ServletContext ; 72 import javax.servlet.ServletException ; 73 import javax.servlet.http.HttpServlet ; 74 import javax.servlet.http.HttpServletRequest ; 75 import javax.servlet.http.HttpServletResponse ; 76 77 import org.apache.commons.configuration.Configuration; 78 import org.apache.commons.configuration.ConfigurationFactory; 79 import org.apache.commons.configuration.PropertiesConfiguration; 80 import org.apache.commons.http.HttpUtils; 81 import org.apache.commons.lang.StringUtils; 82 import org.apache.commons.lang.exception.ExceptionUtils; 83 import org.apache.commons.logging.Log; 84 import org.apache.commons.logging.LogFactory; 85 import org.apache.fulcrum.ServiceManager; 86 import org.apache.fulcrum.TurbineServices; 87 import org.apache.log4j.PropertyConfigurator; 88 import org.apache.turbine.modules.ModuleLoader; 89 import org.apache.turbine.pipeline.TurbinePipeline; 90 import org.apache.turbine.services.rundata.RunDataService; 91 92 import com.thoughtworks.xstream.XStream; 93 import com.thoughtworks.xstream.io.xml.DomDriver; 94 95 135 public class Turbine 136 extends HttpServlet 137 implements TurbineConstants 138 { 139 140 private static Log log = LogFactory.getLog(Turbine.class); 141 142 147 private static boolean firstInit = true; 148 149 152 private static Throwable initFailure = null; 153 154 158 private static boolean firstDoGet = true; 159 160 163 private static Configuration configuration; 164 165 172 public final void init(ServletConfig config) 173 throws ServletException 174 { 175 super.init(config); 176 177 synchronized ( this.getClass() ) 178 { 179 if (!firstInit) 180 { 181 log.warn("Double initializaton of Turbine was attempted!"); 182 return; 183 } 184 firstInit = false; 187 188 try 189 { 190 ServletContext context = config.getServletContext(); 192 193 configure(config, context); 194 } 195 catch ( Exception e ) 196 { 197 initFailure = e; 199 System.err.println(ExceptionUtils.getStackTrace(e)); 200 log.info("init failed: " + ExceptionUtils.getStackTrace(e)); 201 return; 202 } 203 log.info("init complete, Ready to Rumble!"); 204 } 205 } 206 207 213 public final void init(RunData data) 214 { 215 synchronized (Turbine.class) 216 { 217 if (firstDoGet) 218 { 219 saveServletInfo(data); 225 226 firstDoGet = false; 228 } 229 } 230 } 231 232 236 public final void destroy() 237 { 238 TurbineServices.getInstance().shutdownServices(); 240 System.gc(); 241 242 firstInit = true; 244 245 log.info("Done shutting down!"); 246 } 247 248 256 public final void doGet (HttpServletRequest req, HttpServletResponse res) 257 throws IOException , 258 ServletException 259 { 260 RunData data = null; 262 try 263 { 264 if (initFailure != null) 266 { 267 throw initFailure; 268 } 269 270 data = (RunData)req.getAttribute(RUNDATA_REQUEST_KEY); 276 if ( data == null ) 277 { 278 data = runDataService.getRunData(req, res, getServletConfig()); 279 } 280 else 281 { 282 data.setRequest(req); 283 data.setResponse(res); 284 } 285 286 287 if (firstDoGet) 291 { 292 init(data); 293 } 294 295 pipeline.invoke(data); 299 300 312 } 313 catch (Throwable t) 314 { 315 handleException(data, req, res, t); 316 } 317 finally 318 { 319 if ( req.getAttribute(RUNDATA_REQUEST_KEY) == null ) 323 { 324 runDataService.putRunData(data); 326 } 327 } 328 } 329 330 338 public final void doPost (HttpServletRequest req, 339 HttpServletResponse res) 340 throws IOException , 341 ServletException 342 { 343 doGet(req, res); 344 } 345 346 351 public final String getServletInfo() 352 { 353 return "Turbine Servlet @VERSION@"; 354 } 355 356 370 private final void handleException(RunData data, 371 HttpServletRequest req, 372 HttpServletResponse res, 373 Throwable t) 374 throws ServletException 375 { 376 log.error("handleException: " + t.getMessage(), t); 378 379 try 380 { 381 exceptionHandler.handleException( data, t ); 382 } 383 catch (ServletException e) 384 { 385 if ( INTEGRATED.equals(configuration.getString(MODE)) || 386 req.getAttribute(INTEGRATED_REQUEST_KEY) != null ) 387 { 388 throw e; 390 } 391 else 392 { 393 handleExceptionHandlerException(data, res, e, t); 394 } 395 } 396 catch (Exception f) 397 { 398 handleExceptionHandlerException(data, res, f, t); 399 } 400 } 401 402 private void handleExceptionHandlerException(RunData data, 403 HttpServletResponse res, 404 Exception f, 405 Throwable t) 406 { 407 log.error( "Failed to dispatch to exception handler", f ); 408 409 String mimeType = "text/plain"; 410 try 411 { 412 String trace = ExceptionUtils.getStackTrace(t); 415 data.setStackTrace(trace,t); 416 res.setContentType(data.getContentType()); 417 res.setStatus(data.getStatusCode()); 418 data.getOut().print("<pre>\n" + trace + "\n</pre>"); 419 } 420 catch ( java.lang.NoSuchFieldError e ) 423 { 424 try 425 { 426 res.setContentType( mimeType ); 427 res.setStatus ( 200 ); 428 } 429 catch (Exception ignored) {} 430 431 try 432 { 433 data.getOut().print ("java.lang.NoSuchFieldError: " + 434 "Please recompile all of your " + 435 "source code."); 436 } 437 catch (IOException ignored) {} 438 439 log.info ( data.getStackTrace() ); 440 log.error ( e.getMessage(), e ); 441 } 442 catch ( Throwable reallyScrewedNow ) 444 { 445 StringBuffer msg = new StringBuffer (); 446 msg.append("Horrible Exception: "); 447 if (data != null) 448 { 449 msg.append(data.getStackTrace()); 450 } 451 else 452 { 453 msg.append(t); 454 } 455 try 456 { 457 res.setContentType( mimeType ); 458 res.setStatus ( 200 ); 459 res.getWriter().print (msg.toString()); 460 } 461 catch (Exception ignored) 462 { 463 } 464 log.error(reallyScrewedNow.getMessage(), reallyScrewedNow); 465 } 466 } 467 468 490 493 private static String serverName; 494 495 498 private static String serverPort; 499 500 503 private static String serverScheme; 504 505 508 private static String scriptName; 509 510 515 private static String applicationRoot; 516 517 520 private static ServletConfig servletConfig; 521 522 525 private static ServletContext servletContext; 526 527 532 private static ModuleLoader moduleLoader; 533 534 private static Resolver resolver; 535 536 private static ExceptionHandler exceptionHandler; 537 538 private static Pipeline pipeline; 539 540 private static RunDataService runDataService; 541 542 553 public static synchronized void configure(ServletConfig config, 554 ServletContext context) 555 throws Exception 556 { 557 try 558 { 559 applicationRoot = 562 findInitParameter(context, config, APPLICATION_ROOT, null); 563 564 if (applicationRoot == null || applicationRoot.equals(WEB_CONTEXT)) 565 { 566 applicationRoot = config.getServletContext().getRealPath(""); 567 } 568 569 setApplicationRoot(applicationRoot); 571 572 createRuntimeDirectories(context, config); 578 579 580 581 582 583 setTurbineServletConfig(config); 592 setTurbineServletContext(context); 593 594 ServiceManager serviceManager = TurbineServices.getInstance(); 596 597 serviceManager.setApplicationRoot(getApplicationRoot()); 600 601 602 630 String confFile= findInitParameter(context, config, 631 TurbineConfig.CONFIGURATION_PATH_KEY, 632 null); 633 634 String confPath; 635 String confStyle = "unset"; 636 637 if (StringUtils.isNotEmpty(confFile)) 638 { 639 confPath = getRealPath(confFile); 640 ConfigurationFactory configurationFactory = new ConfigurationFactory(confPath); 641 configurationFactory.setBasePath(getApplicationRoot()); 642 configuration = configurationFactory.getConfiguration(); 643 confStyle = "XML"; 644 } 645 else 646 { 647 confFile = findInitParameter(context, config, 648 TurbineConfig.PROPERTIES_KEY, 649 "TurbineResources.properties"); 650 651 confPath = getRealPath(confFile); 652 653 configuration = (Configuration) new PropertiesConfiguration(confPath); 657 confStyle = "Properties"; 658 } 659 660 configuration.setProperty(APPLICATION_ROOT, applicationRoot); 666 configuration.setProperty(WEBAPP_ROOT, 667 config.getServletContext().getRealPath("")); 668 669 String log4jFile = configuration.getString(LOG4J_CONFIG_FILE, 673 LOG4J_CONFIG_FILE_DEFAULT); 674 675 log4jFile = getRealPath(log4jFile); 676 677 Properties p = new Properties (); 682 try 683 { 684 p.load(new FileInputStream (log4jFile)); 685 p.setProperty(APPLICATION_ROOT, getApplicationRoot()); 686 PropertyConfigurator.configure(p); 687 688 log = LogFactory.getLog(Turbine.class.getName()); 691 692 log.info("Configured log4j from " + log4jFile); 693 } 694 catch (FileNotFoundException fnf) 695 { 696 System.err.println("Could not open Log4J configuration file " 697 + log4jFile + ": "); 698 fnf.printStackTrace(); 699 } 700 701 serviceManager.setConfiguration(configuration); 702 703 serviceManager.init(); 708 709 moduleLoader = new ModuleLoader(); 714 moduleLoader.setConfiguration(configuration); 715 moduleLoader.init(); 716 717 String resolverClass; 719 resolverClass = configuration.getString(RESOLVER, 720 "org.apache.turbine.pipeline.DefaultResolver"); 721 722 log.debug("Using Resolver: " + resolverClass); 723 resolver = (Resolver) Class.forName(resolverClass).newInstance(); 724 resolver.init(); 725 726 728 String exceptionHandlerClass = 729 configuration.getString( EXCEPTION_HANDLER, 730 "org.apache.turbine.exception.DefaultExceptionHandler" ); 731 log.debug("Using error handler: " + exceptionHandlerClass); 732 733 exceptionHandler = ( ExceptionHandler ) 734 Class.forName( exceptionHandlerClass ).newInstance(); 735 736 Configuration systemProperties = configuration.subset(SYSTEM); 738 739 if (systemProperties != null) 740 { 741 for (Iterator k = systemProperties.getKeys(); k.hasNext();) 742 { 743 String name = (String ) k.next(); 744 String value = systemProperties.getString(name); 745 log.debug("System Property: " + name + " => " + value); 746 System.getProperties().setProperty(name, value); 747 } 748 } 749 750 Class pipelineClass = Class.forName 754 (configuration.getString("pipeline.default", STANDARD_PIPELINE)); 755 756 log.debug("Using Pipeline: " + pipelineClass.getName()); 757 if (TurbinePipeline.class.isAssignableFrom(pipelineClass)) 758 { 759 Reader reader =null; 762 String descriptorPath = configuration.getString( 763 "pipeline.default.descriptor", TurbinePipeline.CLASSIC_PIPELINE); 764 InputStream inputStream = Turbine.class.getClassLoader().getResourceAsStream(descriptorPath); 765 if(inputStream != null) 766 { 767 reader = new BufferedReader (new InputStreamReader (inputStream)); 768 } 769 else 770 { 771 descriptorPath = getRealPath(descriptorPath); 772 reader = new BufferedReader (new FileReader (descriptorPath)); 773 } 774 log.debug("Using descriptor path: " + descriptorPath); 775 XStream pipelineMapper = new XStream(new DomDriver()); pipeline = (Pipeline) pipelineMapper.fromXML(reader); 777 } 778 else 779 { 780 pipeline = (Pipeline) pipelineClass.newInstance(); 784 } 785 786 log.debug("Initializing pipeline"); 787 pipeline.initialize(); 788 789 log.debug("Getting rundataservice: "); 790 runDataService = (RunDataService) TurbineServices.getInstance() 792 .getService(RunDataService.SERVICE_NAME); 793 log.debug("RunDataService: " + runDataService); 794 } 795 catch (Throwable e) 796 { 797 e.printStackTrace(); 798 log.error(e); 799 throw new TurbineException(e); 800 } 801 } 802 803 820 private static void createRuntimeDirectories(ServletContext context, 821 ServletConfig config) 822 { 823 String path = findInitParameter(context, config, LOGGING_ROOT, "/logs"); 824 File logDir = new File (getRealPath(path)); 825 if (!logDir.exists()) 826 { 827 if (!logDir.mkdirs()) 829 { 830 System.err.println("Cannot create directory for logs!"); 831 } 832 } 833 } 834 835 841 protected static final String findInitParameter(ServletContext context, 842 ServletConfig config, 843 String name, 844 String defaultValue) 845 { 846 String path = null; 847 848 boolean usingNamespace = name.startsWith(CONFIG_NAMESPACE); 850 while (true) 851 { 852 path = config.getInitParameter(name); 853 if (StringUtils.isEmpty(path)) 854 { 855 path = context.getInitParameter(name); 856 if (StringUtils.isEmpty(path)) 857 { 858 if (usingNamespace) 860 { 861 path = defaultValue; 862 } 863 else 864 { 865 name = CONFIG_NAMESPACE + '.' + name; 867 usingNamespace = true; 868 continue; 869 } 870 } 871 } 872 break; 873 } 874 875 return path; 876 } 877 878 885 public static ModuleLoader getModuleLoader() 886 { 887 return moduleLoader; 888 } 889 890 894 public static Resolver getResolver() 895 { 896 return resolver; 897 } 898 899 906 public static synchronized void saveServletInfo(RunData data) 907 { 908 serverName = data.getRequest().getServerName(); 909 serverPort = new Integer (data.getRequest().getServerPort()).toString(); 910 serverScheme = data.getRequest().getScheme(); 911 scriptName = applicationRoot + data.getRequest().getServletPath(); 912 } 913 914 919 public static void setApplicationRoot(String val) 920 { 921 applicationRoot = val; 922 } 923 924 929 public static String getApplicationRoot() 930 { 931 return applicationRoot; 932 } 933 934 939 public static String getRealPath(String path) 940 { 941 return getApplicationRoot() + '/' + path; 942 } 943 944 949 public static String getServerName() 950 { 951 return serverName; 952 } 953 954 959 public static String getServerPort() 960 { 961 return serverPort; 962 } 963 964 969 public static String getServerScheme() 970 { 971 return serverScheme; 972 } 973 974 981 public static String getScriptName() 982 { 983 return scriptName; 984 } 985 986 991 public static void setTurbineServletConfig(ServletConfig s) 992 { 993 servletConfig = s; 994 } 995 996 1001 public static ServletConfig getTurbineServletConfig() 1002 { 1003 return servletConfig; 1004 } 1005 1006 1011 public static void setTurbineServletContext(ServletContext s) 1012 { 1013 servletContext = s; 1014 } 1015 1016 1021 public static ServletContext getTurbineServletContext() 1022 { 1023 return servletContext; 1024 } 1025 1026 1031 public static Configuration getConfiguration() 1032 { 1033 return configuration; 1034 } 1035 1036 1045 public static void setCacheHeaders(RunData data, int expiry) 1046 { 1047 if ( expiry == 0 ) 1048 { 1049 data.getResponse().setHeader("Pragma", "no-cache"); 1050 data.getResponse().setHeader("Cache-Control", "no-cache"); 1051 data.getResponse().setHeader( 1052 "Expires", HttpUtils.formatHttpDate(new Date ())); 1053 } 1054 else 1055 { 1056 Date expiryDate = new Date ( System.currentTimeMillis() + expiry ); 1057 data.getResponse().setHeader( 1058 "Expires", HttpUtils.formatHttpDate(expiryDate)); 1059 } 1060 } 1061} 1062 | Popular Tags |