1 16 package org.apache.cocoon; 17 18 import org.apache.avalon.excalibur.component.ComponentProxyGenerator; 19 import org.apache.avalon.excalibur.component.DefaultRoleManager; 20 import org.apache.avalon.excalibur.component.ExcaliburComponentManager; 21 import org.apache.avalon.excalibur.logger.LoggerManager; 22 import org.apache.avalon.framework.activity.Disposable; 23 import org.apache.avalon.framework.activity.Initializable; 24 import org.apache.avalon.framework.component.Component; 25 import org.apache.avalon.framework.component.ComponentException; 26 import org.apache.avalon.framework.component.ComponentManager; 27 import org.apache.avalon.framework.component.Composable; 28 import org.apache.avalon.framework.configuration.Configuration; 29 import org.apache.avalon.framework.configuration.ConfigurationException; 30 import org.apache.avalon.framework.configuration.DefaultConfiguration; 31 import org.apache.avalon.framework.configuration.SAXConfigurationHandler; 32 import org.apache.avalon.framework.container.ContainerUtil; 33 import org.apache.avalon.framework.context.Context; 34 import org.apache.avalon.framework.context.ContextException; 35 import org.apache.avalon.framework.context.Contextualizable; 36 import org.apache.avalon.framework.context.DefaultContext; 37 import org.apache.avalon.framework.logger.AbstractLogEnabled; 38 import org.apache.avalon.framework.logger.Logger; 39 import org.apache.avalon.framework.thread.ThreadSafe; 40 41 import org.apache.cocoon.components.CocoonComponentManager; 42 import org.apache.cocoon.components.ComponentContext; 43 import org.apache.cocoon.components.pipeline.ProcessingPipeline; 44 import org.apache.cocoon.components.source.SourceUtil; 45 import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper; 46 import org.apache.cocoon.environment.Environment; 47 import org.apache.cocoon.environment.ObjectModelHelper; 48 import org.apache.cocoon.environment.Request; 49 import org.apache.cocoon.environment.Session; 50 import org.apache.cocoon.util.ClassUtils; 51 import org.apache.cocoon.util.Deprecation; 52 import org.apache.cocoon.util.location.Location; 53 import org.apache.cocoon.util.location.LocationImpl; 54 import org.apache.cocoon.util.location.LocationUtils; 55 56 import org.apache.commons.lang.SystemUtils; 57 import org.apache.excalibur.instrument.InstrumentManageable; 58 import org.apache.excalibur.instrument.InstrumentManager; 59 import org.apache.excalibur.source.Source; 60 import org.apache.excalibur.source.SourceResolver; 61 import org.apache.excalibur.source.impl.URLSource; 62 import org.apache.excalibur.xml.impl.XercesParser; 63 import org.apache.excalibur.xml.sax.SAXParser; 64 import org.xml.sax.InputSource ; 65 66 import java.io.BufferedInputStream ; 67 import java.io.File ; 68 import java.io.IOException ; 69 import java.net.URL ; 70 import java.util.Collections ; 71 import java.util.Enumeration ; 72 import java.util.Map ; 73 74 82 public class Cocoon 83 extends AbstractLogEnabled 84 implements ThreadSafe, 85 Component, 86 Initializable, 87 Disposable, 88 Modifiable, 89 Processor, 90 Contextualizable, 91 Composable, 92 InstrumentManageable { 93 94 private static final LocationUtils.LocationFinder confLocFinder = new LocationUtils.LocationFinder() { 97 public Location getLocation(Object obj, String description) { 98 if (obj instanceof Configuration) { 99 Configuration config = (Configuration)obj; 100 String locString = config.getLocation(); 101 Location result = LocationUtils.parse(locString); 102 if (LocationUtils.isKnown(result)) { 103 StringBuffer desc = new StringBuffer ().append('<'); 105 try { 107 if (config.getNamespace().startsWith("http://apache.org/cocoon/sitemap/")) { 108 desc.append("map:"); 109 } 110 } catch (ConfigurationException e) { 111 } 113 desc.append(config.getName()).append('>'); 114 return new LocationImpl(desc.toString(), result); 115 } else { 116 return result; 117 } 118 } 119 120 if (obj instanceof Exception ) { 121 String msg = ((Exception )obj).getMessage(); 123 if (msg == null) return null; 124 125 int pos = msg.lastIndexOf(" at "); 126 if (pos != -1) { 127 return LocationUtils.parse(msg.substring(pos + 4)); 128 } else { 129 return null; 131 } 132 } 133 134 return null; 136 } 137 }; 138 139 static { 140 LocationUtils.addFinder(confLocFinder); 141 } 142 143 static Cocoon instance; 144 145 146 private Logger rootLogger; 147 148 149 private Context context; 150 151 152 private Source configurationFile; 153 154 155 private Configuration configuration; 156 157 158 private LoggerManager loggerManager; 159 160 161 private InstrumentManager instrumentManager; 162 163 164 private String classpath; 165 166 167 private File workDir; 168 169 170 private ExcaliburComponentManager componentManager; 171 172 173 private ComponentManager parentComponentManager; 174 175 176 private boolean disposed; 177 178 179 private volatile int activeRequestCount; 180 181 182 private Processor threadSafeProcessor; 183 184 185 protected SourceResolver sourceResolver; 186 187 188 protected RequestListener requestListener; 189 190 195 public Cocoon() throws ConfigurationException { 196 setSystemProperties(); 198 199 Cocoon.instance = this; 202 } 203 204 public void enableLogging(Logger logger) { 205 this.rootLogger = logger; 206 super.enableLogging(logger.getChildLogger("cocoon")); 207 } 208 209 215 public void compose(ComponentManager manager) 216 throws ComponentException { 217 this.parentComponentManager = manager; 218 } 219 220 226 public void contextualize(Context context) throws ContextException { 227 if (this.context == null) { 228 this.context = new ComponentContext(context); 229 ((DefaultContext) this.context).makeReadOnly(); 230 231 this.classpath = (String )context.get(Constants.CONTEXT_CLASSPATH); 232 this.workDir = (File )context.get(Constants.CONTEXT_WORK_DIR); 233 try { 234 URLSource urlSource = new URLSource(); 237 urlSource.init((URL ) context.get(Constants.CONTEXT_CONFIG_URL), null); 238 this.configurationFile = new DelayedRefreshSourceWrapper(urlSource, 239 1000L); 240 241 } catch (IOException e) { 242 throw new ContextException("Could not open configuration file.", e); 243 } catch (Exception e) { 244 throw new ContextException("contextualize(..) Exception", e); 245 } 246 } 247 } 248 249 255 public void setLoggerManager(LoggerManager loggerManager) { 256 this.loggerManager = loggerManager; 257 Deprecation.setLogger(this.loggerManager.getLoggerForCategory("deprecation")); 258 } 259 260 265 public void setInstrumentManager(final InstrumentManager manager) { 266 this.instrumentManager = manager; 267 } 268 269 274 public void initialize() throws Exception { 275 if (parentComponentManager != null) { 276 this.componentManager = new CocoonComponentManager(parentComponentManager, 277 (ClassLoader ) this.context.get(Constants.CONTEXT_CLASS_LOADER)); 278 } else { 279 this.componentManager = new CocoonComponentManager((ClassLoader ) this.context.get(Constants.CONTEXT_CLASS_LOADER)); 280 } 281 ContainerUtil.enableLogging(this.componentManager, this.rootLogger.getChildLogger("manager")); 282 ContainerUtil.contextualize(this.componentManager, this.context); 283 this.componentManager.setInstrumentManager(this.instrumentManager); 284 getLogger().debug("New Cocoon object."); 285 286 dumpSystemProperties(); 288 289 String parser = getSystemProperty(Constants.DEPRECATED_PARSER_PROPERTY, Constants.DEFAULT_PARSER); 293 if (!Constants.DEFAULT_PARSER.equals(parser)) { 294 getLogger().warn("Deprecated property " + 295 Constants.DEPRECATED_PARSER_PROPERTY + " is used. Please use " + 296 Constants.PARSER_PROPERTY + " instead."); 297 if ("org.apache.cocoon.components.parser.XercesParser".equals(parser)) { 298 parser = XercesParser.class.getName(); 299 } else { 300 getLogger().warn("Unknown value for deprecated property: " + 301 Constants.DEPRECATED_PARSER_PROPERTY + ", value: " + parser + 302 ". If you experience problems during startup, check the parser configuration section of the documentation."); 303 } 304 } else { 305 parser = getSystemProperty(Constants.PARSER_PROPERTY, Constants.DEFAULT_PARSER); 306 } 307 if (getLogger().isDebugEnabled()) { 308 getLogger().debug("Parser: " + parser); 309 getLogger().debug("Classpath: " + classpath); 310 getLogger().debug("Work directory: " + workDir.getCanonicalPath()); 311 } 312 313 ExcaliburComponentManager startupManager = new ExcaliburComponentManager((ClassLoader ) this.context.get(Constants.CONTEXT_CLASS_LOADER)); 314 ContainerUtil.enableLogging(startupManager, this.rootLogger.getChildLogger("startup")); 315 ContainerUtil.contextualize(startupManager, this.context); 316 startupManager.setLoggerManager(this.loggerManager); 317 318 try { 319 startupManager.addComponent(SAXParser.ROLE, 320 ClassUtils.loadClass(parser), 321 new DefaultConfiguration("", "empty")); 322 } catch (Exception e) { 323 throw new ConfigurationException("Could not load parser " + parser, e); 324 } 325 326 ContainerUtil.initialize(startupManager); 327 configure(startupManager); 328 ContainerUtil.dispose(startupManager); 329 startupManager = null; 330 331 final ComponentProxyGenerator proxyGenerator = new ComponentProxyGenerator(); 333 final Component loggerManagerProxy = proxyGenerator.getProxy(LoggerManager.class.getName(),loggerManager); 334 componentManager.addComponentInstance(LoggerManager.ROLE,loggerManagerProxy); 335 336 ContainerUtil.initialize(this.componentManager); 337 338 Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE); 340 if (processor instanceof ThreadSafe) { 341 if (getLogger().isDebugEnabled()) { 342 getLogger().debug("Processor of class " + processor.getClass().getName() + 343 " is ThreadSafe"); 344 } 345 this.threadSafeProcessor = processor; 346 } else { 347 if (getLogger().isDebugEnabled()) { 348 getLogger().debug("Processor of class " + processor.getClass().getName() + 349 " is NOT ThreadSafe -- will be looked up at each request"); 350 } 351 this.componentManager.release(processor); 352 } 353 354 this.sourceResolver = (SourceResolver)this.componentManager.lookup(SourceResolver.ROLE); 355 356 if (this.componentManager.hasComponent(RequestListener.ROLE)){ 357 this.requestListener = (RequestListener) this.componentManager.lookup(RequestListener.ROLE); 358 } 359 } 360 361 362 private void dumpSystemProperties() { 363 if (getLogger().isDebugEnabled()) { 364 try { 365 Enumeration e = System.getProperties().propertyNames(); 366 getLogger().debug("===== System Properties Start ====="); 367 for (; e.hasMoreElements();) { 368 String key = (String ) e.nextElement(); 369 getLogger().debug(key + "=" + System.getProperty(key)); 370 } 371 getLogger().debug("===== System Properties End ====="); 372 } catch (SecurityException se) { 373 } 375 } 376 } 377 378 385 public void configure(ExcaliburComponentManager startupManager) throws ConfigurationException, ContextException { 386 SAXParser p = null; 387 388 Configuration roles = null; 389 try { 390 p = (SAXParser) startupManager.lookup(SAXParser.ROLE); 391 SAXConfigurationHandler b = new SAXConfigurationHandler(); 392 URL url = ClassUtils.getResource("org/apache/cocoon/cocoon.roles"); 393 InputSource is = new InputSource (url.openStream()); 394 is.setSystemId(url.toString()); 395 p.parse(is, b); 396 roles = b.getConfiguration(); 397 } catch (Exception e) { 398 throw new ConfigurationException("Error trying to load configurations", e); 399 } finally { 400 if (p != null) startupManager.release((Component) p); 401 } 402 403 DefaultRoleManager drm = new DefaultRoleManager(); 404 ContainerUtil.enableLogging(drm, this.rootLogger.getChildLogger("roles")); 405 ContainerUtil.configure(drm, roles); 406 roles = null; 407 408 try { 409 this.configurationFile.refresh(); 410 p = (SAXParser)startupManager.lookup(SAXParser.ROLE); 411 SAXConfigurationHandler b = new SAXConfigurationHandler(); 412 InputSource is = SourceUtil.getInputSource(this.configurationFile); 413 p.parse(is, b); 414 this.configuration = b.getConfiguration(); 415 } catch (Exception e) { 416 throw new ConfigurationException("Error trying to load configurations",e); 417 } finally { 418 if (p != null) startupManager.release((Component)p); 419 } 420 421 Configuration conf = this.configuration; 422 if (getLogger().isDebugEnabled()) { 423 getLogger().debug("Root configuration: " + conf.getName()); 424 } 425 if (!"cocoon".equals(conf.getName())) { 426 throw new ConfigurationException("Invalid configuration file\n" + conf.toString()); 427 } 428 if (getLogger().isDebugEnabled()) { 429 getLogger().debug("Configuration version: " + conf.getAttribute("version")); 430 } 431 if (!Constants.CONF_VERSION.equals(conf.getAttribute("version"))) { 432 throw new ConfigurationException("Invalid configuration schema version. Must be '" + Constants.CONF_VERSION + "'."); 433 } 434 435 String userRoles = conf.getAttribute("user-roles", ""); 436 if (!"".equals(userRoles)) { 437 try { 438 p = (SAXParser)startupManager.lookup(SAXParser.ROLE); 439 SAXConfigurationHandler b = new SAXConfigurationHandler(); 440 org.apache.cocoon.environment.Context context = 441 (org.apache.cocoon.environment.Context) this.context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); 442 URL url = context.getResource(userRoles); 443 if (url == null) { 444 throw new ConfigurationException("User-roles configuration '"+userRoles+"' cannot be found."); 445 } 446 InputSource is = new InputSource (new BufferedInputStream (url.openStream())); 447 is.setSystemId(url.toString()); 448 p.parse(is, b); 449 roles = b.getConfiguration(); 450 } catch (Exception e) { 451 throw new ConfigurationException("Error trying to load user-roles configuration", e); 452 } finally { 453 startupManager.release((Component)p); 454 } 455 456 DefaultRoleManager urm = new DefaultRoleManager(drm); 457 ContainerUtil.enableLogging(urm, this.rootLogger.getChildLogger("roles").getChildLogger("user")); 458 ContainerUtil.configure(urm, roles); 459 roles = null; 460 drm = urm; 461 } 462 463 this.componentManager.setRoleManager(drm); 464 this.componentManager.setLoggerManager(this.loggerManager); 465 466 getLogger().debug("Setting up components..."); 467 ContainerUtil.configure(this.componentManager, conf); 468 } 469 470 476 public boolean modifiedSince(long date) { 477 return date < this.configurationFile.getLastModified(); 478 } 479 480 484 public static String getSystemProperty(String property, String value) { 485 try { 486 return System.getProperty(property, value); 487 } catch (SecurityException e) { 488 System.err.println("Caught a SecurityException reading the system property '" + property + "';" + 489 " Cocoon will default to '" + value + "' value."); 490 return value; 491 } 492 } 493 494 497 protected void setSystemProperties() { 498 try { 499 if (getSystemProperty("org.xml.sax.driver", null) == null) { 503 System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); 504 } 505 } catch (SecurityException e) { 506 System.out.println("Caught a SecurityException writing the system property: " + e); 508 } 509 510 try { 511 if (getSystemProperty("javax.xml.parsers.DocumentBuilderFactory", "").startsWith("weblogic")) { 513 System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); 514 System.setProperty("javax.xml.parsers.SAXParserFactory","org.apache.xerces.jaxp.SAXParserFactoryImpl"); 515 } 516 } catch (SecurityException e) { 517 System.out.println("Caught a SecurityException writing the system property: " + e); 519 } 520 } 521 522 525 public void dispose() { 526 if (this.componentManager != null) { 527 if (this.requestListener != null) { 528 this.componentManager.release(this.requestListener); 529 } 530 this.componentManager.release(this.threadSafeProcessor); 531 this.threadSafeProcessor = null; 532 533 this.componentManager.release(this.sourceResolver); 534 this.sourceResolver = null; 535 536 ContainerUtil.dispose(this.componentManager); 537 this.componentManager = null; 538 } 539 540 this.context = null; 541 if (Cocoon.instance == this) { 542 Cocoon.instance = null; 543 } 544 this.disposed = true; 545 } 546 547 552 protected void debug(Environment environment, boolean internal) { 553 String lineSeparator = SystemUtils.LINE_SEPARATOR; 554 Map objectModel = environment.getObjectModel(); 555 Request request = ObjectModelHelper.getRequest(objectModel); 556 Session session = request.getSession(false); 557 StringBuffer msg = new StringBuffer (); 558 msg.append("DEBUGGING INFORMATION:").append(lineSeparator); 559 if (internal) { 560 msg.append("INTERNAL "); 561 } 562 msg.append("REQUEST: ").append(request.getRequestURI()).append(lineSeparator).append(lineSeparator); 563 msg.append("CONTEXT PATH: ").append(request.getContextPath()).append(lineSeparator); 564 msg.append("SERVLET PATH: ").append(request.getServletPath()).append(lineSeparator); 565 msg.append("PATH INFO: ").append(request.getPathInfo()).append(lineSeparator).append(lineSeparator); 566 567 msg.append("REMOTE HOST: ").append(request.getRemoteHost()).append(lineSeparator); 568 msg.append("REMOTE ADDRESS: ").append(request.getRemoteAddr()).append(lineSeparator); 569 msg.append("REMOTE USER: ").append(request.getRemoteUser()).append(lineSeparator); 570 msg.append("REQUEST SESSION ID: ").append(request.getRequestedSessionId()).append(lineSeparator); 571 msg.append("REQUEST PREFERRED LOCALE: ").append(request.getLocale().toString()).append(lineSeparator); 572 msg.append("SERVER HOST: ").append(request.getServerName()).append(lineSeparator); 573 msg.append("SERVER PORT: ").append(request.getServerPort()).append(lineSeparator).append(lineSeparator); 574 575 msg.append("METHOD: ").append(request.getMethod()).append(lineSeparator); 576 msg.append("CONTENT LENGTH: ").append(request.getContentLength()).append(lineSeparator); 577 msg.append("PROTOCOL: ").append(request.getProtocol()).append(lineSeparator); 578 msg.append("SCHEME: ").append(request.getScheme()).append(lineSeparator); 579 msg.append("AUTH TYPE: ").append(request.getAuthType()).append(lineSeparator).append(lineSeparator); 580 msg.append("CURRENT ACTIVE REQUESTS: ").append(activeRequestCount).append(lineSeparator); 581 582 Enumeration e = request.getParameterNames(); 584 585 msg.append("REQUEST PARAMETERS:").append(lineSeparator).append(lineSeparator); 586 587 while (e.hasMoreElements()) { 588 String p = (String ) e.nextElement(); 589 590 msg.append("PARAM: '").append(p).append("' ") 591 .append("VALUES: '"); 592 String [] params = request.getParameterValues(p); 593 for (int i = 0; i < params.length; i++) { 594 msg.append("[" + params[i] + "]"); 595 if (i != (params.length - 1)) { 596 msg.append(", "); 597 } 598 } 599 600 msg.append("'").append(lineSeparator); 601 } 602 603 Enumeration e2 = request.getHeaderNames(); 605 606 msg.append("HEADER PARAMETERS:").append(lineSeparator).append(lineSeparator); 607 608 while (e2.hasMoreElements()) { 609 String p = (String ) e2.nextElement(); 610 611 msg.append("PARAM: '").append(p).append("' ") 612 .append("VALUES: '"); 613 Enumeration e3 = request.getHeaders(p); 614 while (e3.hasMoreElements()) { 615 msg.append("[" + e3.nextElement() + "]"); 616 if (e3.hasMoreElements()) { 617 msg.append(", "); 618 } 619 } 620 621 msg.append("'").append(lineSeparator); 622 } 623 624 msg.append(lineSeparator).append("SESSION ATTRIBUTES:").append(lineSeparator).append(lineSeparator); 625 626 if (session != null) { 628 synchronized (session) { 631 e = session.getAttributeNames(); 632 while (e.hasMoreElements()) { 633 String p = (String ) e.nextElement(); 634 msg.append("PARAM: '").append(p).append("' ") 635 .append("VALUE: '").append(session.getAttribute(p)).append("'") 636 .append(lineSeparator); 637 } 638 } 639 } 640 641 getLogger().debug(msg.toString()); 642 } 643 644 651 public boolean process(Environment environment) 652 throws Exception { 653 if (this.disposed) { 654 throw new IllegalStateException ("You cannot process a Disposed Cocoon engine."); 655 } 656 657 Object key = CocoonComponentManager.startProcessing(environment); 658 final int environmentDepth = CocoonComponentManager.markEnvironment(); 659 CocoonComponentManager.enterEnvironment(environment, 660 this.componentManager, 661 this); 662 try { 663 boolean result; 664 if (getLogger().isDebugEnabled()) { 665 ++activeRequestCount; 666 debug(environment, false); 667 } 668 669 670 if (this.requestListener != null) { 671 try { 672 requestListener.onRequestStart(environment); 673 } catch (Exception e) { 674 getLogger().error("Error encountered monitoring request start: " + e.getMessage()); 675 } 676 } 677 678 if (this.threadSafeProcessor != null) { 679 result = this.threadSafeProcessor.process(environment); 680 if (this.requestListener != null) { 681 try { 682 requestListener.onRequestEnd(environment); 683 } catch (Exception e) { 684 getLogger().error("Error encountered monitoring request start: " + e.getMessage()); 685 } 686 } 687 } else { 688 Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE); 689 try { 690 result = processor.process(environment); 691 if (this.requestListener != null) { 692 try { 693 requestListener.onRequestEnd(environment); 694 } catch (Exception e) { 695 getLogger().error("Error encountered monitoring request start: " + e.getMessage()); 696 } 697 } 698 } finally { 699 this.componentManager.release(processor); 700 } 701 } 702 environment.commitResponse(); 704 705 return result; 706 } catch (Exception any) { 707 if (this.requestListener != null) { 708 try { 709 requestListener.onRequestException(environment, any); 710 } catch (Exception e) { 711 getLogger().error("Error encountered monitoring request start: " + e.getMessage()); 712 } 713 } 714 environment.tryResetResponse(); 716 throw any; 717 } finally { 718 CocoonComponentManager.leaveEnvironment(); 719 CocoonComponentManager.endProcessing(environment, key); 720 if (getLogger().isDebugEnabled()) { 721 --activeRequestCount; 722 } 723 724 CocoonComponentManager.checkEnvironment(environmentDepth, getLogger()); 726 } 727 } 728 729 734 public ProcessingPipeline buildPipeline(Environment environment) 735 throws Exception { 736 if (disposed) { 737 throw new IllegalStateException ("You cannot process a Disposed Cocoon engine."); 738 } 739 740 try { 741 if (getLogger().isDebugEnabled()) { 742 ++activeRequestCount; 743 debug(environment, true); 744 } 745 746 if (this.threadSafeProcessor != null) { 747 return this.threadSafeProcessor.buildPipeline(environment); 748 } else { 749 Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE); 750 try { 751 return processor.buildPipeline(environment); 752 } finally { 753 this.componentManager.release(processor); 754 } 755 } 756 757 } finally { 758 if (getLogger().isDebugEnabled()) { 759 --activeRequestCount; 760 } 761 } 762 } 763 764 768 public Map getComponentConfigurations() { 769 return Collections.EMPTY_MAP; 770 } 771 772 776 public Processor getRootProcessor() { 777 return this; 778 } 779 780 783 public int getActiveRequestCount() { 784 return activeRequestCount; 785 } 786 787 public ExcaliburComponentManager getComponentManager() { 788 return this.componentManager; 789 } 790 } 791 | Popular Tags |