cziegeler 2003/04/29 03:45:22
Modified: src/java/org/apache/cocoon/selection ExceptionSelector.java
src/java/org/apache/cocoon/components/treeprocessor/sitemap
ErrorHandlerHelper.java MountNode.java
src/java/org/apache/cocoon/environment/wrapper
EnvironmentWrapper.java
src/documentation/xdocs/userdocs/concepts book.xml
src/webapp/samples samples.xml
src/java/org/apache/cocoon/servlet CocoonServlet.java
src/java/org/apache/cocoon/environment/http
HttpEnvironment.java
src/java/org/apache/cocoon/environment Environment.java
AbstractEnvironment.java
src/java/org/apache/cocoon/components
CocoonComponentManager.java
Added: src/java/org/apache/cocoon/selection
XPathExceptionSelector.java
src/webapp/samples/errorhandling resourceNotFound.htm
main.htm generalerror.htm sitemap.xmap
src/webapp/samples/errorhandling/exception validation.htm
application.htm sitemap.xmap application1.htm
application2.htm
src/documentation/xdocs/userdocs/concepts errorhandling.xml
src/samples/org/apache/cocoon/samples/errorhandling
ValidationException.java ExceptionGenerator.java
ApplicationException.java
Log:
Applying patches from Bjoern Luetkemeier ([EMAIL PROTECTED]):
- Fixing resolving of resources in error handling
- Switching environment from URL to Source
- Enhancing error selector
Revision Changes Path
1.3 +47 -8
cocoon-2.1/src/java/org/apache/cocoon/selection/ExceptionSelector.java
Index: ExceptionSelector.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/selection/ExceptionSelector.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ExceptionSelector.java 10 Apr 2003 13:59:32 -0000 1.2
+++ ExceptionSelector.java 29 Apr 2003 10:45:19 -0000 1.3
@@ -83,6 +83,8 @@
* Note that both "name" and "unroll" can be specified. In that case, we
first try to unroll the exception,
* and if none of the causes has a name, then the "name" attribute is
considered.
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">J�rgen Seitz</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
* @since 2.1
* @version CVS $Id$
@@ -149,10 +151,10 @@
throw new IllegalStateException("No exception in object model.
ExceptionSelector can only be used in <map:handle-errors>");
}
- return findName(thr);
+ return find(thr);
}
- private String findName(Throwable thr) {
+ private FindResult find(Throwable thr) {
// Now find the proper name
for (int i = 0; i < this.clazz.length; i++) {
if (this.clazz[i].isInstance(thr)) {
@@ -162,15 +164,15 @@
if (this.unroll[i]) {
Throwable cause = ExceptionUtils.getCause(thr);
if (cause != null) {
- String causeName = findName(cause);
- if (causeName != null) {
- return causeName;
+ FindResult result = find(cause);
+ if (result != null) {
+ return result;
}
}
}
// Not unrolled
- return this.name[i];
+ return new FindResult(this.name[i], thr);
}
}
@@ -180,7 +182,44 @@
public boolean select(String expression, Object selectorContext) {
// Just compare the expression with the previously found name
- return expression.equals(selectorContext);
+ boolean result =
expression.equals(((FindResult)selectorContext).getName());
+
+ if (result) {
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("select succesfull for
condition " + selectorContext.toString());
+ }
+
+ return result;
+ }
+
+ class FindResult {
+ private String name;
+ private Throwable throwable;
+
+ public FindResult(String name, Throwable throwable) {
+ this.name = name;
+ this.throwable = throwable;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Throwable getThrowable() {
+ return this.throwable;
+ }
+
+ public void setThrowable(Throwable throwable) {
+ this.throwable = throwable;
+ }
+
+ public String toString() {
+ return this.name;
+ }
}
}
1.1
cocoon-2.1/src/java/org/apache/cocoon/selection/XPathExceptionSelector.java
Index: XPathExceptionSelector.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.selection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.commons.jxpath.CompiledExpression;
import org.apache.commons.jxpath.JXPathContext;
/**
* Additional to the inherited functionality from its superclass
ExceptionSelector,
* this selector allows to define xpath expressions to evaluate supplemental
information
* given in the thrown exception.
* The configuration of this selector allows to map not only exceptions but
also
* xpath expressions to symbolic names that are used in the <map:when>
alternatives.
* <p>
* Example configuration :
* <pre>
* <map:selector type="error" src="....XPathExceptionSelector">
* <exception name="denied" class="my.comp.auth.AuthenticationFailure">
* <xpath name="PasswordWrong" test="authCode=10"/>
* <xpath name="PasswordExpired" test="errorCode=11"/>
* <xpath name="AccessForbidden" test="errorCode>11"/>
* </exception>
* </map:selector>
* </pre>
* This example shows several features :
* <li>the test is the xpath expression that will be evaluated against the
exception ,</li>
* <li>an xpath expression can be given a name, which is used in the
<map:when> tests,</li>
*
* @author <a href="mailto:[EMAIL PROTECTED]">J�rgen Seitz</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @since 2.1
* @version CVS $Id: XPathExceptionSelector.java,v 1.1 2003/04/29 10:45:19
cziegeler Exp $
*/
public class XPathExceptionSelector extends ExceptionSelector implements
Configurable {
private Map exception2XPath = new HashMap();
public void configure(Configuration conf) throws ConfigurationException {
super.configure(conf);
Configuration[] children = conf.getChildren("exception");
Configuration[] xPathChildren;
for (int i = 0; i < children.length; i++) {
// Check if there are XPath-Expressions configured
xPathChildren = children[i].getChildren("xpath");
Map xPathMap = new HashMap();
for (int j = 0; j < xPathChildren.length; j++) {
Configuration xPathChild = xPathChildren[j];
String xPathName =
xPathChild.getAttribute("name");
CompiledExpression xPath =
JXPathContext.compile(xPathChild.getAttribute("test"));
xPathMap.put(xPath, xPathName);
}
if (xPathMap.size() > 0)
// store xpath - config if there is some
exception2XPath.put(children[i].getAttribute("name", null), xPathMap);
}
}
/**
* Compute the exception type, given the configuration and the exception
stored in the object model.
*
* @see ObjectModelHelper#getThrowable()
*/
public Object getSelectorContext(Map objectModel, Parameters parameters) {
// get exception from super class
FindResult selectorContext =
(FindResult)super.getSelectorContext(objectModel, parameters);
if (selectorContext != null) {
String exceptionName = selectorContext.getName();
Throwable t = selectorContext.getThrowable();
Map xPathMap = (Map) exception2XPath.get(exceptionName);
if (xPathMap != null) {
// create a context for the thrown exception
JXPathContext context =
JXPathContext.newContext(t);
for (Iterator iterator =
xPathMap.entrySet().iterator(); iterator.hasNext();) {
Entry entry = (Entry) iterator.next();
if (((CompiledExpression)
entry.getKey()).getValue(context).equals(Boolean.TRUE)) {
// set the configured name if
the expression is succesfull
selectorContext.setName((String)entry.getValue());
return selectorContext;
}
}
}
}
return selectorContext;
}
}
1.1
cocoon-2.1/src/webapp/samples/errorhandling/resourceNotFound.htm
Index: resourceNotFound.htm
===================================================================
<html>
<body>
<p>A ResourceNotFoundException has occured. Handled by
pipeline's error handler in parent sitemap.</p>
</body>
</html>
1.1 cocoon-2.1/src/webapp/samples/errorhandling/main.htm
Index: main.htm
===================================================================
<html>
<body>
<p>Please choose an exception:</p>
<form action="exception/exception">
<input type="hidden" name="exception"
value="validation"/>
<input type="submit" value="ValidationException"/>
</form>
<form action="exception/exception">
<input type="hidden" name="exception"
value="application"/>
<input type="hidden" name="code" value="1"/>
<input type="submit" value="ApplicationException (1)"/>
</form>
<form action="exception/exception">
<input type="hidden" name="exception"
value="application"/>
<input type="hidden" name="code" value="2"/>
<input type="submit" value="ApplicationException (2)"/>
</form>
<form action="exception/exception">
<input type="hidden" name="exception"
value="application"/>
<input type="hidden" name="code" value="3"/>
<input type="submit" value="ApplicationException (3)"/>
</form>
<form action="exception/exception">
<input type="hidden" name="exception"
value="resourceNotFound"/>
<input type="submit" value="ResourceNotFoundException"/>
</form>
<form action="exception/exception">
<input type="hidden" name="exception"
value="nullPointer"/>
<input type="submit" value="NullPointerException"/>
</form>
<form action="exception/exception">
<input type="submit" value="No exception"/>
</form>
</body>
</html>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/generalerror.htm
Index: generalerror.htm
===================================================================
<html>
<body>
<p>An error has occured. Handled by pipelines' error handler in
parent sitemap.</p>
</body>
</html>
1.1 cocoon-2.1/src/webapp/samples/errorhandling/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:selectors default="browser">
<map:selector name="exception"
src="org.apache.cocoon.selection.XPathExceptionSelector">
<exception name="application"
class="org.apache.cocoon.samples.errorhandling.ApplicationException">
<xpath name="application1"
test="errorCode=1"/>
<xpath name="application2"
test="errorCode=2"/>
</exception>
<exception name="validation"
class="org.apache.cocoon.samples.errorhandling.ValidationException"/>
<exception name="resourceNotFound"
class="org.apache.cocoon.ResourceNotFoundException"/>
<exception class="java.lang.Throwable"
unroll="true"/>
</map:selector>
</map:selectors>
</map:components>
<map:pipelines>
<map:pipeline>
<map:match pattern="main">
<map:generate src="main.htm"/>
<map:serialize/>
</map:match>
</map:pipeline>
<map:pipeline>
<map:mount uri-prefix="exception" src="exception/"/>
<map:handle-errors>
<map:select type="exception">
<map:when test="resourceNotFound">
<map:generate
src="resourceNotFound.htm"/>
<map:serialize/>
</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
<map:handle-errors>
<map:generate src="generalerror.htm"/>
<map:serialize/>
</map:handle-errors>
</map:pipelines>
</map:sitemap>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/exception/validation.htm
Index: validation.htm
===================================================================
<html>
<body>
<p>A ValidationException has occured. Handled by pipeline's
error handler.</p>
</body>
</html>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/exception/application.htm
Index: application.htm
===================================================================
<html>
<body>
<p>An ApplicationException has occured. Handled by pipelines'
error handler.</p>
</body>
</html>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/exception/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:generators default="file">
<map:generator name="exception"
src="org.apache.cocoon.samples.errorhandling.ExceptionGenerator"/>
</map:generators>
</map:components>
<map:pipelines>
<map:pipeline>
<map:match pattern="exception">
<map:generate type="exception"/>
<map:serialize/>
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="validation">
<map:generate
src="validation.htm"/>
<map:serialize/>
</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
<map:handle-errors>
<map:select type="exception">
<map:when test="application1">
<map:generate src="application1.htm"/>
<map:serialize/>
</map:when>
<map:when test="application2">
<map:generate src="application2.htm"/>
<map:serialize/>
</map:when>
<map:when test="application">
<map:generate src="application.htm"/>
<map:serialize/>
</map:when>
</map:select>
</map:handle-errors>
</map:pipelines>
</map:sitemap>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/exception/application1.htm
Index: application1.htm
===================================================================
<html>
<body>
<p>An ApplicationException with errorCode=1 has occured.
Handled by pipelines' error handler.</p>
</body>
</html>
1.1
cocoon-2.1/src/webapp/samples/errorhandling/exception/application2.htm
Index: application2.htm
===================================================================
<html>
<body>
<p>An ApplicationException with errorCode=2 has occured.
Handled by pipelines' error handler.</p>
</body>
</html>
1.2 +4 -4
cocoon-2.1/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java
Index: ErrorHandlerHelper.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ErrorHandlerHelper.java 11 Apr 2003 13:14:51 -0000 1.1
+++ ErrorHandlerHelper.java 29 Apr 2003 10:45:20 -0000 1.2
@@ -86,7 +86,7 @@
Map objectModel = env.getObjectModel();
InvokeContext errorContext = null;
- boolean nodeSuccesfull = false;
+ boolean nodeSuccessfull = false;
try {
if (objectModel.get(Constants.NOTIFYING_OBJECT) == null) {
@@ -117,7 +117,7 @@
errorContext.enableLogging(getLogger());
errorContext.compose(this.manager);
- nodeSuccesfull = node.invoke(env, errorContext);
+ nodeSuccessfull = node.invoke(env, errorContext);
} catch (Exception subEx) {
getLogger().error("An exception occured in while handling errors
at " + node.getLocation(), subEx);
// Rethrow it : it will either be handled by the parent sitemap
or by the environment (e.g. Cocoon servlet)
@@ -128,7 +128,7 @@
}
}
- if (nodeSuccesfull) {
+ if (nodeSuccessfull) {
return true;
} else {
throw ex;
1.2 +9 -6
cocoon-2.1/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
Index: MountNode.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MountNode.java 9 Mar 2003 00:09:21 -0000 1.1
+++ MountNode.java 29 Apr 2003 10:45:20 -0000 1.2
@@ -50,6 +50,10 @@
*/
package org.apache.cocoon.components.treeprocessor.sitemap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
@@ -59,13 +63,11 @@
import org.apache.cocoon.components.treeprocessor.TreeProcessor;
import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
import org.apache.cocoon.environment.Environment;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import org.apache.excalibur.source.Source;
/**
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
* @version CVS $Id$
*/
@@ -114,6 +116,7 @@
String oldPrefix = env.getURIPrefix();
String oldURI = env.getURI();
+ String oldContext = env.getContext();
try {
env.changeContext(resolvedPrefix, resolvedSource);
@@ -132,7 +135,7 @@
}
} finally {
// Restore context
- env.setContext(oldPrefix, oldURI);
+ env.setContext(oldPrefix, oldURI, oldContext);
// Recompose pipelines which may have been recomposed by
subsitemap
context.recompose(this.manager);
1.4 +6 -6
cocoon-2.1/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java
Index: EnvironmentWrapper.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- EnvironmentWrapper.java 16 Mar 2003 17:49:14 -0000 1.3
+++ EnvironmentWrapper.java 29 Apr 2003 10:45:20 -0000 1.4
@@ -53,7 +53,6 @@
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
-import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -75,6 +74,7 @@
* It has the same properties except that the object model
* contains a <code>RequestWrapper</code> object.
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id$
*/
@@ -95,7 +95,7 @@
protected Request request;
/** The last context */
- protected URL lastContext;
+ protected String lastContext;
/** The last prefix */
protected String lastPrefix;
@@ -142,12 +142,12 @@
ComponentManager manager,
boolean rawMode)
throws MalformedURLException {
- super(env.getURI(), env.getView(), env.getRootContext(),
env.getAction());
+ super(env.getURI(), env.getView(), env.getContext(),
env.getAction());
+ this.rootContext = env.getRootContext();
this.enableLogging(logger);
this.environment = env;
- this.context = env.getContext();
this.prefix = new StringBuffer(env.getURIPrefix());
// create new object model and replace the request object
@@ -319,7 +319,7 @@
}
public void changeContext(String prefix, String context)
- throws MalformedURLException {
+ throws IOException {
super.changeContext(prefix, context);
this.lastContext = this.context;
this.lastPrefix = this.prefix.toString();
1.3 +1 -0
cocoon-2.1/src/documentation/xdocs/userdocs/concepts/book.xml
Index: book.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/documentation/xdocs/userdocs/concepts/book.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- book.xml 24 Mar 2003 17:14:31 -0000 1.2
+++ book.xml 29 Apr 2003 10:45:20 -0000 1.3
@@ -27,6 +27,7 @@
<menu-item label="Databases" href="databases.html"/>
<menu-item label="Modules" href="modules.html"/>
<menu-item label="Profiler" href="profiler.html"/>
+ <menu-item label="Error Handling" href="errorhandling.html"/>
</menu>
</book>
1.1
cocoon-2.1/src/documentation/xdocs/userdocs/concepts/errorhandling.xml
Index: errorhandling.xml
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"../../dtd/document-v10.dtd">
<document>
<header>
<title>Error Handling</title>
<authors>
<person name="Bj�rn L�tkemeier" email="[EMAIL
PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Error Handling">
<p>
During the execution of a Cocoon pipeline
exceptions may occur within the involved components like generators,
transformers etc. There are two possibilities to deal with them: The one would
be not to handle them explicitly in the sitemap, which causes them to be logged
and a default Cocoon error page to be displayed in the browser. The second is
to define an error handling by using the sitemap tag <map:handle-errors>.
Therein you are able to define any pipeline, that is executed in case of an
exception occurred and displays an appropriate page.
</p>
<s2 title="ExceptionSelector">
<p>
The ExceptionSelector allows to realize
conditional error handling within <map:handle-errors>-tags depending on
the type of the occurred exception. Each exception is configured centrally at
the selector in the sitemap by associating a symbolic name to its class.
</p>
<p>
Furthermore it is possible to define,
what exceptions are to be "unrolled". This means, that if an exception has been
rethrown embedded in another exception, this original exception can be
considered for choosing the correct error handling.
</p>
<p>
Example:
</p>
<source>
<![CDATA[
<map:selector name="exception"
src="org.apache.cocoon.selection.ExceptionSelector">
<exception name="processing" class="ProcessingException" unroll="true"/>
<exception name="sax" class="SAXException"/>
<exception name="application" class="ApplicationException"/>
</map:selector>
...
<map:pipeline>
<map:match pattern="resource">
...
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="processing">...</map:when>
<map:when test="sax">...</map:when>
<map:when test="application">...</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
]]>
</source>
<p>
Let's consider the following nested
exceptions to occur:
</p>
<ol>
<li>
ProcessingException (
ApplicationException ): The ProcessingException is unrolled, so the error
pipeline for "application" will be executed.
</li>
<li>
ProcessingException (
ValidationException ): Since ValidationException is not configured at all and
therefore unknown, the ProcessingException is not unrolled even if unrolling is
enabled. Therefore the pipeline for "processing" will be executed.
</li>
<li>
SAXException (
ApplicationException ): The unrolling is not enabled for SAXException, so the
pipeline for "sax" will be executed.
</li>
</ol>
<p>
Please notice that the selector
configuration is processed from top to bottom and stops at the first matching
exception. Therefore the most specific classes must be configured first. This
behaviour is the same as with Java catch statements.
</p>
</s2>
<s2 title="XPathExceptionSelector">
<p>
The XPathExceptionSelector is an
extension to the standard selector described above. It adds the possibility to
configure additional conditions for each exception type by using JXPath
expressions, that operate on the exception object. This configuration is also
done centrally at the selector in the sitemap, where symbolic names are defined
for all specific error situations.
</p>
<p>
Example:
</p>
<source>
<![CDATA[
<map:selector name="exception"
src="org.apache.cocoon.selection.XPathExceptionSelector">
<exception name="Denied" class="AuthenticationFailure">
<xpath name="PasswordWrong" test="authCode=10"/>
<xpath name="PasswordExpired" test="errorCode=11"/>
<xpath name="AccessForbidden" test="errorCode>11"/>
</exception>
</map:selector>
...
<map:pipeline>
<map:match pattern="login">
...
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="PasswordWrong">...</map:when>
<map:when test="PasswordExpired">...</map:when>
<map:when test="AccessForbidden">...</map:when>
<map:when test="Denied">...</map:when>
<map:otherwise>...</map:otherwise>
</map:select>
</map:handle-errors>
</map:pipeline>
]]>
</source>
<p>
In this example the exception
AuthenticationFailure is configured under name "Denied". Additionally three
further conditions "PasswordWrong", "PasswordExpired" and "AccessForbidden" are
defined by using JXPath expressions. Therefore instances of
AuthenticationFailure are expected to have methods getAuthCode() and
getErrorCode(). Now the error handler defined for resource "login" has five
branches: If situation "PasswordWrong" occurs, which means that an
AuthenticationFailure exception with auth code 10 has been thrown, the first
error pipeline is executed. If the error code equals to 11 the second pipeline
is executed, if it is greater that 11 the third one and all other
AuthenticationFailure errors are handled by the fourth one. In any other error
situation the fifth branch would be chosen.
</p>
<p>
Please notice that the selector stops
when it finds the first JXPath expression in the configuration that matches:
</p>
<p>
Example:
</p>
<source>
<![CDATA[
<map:selector name="exception"
src="org.apache.cocoon.selection.XPathExceptionSelector">
<exception name="application" class="ApplicationException">
<xpath name="error3" test="errorCode>3"/>
<xpath name="error6" test="errorCode>6"/>
</exception>
</map:selector>
...
<map:pipeline>
<map:match pattern="processForm">
...
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="error6">...</map:when> <!--
handler 1 -->
<map:when test="error3">...</map:when> <!--
handler 2 -->
</map:select>
</map:handle-errors>
</map:pipeline>
]]>
</source>
<p>
If an ApplicationException with error
code 9 occurs, handler 2 is executed since error situation "error3" is
configured before "error6" at the selector even if the expression for "error6"
also evaluates to "true".
</p>
</s2>
<s2 title="Error Handler Hierarchy">
<p>
The tag <map:handle-errors> may
be attached to any <map:pipeline> or the <map:pipelines> tag of the
root sitemap or a subsitemap. Therefore it is possible to define two kinds of
error handlers: A default handler may be defined within <map:pipelines>
for applying to all resources of a sitemap. Alternatively individual handlers
may be configured for sets of resources within <map:pipeline>.
</p>
<p>
Example:
</p>
<source>
<![CDATA[
<map:pipelines>
<map:pipeline name="pipe1">
<map:match pattern="res1">
...
</map:match>
<map:handle-errors>
<!-- this is an individual handler for pipe1 -->
</map:handle-errors>
</map:pipeline>
<map:pipeline name="pipe2">
<map:match pattern="res2">
...
</map:match>
</map:pipeline>
<map:pipeline name="pipe3">
<map:match pattern="res3">
...
</map:match>
</map:pipeline>
<map:handle-errors>
<!-- this is the default handler for the whole sitemap -->
</map:handle-errors>
</map:pipelines>
]]>
</source>
<p>
In conjunction with the
ExceptionSelector resp. the XPathExceptionSelector it is possible to define a
hierarchy of error handlers for an application. The behaviour then is the
following: If an error occurs within a pipeline, Cocoon at first checks if an
individual handler for this pipeline is defined. If so and it is able to handle
the error due to its selection the processing terminates. Otherwise Cocoon
looks for a default handler of the current sitemap. If one is found it is
called. Now there is the same behaviour as above: If it can handle the
exception the processing terminates otherwise the searching proceeds within the
pipeline where the subsitemap is mounted. This goes on until the default
handler of the root sitemap has been considered. If an error could not be
handled at all, it is processed by the Cocoon engine in the end.
</p>
<p>
Please notice that a
<map:otherwise> breaks the hierarchy since all errors will be handled on
this level. Therefore all levels above will be called never.
</p>
<p>
Example:
</p>
<source>
<![CDATA[
Root sitemap:
<map:pipelines>
<map:pipeline>
<map:mount uri-prefix="sub" src="sub/"/>
<map:handle-errors>
<map:select type="exception">
<map:when test="resourceNotFound">...</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
<map:handle-errors>
<map:generate src="generalerror.htm"/>
<map:serialize/>
</map:handle-errors>
</map:pipelines>
Subsitemap:
<map:pipelines>
<map:pipeline>
<map:match pattern="processForm">
...
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="validation">...</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
<map:handle-errors>
<map:select type="exception">
<map:when test="application">...</map:when>
</map:select>
</map:handle-errors>
</map:pipelines>
]]>
</source>
<p>
Let's consider four situations
concerning the above example:
</p>
<ol>
<li>
A ValidationException occurs,
because for instance the user entered an invalid value: The defined pipeline's
handler is called. Since it has a matching <map:when>-section it is able
to handle such an exception and therefore the processing is finished.
</li>
<li>
An ApplicationException occurs,
because for instance a database connection has failed: The pipeline's handler
is not able to handle the exception, so next the subsitemap's default handler
is called. It has a matching <map:when>-section and is therefore able to
handle the exception.
</li>
<li>
A ResourceNotFoundException
occurs, because for instance some file is missing. Both the pipeline's and the
subsitemaps' handlers are not able to handle it. Now Cocoon proceeds after the
mount point of the subsitemap and finds its pipeline's handler next. It is able
to handle a ResourceNotFoundException and therefore produces the output in this
case.
</li>
<li>
A NullPointerException occurs,
because something went completely wrong in the application: All handlers are
not configured for such an exception and so the root sitemaps default handler
will apply to it showing a general error page.
</li>
</ol>
<p>
When handling exceptions in error
handlers one has to take care about recursion when working with redirects.
Consider the following sitemap:
</p>
<p>
Example:
</p>
<source>
<![CDATA[
<map:pipelines>
<map:pipeline>
<map:match pattern="resource">
...
<map:transformer type="foo"/>
...
</map:match>
<map:match pattern="error">
...
<map:transformer type="foo"/>
...
</map:match>
<map:handle-errors>
<map:select type="exception">
<map:when test="connection">
<map:act type="redirect"
src="cocoon:/error"/>
</map:when>
</map:select>
</map:handle-errors>
</map:pipeline>
</map:pipelines>
]]>
</source>
<p>
This configuration may lead to an
infinite loop: Imagine to call "resource" where the FooTransformer throws a
ConnectionException, because the connection to a backend system has broken. The
defined error handler will handle it and the used action internally redirects
to resource "error". This resource itself uses the FooTransformer to get some
data from the backend, which of cause also causes a ConnectionException. This
is handled by the error handler, which redirects to resource "error" and so on.
Such an infinite loop may also occur when using several "nested" redirects,
i.e. the error handler redirects to a resource, which redirects to another
resource, which might produce the original exception.
</p>
<p>
When defining error handlers for an
application such situation must be avoided. An easy rule would be: An error
handling routine must never redirect to a resource for which the routine itself
is responsible and which might produce the same error as just handled.
</p>
</s2>
</s1>
</body>
</document>
1.1
cocoon-2.1/src/samples/org/apache/cocoon/samples/errorhandling/ValidationException.java
Index: ValidationException.java
===================================================================
/*
ValidationException.java
Author: Bj�rn L�tkemeier <[EMAIL PROTECTED]>
Date: April 23, 2003
*/
package org.apache.cocoon.samples.errorhandling;
public class ValidationException
extends Exception {
}
1.1
cocoon-2.1/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionGenerator.java
Index: ExceptionGenerator.java
===================================================================
/*
ExceptionGenerator.java
Author: Bj�rn L�tkemeier <[EMAIL PROTECTED]>
Date: April 23, 2003
*/
package org.apache.cocoon.samples.errorhandling;
import java.io.IOException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.generation.AbstractGenerator;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
public class ExceptionGenerator
extends AbstractGenerator {
/*
* Name of request parameters.
*/
public static final String PAR_EXCEPTION = "exception";
public static final String PAR_CODE = "code";
/**
* Overridden from superclass.
*/
public void generate()
throws IOException, SAXException, ProcessingException {
Request request =
ObjectModelHelper.getRequest(this.objectModel);
String exception = request.getParameter(PAR_EXCEPTION);
String text = null;
if (exception == null) {
text = "No exception occured.";
} else if (exception.equals("validation")) {
throw new ProcessingException(new
ValidationException());
} else if (exception.equals("application")) {
throw new ProcessingException(new ApplicationException(
Integer.parseInt(request.getParameter(PAR_CODE))));
} else if (exception.equals("resourceNotFound")) {
throw new ProcessingException(new
ResourceNotFoundException(""));
} else if (exception.equals("nullPointer")) {
throw new ProcessingException(new
NullPointerException());
} else {
text = "Unknown exception requested.";
}
Attributes noAttrs = new AttributesImpl();
this.contentHandler.startDocument();
this.contentHandler.startElement(null, "html", "html", noAttrs);
this.contentHandler.startElement(null, "body", "body", noAttrs);
this.contentHandler.startElement(null, "p", "p", noAttrs);
this.contentHandler.characters(text.toCharArray(), 0,
text.length());
this.contentHandler.endElement(null, "p", "p");
this.contentHandler.endElement(null, "body", "body");
this.contentHandler.endElement(null, "html", "html");
this.contentHandler.endDocument();
}
}
1.1
cocoon-2.1/src/samples/org/apache/cocoon/samples/errorhandling/ApplicationException.java
Index: ApplicationException.java
===================================================================
/*
ApplicationException.java
Author: Bj�rn L�tkemeier <[EMAIL PROTECTED]>
Date: April 23, 2003
*/
package org.apache.cocoon.samples.errorhandling;
public class ApplicationException
extends Exception {
private int errorCode;
public ApplicationException(int errorCode) {
this.errorCode = errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public int getErrorCode() {
return this.errorCode;
}
}
1.11 +8 -1 cocoon-2.1/src/webapp/samples/samples.xml
Index: samples.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/webapp/samples/samples.xml,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- samples.xml 25 Apr 2003 08:35:02 -0000 1.10
+++ samples.xml 29 Apr 2003 10:45:21 -0000 1.11
@@ -150,4 +150,11 @@
</sample>
</group>
+ <group name="Error handling">
+ <sample name="Error handling" href="errorhandling/main">
+ An example page producing exceptions and handling them. Demonstrates
the
+ handler hierarchy and the exception selectors.
+ </sample>
+ </group>
+
</samples>
1.6 +6 -6
cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java
Index: CocoonServlet.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- CocoonServlet.java 27 Apr 2003 17:00:44 -0000 1.5
+++ CocoonServlet.java 29 Apr 2003 10:45:21 -0000 1.6
@@ -97,12 +97,12 @@
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.http.HttpContext;
import org.apache.cocoon.environment.http.HttpEnvironment;
+import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
import org.apache.cocoon.servlet.multipart.RequestFactory;
import org.apache.cocoon.util.ClassUtils;
import org.apache.cocoon.util.IOUtils;
import org.apache.cocoon.util.StringUtils;
import org.apache.cocoon.util.log.CocoonLogFormatter;
-import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
import org.apache.excalibur.instrument.InstrumentManager;
import org.apache.excalibur.instrument.manager.DefaultInstrumentManager;
import org.apache.log.ContextMap;
@@ -239,7 +239,7 @@
/**
* This is the url to the servlet context directory
*/
- protected URL servletContextURL;
+ protected String servletContextURL;
/**
* The RequestFactory is responsible for wrapping multipart-encoded
@@ -338,16 +338,16 @@
try {
if (path.indexOf(':') > 1) {
- this.servletContextURL = new URL(path);
+ this.servletContextURL = path;
} else {
- this.servletContextURL = new File(path).toURL();
+ this.servletContextURL = new
File(path).toURL().toExternalForm();
}
} catch (MalformedURLException me) {
// VG: Novell has absolute file names starting with the
// volume name which is easily more then one letter.
// Examples: sys:/apache/cocoon or sys:\apache\cocoon
try {
- this.servletContextURL = new File(path).toURL();
+ this.servletContextURL = new
File(path).toURL().toExternalForm();
} catch (MalformedURLException ignored) {
throw new ServletException("Unable to determine servlet
context URL.", me);
}
1.4 +3 -3
cocoon-2.1/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java
Index: HttpEnvironment.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- HttpEnvironment.java 9 Apr 2003 09:52:50 -0000 1.3
+++ HttpEnvironment.java 29 Apr 2003 10:45:21 -0000 1.4
@@ -100,7 +100,7 @@
* and HttpServletResponse objects
*/
public HttpEnvironment (String uri,
- URL rootURL,
+ String root,
HttpServletRequest req,
HttpServletResponse res,
ServletContext servletContext,
@@ -108,7 +108,7 @@
String containerEncoding,
String defaultFormEncoding)
throws MalformedURLException, IOException {
- super(uri, req.getParameter(Constants.VIEW_PARAM), rootURL,
extractAction(req));
+ super(uri, req.getParameter(Constants.VIEW_PARAM), root,
extractAction(req));
this.request = new HttpRequest(req, this);
this.request.setCharacterEncoding(defaultFormEncoding);
1.2 +9 -9
cocoon-2.1/src/java/org/apache/cocoon/environment/Environment.java
Index: Environment.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/environment/Environment.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Environment.java 9 Mar 2003 00:09:28 -0000 1.1
+++ Environment.java 29 Apr 2003 10:45:21 -0000 1.2
@@ -52,13 +52,13 @@
import java.io.IOException;
import java.io.OutputStream;
-import java.net.URL;
import java.util.Enumeration;
import java.util.Map;
/**
* Base interface for an environment abstraction
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id$
@@ -80,12 +80,12 @@
/**
* Get the Root Context
*/
- URL getRootContext();
+ String getRootContext();
/**
* Get current context
*/
- URL getContext();
+ String getContext();
/**
* Get the view to process
@@ -97,11 +97,11 @@
*/
String getAction();
- /**
- * Set the context. This is similar to changeContext()
- * except that it is absolute.
- */
- void setContext(String prefix, String uri);
+ /**
+ * Set the context. This is similar to changeContext()
+ * except that it is absolute.
+ */
+ void setContext(String prefix, String uri, String context);
/**
* Change the context from uriprefix to context
1.9 +82 -57
cocoon-2.1/src/java/org/apache/cocoon/environment/AbstractEnvironment.java
Index: AbstractEnvironment.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/environment/AbstractEnvironment.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- AbstractEnvironment.java 28 Apr 2003 12:37:37 -0000 1.8
+++ AbstractEnvironment.java 29 Apr 2003 10:45:21 -0000 1.9
@@ -80,6 +80,7 @@
/**
* Base class for any environment
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id$
@@ -99,10 +100,13 @@
protected String action = null;
/** The Context path */
- protected URL context = null;
+ protected String context = null;
+
+ /** The context path stored temporarily between constructor and
startingProcessing */
+ private String tempInitContext = null;
/** The root context path */
- protected URL rootContext = null;
+ protected String rootContext = null;
/** The servlet object model */
protected HashMap objectModel = null;
@@ -129,27 +133,11 @@
static protected Constructor avalonToCocoonSourceWrapper;
/** Do we have our components ? */
- protected boolean initializedComponents;
+ protected boolean initializedComponents = false;
/**
* Constructs the abstract environment
*/
- public AbstractEnvironment(String uri, String view, String file)
- throws MalformedURLException {
- this(uri, view, new File(file), null);
- }
-
- /**
- * Constructs the abstract environment
- */
- public AbstractEnvironment(String uri, String view, String file, String
action)
- throws MalformedURLException {
- this(uri, view, new File(file), action);
- }
-
- /**
- * Constructs the abstract environment
- */
public AbstractEnvironment(String uri, String view, File file)
throws MalformedURLException {
this(uri, view, file, null);
@@ -160,21 +148,20 @@
*/
public AbstractEnvironment(String uri, String view, File file, String
action)
throws MalformedURLException {
- this(uri, view, file.toURL(), action);
+ this(uri, view, file.toURL().toExternalForm(), action);
}
- /**
- * Constructs the abstract environment
- */
- public AbstractEnvironment(String uri, String view, URL context, String
action)
- throws MalformedURLException {
- this.uris = uri;
- this.view = view;
- this.context = context;
- this.action = action;
- this.objectModel = new HashMap();
- this.rootContext = context;
- }
+ /**
+ * Constructs the abstract environment
+ */
+ public AbstractEnvironment(String uri, String view, String context,
String action)
+ throws MalformedURLException {
+ this.uris = uri;
+ this.view = view;
+ this.tempInitContext = context;
+ this.action = action;
+ this.objectModel = new HashMap();
+ }
// Sitemap methods
@@ -188,14 +175,20 @@
/**
* Get the Root Context
*/
- public URL getRootContext() {
+ public String getRootContext() {
+ if ( !this.initializedComponents) {
+ this.initComponents();
+ }
return this.rootContext;
}
/**
* Get the current Context
*/
- public URL getContext() {
+ public String getContext() {
+ if ( !this.initializedComponents) {
+ this.initComponents();
+ }
return this.context;
}
@@ -219,31 +212,35 @@
/**
* Set the context.
*/
- protected void setContext(URL context) {
+ protected void setContext(String context) {
this.context = context;
}
- /**
- * Set the context. This is similar to changeContext()
- * except that it is absolute.
- */
- public void setContext(String prefix, String uri) {
- this.setContext(getRootContext());
- this.setURIPrefix(prefix == null ? "" : prefix);
- this.uris = uri;
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Reset context to " + this.context);
- }
- }
+ /**
+ * Set the context. This is similar to changeContext()
+ * except that it is absolute.
+ */
+ public void setContext(String prefix, String uri, String context) {
+ this.setContext(context);
+ this.setURIPrefix(prefix == null ? "" : prefix);
+ this.uris = uri;
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Reset context to " + this.context);
+ }
+ }
/**
* Adds an prefix to the overall stripped off prefix from the request uri
*/
public void changeContext(String prefix, String newContext)
- throws MalformedURLException {
+ throws IOException {
+ if ( !this.initializedComponents) {
+ this.initComponents();
+ }
+
if (getLogger().isDebugEnabled()) {
getLogger().debug("Changing Cocoon context");
- getLogger().debug(" from context(" +
this.context.toExternalForm() + ") and prefix(" + this.prefix + ")");
+ getLogger().debug(" from context(" + this.context + ") and
prefix(" + this.prefix + ")");
getLogger().debug(" to context(" + newContext + ") and prefix("
+ prefix + ")");
getLogger().debug(" at URI " + this.uris);
}
@@ -265,13 +262,20 @@
}
}
- if (this.context.getProtocol().equals("zip")) {
+ if (SourceUtil.getScheme(this.context).equals("zip")) {
// if the resource is zipped into a war file (e.g. Weblogic temp
deployment)
// FIXME (VG): Is this still required? Better to unify both
cases.
if (getLogger().isDebugEnabled()) {
getLogger().debug("Base context is zip: " + this.context);
}
- this.context = new URL(this.context.toString() + newContext);
+
+ org.apache.excalibur.source.Source source = null;
+ try {
+ source = this.sourceResolver.resolveURI(this.context +
newContext);
+ this.context = source.getURI();
+ } finally {
+ this.sourceResolver.release(source);
+ }
} else {
String sContext;
// if we got a absolute context or one with a protocol resolve it
@@ -283,7 +287,7 @@
sContext = newContext;
} else {
// context is relative to old one
- sContext = new URL(this.context, newContext).toString();
+ sContext = new URL(new URL(this.context),
newContext).toString();
}
// Cut the file name part from context (if present)
@@ -291,11 +295,18 @@
if (i != -1 && i + 1 < sContext.length()) {
sContext = sContext.substring(0, i + 1);
}
- this.context = new URL(sContext);
+
+ org.apache.excalibur.source.Source source = null;
+ try {
+ source = this.sourceResolver.resolveURI(sContext);
+ this.context = source.getURI();
+ } finally {
+ this.sourceResolver.release(source);
+ }
}
if (getLogger().isDebugEnabled()) {
- getLogger().debug("New context is " +
this.context.toExternalForm());
+ getLogger().debug("New context is " + this.context);
}
}
@@ -573,11 +584,25 @@
this.manager =
CocoonComponentManager.getSitemapComponentManager();
this.xmlizer = (XMLizer)this.manager.lookup(XMLizer.ROLE);
this.sourceResolver =
(org.apache.excalibur.source.SourceResolver)this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
-
+ if (this.tempInitContext != null) {
+ org.apache.excalibur.source.Source source =
null;
+ try {
+ source =
this.sourceResolver.resolveURI(this.tempInitContext);
+ this.context = source.getURI();
+
+ if (this.rootContext == null) // hack
for EnvironmentWrapper
+ this.rootContext = this.context;
+ } finally {
+ this.sourceResolver.release(source);
+ }
+ this.tempInitContext = null;
+ }
} catch (ComponentException ce) {
// this should never happen!
throw new CascadingRuntimeException("Unable to lookup
component.", ce);
- }
+ } catch (IOException ie) {
+ throw new CascadingRuntimeException("Unable to resolve
URI: "+this.tempInitContext, ie);
+ }
}
/**
1.11 +3 -2
cocoon-2.1/src/java/org/apache/cocoon/components/CocoonComponentManager.java
Index: CocoonComponentManager.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/components/CocoonComponentManager.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CocoonComponentManager.java 26 Apr 2003 14:06:50 -0000 1.10
+++ CocoonComponentManager.java 29 Apr 2003 10:45:22 -0000 1.11
@@ -82,6 +82,7 @@
* directly - and do not assume that a [EMAIL PROTECTED] ComponentManager}
you get
* via the compose() method is an instance of CocoonComponentManager.
*
+ * @author <a href="mailto:[EMAIL PROTECTED]">Bj�rn L�tkemeier</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id$
*/
@@ -443,7 +444,7 @@
final EnvironmentStack stack =
(EnvironmentStack)environmentStack.get();
if ( null != stack && !stack.empty()) {
final Object[] objects = (Object[])stack.getCurrent();
- baseURI =
((Environment)objects[0]).getContext().toExternalForm();
+ baseURI = ((Environment)objects[0]).getContext();
}
}
return this.sourceResolver.resolveURI(location, baseURI, parameters);