You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/08/01 15:10:22 UTC
svn commit: r226786 - in /cocoon/branches/BRANCH_2_1_X: ./
src/java/org/apache/cocoon/ src/java/org/apache/cocoon/components/flow/
src/java/org/apache/cocoon/components/notification/
src/java/org/apache/cocoon/components/treeprocessor/sitemap/ src/java...
Author: sylvain
Date: Mon Aug 1 06:10:02 2005
New Revision: 226786
URL: http://svn.apache.org/viewcvs?rev=226786&view=rev
Log:
Cocoon stacktraces: new location handling stuff and refactored exception management
Added:
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java (with props)
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java (with props)
cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/
cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java (with props)
cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt (with props)
Modified:
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ConnectionResetException.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ProcessingException.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ResourceNotFoundException.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/selection/ExceptionSelector.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocationAttributes.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java
cocoon/branches/BRANCH_2_1_X/src/webapp/sitemap.xmap
cocoon/branches/BRANCH_2_1_X/status.xml
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ConnectionResetException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ConnectionResetException.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ConnectionResetException.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ConnectionResetException.java Mon Aug 1 06:10:02 2005
@@ -20,7 +20,7 @@
* due to a connection reset by peer.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
- * @version CVS $Id: ConnectionResetException.java,v 1.2 2004/03/05 13:02:42 bdelacretaz Exp $
+ * @version CVS $Id$
*/
public class ConnectionResetException extends ProcessingException {
@@ -30,7 +30,7 @@
* @param message a <code>String</code> value
*/
public ConnectionResetException(String message) {
- super(message, null);
+ super(message);
}
/**
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ProcessingException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ProcessingException.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ProcessingException.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ProcessingException.java Mon Aug 1 06:10:02 2005
@@ -15,14 +15,17 @@
*/
package org.apache.cocoon;
-import org.apache.avalon.framework.CascadingException;
-
import java.io.PrintStream;
import java.io.PrintWriter;
-import org.xml.sax.SAXParseException;
-import javax.xml.transform.TransformerException;
import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.avalon.framework.CascadingException;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.LocatedException;
+import org.apache.cocoon.util.location.Location;
+import org.xml.sax.SAXParseException;
/**
* This Exception is thrown every time there is a problem in processing
@@ -30,15 +33,15 @@
*
* @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
* (Apache Software Foundation)
- * @version CVS $Id: ProcessingException.java,v 1.2 2004/03/05 13:02:42 bdelacretaz Exp $
+ * @version CVS $Id$
*/
-public class ProcessingException extends CascadingException {
-
+public class ProcessingException extends LocatedException {
+
/**
* Construct a new <code>ProcessingException</code> instance.
*/
public ProcessingException(String message) {
- super(message, null);
+ super(message);
}
/**
@@ -58,71 +61,79 @@
super(message, t);
}
- public String toString() {
- StringBuffer s = new StringBuffer();
- s.append(super.toString());
- final Throwable t = getCause();
- if(t!=null) {
- s.append(": ");
- // be more verbose try to get location info
- s.append( extraInfo(t) );
- s.append(t.toString());
- }
- return s.toString();
+ public ProcessingException(String message, Location location) {
+ super(message, location);
}
- /**
- * Examine Throwable and try to figure out location information.
- * <p>
- * At the moment only SAXParseException, and TransformerException
- * are considered.
- * </p>
- *
- * @return String containing location information of the format
- * <code>{file-name}:{line}:{column}:</code>, if no location info is
- * available return empty string
- */
- private String extraInfo( Throwable t ) {
- StringBuffer sb = new StringBuffer();
- if (t instanceof SAXParseException) {
- SAXParseException spe = (SAXParseException)t;
- sb.append( String.valueOf(spe.getSystemId()));
- sb.append( ":" );
- sb.append( String.valueOf(spe.getLineNumber()));
- sb.append( ":" );
- sb.append( String.valueOf(spe.getColumnNumber()));
- sb.append( ":" );
- } else if (t instanceof TransformerException) {
- TransformerException transformerException = (TransformerException) t;
- SourceLocator sourceLocator = transformerException.getLocator();
-
- if( null != sourceLocator ) {
- sb.append( String.valueOf(sourceLocator.getSystemId()));
- sb.append( ":" );
- sb.append( String.valueOf(sourceLocator.getLineNumber()));
- sb.append( ":" );
- sb.append( String.valueOf(sourceLocator.getColumnNumber()));
- sb.append( ":" );
- }
- }
- return sb.toString();
+ public ProcessingException(String message, Throwable t, Location location) {
+ super(message, t, location);
}
- public void printStackTrace() {
- super.printStackTrace();
- if(getCause()!=null)
- getCause().printStackTrace();
- }
-
- public void printStackTrace( PrintStream s ) {
- super.printStackTrace(s);
- if(getCause()!=null)
- getCause().printStackTrace(s);
- }
-
- public void printStackTrace( PrintWriter s ) {
- super.printStackTrace(s);
- if(getCause()!=null)
- getCause().printStackTrace(s);
- }
+// public String toString() {
+// StringBuffer s = new StringBuffer();
+// s.append(super.toString());
+// final Throwable t = getCause();
+// if(t!=null) {
+// s.append(": ");
+// // be more verbose try to get location info
+// s.append( extraInfo(t) );
+// s.append(t.toString());
+// }
+// return s.toString();
+// }
+//
+// /**
+// * Examine Throwable and try to figure out location information.
+// * <p>
+// * At the moment only SAXParseException, and TransformerException
+// * are considered.
+// * </p>
+// *
+// * @return String containing location information of the format
+// * <code>{file-name}:{line}:{column}:</code>, if no location info is
+// * available return empty string
+// */
+// private String extraInfo( Throwable t ) {
+// StringBuffer sb = new StringBuffer();
+// if (t instanceof SAXParseException) {
+// SAXParseException spe = (SAXParseException)t;
+// sb.append( String.valueOf(spe.getSystemId()));
+// sb.append( ":" );
+// sb.append( String.valueOf(spe.getLineNumber()));
+// sb.append( ":" );
+// sb.append( String.valueOf(spe.getColumnNumber()));
+// sb.append( ":" );
+// } else if (t instanceof TransformerException) {
+// TransformerException transformerException = (TransformerException) t;
+// SourceLocator sourceLocator = transformerException.getLocator();
+//
+// if( null != sourceLocator ) {
+// sb.append( String.valueOf(sourceLocator.getSystemId()));
+// sb.append( ":" );
+// sb.append( String.valueOf(sourceLocator.getLineNumber()));
+// sb.append( ":" );
+// sb.append( String.valueOf(sourceLocator.getColumnNumber()));
+// sb.append( ":" );
+// }
+// }
+// return sb.toString();
+// }
+//
+// public void printStackTrace() {
+// super.printStackTrace();
+// if(getCause()!=null)
+// getCause().printStackTrace();
+// }
+//
+// public void printStackTrace( PrintStream s ) {
+// super.printStackTrace(s);
+// if(getCause()!=null)
+// getCause().printStackTrace(s);
+// }
+//
+// public void printStackTrace( PrintWriter s ) {
+// super.printStackTrace(s);
+// if(getCause()!=null)
+// getCause().printStackTrace(s);
+// }
}
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ResourceNotFoundException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ResourceNotFoundException.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ResourceNotFoundException.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/ResourceNotFoundException.java Mon Aug 1 06:10:02 2005
@@ -15,12 +15,14 @@
*/
package org.apache.cocoon;
+import org.apache.cocoon.util.location.Location;
+
/**
* This Exception is thrown every time there is a problem in finding
* a resource.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
- * @version CVS $Id: ResourceNotFoundException.java,v 1.2 2004/03/05 13:02:42 bdelacretaz Exp $
+ * @version CVS $Id$
*/
public class ResourceNotFoundException extends ProcessingException {
@@ -28,7 +30,7 @@
* Construct a new <code>ResourceNotFoundException</code> instance.
*/
public ResourceNotFoundException(String message) {
- super(message, null);
+ super(message);
}
/**
@@ -37,5 +39,13 @@
*/
public ResourceNotFoundException(String message, Throwable t) {
super(message, t);
+ }
+
+ public ResourceNotFoundException(String message, Location location) {
+ super(message, location);
+ }
+
+ public ResourceNotFoundException(String message, Throwable t, Location loc) {
+ super(message, t, loc);
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java Mon Aug 1 06:10:02 2005
@@ -21,7 +21,7 @@
* This Exception is thrown whenever an invalid continuation is given.
*
* @author <a href="mailto:tcollen@neuagency.com">Tony Collen</a>
- * @version CVS $Id: InvalidContinuationException.java,v 1.2 2004/03/05 13:02:46 bdelacretaz Exp $
+ * @version CVS $Id$
*/
public class InvalidContinuationException extends ProcessingException {
@@ -29,7 +29,7 @@
* Construct a new <code>InvalidContinuationException</code> instance.
*/
public InvalidContinuationException(String message) {
- super(message, null);
+ super(message);
}
/**
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java Mon Aug 1 06:10:02 2005
@@ -17,8 +17,8 @@
import org.apache.avalon.framework.component.Component;
+import org.apache.cocoon.util.ExceptionUtils;
import org.apache.commons.lang.SystemUtils;
-import org.apache.commons.lang.exception.ExceptionUtils;
import org.xml.sax.SAXParseException;
import javax.xml.transform.SourceLocator;
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java Mon Aug 1 06:10:02 2005
@@ -35,6 +35,7 @@
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.util.location.Location;
/**
* Node handler for calling functions and resuming continuations in
@@ -120,10 +121,13 @@
// the function call, so we invoke it here.
String continuation = continuationId.resolve(context, env.getObjectModel());
if (continuation != null && continuation.length() > 0) {
- interpreter.handleContinuation(continuation, params, redirector);
+ try {
+ interpreter.handleContinuation(continuation, params, redirector);
+ } catch(Exception e) {
+ throw new ProcessingException("Sitemap: error calling continuation", e, Location.parse(getLocation()));
+ }
if (!redirector.hasRedirected()) {
- throw new ProcessingException("<map:call continuation> did not send a response, at " +
- getLocation());
+ throw new ProcessingException("Sitemap: <map:call continuation> did not send a response", Location.parse(getLocation()));
}
return true;
}
@@ -132,15 +136,18 @@
// the specified function
String name = functionName.resolve(context, env.getObjectModel());
if (name != null && name.length() > 0) {
- interpreter.callFunction(name, params, redirector);
+ try {
+ interpreter.callFunction(name, params, redirector);
+ } catch(Exception e) {
+ throw new ProcessingException("Sitemap: error calling function '" + name + "'", e, Location.parse(getLocation()));
+ }
if (!redirector.hasRedirected()) {
- throw new ProcessingException("<map:call function> did not send a response, at " +
- getLocation());
+ throw new ProcessingException("Sitemap: <map:call function> did not send a response", Location.parse(getLocation()));
}
return true;
}
// Found neither continuation nor function to call
- throw new ProcessingException("No function nor continuation given in <map:call function> at " + getLocation());
+ throw new ProcessingException("Sitemap: no function nor continuation given in <map:call function>", Location.parse(getLocation()));
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java Mon Aug 1 06:10:02 2005
@@ -30,6 +30,7 @@
import org.apache.cocoon.components.treeprocessor.TreeProcessor;
import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.util.location.Location;
import org.apache.commons.lang.BooleanUtils;
/**
@@ -116,6 +117,10 @@
// Processor will create its own pipelines
pipelineWasBuilt = processor.process(env);
}
+ } catch(Exception e) {
+ // Wrap with our location
+ throw new ProcessingException("Sitemap: error when calling sub-sitemap", e, Location.parse(getLocation()));
+
} finally {
// We restore the context only if no pipeline was built. This allows the pipeline
// environment to be left unchanged when we go back to ancestor processors.
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java Mon Aug 1 06:10:02 2005
@@ -19,6 +19,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.pipeline.ProcessingPipeline;
import org.apache.cocoon.components.treeprocessor.InvokeContext;
import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
@@ -27,11 +28,12 @@
import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.util.location.Location;
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
- * @version CVS $Id: SerializeNode.java,v 1.8 2004/03/05 13:02:52 bdelacretaz Exp $
+ * @version CVS $Id$
*/
public class SerializeNode extends PipelineEventComponentProcessingNode implements ParameterizableProcessingNode {
@@ -117,7 +119,12 @@
if (! context.isBuildingPipelineOnly()) {
// Process pipeline
- return pipeline.process(env);
+ try {
+ return pipeline.process(env);
+ } catch(Exception e) {
+ // Indicate error location
+ throw new ProcessingException("Sitemap: error during pipeline execution", e, Location.parse(getLocation()));
+ }
} else {
// Return true : pipeline is finished.
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.generation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.ExceptionUtils;
+import org.apache.cocoon.util.location.LocatableException;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.commons.lang.SystemUtils;
+import org.mozilla.javascript.JavaScriptException;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+public class ExceptionGenerator extends AbstractGenerator {
+
+ private Throwable thr;
+
+ public static String EXCEPTION_NS = "http://apache.org/cocoon/exception/1.0";
+
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, src, par);
+ thr = (Throwable)objectModel.get(ObjectModelHelper.THROWABLE_OBJECT);
+ if (thr == null) {
+ throw new ProcessingException("ExceptionGenerator should be used in <map:handle-errors>");
+ }
+ }
+
+ public void generate() throws IOException, SAXException, ProcessingException {
+ this.contentHandler.startDocument();
+ toSAX(thr, this.contentHandler);
+ this.contentHandler.endDocument();
+ }
+
+ public static void toSAX(Throwable thr, ContentHandler handler) throws SAXException {
+ Throwable root = ExceptionUtils.getRootCause(thr);
+ if (root == null) root = thr;
+
+ AttributesImpl attr = new AttributesImpl();
+ handler.startPrefixMapping("ex", EXCEPTION_NS);
+ attr.addCDATAAttribute("class", root.getClass().getName());
+ Location loc = ExceptionUtils.getLocation(root);
+ if (loc != null) {
+ attr.addCDATAAttribute("uri", loc.getURI());
+ attr.addCDATAAttribute("line", Integer.toString(loc.getLine()));
+ attr.addCDATAAttribute("column", Integer.toString(loc.getColumn()));
+ }
+ handler.startElement(EXCEPTION_NS, "exception", "ex:exception", attr);
+
+ // Root exception message
+ attr.clear();
+ textElement("message", attr, root.getMessage(), handler);
+
+ // Locations
+ handler.startElement(EXCEPTION_NS, "locations", "ex:locations", attr);
+ Throwable current = thr;
+ while (current != null) {
+ loc = ExceptionUtils.getLocation(current);
+ if (loc != null) {
+ attr.clear();
+ attr.addCDATAAttribute("uri", loc.getURI());
+ attr.addCDATAAttribute("line", Integer.toString(loc.getLine()));
+ attr.addCDATAAttribute("column", Integer.toString(loc.getColumn()));
+
+ // Get raw message for LocatableExceptions, message otherwise
+ String message = current instanceof LocatableException ?
+ ((LocatableException)current).getRawMessage() :
+ current.getMessage();
+
+ textElement("location", attr, message, handler);
+ }
+
+ // Dump parent location
+ current = ExceptionUtils.getCause(current);
+ }
+
+ handler.endElement(EXCEPTION_NS, "locations", "ex:locations");
+
+ // Root exception stacktrace
+ attr.clear();
+ textElement("stacktrace", attr, ExceptionUtils.getStackTrace(root), handler);
+
+ // Full stack trace (if exception is chained)
+ if (thr != root) {
+ String trace = SystemUtils.isJavaVersionAtLeast(140) ?
+ ExceptionUtils.getStackTrace(thr) :
+ ExceptionUtils.getFullStackTrace(thr);
+
+ textElement("full-stacktrace", attr, trace, handler);
+ }
+
+ handler.endElement(EXCEPTION_NS, "exception", "ex:exception");
+ handler.endPrefixMapping("ex");
+ }
+
+ private static void textElement(String name, Attributes attr, String value, ContentHandler handler) throws SAXException {
+ handler.startElement(EXCEPTION_NS, name, "ex:" + name, attr);
+ handler.characters(value.toCharArray(), 0, value.length());
+ handler.endElement(EXCEPTION_NS, name, "ex:" + name);
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/selection/ExceptionSelector.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/selection/ExceptionSelector.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/selection/ExceptionSelector.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/selection/ExceptionSelector.java Mon Aug 1 06:10:02 2005
@@ -23,7 +23,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.util.ClassUtils;
-import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.cocoon.util.ExceptionUtils;
/**
* In a <map:handle-errors>, selects depending on the exception that caused the error.
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util;
+
+import java.util.Vector;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.mozilla.javascript.EcmaError;
+import org.mozilla.javascript.JavaScriptException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * This class builds on <a href="http://jakarta.apache.org/commons/lang/">Jakarta Commons Lang</a>'s
+ * <code><a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/exception/ExceptionUtils.html">ExceptionUtils</a></code>
+ * to handle exception chains, with additional heuristics to unroll exceptions, and other Cocoon-specific stuff
+ * such as getting the {@link Location} of an exception.
+ *
+ * @version $Id$
+ */
+public class ExceptionUtils extends org.apache.commons.lang.exception.ExceptionUtils {
+
+ /**
+ * Get the cause of a <code>Throwable</code>
+ *
+ * @param thr the throwable
+ * @return <code>thr</code>'s parent, or <code>null</code> if none exists.
+ */
+ public static final Throwable getCause(Throwable thr) {
+ // Specific case of JavaScriptException, which holds the wrapped exception
+ // in its 'value' property, which ExceptionUtils cannot find
+ if (thr instanceof JavaScriptException) {
+ Object obj = ((JavaScriptException)thr).getValue();
+ if (obj instanceof Throwable) {
+ return (Throwable)obj;
+ } else {
+ return null;
+ }
+ } else {
+ return org.apache.commons.lang.exception.ExceptionUtils.getCause(thr);
+ }
+ }
+
+ /**
+ * Get the root cause of a <code>Throwable</code>.
+ *
+ * @param thr the throwable
+ * @return <code>thr</code>'s root parent, or <code>null</code> if none exists.
+ */
+ public static final Throwable getRootCause(Throwable thr) {
+ Throwable parent;
+ Throwable current = thr;
+ while ((parent = getCause(current)) != null) {
+ current = parent;
+ }
+
+ // Return current only if not the original throwable (happens when there's no cause)
+ return current == thr ? null : current;
+ }
+
+ /**
+ * Get the location of a throwable. Checks various ways to get the exception location.
+ *
+ * @param thr the throwable
+ * @return the location, or <code>null</code> if it could not be determined
+ */
+ public static Location getLocation(Throwable thr) {
+
+ if (thr instanceof Locatable) {
+ return ((Locatable)thr).getLocation();
+
+ } else if (thr instanceof SAXParseException) {
+ SAXParseException spe = (SAXParseException)thr;
+ if (spe.getSystemId() != null) {
+ return new Location(spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber());
+ } else {
+ return null;
+ }
+
+ } else if (thr instanceof TransformerException) {
+ TransformerException ex = (TransformerException)thr;
+ SourceLocator locator = ex.getLocator();
+ if (locator != null && locator.getSystemId() != null) {
+ return new Location(locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ return null;
+ }
+
+ } else if (thr instanceof EcmaError) {
+ EcmaError ex = (EcmaError)thr;
+ if (ex.getSourceName() != null) {
+ return new Location(ex.getSourceName(), ex.getLineNumber(), ex.getColumnNumber());
+ } else {
+ return null;
+ }
+
+ } else if (thr instanceof JavaScriptException) {
+ JavaScriptException ex = (JavaScriptException)thr;
+ Vector stackTrace = ex.getJSStackTrace();
+ if (stackTrace != null) {
+ // see JavaScriptException.getMessage()
+ int i = stackTrace.size() - 1;
+ String sourceName = (String)stackTrace.elementAt(i-2);
+ int lineNum = ((Integer)stackTrace.elementAt(i)).intValue();
+ return new Location(sourceName, lineNum, -1);
+ } else {
+ return null;
+ }
+ }
+
+ return null;
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/ExceptionUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+/**
+ * A interface that should be implemented by objects knowning their location (i.e. where they
+ * have been created from).
+ *
+ * @version $Id$
+ */
+public interface Locatable {
+ /**
+ * Get the location of this object
+ *
+ * @return the location
+ */
+ Location getLocation();
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Locatable.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+/**
+ * Extension of {@link Locatable} for exceptions.
+ * <p>
+ * In order to dump location information in the stacktrace, the <code>getMessage()</code> method of
+ * a {@link Locatable} exception should return a concatenation of the raw message (given in the
+ * constructor) and the exception's location, e.g. "<code>foo failed (file.xml:12:3)</code>". However,
+ * {@link Locatable}-aware classes will want to handle the raw message (i.e. "<code>foo failed</code>")
+ * and location separately.
+ * <p>
+ * This interface gives access to the raw message.
+ *
+ * @version $Id$
+ */
+public interface LocatableException extends Locatable {
+
+ /**
+ * Get the raw message of the exception (the one used in the constructor)
+ *
+ * @return the raw message
+ */
+ public String getRawMessage();
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatableException.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+import org.apache.avalon.framework.CascadingException;
+
+/**
+ * A cascading and located <code>Exception</code>.
+ *
+ * @version $Id$
+ */
+public class LocatedException extends CascadingException implements LocatableException {
+
+ private Location location;
+
+ public LocatedException(String message) {
+ super(message, null);
+ }
+
+ public LocatedException(String message, Throwable thr) {
+ super(message, thr);
+ }
+
+ public LocatedException(String message, Location location) {
+ super(message, null);
+ this.location = location;
+ }
+
+ public LocatedException(String message, Throwable thr, Location location) {
+ super(message, thr);
+ this.location = location;
+ }
+
+ public Location getLocation() {
+ return this.location;
+ }
+
+ public String getRawMessage() {
+ return super.getMessage();
+ }
+
+ public String getMessage() {
+ return this.location == null ? super.getMessage() :
+ super.getMessage() + " (" + this.location.toString() + ")";
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedException.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+/**
+ * A cascading and located <code>RuntimeException</code>.
+ *
+ * @version $Id$
+ */
+public class LocatedRuntimeException extends CascadingRuntimeException implements LocatableException {
+
+ private Location location;
+
+ public LocatedRuntimeException(String message) {
+ super(message, null);
+ }
+
+ public LocatedRuntimeException(String message, Throwable thr) {
+ super(message, thr);
+ }
+
+ public LocatedRuntimeException(String message, Location location) {
+ super(message, null);
+ this.location = location;
+ }
+
+ public LocatedRuntimeException(String message, Throwable thr, Location location) {
+ super(message, thr);
+ this.location = location;
+ }
+
+ public Location getLocation() {
+ return this.location;
+ }
+
+ public String getRawMessage() {
+ return super.getMessage();
+ }
+
+ public String getMessage() {
+ return this.location == null ? super.getMessage() :
+ super.getMessage() + " (" + this.location.toString() + ")";
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+import java.io.Serializable;
+
+/**
+ * A location in a resource. The location is composed of the URI of the resource, and
+ * the line and column numbers within that resource (when available).
+ * <p>
+ * Locations are mostly used by {@link Locatable}s objects.
+ *
+ * @version $Id$
+ */
+public class Location implements Serializable {
+ private final String uri;
+ private final int line;
+ private final int column;
+ private transient String stringValue;
+
+ /**
+ * Constant for unknown locations.
+ */
+ public static final Location UNKNOWN = new Location();
+
+ /**
+ * The string representation of an {@link #UNKNOWN unknown location}: "<code>[unknown location]</code>".
+ */
+ public static final String UNKNOWN_STRING = "[unknown location]";
+
+ private Location() {
+ // Null location
+ uri = "";
+ line = -1;
+ column = -1;
+ stringValue = UNKNOWN_STRING;
+ }
+
+ /**
+ * Build a location for a given URI, with unknown line and column numbers.
+ *
+ * @param uri the resource URI
+ */
+ public Location(String uri) {
+ this(uri, -1, -1);
+ }
+
+ /**
+ * Build a location for a given URI and line and columb numbers.
+ *
+ * @param uri the resource URI
+ * @param line the line number (starts at 1)
+ * @param column the column number (starts at 1)
+ */
+ public Location(String uri, int line, int column) {
+ this.uri = uri;
+ this.line = line;
+ this.column = column;
+ }
+
+ /**
+ * Parse a location string of the form "<code><em>uri</em>:<em>line</em>:<em>column</em></code>" (e.g.
+ * "<code>path/to/file.xml:3:40</code>") to a Location object.
+ *
+ * @param text the text to parse
+ * @return the location
+ */
+ public static Location parse(String text) throws Exception {
+ if (text == null || text.equals(UNKNOWN_STRING)) {
+ return UNKNOWN;
+ }
+
+ try {
+ int colSep = text.lastIndexOf(':');
+ if (colSep > -1) {
+ int column = Integer.parseInt(text.substring(colSep + 1));
+
+ int lineSep = text.lastIndexOf(':', colSep - 1);
+ if (lineSep > -1) {
+ int line = Integer.parseInt(text.substring(lineSep + 1, colSep));
+ return new Location(text.substring(0, lineSep), line, column);
+ }
+ }
+ } catch(Exception e) {
+ // Ignore: we throw another one below
+ }
+
+ throw new IllegalArgumentException("Invalid location string: " + text);
+ }
+
+ /**
+ * Get the URI of this location
+ *
+ * @return the URI (empty string if unknown).
+ */
+ public String getURI() {
+ return this.uri;
+ }
+
+ /**
+ * Get the line number of this location
+ *
+ * @return the line number (<code>-1</code> if unknown)
+ */
+ public int getLine() {
+ return this.line;
+ }
+
+ /**
+ * Get the column number of this location
+ *
+ * @return the column number (<code>-1</code> if unknown)
+ */
+ public int getColumn() {
+ return this.column;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj instanceof Location) {
+ Location other = (Location)obj;
+ return this.line == other.line && other.column == other.column && this.uri.equals(other.uri);
+ }
+
+ return false;
+ }
+
+ public int hashCode() {
+ return uri.hashCode() ^ line ^ column;
+ }
+
+ /**
+ * Builds a string representation of the location, in the "<code><em>uri</em>:<em>line</em>:<em>column</em></code>"
+ * format (e.g. "<code>path/to/file.xml:3:40</code>"). For {@link #UNKNOWN an unknown location}, returns
+ * {@link #UNKNOWN_STRING}.
+ *
+ * @return the string representation
+ */
+ public String toString() {
+ if (stringValue == null) {
+ stringValue = uri + ":" + Integer.toString(line) + ":" + Integer.toString(column);
+ }
+ return stringValue;
+ }
+
+ /**
+ * Ensure serialized unknown location resolve to {@link UNKNOWN}.
+ */
+ private Object readResolve() {
+ return this.equals(UNKNOWN) ? UNKNOWN : this;
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/Location.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocationAttributes.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocationAttributes.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocationAttributes.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/location/LocationAttributes.java Mon Aug 1 06:10:02 2005
@@ -48,9 +48,6 @@
/** Attribute qualified name for the column number */
public static final String Q_COL_ATTR = "loc:column";
- /** Value returned when location is unknown */
- public static final String UNKNOWN_LOCATION = "[unknown location]";
-
// Private constructor, we only have static methods
private LocationAttributes() {
// Nothing
@@ -79,18 +76,34 @@
return newAttrs;
}
+
+ /**
+ * Returns the {@link Location} of an element (SAX flavor).
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @return a {@link Location} object
+ */
+ public static Location getLocation(Attributes attrs) {
+ String src = attrs.getValue(URI, SRC_ATTR);
+ if (src == null) {
+ return Location.UNKNOWN;
+ }
+
+ return new Location(src, getLine(attrs), getColumn(attrs));
+ }
/**
- * Returns the location of an element (SAX flavor).
+ * Returns the location of an element (SAX flavor). If the location is to be kept
+ * into an object built from this element, consider using {@link #getLocation(Attributes)}
+ * and the {@link Locatable} interface.
*
* @param attrs the element's attributes that hold the location information
- * @return a location string of type "<code>foo.xml:10:80</code>" or
- * "<code>[unknown location]</code>" if <code>attrs</code> has no location information.
+ * @return a location string as defined by {@link Location#toString()}.
*/
public static String getLocationString(Attributes attrs) {
String src = attrs.getValue(URI, SRC_ATTR);
if (src == null) {
- return UNKNOWN_LOCATION;
+ return Location.UNKNOWN_STRING;
}
return src + ":" + attrs.getValue(URI, LINE_ATTR) + ":" + attrs.getValue(URI, COL_ATTR);
@@ -105,7 +118,7 @@
*/
public static String getURI(Attributes attrs) {
String src = attrs.getValue(URI, SRC_ATTR);
- return src != null ? src : UNKNOWN_LOCATION;
+ return src != null ? src : Location.UNKNOWN_STRING;
}
/**
@@ -133,16 +146,32 @@
}
/**
+ * Returns the {@link Location} of an element (DOM flavor).
+ *
+ * @param attrs the element that holds the location information
+ * @return a {@link Location} object
+ */
+ public static Location getLocation(Element elem) {
+ Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+ if (srcAttr == null) {
+ return Location.UNKNOWN;
+ }
+
+ return new Location(srcAttr.getValue(), getLine(elem), getColumn(elem));
+ }
+
+ /**
* Returns the location of an element that has been processed by this pipe (DOM flavor).
+ * If the location is to be kept into an object built from this element, consider using
+ * {@link #getLocation(Element)} and the {@link Locatable} interface.
*
* @param elem the element that holds the location information
- * @return a location string of type "<code>foo.xml:10:80</code>" or
- * "<code>[unknown location]</code>" if <code>attrs</code> has no location information.
+ * @return a location string as defined by {@link Location#toString()}.
*/
public static String getLocationString(Element elem) {
Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
if (srcAttr == null) {
- return UNKNOWN_LOCATION;
+ return Location.UNKNOWN_STRING;
}
return srcAttr.getValue() + ":" + elem.getAttributeNS(URI, LINE_ATTR) + ":" + elem.getAttributeNS(URI, COL_ATTR);
@@ -157,7 +186,7 @@
*/
public static String getURI(Element elem) {
Attr attr = elem.getAttributeNodeNS(URI, SRC_ATTR);
- return attr != null ? attr.getValue() : UNKNOWN_LOCATION;
+ return attr != null ? attr.getValue() : Location.UNKNOWN_STRING;
}
/**
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java Mon Aug 1 06:10:02 2005
@@ -20,9 +20,9 @@
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.util.ExceptionUtils;
import org.apache.commons.lang.ClassUtils;
-import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log.ContextMap;
import org.apache.log.LogEvent;
import org.apache.log.Logger;
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java Mon Aug 1 06:10:02 2005
@@ -36,7 +36,7 @@
* document event.
*/
public void setDocumentLocator(Locator locator) {
- if (contentHandler != null) contentHandler.setDocumentLocator(locator);
+ contentHandler.setDocumentLocator(locator);
}
/**
@@ -44,7 +44,7 @@
*/
public void startDocument()
throws SAXException {
- if (contentHandler != null) contentHandler.startDocument();
+ contentHandler.startDocument();
}
/**
@@ -52,7 +52,7 @@
*/
public void endDocument()
throws SAXException {
- if (contentHandler != null) contentHandler.endDocument();
+ contentHandler.endDocument();
}
/**
@@ -63,7 +63,7 @@
*/
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
- if (contentHandler != null) contentHandler.startPrefixMapping(prefix, uri);
+ contentHandler.startPrefixMapping(prefix, uri);
}
/**
@@ -73,7 +73,7 @@
*/
public void endPrefixMapping(String prefix)
throws SAXException {
- if (contentHandler != null) contentHandler.endPrefixMapping(prefix);
+ contentHandler.endPrefixMapping(prefix);
}
/**
@@ -91,7 +91,7 @@
*/
public void startElement(String uri, String loc, String raw, Attributes a)
throws SAXException {
- if (contentHandler != null) contentHandler.startElement(uri, loc, raw, a);
+ contentHandler.startElement(uri, loc, raw, a);
}
@@ -108,7 +108,7 @@
*/
public void endElement(String uri, String loc, String raw)
throws SAXException {
- if (contentHandler != null) contentHandler.endElement(uri, loc, raw);
+ contentHandler.endElement(uri, loc, raw);
}
/**
@@ -120,7 +120,7 @@
*/
public void characters(char c[], int start, int len)
throws SAXException {
- if (contentHandler != null) contentHandler.characters(c, start, len);
+ contentHandler.characters(c, start, len);
}
/**
@@ -132,7 +132,7 @@
*/
public void ignorableWhitespace(char c[], int start, int len)
throws SAXException {
- if (contentHandler != null) contentHandler.ignorableWhitespace(c, start, len);
+ contentHandler.ignorableWhitespace(c, start, len);
}
/**
@@ -144,7 +144,7 @@
*/
public void processingInstruction(String target, String data)
throws SAXException {
- if (contentHandler != null) contentHandler.processingInstruction(target, data);
+ contentHandler.processingInstruction(target, data);
}
/**
@@ -155,7 +155,7 @@
*/
public void skippedEntity(String name)
throws SAXException {
- if (contentHandler != null) contentHandler.skippedEntity(name);
+ contentHandler.skippedEntity(name);
}
/**
@@ -169,7 +169,7 @@
*/
public void startDTD(String name, String publicId, String systemId)
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.startDTD(name, publicId, systemId);
+ lexicalHandler.startDTD(name, publicId, systemId);
}
/**
@@ -177,7 +177,7 @@
*/
public void endDTD()
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.endDTD();
+ lexicalHandler.endDTD();
}
/**
@@ -188,7 +188,7 @@
*/
public void startEntity(String name)
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.startEntity(name);
+ lexicalHandler.startEntity(name);
}
/**
@@ -198,7 +198,7 @@
*/
public void endEntity(String name)
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.endEntity(name);
+ lexicalHandler.endEntity(name);
}
/**
@@ -206,7 +206,7 @@
*/
public void startCDATA()
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.startCDATA();
+ lexicalHandler.startCDATA();
}
/**
@@ -214,7 +214,7 @@
*/
public void endCDATA()
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.endCDATA();
+ lexicalHandler.endCDATA();
}
/**
@@ -226,6 +226,6 @@
*/
public void comment(char ch[], int start, int len)
throws SAXException {
- if (lexicalHandler != null) lexicalHandler.comment(ch, start, len);
+ lexicalHandler.comment(ch, start, len);
}
}
Added: cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java (added)
+++ cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java Mon Aug 1 06:10:02 2005
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.util.location;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+public class LocationTestCase extends TestCase {
+
+ public LocationTestCase(String name) {
+ super(name);
+ }
+
+ static final String str = "path/to/file.xml:1:40";
+
+ public void testParse() throws Exception {
+ String str = "path/to/file.xml:1:40";
+ Location loc = Location.parse(str);
+
+ assertEquals("URI", "path/to/file.xml", loc.getURI());
+ assertEquals("line", 1, loc.getLine());
+ assertEquals("column", 40, loc.getColumn());
+ assertEquals("string representation", str, loc.toString());
+ }
+
+ public void testEquals() throws Exception {
+ Location loc1 = Location.parse(str);
+ Location loc2 = new Location("path/to/file.xml", 1, 40);
+
+ assertEquals("locations", loc1, loc2);
+ assertEquals("hashcode", loc1.hashCode(), loc2.hashCode());
+ assertEquals("string representation", loc1.toString(), loc2.toString());
+ }
+
+ /**
+ * Test that Location.UNKNOWN is kept identical on deserialization
+ */
+ public void testSerializeUnknown() throws Exception {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+
+ oos.writeObject(Location.UNKNOWN);
+ oos.close();
+ bos.close();
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+
+ Object obj = ois.readObject();
+
+ assertSame("unknown location", Location.UNKNOWN, obj);
+ }
+}
Propchange: cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/test/org/apache/cocoon/util/location/LocationTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/branches/BRANCH_2_1_X/src/webapp/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/webapp/sitemap.xmap?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/webapp/sitemap.xmap (original)
+++ cocoon/branches/BRANCH_2_1_X/src/webapp/sitemap.xmap Mon Aug 1 06:10:02 2005
@@ -74,9 +74,11 @@
<map:generator label="content" logger="sitemap.generator.stream" name="stream" pool-max="16" src="org.apache.cocoon.generation.StreamGenerator"/>
<map:generator label="content" logger="sitemap.generator.status" name="status" pool-max="16" src="org.apache.cocoon.generation.StatusGenerator"/>
<map:generator label="content" logger="sitemap.generator.jx" name="jx" pool-max="16" src="org.apache.cocoon.generation.JXTemplateGenerator"/>
- <!-- The notifying generator can only be used in a <handle-errors> section : it produces an XML
- representation of the exception that caused the error handler to be executed -->
+ <!-- The notifying generator can only be used in a <handle-errors> section -->
<map:generator name="notifying" src="org.apache.cocoon.sitemap.NotifyingGenerator"/>
+ <!-- The exception generator can only be used in a <handle-errors> section : it produces an XML
+ representation of the exception that caused the error handler to be executed -->
+ <map:generator name="exception" src="org.apache.cocoon.generation.ExceptionGenerator"/>
</map:generators>
@@ -676,27 +678,30 @@
<map:select type="exception">
<map:when test="not-found">
- <map:generate type="notifying"/>
- <map:transform src="stylesheets/system/error2html.xslt">
+ <map:generate type="exception"/>
+ <map:transform src="stylesheets/system/exception2html.xslt">
<map:parameter name="contextPath" value="{request:contextPath}"/>
+ <map:parameter name="realPath" value="{realpath:}"/>
<map:parameter name="pageTitle" value="Resource not found"/>
</map:transform>
<map:serialize status-code="404"/>
</map:when>
<map:when test="invalid-continuation">
- <map:generate type="notifying"/>
- <map:transform src="stylesheets/system/error2html.xslt">
+ <map:generate type="exception"/>
+ <map:transform src="stylesheets/system/exception2html.xslt">
<map:parameter name="contextPath" value="{request:contextPath}"/>
+ <map:parameter name="realPath" value="{realpath:}"/>
<map:parameter name="pageTitle" value="Invalid Continuation"/>
</map:transform>
<map:serialize status-code="404"/>
</map:when>
<map:otherwise>
- <map:generate type="notifying"/>
- <map:transform src="stylesheets/system/error2html.xslt">
+ <map:generate type="exception"/>
+ <map:transform src="stylesheets/system/exception2html.xslt">
<map:parameter name="contextPath" value="{request:contextPath}"/>
+ <map:parameter name="realPath" value="{realpath:}"/>
</map:transform>
<map:serialize status-code="500"/>
</map:otherwise>
Added: cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt?rev=226786&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt (added)
+++ cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt Mon Aug 1 06:10:02 2005
@@ -0,0 +1,152 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ex="http://apache.org/cocoon/exception/1.0">
+
+ <xsl:param name="contextPath"/>
+ <xsl:param name="realPath"/>
+
+ <!-- let sitemap override default page title -->
+ <xsl:param name="pageTitle">An error has occured</xsl:param>
+
+ <xsl:template match="ex:exception">
+ <html>
+ <head>
+ <title>
+ <xsl:value-of select="$pageTitle"/>
+ </title>
+ <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+ <style>
+ h1 { color: #336699; text-align: left; margin: 0px 0px 30px 0px; padding: 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+ p.message { padding: 10px 30px 10px 30px; font-weight: bold; font-size: 130%; border-width: 1px; border-style: dashed; border-color: #336699; }
+ p.description { padding: 10px 30px 20px 30px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+ p.topped { padding-top: 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }
+ pre { font-size: 120%; }
+ </style>
+ <script src="{$contextPath}/scripts/main.js" type="text/javascript"/>
+ </head>
+ <body>
+ <xsl:attribute name="onload">
+ <xsl:if test="ex:stacktrace">toggle('stacktrace');</xsl:if>
+ <xsl:if test="ex:full-stacktrace">toggle('full-stacktrace');</xsl:if>
+ </xsl:attribute>
+
+ <h1><xsl:value-of select="$pageTitle"/></h1>
+ <p class="message">
+ <xsl:value-of select="@class"/>:<br/><xsl:value-of select="ex:message"/>
+ <xsl:if test="@uri">
+ <br/><span style="font-weight: normal"><xsl:call-template name="dump-location"/></span>
+ </xsl:if>
+ </p>
+
+ <xsl:if test="count(ex:locations/*)">
+ <p><span class="description">Cocoon stacktrace</span>
+ <span class="switch" id="locations-switch" onclick="toggle('locations')">[hide]</span>
+ </p>
+ <div id="locations">
+ <xsl:for-each select="ex:locations/*">
+ <xsl:sort select="position()" order="descending"/>
+ <p><strong><xsl:value-of select="."/></strong><br/>
+ <xsl:call-template name="dump-location"/>
+ </p>
+ </xsl:for-each>
+ </div>
+ </xsl:if>
+
+ <xsl:apply-templates select="ex:stacktrace"/>
+ <xsl:apply-templates select="ex:full-stacktrace"/>
+
+<!-- Do we really need all that stuff?
+ Application developers know this, and application users get really confused by this information.
+
+ <p class="topped">
+ If you need help and this information is not enough, you
+ are invited to read the
+ <a href="http://cocoon.apache.org/2.1/faq/">Cocoon FAQ</a>.<br/>
+ If you still don't find the answers you need,
+ can send a mail to the
+ <a href="http://cocoon.apache.org/community/mail-lists.html">
+ Cocoon mailing lists</a>,
+ remembering to:
+ </p>
+
+ <ul>
+ <li>specify the version of Cocoon you're using, or we'll assume that you
+ are talking about the latest released version;</li>
+ <li>specify the platform-operating system-version-servlet container version;</li>
+ <li>send any pertinent error message;</li>
+ <li>send pertinent log snippets;</li>
+ <li>send pertinent sitemap snippets;</li>
+ <li>send pertinent parts of the page that give you problems.</li>
+ </ul>
+
+ <p>
+ For more detailed technical information, take a look at the log
+ files in the log directory of Cocoon, which is placed by default in
+ the <code>WEB-INF/logs/</code> folder of your cocoon webapp context.<br/>
+ If the logs don't give you enough information, you might want to increase the
+ log level by changing the Logging configuration which is by default the
+ <code>WEB-INF/logkit.xconf</code> file.
+ </p>
+
+ <p>
+ If you think you found a bug, please report it to
+ <a href="http://issues.apache.org/bugzilla/">Apache's Bugzilla</a>;
+ a message will automatically be sent to the developer mailing list and you'll
+ be kept in contact automatically with the further progress on that bug.
+ </p>
+
+ <p>
+ Thanks, and sorry for the trouble if this is our fault.
+ </p>
+-->
+ <p class="topped">
+ The <a href="http://cocoon.apache.org/">Apache Cocoon</a> Project
+ </p>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="ex:stacktrace|ex:full-stacktrace">
+ <p class="stacktrace">
+ <span class="description">Java <xsl:value-of select="translate(local-name(), '-', ' ')"/></span>
+ <span class="switch" id="{local-name()}-switch" onclick="toggle('{local-name()}')">[hide]</span>
+ <pre id="{local-name()}">
+ <xsl:value-of select="translate(.,' ','')"/>
+ </pre>
+ </p>
+ </xsl:template>
+
+ <xsl:template name="dump-location">
+ <xsl:choose>
+ <xsl:when test="contains(@uri, $realPath)">
+ <xsl:text>context:/</xsl:text>
+ <xsl:value-of select="substring-after(@uri, $realPath)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@uri"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> - </xsl:text>
+ <xsl:value-of select="@line"/>:<xsl:value-of select="@column"/>
+ </xsl:template>
+
+</xsl:stylesheet>
Propchange: cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/branches/BRANCH_2_1_X/src/webapp/stylesheets/system/exception2html.xslt
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/status.xml?rev=226786&r1=226785&r2=226786&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Mon Aug 1 06:10:02 2005
@@ -196,6 +196,10 @@
<changes>
<release version="@version@" date="@date@">
+ <action dev="SW" type="add">
+ Added Cocoon stacktraces. This is based on location classes in the new org.apache.cocoon.util.location package
+ and a refactoring of the exception management to attach locations to exceptions.
+ </action>
<action dev="AG" type="update">
Updated hsqldb to 1.8.0.
</action>