blob: fed17547afe2298b198fdf5a2aafc1a19ee6ccc9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon;
import org.apache.avalon.excalibur.component.ComponentProxyGenerator;
import org.apache.avalon.excalibur.component.DefaultRoleManager;
import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.CocoonComponentManager;
import org.apache.cocoon.components.ComponentContext;
import org.apache.cocoon.components.PropertyAwareSAXConfigurationHandler;
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
import org.apache.cocoon.components.source.SourceUtil;
import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.util.ClassUtils;
import org.apache.cocoon.util.Deprecation;
import org.apache.cocoon.util.SimpleSourceResolver;
import org.apache.cocoon.util.Settings;
import org.apache.cocoon.util.SettingsHelper;
import org.apache.cocoon.util.location.Location;
import org.apache.cocoon.util.location.LocationImpl;
import org.apache.cocoon.util.location.LocationUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.excalibur.instrument.InstrumentManageable;
import org.apache.excalibur.instrument.InstrumentManager;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.excalibur.source.impl.URLSource;
import org.apache.excalibur.xml.impl.XercesParser;
import org.apache.excalibur.xml.sax.SAXParser;
import org.xml.sax.InputSource;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.ConcurrentModificationException;
/**
* The Cocoon Object is the main Kernel for the entire Cocoon system.
*
* @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a> (Apache Software Foundation)
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:leo.sutic@inspireinfrastructure.com">Leo Sutic</a>
* @version CVS $Id$
*/
public class Cocoon
extends AbstractLogEnabled
implements ThreadSafe,
Component,
Initializable,
Disposable,
Modifiable,
Processor,
Contextualizable,
Composable,
InstrumentManageable {
// Register the location finder for Avalon configuration objects and exceptions
// and keep a strong reference to it.
private static final LocationUtils.LocationFinder LOCATION_FINDER = new LocationUtils.LocationFinder() {
public Location getLocation(Object obj, String description) {
if (obj instanceof Configuration) {
Configuration config = (Configuration) obj;
String locString = config.getLocation();
Location result = LocationUtils.parse(locString);
if (LocationUtils.isKnown(result)) {
// Add description
StringBuffer desc = new StringBuffer().append('<');
// Unfortunately Configuration.getPrefix() is not public
try {
if (config.getNamespace().startsWith("http://apache.org/cocoon/sitemap/")) {
desc.append("map:");
}
} catch (ConfigurationException e) {
// no namespace: ignore
}
desc.append(config.getName()).append('>');
return new LocationImpl(desc.toString(), result);
} else {
return result;
}
}
if (obj instanceof Exception) {
// Many exceptions in Cocoon have a message like "blah blah at file://foo/bar.xml:12:1"
String msg = ((Exception)obj).getMessage();
if (msg == null) {
return null;
}
int pos = msg.lastIndexOf(" at ");
if (pos != -1) {
return LocationUtils.parse(msg.substring(pos + 4));
} else {
// Will try other finders
return null;
}
}
// Try next finders.
return null;
}
};
static {
LocationUtils.addFinder(LOCATION_FINDER);
}
static Cocoon instance;
/** The root Cocoon logger */
private Logger rootLogger;
/** The application context */
private Context context;
/** The configuration file */
private Source configurationFile;
/** The configuration tree */
private Configuration configuration;
/** The logger manager */
private LoggerManager loggerManager;
/** The instrument manager */
private InstrumentManager instrumentManager;
/** The classpath (null if not available) */
private String classpath;
/** The working directory (null if not available) */
private File workDir;
/** The component manager. */
private ExcaliburComponentManager componentManager;
/** The parent component manager. */
private ComponentManager parentComponentManager;
/** Flag for disposed or not */
private boolean disposed;
/** Active request count */
private volatile int activeRequestCount;
/** The Processor if it is ThreadSafe */
private Processor threadSafeProcessor;
/** The source resolver */
protected SourceResolver sourceResolver;
/** An optional Avalon Component that is called before and after processing all requests. */
protected RequestListener requestListener;
/**
* Creates a new <code>Cocoon</code> instance.
*
* @exception ConfigurationException if an error occurs
*/
public Cocoon() throws ConfigurationException {
// Set the system properties needed by Xalan2.
this.setSystemProperties();
// HACK: Provide a way to share an instance of Cocoon object between
// several servlets/portlets.
Cocoon.instance = this;
}
public void enableLogging(Logger logger) {
this.rootLogger = logger;
super.enableLogging(logger.getChildLogger("cocoon"));
}
/**
* Get the parent component manager. For purposes of
* avoiding extra method calls, the manager parameter may be null.
*
* @param manager the parent component manager. May be <code>null</code>
*/
public void compose(ComponentManager manager)
throws ComponentException {
this.parentComponentManager = manager;
}
/**
* Describe <code>contextualize</code> method here.
*
* @param context a <code>Context</code> value
* @exception ContextException if an error occurs
*/
public void contextualize(Context context) throws ContextException {
if (this.context == null) {
this.context = new ComponentContext(context);
SettingsHelper.createSettings((DefaultContext)this.context, this.getLogger());
((DefaultContext) this.context).makeReadOnly();
this.classpath = (String)context.get(Constants.CONTEXT_CLASSPATH);
this.workDir = (File)context.get(Constants.CONTEXT_WORK_DIR);
try {
// FIXME: add a configuration option for the refresh delay.
// for now, hard-coded to 1 second.
URLSource urlSource = new URLSource();
urlSource.init((URL) context.get(Constants.CONTEXT_CONFIG_URL), null);
this.configurationFile = new DelayedRefreshSourceWrapper(urlSource,
1000L);
} catch (IOException e) {
throw new ContextException("Could not open configuration file.", e);
} catch (Exception e) {
throw new ContextException("contextualize(..) Exception", e);
}
}
}
/**
* The <code>setLoggerManager</code> method will get a <code>LoggerManager</code>
* for further use.
*
* @param loggerManager a <code>LoggerManager</code> value
*/
public void setLoggerManager(LoggerManager loggerManager) {
this.loggerManager = loggerManager;
Deprecation.setLogger(this.loggerManager.getLoggerForCategory("deprecation"));
}
/**
* Set the <code>InstrumentManager</code> for this Cocoon instance.
*
* @param manager an <code>InstrumentManager</code> instance
*/
public void setInstrumentManager(final InstrumentManager manager) {
this.instrumentManager = manager;
}
/**
* The <code>initialize</code> method
*
* @exception Exception if an error occurs
*/
public void initialize() throws Exception {
if (this.parentComponentManager != null) {
this.componentManager = new CocoonComponentManager(this.parentComponentManager,
(ClassLoader) this.context.get(Constants.CONTEXT_CLASS_LOADER));
} else {
this.componentManager = new CocoonComponentManager((ClassLoader) this.context.get(Constants.CONTEXT_CLASS_LOADER));
}
ContainerUtil.enableLogging(this.componentManager, this.rootLogger.getChildLogger("manager"));
ContainerUtil.contextualize(this.componentManager, this.context);
this.componentManager.setInstrumentManager(this.instrumentManager);
this.getLogger().debug("New Cocoon object.");
// Log the System Properties.
this.dumpSystemProperties();
// Setup the default parser, for parsing configuration.
// If one need to use a different parser, set the given system property
// first check for deprecated property to be compatible:
String parser = getSystemProperty(Constants.DEPRECATED_PARSER_PROPERTY, Constants.DEFAULT_PARSER);
if (!Constants.DEFAULT_PARSER.equals(parser)) {
this.getLogger().warn("Deprecated property " +
Constants.DEPRECATED_PARSER_PROPERTY + " is used. Please use " +
Constants.PARSER_PROPERTY + " instead.");
if ("org.apache.cocoon.components.parser.XercesParser".equals(parser)) {
parser = XercesParser.class.getName();
} else {
this.getLogger().warn("Unknown value for deprecated property: " +
Constants.DEPRECATED_PARSER_PROPERTY + ", value: " + parser +
". If you experience problems during startup, check the parser configuration section of the documentation.");
}
} else {
parser = getSystemProperty(Constants.PARSER_PROPERTY, Constants.DEFAULT_PARSER);
}
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("Parser: " + parser);
this.getLogger().debug("Classpath: " + this.classpath);
this.getLogger().debug("Work directory: " + this.workDir.getCanonicalPath());
}
ExcaliburComponentManager startupManager = new ExcaliburComponentManager((ClassLoader) this.context.get(Constants.CONTEXT_CLASS_LOADER));
ContainerUtil.enableLogging(startupManager, this.rootLogger.getChildLogger("startup"));
ContainerUtil.contextualize(startupManager, this.context);
startupManager.setLoggerManager(this.loggerManager);
try {
startupManager.addComponent(SAXParser.ROLE,
ClassUtils.loadClass(parser),
new DefaultConfiguration("", "empty"));
} catch (Exception e) {
throw new ConfigurationException("Could not load parser " + parser, e);
}
ContainerUtil.initialize(startupManager);
this.configure(startupManager);
ContainerUtil.dispose(startupManager);
startupManager = null;
// add the logger manager to the component locator
final ComponentProxyGenerator proxyGenerator = new ComponentProxyGenerator();
final Component loggerManagerProxy = proxyGenerator.getProxy(LoggerManager.class.getName(),this.loggerManager);
this.componentManager.addComponentInstance(LoggerManager.ROLE,loggerManagerProxy);
ContainerUtil.initialize(this.componentManager);
// Get the Processor and keep it if it's ThreadSafe
Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE);
if (processor instanceof ThreadSafe) {
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("Processor of class " + processor.getClass().getName() +
" is ThreadSafe");
}
this.threadSafeProcessor = processor;
} else {
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("Processor of class " + processor.getClass().getName() +
" is NOT ThreadSafe -- will be looked up at each request");
}
this.componentManager.release(processor);
}
this.sourceResolver = (SourceResolver)this.componentManager.lookup(SourceResolver.ROLE);
if (this.componentManager.hasComponent(RequestListener.ROLE)){
this.requestListener = (RequestListener) this.componentManager.lookup(RequestListener.ROLE);
}
}
/** Dump System Properties */
private void dumpSystemProperties() {
if (this.getLogger().isDebugEnabled()) {
try {
Enumeration e = System.getProperties().propertyNames();
this.getLogger().debug("===== System Properties Start =====");
for (; e.hasMoreElements();) {
String key = (String) e.nextElement();
this.getLogger().debug(key + "=" + System.getProperty(key));
}
this.getLogger().debug("===== System Properties End =====");
} catch (SecurityException se) {
// Ignore Exceptions.
}
}
}
/**
* Configure this <code>Cocoon</code> instance.
*
* @param startupManager an <code>ExcaliburComponentManager</code> value
* @exception ConfigurationException if an error occurs
* @exception ContextException if an error occurs
*/
public void configure(ExcaliburComponentManager startupManager) throws ConfigurationException, ContextException {
SAXParser p = null;
Settings settings = SettingsHelper.getSettings(this.context);
Configuration roles = null;
try {
p = (SAXParser) startupManager.lookup(SAXParser.ROLE);
SAXConfigurationHandler b = new PropertyAwareSAXConfigurationHandler(settings, this.getLogger());
URL url = ClassUtils.getResource("org/apache/cocoon/cocoon.roles");
InputSource is = new InputSource(url.openStream());
is.setSystemId(url.toString());
p.parse(is, b);
roles = b.getConfiguration();
} catch (Exception e) {
throw new ConfigurationException("Error trying to load configurations", e);
} finally {
if (p != null) startupManager.release((Component) p);
}
DefaultRoleManager drm = new DefaultRoleManager();
ContainerUtil.enableLogging(drm, this.rootLogger.getChildLogger("roles"));
ContainerUtil.configure(drm, roles);
roles = null;
try {
this.configurationFile.refresh();
p = (SAXParser)startupManager.lookup(SAXParser.ROLE);
SAXConfigurationHandler b = new PropertyAwareSAXConfigurationHandler(settings, this.getLogger());
InputSource is = SourceUtil.getInputSource(this.configurationFile);
p.parse(is, b);
this.configuration = b.getConfiguration();
} catch (Exception e) {
throw new ConfigurationException("Error trying to load configurations",e);
} finally {
if (p != null) startupManager.release((Component)p);
}
Configuration conf = this.configuration;
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("Root configuration: " + conf.getName());
}
if (!"cocoon".equals(conf.getName())) {
throw new ConfigurationException("Invalid configuration file\n" + conf.toString());
}
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("Configuration version: " + conf.getAttribute("version"));
}
if (!Constants.CONF_VERSION.equals(conf.getAttribute("version"))) {
throw new ConfigurationException("Invalid configuration schema version. Must be '" + Constants.CONF_VERSION + "'.");
}
String userRoles = conf.getAttribute("user-roles", "");
if (!"".equals(userRoles)) {
try {
p = (SAXParser)startupManager.lookup(SAXParser.ROLE);
SAXConfigurationHandler b = new PropertyAwareSAXConfigurationHandler(settings, this.getLogger());
org.apache.cocoon.environment.Context context =
(org.apache.cocoon.environment.Context) this.context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
URL url = context.getResource(userRoles);
if (url == null) {
throw new ConfigurationException("User-roles configuration '"+userRoles+"' cannot be found.");
}
InputSource is = new InputSource(new BufferedInputStream(url.openStream()));
is.setSystemId(url.toString());
p.parse(is, b);
roles = b.getConfiguration();
} catch (Exception e) {
throw new ConfigurationException("Error trying to load user-roles configuration", e);
} finally {
startupManager.release((Component)p);
}
DefaultRoleManager urm = new DefaultRoleManager(drm);
ContainerUtil.enableLogging(urm, this.rootLogger.getChildLogger("roles").getChildLogger("user"));
ContainerUtil.configure(urm, roles);
roles = null;
drm = urm;
}
this.componentManager.setRoleManager(drm);
this.componentManager.setLoggerManager(this.loggerManager);
this.getLogger().debug("Setting up components...");
ContainerUtil.configure(this.componentManager, conf);
}
/**
* Queries the class to estimate its ergodic period termination.
*
* @param date a <code>long</code> value
* @return a <code>boolean</code> value
*/
public boolean modifiedSince(long date) {
return date < this.configurationFile.getLastModified();
}
/**
* Helper method to retrieve system property.
* Returns default value if SecurityException is caught.
*/
public static String getSystemProperty(String property, String value) {
try {
return System.getProperty(property, value);
} catch (SecurityException e) {
System.err.println("Caught a SecurityException reading the system property '" + property + "';" +
" Cocoon will default to '" + value + "' value.");
return value;
}
}
/**
* Sets required system properties.
*/
protected void setSystemProperties() {
try {
// FIXME We shouldn't have to specify the SAXParser...
// This is needed by Xalan2, it is used by org.xml.sax.helpers.XMLReaderFactory
// to locate the SAX2 driver.
if (getSystemProperty("org.xml.sax.driver", null) == null) {
System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
}
} catch (SecurityException e) {
// Ignore security exceptions
System.out.println("Caught a SecurityException writing the system property: " + e);
}
try {
// FIXME We shouldn't have to specify these. Needed to override jaxp implementation of weblogic.
if (getSystemProperty("javax.xml.parsers.DocumentBuilderFactory", "").startsWith("weblogic")) {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory","org.apache.xerces.jaxp.SAXParserFactoryImpl");
}
} catch (SecurityException e) {
// Ignore security exceptions
System.out.println("Caught a SecurityException writing the system property: " + e);
}
}
/**
* Dispose this instance
*/
public void dispose() {
if (this.componentManager != null) {
if (this.requestListener != null) {
this.componentManager.release(this.requestListener);
}
this.componentManager.release(this.threadSafeProcessor);
this.threadSafeProcessor = null;
this.componentManager.release((Component)this.sourceResolver);
this.sourceResolver = null;
ContainerUtil.dispose(this.componentManager);
this.componentManager = null;
}
this.context = null;
if (Cocoon.instance == this) {
Cocoon.instance = null;
}
this.disposed = true;
}
/**
* Log debug information about the current environment.
*
* @param environment an <code>Environment</code> value
*/
protected void debug(Environment environment, boolean internal) {
String lineSeparator = SystemUtils.LINE_SEPARATOR;
Map objectModel = environment.getObjectModel();
Request request = ObjectModelHelper.getRequest(objectModel);
Session session = request.getSession(false);
StringBuffer msg = new StringBuffer(2048);
msg.append("DEBUGGING INFORMATION:").append(lineSeparator);
if (internal) {
msg.append("INTERNAL ");
}
msg.append("REQUEST: ").append(request.getRequestURI()).append(lineSeparator).append(lineSeparator);
msg.append("CONTEXT PATH: ").append(request.getContextPath()).append(lineSeparator);
msg.append("SERVLET PATH: ").append(request.getServletPath()).append(lineSeparator);
msg.append("PATH INFO: ").append(request.getPathInfo()).append(lineSeparator).append(lineSeparator);
msg.append("REMOTE HOST: ").append(request.getRemoteHost()).append(lineSeparator);
msg.append("REMOTE ADDRESS: ").append(request.getRemoteAddr()).append(lineSeparator);
msg.append("REMOTE USER: ").append(request.getRemoteUser()).append(lineSeparator);
msg.append("REQUEST SESSION ID: ").append(request.getRequestedSessionId()).append(lineSeparator);
msg.append("REQUEST PREFERRED LOCALE: ").append(request.getLocale().toString()).append(lineSeparator);
msg.append("SERVER HOST: ").append(request.getServerName()).append(lineSeparator);
msg.append("SERVER PORT: ").append(request.getServerPort()).append(lineSeparator).append(lineSeparator);
msg.append("METHOD: ").append(request.getMethod()).append(lineSeparator);
msg.append("CONTENT LENGTH: ").append(request.getContentLength()).append(lineSeparator);
msg.append("PROTOCOL: ").append(request.getProtocol()).append(lineSeparator);
msg.append("SCHEME: ").append(request.getScheme()).append(lineSeparator);
msg.append("AUTH TYPE: ").append(request.getAuthType()).append(lineSeparator).append(lineSeparator);
msg.append("CURRENT ACTIVE REQUESTS: ").append(this.activeRequestCount).append(lineSeparator);
// log all of the request parameters
Enumeration e = request.getParameterNames();
msg.append("REQUEST PARAMETERS:").append(lineSeparator).append(lineSeparator);
while (e.hasMoreElements()) {
String p = (String) e.nextElement();
msg.append("PARAM: '").append(p).append("' ")
.append("VALUES: '");
String[] params = request.getParameterValues(p);
for (int i = 0; i < params.length; i++) {
msg.append("[" + params[i] + "]");
if (i != (params.length - 1)) {
msg.append(", ");
}
}
msg.append("'").append(lineSeparator);
}
// log all of the header parameters
Enumeration e2 = request.getHeaderNames();
msg.append("HEADER PARAMETERS:").append(lineSeparator).append(lineSeparator);
while (e2.hasMoreElements()) {
String p = (String) e2.nextElement();
msg.append("PARAM: '").append(p).append("' ")
.append("VALUES: '");
Enumeration e3 = request.getHeaders(p);
while (e3.hasMoreElements()) {
msg.append("[" + e3.nextElement() + "]");
if (e3.hasMoreElements()) {
msg.append(", ");
}
}
msg.append("'").append(lineSeparator);
}
msg.append(lineSeparator).append("SESSION ATTRIBUTES:").append(lineSeparator).append(lineSeparator);
// log all of the session attributes
if (session != null) {
StringBuffer buffer = new StringBuffer("");
int count = -1;
while (count <= 0) {
// Fix bug #12139: Session can be modified while still
// being enumerated here
try {
e = session.getAttributeNames();
while (e.hasMoreElements()) {
String p = (String) e.nextElement();
buffer.append("PARAM: '").append(p).append("' ")
.append("VALUE: '").append(session.getAttribute(p)).append("'")
.append(lineSeparator);
}
break;
} catch (ConcurrentModificationException ex) {
buffer = new StringBuffer("");
++count;
}
}
msg.append(buffer.toString());
}
this.getLogger().debug(msg.toString());
}
/**
* Process the given <code>Environment</code> to produce the output.
*
* @param environment an <code>Environment</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
public boolean process(Environment environment)
throws Exception {
if (this.disposed) {
throw new IllegalStateException("You cannot process a Disposed Cocoon engine.");
}
Object key = CocoonComponentManager.startProcessing(environment);
final int environmentDepth = CocoonComponentManager.markEnvironment();
CocoonComponentManager.enterEnvironment(environment,
this.componentManager,
this);
try {
boolean result;
if (this.getLogger().isDebugEnabled()) {
++this.activeRequestCount;
this.debug(environment, false);
}
if (this.requestListener != null) {
try {
this.requestListener.onRequestStart(environment);
} catch (Exception e) {
this.getLogger().error("Error encountered monitoring request start: " + e.getMessage());
}
}
if (this.threadSafeProcessor != null) {
result = this.threadSafeProcessor.process(environment);
if (this.requestListener != null) {
try {
this.requestListener.onRequestEnd(environment);
} catch (Exception e) {
this.getLogger().error("Error encountered monitoring request start: " + e.getMessage());
}
}
} else {
Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE);
try {
result = processor.process(environment);
if (this.requestListener != null) {
try {
this.requestListener.onRequestEnd(environment);
} catch (Exception e) {
this.getLogger().error("Error encountered monitoring request start: " + e.getMessage());
}
}
} finally {
this.componentManager.release(processor);
}
}
// commit response on success
environment.commitResponse();
return result;
} catch (Exception any) {
if (this.requestListener != null) {
try {
this.requestListener.onRequestException(environment, any);
} catch (Exception e) {
this.getLogger().error("Error encountered monitoring request start: " + e.getMessage());
}
}
// reset response on error
environment.tryResetResponse();
throw any;
} finally {
CocoonComponentManager.leaveEnvironment();
CocoonComponentManager.endProcessing(environment, key);
if (this.getLogger().isDebugEnabled()) {
--this.activeRequestCount;
}
// TODO (CZ): This is only for testing - remove it later on
CocoonComponentManager.checkEnvironment(environmentDepth, this.getLogger());
}
}
/**
* Process the given <code>Environment</code> to assemble
* a <code>ProcessingPipeline</code>.
* @since 2.1
*/
public ProcessingPipeline buildPipeline(Environment environment)
throws Exception {
if (this.disposed) {
throw new IllegalStateException("You cannot process a Disposed Cocoon engine.");
}
try {
if (this.getLogger().isDebugEnabled()) {
++this.activeRequestCount;
this.debug(environment, true);
}
if (this.threadSafeProcessor != null) {
return this.threadSafeProcessor.buildPipeline(environment);
} else {
Processor processor = (Processor)this.componentManager.lookup(Processor.ROLE);
try {
return processor.buildPipeline(environment);
} finally {
this.componentManager.release(processor);
}
}
} finally {
if (this.getLogger().isDebugEnabled()) {
--this.activeRequestCount;
}
}
}
/**
* Get the sitemap component configurations
* @since 2.1
*/
public Map getComponentConfigurations() {
return Collections.EMPTY_MAP;
}
/**
* Return this (Cocoon is always at the root of the processing chain).
* @since 2.1.1
*/
public Processor getRootProcessor() {
return this;
}
/**
* Accessor for active request count
*/
public int getActiveRequestCount() {
return this.activeRequestCount;
}
public ExcaliburComponentManager getComponentManager() {
return this.componentManager;
}
/**
* Create a simple source resolver.
*/
protected SourceResolver createSourceResolver(Logger logger) throws ContextException {
// Create our own resolver
final SimpleSourceResolver resolver = new SimpleSourceResolver();
resolver.enableLogging(logger);
try {
resolver.contextualize(this.context);
} catch (ContextException ce) {
throw new ContextException(
"Cannot setup source resolver.", ce);
}
return resolver;
}
}