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/18 20:07:53 UTC
svn commit: r233343 [1/3] - in /cocoon/trunk/src: java/org/apache/cocoon/
java/org/apache/cocoon/components/flow/
java/org/apache/cocoon/components/flow/javascript/
java/org/apache/cocoon/components/flow/javascript/fom/
java/org/apache/cocoon/component...
Author: sylvain
Date: Thu Aug 18 11:06:44 2005
New Revision: 233343
URL: http://svn.apache.org/viewcvs?rev=233343&view=rev
Log:
Porting Cocoon stacktraces to trunk
Added:
cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/ExceptionUtils.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/Locatable.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocatableException.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocatedException.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/Location.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocationImpl.java (with props)
cocoon/trunk/src/java/org/apache/cocoon/util/location/MultiLocatable.java (with props)
cocoon/trunk/src/test/org/apache/cocoon/util/location/
cocoon/trunk/src/test/org/apache/cocoon/util/location/LocationTestCase.java (with props)
cocoon/trunk/src/webapp/stylesheets/system/exception2html.xslt (with props)
Removed:
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocatorToAttributesPipe.java
cocoon/trunk/src/java/org/apache/cocoon/xml/NamespaceSupport.java
Modified:
cocoon/trunk/src/java/org/apache/cocoon/ConnectionResetException.java
cocoon/trunk/src/java/org/apache/cocoon/ProcessingException.java
cocoon/trunk/src/java/org/apache/cocoon/ResourceNotFoundException.java
cocoon/trunk/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java
cocoon/trunk/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java
cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java
cocoon/trunk/src/java/org/apache/cocoon/selection/ExceptionSelector.java
cocoon/trunk/src/java/org/apache/cocoon/sitemap/ExecutionContext.java
cocoon/trunk/src/java/org/apache/cocoon/sitemap/SitemapParameters.java
cocoon/trunk/src/java/org/apache/cocoon/transformation/TraxTransformer.java
cocoon/trunk/src/java/org/apache/cocoon/util/location/LocationAttributes.java
cocoon/trunk/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java
cocoon/trunk/src/java/org/apache/cocoon/util/log/CocoonStreamTargetFactory.java
cocoon/trunk/src/java/org/apache/cocoon/util/log/CocoonTargetFactory.java
cocoon/trunk/src/java/org/apache/cocoon/util/log/ExtensiblePatternFormatter.java
cocoon/trunk/src/java/org/apache/cocoon/util/log/XMLCocoonLogFormatter.java
cocoon/trunk/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java
cocoon/trunk/src/java/org/apache/cocoon/xml/NamespacesTable.java
cocoon/trunk/src/test/org/apache/cocoon/xml/NamespacesTableTestCase.java
cocoon/trunk/src/webapp/sitemap.xmap
Modified: cocoon/trunk/src/java/org/apache/cocoon/ConnectionResetException.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/ConnectionResetException.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/ConnectionResetException.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/ConnectionResetException.java Thu Aug 18 11:06:44 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/trunk/src/java/org/apache/cocoon/ProcessingException.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/ProcessingException.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/ProcessingException.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/ProcessingException.java Thu Aug 18 11:06:44 2005
@@ -15,14 +15,12 @@
*/
package org.apache.cocoon;
-import org.apache.avalon.framework.CascadingException;
+import java.util.List;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-import org.xml.sax.SAXParseException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.SourceLocator;
+import org.apache.cocoon.util.location.LocatedException;
+import org.apache.cocoon.util.location.LocatedRuntimeException;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.MultiLocatable;
/**
* This Exception is thrown every time there is a problem in processing
@@ -30,15 +28,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 implements MultiLocatable {
/**
* Construct a new <code>ProcessingException</code> instance.
*/
public ProcessingException(String message) {
- super(message, null);
+ super(message);
}
/**
@@ -58,71 +56,173 @@
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();
+ /**
+ * Construct a new <code>ProcessingException</code> that has an associated location.
+ */
+ public ProcessingException(String message, Location location) {
+ super(message, location);
}
/**
- * Examine Throwable and try to figure out location information.
+ * Construct a new <code>ProcessingException</code> that has a parent exception
+ * and an associated location.
* <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();
+ * This constructor is protected to enforce the use of {@link #throwLocated(String, Throwable, Location)}
+ * which limits exception nesting as far as possible.
+ */
+ protected ProcessingException(String message, Throwable t, Location location) {
+ super(message, t, location);
}
- public void printStackTrace( PrintStream s ) {
- super.printStackTrace(s);
- if(getCause()!=null)
- getCause().printStackTrace(s);
+ /**
+ * Throw a located exception given an existing exception and the location where
+ * this exception was catched.
+ * <p>
+ * If the exception is already a <code>ProcessingException</code> or a {@link LocatedRuntimeException},
+ * the location is added to the original exception's location chain and the original exception
+ * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
+ * <code>ProcessingException</code> is thrown, wrapping the original exception.
+ * <p>
+ * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
+ * semantics in the caller code, i.e. write<br>
+ * <code> throw ProcessingException.throwLocated(...);</code><br>
+ * instead of<br>
+ * <code> ProcessingException.throwLocated(...);</code><br>
+ * <code> return;</code>
+ *
+ * @param message a message (can be <code>null</code>)
+ * @param thr the original exception (can be <code>null</code>)
+ * @param location the location (can be <code>null</code>)
+ * @return a (fake) located exception
+ * @throws ProcessingException or <code>LocatedRuntimeException</code>
+ */
+ public static ProcessingException throwLocated(String message, Throwable thr, Location location) throws ProcessingException {
+ if (thr instanceof ProcessingException) {
+ ProcessingException pe = (ProcessingException)thr;
+ pe.addLocation(location);
+ throw pe;
+
+ } else if (thr instanceof LocatedRuntimeException) {
+ LocatedRuntimeException re = (LocatedRuntimeException)thr;
+ re.addLocation(location);
+ // Rethrow
+ throw re;
+ }
+
+ throw new ProcessingException(message, thr, location);
}
- public void printStackTrace( PrintWriter s ) {
- super.printStackTrace(s);
- if(getCause()!=null)
- getCause().printStackTrace(s);
+ /**
+ * Throw a located exception given an existing exception and the locations where
+ * this exception was catched.
+ * <p>
+ * If the exception is already a <code>ProcessingException</code> or a {@link LocatedRuntimeException},
+ * the locations are added to the original exception's location chain and the original exception
+ * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
+ * <code>ProcessingException</code> is thrown, wrapping the original exception.
+ * <p>
+ * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
+ * semantics in the caller code, i.e. write<br>
+ * <code> throw ProcessingException.throwLocated(...);</code><br>
+ * instead of<br>
+ * <code> ProcessingException.throwLocated(...);</code><br>
+ * <code> return;</code>
+ *
+ * @param message a message (can be <code>null</code>)
+ * @param thr the original exception (can be <code>null</code>)
+ * @param locations the locations (can be <code>null</code>)
+ * @return a (fake) located exception
+ * @throws ProcessingException or <code>LocatedRuntimeException</code>
+ */
+ public static ProcessingException throwLocated(String message, Throwable thr, List locations) throws ProcessingException {
+ MultiLocatable multiloc;
+ if (thr instanceof ProcessingException) {
+ multiloc = (ProcessingException)thr;
+ } else if (thr instanceof LocatedRuntimeException) {
+ multiloc = (LocatedRuntimeException)thr;
+ } else {
+ multiloc = new ProcessingException(message, thr);
+ }
+
+ if (locations != null) {
+ for (int i = 0; i < locations.size(); i++) {
+ multiloc.addLocation((Location)locations.get(i));
+ }
+ }
+
+ if (multiloc instanceof LocatedRuntimeException) {
+ throw (LocatedRuntimeException)multiloc;
+ } else {
+ throw (ProcessingException)multiloc;
+ }
}
+
+
+// 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/trunk/src/java/org/apache/cocoon/ResourceNotFoundException.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/ResourceNotFoundException.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/ResourceNotFoundException.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/ResourceNotFoundException.java Thu Aug 18 11:06:44 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/trunk/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java Thu Aug 18 11:06:44 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);
}
/**
Added: cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java?rev=233343&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java Thu Aug 18 11:06:44 2005
@@ -0,0 +1,122 @@
+/*
+ * 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.components.flow.javascript;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.util.ExceptionUtils;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.debug.DebugFrame;
+import org.mozilla.javascript.debug.DebuggableScript;
+import org.mozilla.javascript.debug.Debugger;
+
+/**
+ * A Rhino debugger that tracks location information when an exception is raised in some JavaScript code.
+ * It's purpose is to build a {@link org.apache.cocoon.ProcessingException} that holds the stacktrace
+ * in the JavaScript code.
+ * <p>
+ * This debugger implementation is designed to be as lightweight and fast as possible, in order to have a
+ * negligible impact on the performances of the Rhino interpreter.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocationTrackingDebugger implements Debugger {
+
+ private List locations;
+ private Throwable throwable;
+
+ public void handleCompilationDone(Context cx, DebuggableScript fnOrScript, String source) {
+ // nothing
+ }
+
+ public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
+ return new StackTrackingFrame(fnOrScript);
+ }
+
+ /**
+ * Get an exception that reflects the known location stack
+ *
+ * @param description a description for the exception
+ * @param originalException the original exception
+ *
+ * @return a suitable exception to throw
+ * @see ProcessingException#throwLocated(String, Throwable, Location)
+ */
+ public Exception getException(String description, Exception originalException) throws ProcessingException {
+ if (throwable == null || locations == null) {
+ // Cannot to better for now
+ return originalException;
+ }
+
+ // Unwrap original exception, if any, wrapped by Rhino (the wrapping
+ // class is different in Rhino+cont and Rhino 1.6)
+ Throwable cause = ExceptionUtils.getCause(throwable);
+ if (cause != null)
+ throwable = cause;
+
+ return ProcessingException.throwLocated(description, throwable, locations);
+ }
+
+ private class StackTrackingFrame implements DebugFrame {
+
+ DebuggableScript script;
+ int line;
+
+ public StackTrackingFrame(DebuggableScript script) {
+ this.script = script;
+ }
+
+ public void onEnter(Context cx, Scriptable activation, Scriptable thisObj, Object[] args) {
+ // nothing
+ }
+
+ public void onLineChange(Context cx, int lineNumber) {
+ line = lineNumber;
+ }
+
+ public void onExceptionThrown(Context cx, Throwable ex) {
+ throwable = ex;
+ }
+
+ public void onExit(Context cx, boolean byThrow, Object resultOrException) {
+ if (byThrow) {
+ String name = null;
+ if (script.isFunction()) {
+ name = script.getFunctionName();
+ } else {
+ name = "[script]";
+ }
+
+ if (locations == null) {
+ locations = new ArrayList(1); // start small
+ }
+
+ locations.add(new LocationImpl(name, script.getSourceName(), line, -1));
+
+ } else if (locations != null) {
+ // The exception was handled by the script: clear any recorded locations
+ locations = null;
+ }
+ }
+ }
+}
+
Propchange: cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java Thu Aug 18 11:06:44 2005
@@ -15,14 +15,23 @@
*/
package org.apache.cocoon.components.flow.javascript.fom;
-import org.apache.avalon.framework.CascadingRuntimeException;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
import org.apache.avalon.framework.activity.Initializable;
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.service.ServiceManager;
-
-import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.components.flow.CompilingInterpreter;
@@ -30,13 +39,13 @@
import org.apache.cocoon.components.flow.InvalidContinuationException;
import org.apache.cocoon.components.flow.WebContinuation;
import org.apache.cocoon.components.flow.javascript.JSErrorReporter;
+import org.apache.cocoon.components.flow.javascript.LocationTrackingDebugger;
import org.apache.cocoon.components.flow.javascript.ScriptablePointerFactory;
import org.apache.cocoon.components.flow.javascript.ScriptablePropertyHandler;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
-
import org.apache.commons.jxpath.JXPathIntrospector;
import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
import org.apache.excalibur.source.Source;
@@ -45,7 +54,6 @@
import org.apache.regexp.REProgram;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EcmaError;
-import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NativeJavaClass;
@@ -58,22 +66,9 @@
import org.mozilla.javascript.WrappedException;
import org.mozilla.javascript.Wrapper;
import org.mozilla.javascript.continuations.Continuation;
-import org.mozilla.javascript.tools.ToolErrorReporter;
import org.mozilla.javascript.tools.debugger.Main;
import org.mozilla.javascript.tools.shell.Global;
-import java.awt.Dimension;
-import java.awt.Toolkit;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PushbackInputStream;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
/**
* Interface with the JavaScript interpreter.
@@ -559,6 +554,12 @@
context.setGeneratingDebug(true);
context.setCompileFunctionsWithDynamicScope(true);
context.setErrorReporter(errorReporter);
+
+ LocationTrackingDebugger locationTracker = new LocationTrackingDebugger();
+ if (!enableDebugger) {
+ //FIXME: add a "tee" debugger that allows both to be used simultaneously
+ context.setDebugger(locationTracker, null);
+ }
ThreadScope thrScope = getSessionScope();
synchronized (thrScope) {
@@ -599,25 +600,11 @@
thrScope.setLock(true);
ScriptRuntime.call(context, fun, thrScope, new Object[0], thrScope);
} catch (JavaScriptException ex) {
- EvaluatorException ee = Context.reportRuntimeError(
- ToolErrorReporter.getMessage("msg.uncaughtJSException",
- ex.getMessage()));
- Throwable unwrapped = unwrap(ex);
- if (unwrapped instanceof ProcessingException) {
- throw (ProcessingException) unwrapped;
- }
- throw new CascadingRuntimeException(ee.getMessage(),
- unwrapped);
+ throw locationTracker.getException("Calling function " + funName, ex);
} catch (EcmaError ee) {
- String msg = ToolErrorReporter.getMessage("msg.uncaughtJSException", ee.toString());
- if (ee.getSourceName() != null) {
- Context.reportRuntimeError(msg, ee.getSourceName(),
- ee.getLineNumber(), ee.getLineSource(),
- ee.getColumnNumber());
- } else {
- Context.reportRuntimeError(msg);
- }
- throw new CascadingRuntimeException(ee.getMessage(), ee);
+ throw locationTracker.getException("Calling function " + funName, ee);
+ } catch (WrappedException ee) {
+ throw locationTracker.getException("Calling function " + funName, ee);
}
} finally {
thrScope.setLock(false);
@@ -648,6 +635,11 @@
context.setOptimizationLevel(OPTIMIZATION_LEVEL);
context.setGeneratingDebug(true);
context.setCompileFunctionsWithDynamicScope(true);
+ LocationTrackingDebugger locationTracker = new LocationTrackingDebugger();
+ if (!enableDebugger) {
+ //FIXME: add a "tee" debugger that allows both to be used simultaneously
+ context.setDebugger(locationTracker, null);
+ }
// Obtain the continuation object from it, and setup the
// FOM_Cocoon object associated in the dynamic scope of the saved
@@ -688,25 +680,27 @@
ScriptableObject.callMethod(cocoon,
"handleContinuation", args);
} catch (JavaScriptException ex) {
- EvaluatorException ee = Context.reportRuntimeError(
- ToolErrorReporter.getMessage("msg.uncaughtJSException",
- ex.getMessage()));
- Throwable unwrapped = unwrap(ex);
- if (unwrapped instanceof ProcessingException) {
- throw (ProcessingException)unwrapped;
- }
- throw new CascadingRuntimeException(ee.getMessage(),
- unwrapped);
+ throw locationTracker.getException("Calling continuation", ex);
+// EvaluatorException ee = Context.reportRuntimeError(
+// ToolErrorReporter.getMessage("msg.uncaughtJSException",
+// ex.getMessage()));
+// Throwable unwrapped = unwrap(ex);
+// if (unwrapped instanceof ProcessingException) {
+// throw (ProcessingException)unwrapped;
+// }
+// throw new CascadingRuntimeException(ee.getMessage(),
+// unwrapped);
} catch (EcmaError ee) {
- String msg = ToolErrorReporter.getMessage("msg.uncaughtJSException", ee.toString());
- if (ee.getSourceName() != null) {
- Context.reportRuntimeError(msg, ee.getSourceName(),
- ee.getLineNumber(), ee.getLineSource(),
- ee.getColumnNumber());
- } else {
- Context.reportRuntimeError(msg);
- }
- throw new CascadingRuntimeException(ee.getMessage(), ee);
+ throw locationTracker.getException("Calling continuation", ee);
+// String msg = ToolErrorReporter.getMessage("msg.uncaughtJSException", ee.toString());
+// if (ee.getSourceName() != null) {
+// Context.reportRuntimeError(msg, ee.getSourceName(),
+// ee.getLineNumber(), ee.getLineSource(),
+// ee.getColumnNumber());
+// } else {
+// Context.reportRuntimeError(msg);
+// }
+// throw new CascadingRuntimeException(ee.getMessage(), ee);
}
} finally {
kScope.setLock(false);
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java Thu Aug 18 11:06:44 2005
@@ -15,8 +15,8 @@
*/
package org.apache.cocoon.components.notification;
+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/trunk/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java Thu Aug 18 11:06:44 2005
@@ -15,6 +15,14 @@
*/
package org.apache.cocoon.components.pipeline;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.ParameterException;
@@ -23,7 +31,6 @@
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
-
import org.apache.cocoon.ConnectionResetException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Processor;
@@ -36,23 +43,15 @@
import org.apache.cocoon.serialization.Serializer;
import org.apache.cocoon.sitemap.SitemapErrorHandler;
import org.apache.cocoon.sitemap.SitemapModelComponent;
-import org.apache.cocoon.sitemap.SitemapParameters;
import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.xml.SaxBuffer;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLProducer;
-import org.apache.cocoon.xml.SaxBuffer;
-
import org.apache.excalibur.source.SourceValidity;
import org.xml.sax.SAXException;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
/**
* This is the base for all implementations of a <code>ProcessingPipeline</code>.
* It is advisable to inherit from this base class instead of doing a complete
@@ -201,17 +200,17 @@
public void setGenerator(String role, String source, Parameters param, Parameters hintParam)
throws ProcessingException {
if (this.generator != null) {
- throw new ProcessingException ("Generator already set. Cannot set generator '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Generator already set. Cannot set generator '" + role + "'",
+ getLocation(param));
}
if (this.reader != null) {
- throw new ProcessingException ("Reader already set. Cannot set generator '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Reader already set. Cannot set generator '" + role + "'",
+ getLocation(param));
}
try {
this.generator = (Generator) this.newManager.lookup(Generator.ROLE + '/' + role);
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of generator '" + role + "' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of generator '" + role + "' failed", ce, getLocation(param));
}
this.generatorSource = source;
this.generatorParam = param;
@@ -232,17 +231,17 @@
throws ProcessingException {
if (this.reader != null) {
// Should normally never happen as setting a reader starts pipeline processing
- throw new ProcessingException ("Reader already set. Cannot add transformer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Reader already set. Cannot add transformer '" + role + "'",
+ getLocation(param));
}
if (this.generator == null) {
- throw new ProcessingException ("Must set a generator before adding transformer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Must set a generator before adding transformer '" + role + "'",
+ getLocation(param));
}
try {
this.transformers.add(this.newManager.lookup(Transformer.ROLE + '/' + role));
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of transformer '"+role+"' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of transformer '"+role+"' failed", ce, getLocation(param));
}
this.transformerSources.add(source);
this.transformerParams.add(param);
@@ -256,23 +255,23 @@
throws ProcessingException {
if (this.serializer != null) {
// Should normally not happen as adding a serializer starts pipeline processing
- throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role + "'",
+ getLocation(param));
}
if (this.reader != null) {
// Should normally never happen as setting a reader starts pipeline processing
- throw new ProcessingException ("Reader already set. Cannot set serializer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Reader already set. Cannot set serializer '" + role + "'",
+ getLocation(param));
}
if (this.generator == null) {
- throw new ProcessingException ("Must set a generator before setting serializer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Must set a generator before setting serializer '" + role + "'",
+ getLocation(param));
}
try {
this.serializer = (Serializer)this.newManager.lookup(Serializer.ROLE + '/' + role);
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of serializer '" + role + "' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of serializer '" + role + "' failed", ce, getLocation(param));
}
this.serializerSource = source;
this.serializerParam = param;
@@ -288,19 +287,19 @@
throws ProcessingException {
if (this.reader != null) {
// Should normally never happen as setting a reader starts pipeline processing
- throw new ProcessingException ("Reader already set. Cannot set reader '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Reader already set. Cannot set reader '" + role + "'",
+ getLocation(param));
}
if (this.generator != null) {
// Should normally never happen as setting a reader starts pipeline processing
- throw new ProcessingException ("Generator already set. Cannot use reader '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Generator already set. Cannot use reader '" + role + "'",
+ getLocation(param));
}
try {
this.reader = (Reader)this.newManager.lookup(Reader.ROLE + '/' + role);
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of reader '"+role+"' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of reader '"+role+"' failed", ce, getLocation(param));
}
this.readerSource = source;
this.readerParam = param;
@@ -367,11 +366,8 @@
this.serializerParam
);
}
-
- } catch (SAXException e) {
- throw new ProcessingException("Could not setup pipeline.", e);
- } catch (IOException e) {
- throw new ProcessingException("Could not setup pipeline.", e);
+ } catch (Exception e) {
+ handleException(e);
}
}
@@ -541,11 +537,8 @@
this.generator.generate();
}
}
- } catch (ProcessingException e) {
- throw e;
} catch (Exception e) {
- // TODO: Unwrap SAXException ?
- throw new ProcessingException("Failed to execute pipeline.", e);
+ handleException(e);
}
return true;
@@ -564,12 +557,8 @@
// should this checking be done somewhere else??
this.expires = readerParam.getParameterAsLong("expires");
}
- } catch (SAXException e){
- throw new ProcessingException("Failed to execute reader pipeline.", e);
- } catch (ParameterException e) {
- throw new ProcessingException("Expires parameter needs to be of type long.",e);
- } catch (IOException e){
- throw new ProcessingException("Failed to execute reader pipeline.", e);
+ } catch (Exception e){
+ handleException(e);
}
}
@@ -855,23 +844,27 @@
return expires;
}
- protected String getLocation(Parameters param) {
- String value = null;
- if ( param instanceof SitemapParameters ) {
- value = ((SitemapParameters)param).getStatementLocation();
+ protected Location getLocation(Parameters param) {
+ Location location = null;
+ if (param instanceof Locatable) {
+ location = ((Locatable)param).getLocation();
}
- if ( value == null ) {
- value = "[unknown location]";
+ if (location == null) {
+ location = Location.UNKNOWN;
}
- return value;
+ return location;
}
/**
* Handles exception which can happen during pipeline processing.
+ * If this not a connection reset, then all locations for pipeline components are
+ * added to the exception.
+ *
* @throws ConnectionResetException if connection reset detected
* @throws ProcessingException in all other cases
*/
protected void handleException(Exception e) throws ProcessingException {
+ // Check if the client aborted the connection
if (e instanceof SocketException) {
if (e.getMessage().indexOf("reset") > 0
|| e.getMessage().indexOf("aborted") > 0
@@ -883,10 +876,26 @@
if (e.getClass().getName().endsWith("ClientAbortException")) {
throw new ConnectionResetException("Connection reset by peer", e);
}
- } else if (e instanceof ProcessingException) {
- throw (ProcessingException) e;
- }
+ } else if (e instanceof ConnectionResetException) {
+ // Exception comes up from a deeper pipeline
+ throw (ConnectionResetException)e;
+ }
+
+ // Not a connection reset: add all location information
+ if (this.reader == null) {
+ // Add all locations in reverse order
+ ArrayList locations = new ArrayList(this.transformers.size() + 2);
+ locations.add(getLocation(this.serializerParam));
+ for (int i = this.transformerParams.size() - 1; i >= 0; i--) {
+ locations.add(getLocation((Parameters)this.transformerParams.get(i)));
+ }
+ locations.add(getLocation(this.generatorParam));
+
+ throw ProcessingException.throwLocated("Failed to process pipeline", e, locations);
- throw new ProcessingException("Error executing pipeline.", e);
+ } else {
+ // Add reader location
+ throw ProcessingException.throwLocated("Failed to process reader", e, getLocation(this.readerParam));
+ }
}
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java Thu Aug 18 11:06:44 2005
@@ -15,38 +15,37 @@
*/
package org.apache.cocoon.components.pipeline;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.context.Context;
-
+import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Processor;
-import org.apache.cocoon.Constants;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.internal.EnvironmentHelper;
import org.apache.cocoon.generation.Generator;
import org.apache.cocoon.serialization.Serializer;
-import org.apache.cocoon.sitemap.SitemapModelComponent;
-import org.apache.cocoon.sitemap.SitemapParameters;
import org.apache.cocoon.sitemap.SitemapErrorHandler;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.xml.SaxBuffer;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLProducer;
-import org.apache.cocoon.xml.SaxBuffer;
-
import org.apache.excalibur.source.SourceValidity;
import org.xml.sax.SAXException;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-
/**
* Pipeline used by virtual pipeline components
*
@@ -157,14 +156,14 @@
public void setGenerator(String role, String source, Parameters param, Parameters hintParam)
throws ProcessingException {
if (this.generator != null) {
- throw new ProcessingException ("Generator already set. Cannot set generator '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Generator already set. Cannot set generator '" + role + "'",
+ getLocation(param));
}
try {
this.generator = (Generator) this.newManager.lookup(Generator.ROLE + '/' + role);
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of generator '" + role + "' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of generator '" + role + "' failed", ce, getLocation(param));
}
this.generatorSource = source;
@@ -186,7 +185,7 @@
try {
this.transformers.add(this.newManager.lookup(Transformer.ROLE + '/' + role));
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of transformer '"+role+"' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of transformer '"+role+"' failed", ce, getLocation(param));
}
this.transformerSources.add(source);
this.transformerParams.add(param);
@@ -200,14 +199,14 @@
throws ProcessingException {
if (this.serializer != null) {
// Should normally not happen as adding a serializer starts pipeline processing
- throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role +
- "' at " + getLocation(param));
+ throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role + "'",
+ getLocation(param));
}
try {
this.serializer = (Serializer)this.newManager.lookup(Serializer.ROLE + '/' + role);
} catch (ServiceException ce) {
- throw new ProcessingException("Lookup of serializer '" + role + "' failed at " + getLocation(param), ce);
+ throw ProcessingException.throwLocated("Lookup of serializer '" + role + "' failed", ce, getLocation(param));
}
this.serializerSource = source;
this.serializerParam = param;
@@ -605,13 +604,13 @@
return null;
}
- protected String getLocation(Parameters param) {
- String value = null;
- if (param instanceof SitemapParameters) {
- value = ((SitemapParameters) param).getStatementLocation();
+ protected Location getLocation(Parameters param) {
+ Location value = null;
+ if (param instanceof Locatable) {
+ value = ((Locatable) param).getLocation();
}
if (value == null) {
- value = "[unknown location]";
+ value = Location.UNKNOWN;
}
return value;
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java Thu Aug 18 11:06:44 2005
@@ -18,6 +18,7 @@
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.cocoon.sitemap.ExecutionContext;
import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.util.location.Location;
/**
*
@@ -29,7 +30,7 @@
extends AbstractLogEnabled
implements ProcessingNode, ExecutionContext {
- protected String location = "unknown location";
+ protected Location location = Location.UNKNOWN;
/** The type of the component */
protected String componentName;
@@ -48,14 +49,14 @@
/**
* Get the location of this node.
*/
- public String getLocation() {
+ public Location getLocation() {
return this.location;
}
/**
* Set the location of this node.
*/
- public void setLocation(String location) {
+ public void setLocation(Location location) {
this.location = location;
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java Thu Aug 18 11:06:44 2005
@@ -15,15 +15,10 @@
*/
package org.apache.cocoon.components.treeprocessor;
-import java.util.Map;
-
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
-import org.apache.cocoon.sitemap.PatternException;
-import org.apache.cocoon.sitemap.SitemapParameters;
/**
*
@@ -52,41 +47,6 @@
*/
protected boolean hasParameters() {
return true;
- }
-
- /**
- * Get <xxx:parameter> elements as a <code>Map</code> of </code>ListOfMapResolver</code>s,
- * that can be turned into parameters using <code>ListOfMapResolver.buildParameters()</code>.
- *
- * @return the Map of ListOfMapResolver, or <code>null</code> if there are no parameters.
- */
- protected Map getParameters(Configuration config) throws ConfigurationException {
- Configuration[] children = config.getChildren("parameter");
-
- if (children.length == 0) {
- // Parameters are only the component's location
- // TODO Optimize this
- return new SitemapParameters.ExtendedHashMap(config);
- }
-
- Map params = new SitemapParameters.ExtendedHashMap(config, children.length+1);
- for (int i = 0; i < children.length; i++) {
- Configuration child = children[i];
- if (true) { // FIXME : check namespace
- String name = child.getAttribute("name");
- String value = child.getAttribute("value");
- try {
- params.put(
- VariableResolverFactory.getResolver(name, this.manager),
- VariableResolverFactory.getResolver(value, this.manager));
- } catch(PatternException pe) {
- String msg = "Invalid pattern '" + value + " at " + child.getLocation();
- throw new ConfigurationException(msg, pe);
- }
- }
- }
-
- return params;
}
/**
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java Thu Aug 18 11:06:44 2005
@@ -46,6 +46,8 @@
import org.apache.cocoon.sitemap.LeaveSitemapEventListener;
import org.apache.cocoon.sitemap.SitemapExecutor;
import org.apache.cocoon.sitemap.SitemapListener;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
import org.apache.commons.jci.monitor.FilesystemAlterationListener;
/**
@@ -535,8 +537,8 @@
/**
* @see org.apache.cocoon.sitemap.ExecutionContext#getLocation()
*/
- public String getLocation() {
- return "Sitemap";
+ public Location getLocation() {
+ return new LocationImpl("[sitemap]", this.wrappingProcessor.source.getURI());
}
/**
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java Thu Aug 18 11:06:44 2005
@@ -24,6 +24,7 @@
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.AbstractConfiguration;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
@@ -43,6 +44,8 @@
import org.apache.cocoon.sitemap.ComponentLocator;
import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
@@ -458,15 +461,16 @@
*/
public ProcessingNode setupNode(ProcessingNode node, Configuration config)
throws Exception {
+ Location location = getLocation(config);
if (node instanceof AbstractProcessingNode) {
- ((AbstractProcessingNode)node).setLocation(config.getLocation());
+ ((AbstractProcessingNode)node).setLocation(location);
((AbstractProcessingNode)node).setSitemapExecutor(this.processor.getSitemapExecutor());
}
this.itsLifecycle.setupComponent(node, false);
if (node instanceof ParameterizableProcessingNode) {
- Map params = getParameters(config);
+ Map params = getParameters(config, location);
((ParameterizableProcessingNode)node).setParameters(params);
}
@@ -481,23 +485,56 @@
return node;
}
+ protected LocationImpl getLocation(Configuration config) {
+ String prefix = "";
+
+ if (config instanceof AbstractConfiguration) {
+ //FIXME: AbstractConfiguration has a _protected_ getPrefix() method.
+ // So make some reasonable guess on the prefix until it becomes public
+ String namespace = null;
+ try {
+ namespace = ((AbstractConfiguration)config).getNamespace();
+ } catch (ConfigurationException e) {
+ // ignore
+ }
+ if ("http://apache.org/cocoon/sitemap/1.0".equals(namespace)) {
+ prefix="map";
+ }
+ }
+
+ StringBuffer desc = new StringBuffer().append('<');
+ if (prefix.length() > 0) {
+ desc.append(prefix).append(':').append(config.getName());
+ } else {
+ desc.append(config.getName());
+ }
+ String type = config.getAttribute("type", null);
+ if (type != null) {
+ desc.append(" type=\"").append(type).append('"');
+ }
+ desc.append('>');
+
+ Location rawLoc = LocationImpl.get(config);
+ return new LocationImpl(desc.toString(), rawLoc.getURI(), rawLoc.getLineNumber(), rawLoc.getColumnNumber());
+ }
+
/**
* Get <xxx:parameter> elements as a <code>Map</code> of </code>ListOfMapResolver</code>s,
* that can be turned into parameters using <code>ListOfMapResolver.buildParameters()</code>.
*
* @return the Map of ListOfMapResolver, or <code>null</code> if there are no parameters.
*/
- protected Map getParameters(Configuration config) throws ConfigurationException {
+ protected Map getParameters(Configuration config, Location location) throws ConfigurationException {
Configuration[] children = config.getChildren("parameter");
if (children.length == 0) {
// Parameters are only the component's location
// TODO Optimize this
- return new SitemapParameters.ExtendedHashMap(config);
+ return new SitemapParameters.LocatedHashMap(location, 0);
}
- Map params = new SitemapParameters.ExtendedHashMap(config, children.length+1);
+ Map params = new SitemapParameters.LocatedHashMap(location, children.length+1);
for (int i = 0; i < children.length; i++) {
Configuration child = children[i];
if (true) { // FIXME : check namespace
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java Thu Aug 18 11:06:44 2005
@@ -132,6 +132,14 @@
this.processingPipelineParameters = parameters;
this.processingPipelineObjectModel = objectModel;
}
+
+ public Parameters getPipelineParameters() {
+ return this.processingPipelineParameters;
+ }
+
+ public String getPipelineType() {
+ return this.processingPipelineName;
+ }
/**
* Get the current <code>ProcessingPipeline</code>
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java Thu Aug 18 11:06:44 2005
@@ -18,14 +18,16 @@
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Id: ProcessingNode.java,v 1.3 2004/05/25 13:30:10 cziegeler Exp $
+ * @version CVS $Id$
*/
-public interface ProcessingNode extends ThreadSafe {
+public interface ProcessingNode extends ThreadSafe, Locatable {
/**
* Process environment.
@@ -35,5 +37,5 @@
/**
* Get the location of this node.
*/
- String getLocation();
+ Location getLocation();
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java Thu Aug 18 11:06:44 2005
@@ -95,10 +95,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, args, redirector);
+ try {
+ interpreter.handleContinuation(continuation, args, redirector);
+ } catch(Exception e) {
+ throw ProcessingException.throwLocated("Sitemap: error calling continuation", e, 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", getLocation());
}
return true;
}
@@ -107,15 +110,18 @@
// the specified function
String name = functionName.resolve(context, objectModel);
if (name != null && name.length() > 0) {
- interpreter.callFunction(name, args, redirector);
+ try {
+ interpreter.callFunction(name, args, redirector);
+ } catch(Exception e) {
+ throw ProcessingException.throwLocated("Sitemap: error calling function '" + name + "'", e, 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", 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>", getLocation());
}
}
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java Thu Aug 18 11:06:44 2005
@@ -30,6 +30,7 @@
import org.apache.cocoon.components.treeprocessor.ProcessingNode;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.sitemap.SitemapParameters;
import java.io.IOException;
import java.util.Map;
@@ -186,6 +187,7 @@
errorContext.enableLogging(getLogger());
errorContext.setRedirector(context.getRedirector());
errorContext.service(this.manager);
+ errorContext.inform(context.getPipelineType(), context.getPipelineParameters(), env.getObjectModel());
try {
// Process error handling node
if (node.invoke(env, errorContext)) {
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java Thu Aug 18 11:06:44 2005
@@ -60,8 +60,8 @@
this.interpreterSelector = (ServiceSelector) manager.lookup(Interpreter.ROLE + "Selector");
// Obtain the Interpreter instance for this language
this.interpreter = (Interpreter) this.interpreterSelector.select(language);
- // Set interpreter ID as location of the flow node (which includes full sitemap file path)
- this.interpreter.setInterpreterID(this.location);
+ // Set interpreter ID as URI of the flow node (full sitemap file path)
+ this.interpreter.setInterpreterID(this.location.getURI());
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java Thu Aug 18 11:06:44 2005
@@ -27,6 +27,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;
/**
@@ -112,6 +113,10 @@
}
// Processor will create its own pipelines
return processor.process(env);
+ } catch(Exception e) {
+ // Wrap with our location
+ throw ProcessingException.throwLocated("Sitemap: error when calling sub-sitemap", e, getLocation());
+
} finally {
// Restore context
env.setURI(oldPrefix, oldURI);
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java Thu Aug 18 11:06:44 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;
@@ -26,7 +27,9 @@
import org.apache.cocoon.components.treeprocessor.ProcessingNode;
import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.PatternException;
import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.util.location.Location;
/**
*
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
@@ -134,7 +137,6 @@
if (! context.isBuildingPipelineOnly()) {
// Process pipeline
return pipeline.process(env);
-
}
// Return true : pipeline is finished.
return true;
Modified: cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java Thu Aug 18 11:06:44 2005
@@ -15,17 +15,18 @@
*/
package org.apache.cocoon.components.treeprocessor.variables;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.cocoon.components.treeprocessor.InvokeContext;
-import org.apache.cocoon.sitemap.PatternException;
-import org.apache.cocoon.sitemap.SitemapParameters;
-
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
/**
* Utility class for handling {...} pattern substitutions in sitemap statements.
*
@@ -54,8 +55,9 @@
VariableResolver other = (VariableResolver)object;
return (this.originalExpr == null && other.originalExpr == null) ||
(this.originalExpr.equals(other.originalExpr));
+ } else {
+ return false;
}
- return false;
}
/**
@@ -85,14 +87,19 @@
* @return a fully resolved <code>Parameters</code>.
*/
public static Parameters buildParameters(Map expressions, InvokeContext context, Map objectModel) throws PatternException {
- if (expressions == null || expressions.size() == 0) {
+ Location location;
+ if (expressions instanceof Locatable) {
+ location = ((Locatable)expressions).getLocation();
+ } else {
+ location = Location.UNKNOWN;
+ }
+
+ if ((expressions == null || expressions.size() == 0) && location.equals(Location.UNKNOWN)) {
return Parameters.EMPTY_PARAMETERS;
}
- SitemapParameters result = new SitemapParameters();
- if ( expressions instanceof SitemapParameters.ExtendedHashMap ) {
- result.setStatementLocation(((SitemapParameters.ExtendedHashMap)expressions).getLocation());
- }
+ SitemapParameters result = new SitemapParameters(location);
+
Iterator iter = expressions.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry)iter.next();
@@ -118,9 +125,8 @@
}
Map result;
- if ( expressions instanceof SitemapParameters.ExtendedHashMap ) {
- Configuration config = ((SitemapParameters.ExtendedHashMap)expressions).getConfiguration();
- result = new SitemapParameters.ExtendedHashMap(config, size );
+ if ( expressions instanceof Locatable ) {
+ result = new SitemapParameters.LocatedHashMap(((Locatable)expressions).getLocation(), size);
} else {
result = new HashMap(size);
}
Added: cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java?rev=233343&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java Thu Aug 18 11:06:44 2005
@@ -0,0 +1,151 @@
+/*
+ * 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.List;
+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.util.location.MultiLocatable;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.commons.lang.SystemUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A generator that dumps an XML representation of the exception raised during a pipeline execution.
+ * <p>
+ * The Cocoon stack trace is produced, reflecting all locations the original exception went through,
+ * along with the root exception stacktrace and the full exception stacktrace.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+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());
+ handler.startElement(EXCEPTION_NS, "exception-report", "ex:exception-report", attr);
+
+ // Root exception location
+ Location loc = ExceptionUtils.getLocation(root);
+ if (loc != null) {
+ attr.clear();
+ dumpLocation(loc, attr, handler);
+ }
+
+ // Root exception message
+ attr.clear();
+ String message = root instanceof LocatableException ? ((LocatableException)root).getRawMessage() : root.getMessage();
+ simpleElement("message", attr, message, handler);
+
+ // Cocoon stacktrace: dump all located exceptions in the exception stack
+ handler.startElement(EXCEPTION_NS, "cocoon-stacktrace", "ex:cocoon-stacktrace", attr);
+ Throwable current = thr;
+ while (current != null) {
+ loc = ExceptionUtils.getLocation(current);
+ if (loc != null) {
+ // One or more locations: dump it
+ handler.startElement(EXCEPTION_NS, "exception", "ex:exception", attr);
+
+ message = current instanceof LocatableException ? ((LocatableException)current).getRawMessage() : current.getMessage();
+ simpleElement("message", attr, message, handler);
+
+ attr.clear();
+ handler.startElement(EXCEPTION_NS, "locations", "ex:locations", attr);
+ dumpLocation(loc, attr, handler);
+
+ if (current instanceof MultiLocatable) {
+ List locations = ((MultiLocatable)current).getLocations();
+ for (int i = 1; i < locations.size(); i++) { // start at 1 because we already dumped the first one
+ attr.clear();
+ dumpLocation((Location)locations.get(i), attr, handler);
+ }
+ }
+ handler.endElement(EXCEPTION_NS, "locations", "ex:locations");
+ handler.endElement(EXCEPTION_NS, "exception", "ex:exception");
+ }
+
+
+ // Dump parent location
+ current = ExceptionUtils.getCause(current);
+ }
+
+ handler.endElement(EXCEPTION_NS, "cocoon-stacktrace", "ex:cocoon-stacktrace");
+
+ // Root exception stacktrace
+ attr.clear();
+ simpleElement("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);
+
+ simpleElement("full-stacktrace", attr, trace, handler);
+ }
+
+ handler.endElement(EXCEPTION_NS, "exception-report", "ex:exception-report");
+ handler.endPrefixMapping("ex");
+ }
+
+ private static void dumpLocation(Location loc, AttributesImpl attr, ContentHandler handler) throws SAXException {
+ attr.addCDATAAttribute("uri", loc.getURI());
+ attr.addCDATAAttribute("line", Integer.toString(loc.getLineNumber()));
+ attr.addCDATAAttribute("column", Integer.toString(loc.getColumnNumber()));
+ simpleElement("location", attr, loc.getDescription(), handler);
+ }
+
+ private static void simpleElement(String name, Attributes attr, String value, ContentHandler handler) throws SAXException {
+ handler.startElement(EXCEPTION_NS, name, "ex:" + name, attr);
+ if (value != null && value.length() > 0) {
+ handler.characters(value.toCharArray(), 0, value.length());
+ }
+ handler.endElement(EXCEPTION_NS, name, "ex:" + name);
+ }
+}
Propchange: cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: cocoon/trunk/src/java/org/apache/cocoon/selection/ExceptionSelector.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/selection/ExceptionSelector.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/selection/ExceptionSelector.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/selection/ExceptionSelector.java Thu Aug 18 11:06:44 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.
@@ -52,7 +52,7 @@
* @author <a href="mailto:bluetkemeier@s-und-n.de">Björn Lütkemeier</a>
* @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
* @since 2.1
- * @version CVS $Id: ExceptionSelector.java,v 1.8 2004/06/24 07:32:53 cziegeler Exp $
+ * @version CVS $Id$
*/
public class ExceptionSelector extends AbstractSwitchSelector implements Configurable {
Modified: cocoon/trunk/src/java/org/apache/cocoon/sitemap/ExecutionContext.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/sitemap/ExecutionContext.java?rev=233343&r1=233342&r2=233343&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/sitemap/ExecutionContext.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/sitemap/ExecutionContext.java Thu Aug 18 11:06:44 2005
@@ -15,6 +15,9 @@
*/
package org.apache.cocoon.sitemap;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
/**
* This context contains information about the current statement that should
@@ -23,14 +26,14 @@
* TODO - This is not finished yet!
*
* @since 2.2
- * @version CVS $Id: ExecutionContext.java,v 1.1 2004/06/09 11:59:23 cziegeler Exp $
+ * @version CVS $Id$
*/
-public interface ExecutionContext {
+public interface ExecutionContext extends Locatable {
/**
* Return the location of the statement in the sitemap.
*/
- String getLocation();
+ Location getLocation();
/**
* Return the component type