KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > treeprocessor > sitemap > ErrorHandlerHelper


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.components.treeprocessor.sitemap;
17
18 import org.apache.avalon.framework.component.ComponentException;
19 import org.apache.avalon.framework.component.ComponentManager;
20 import org.apache.avalon.framework.component.Composable;
21 import org.apache.avalon.framework.logger.AbstractLogEnabled;
22 import org.apache.avalon.framework.logger.Logger;
23
24 import org.apache.cocoon.Constants;
25 import org.apache.cocoon.ResourceNotFoundException;
26 import org.apache.cocoon.components.notification.Notifying;
27 import org.apache.cocoon.components.notification.NotifyingBuilder;
28 import org.apache.cocoon.components.pipeline.ProcessingPipeline;
29 import org.apache.cocoon.components.treeprocessor.InvokeContext;
30 import org.apache.cocoon.components.treeprocessor.ProcessingNode;
31 import org.apache.cocoon.environment.Environment;
32 import org.apache.cocoon.environment.ObjectModelHelper;
33
34 import java.io.IOException JavaDoc;
35 import java.util.Map JavaDoc;
36
37 /**
38  * Helps to call error handlers from PipelineNode and PipelinesNode.
39  *
40  * @author <a HREF="mailto:juergen.seitz@basf-it-services.com">J&uuml;rgen Seitz</a>
41  * @author <a HREF="mailto:bluetkemeier@s-und-n.de">Bj&ouml;rn L&uuml;tkemeier</a>
42  * @version $Id: ErrorHandlerHelper.java 161179 2005-04-13 13:24:55Z vgritsenko $
43  */

44 public class ErrorHandlerHelper extends AbstractLogEnabled
45                                 implements Composable {
46
47     private ComponentManager manager;
48
49     /**
50      * Logger for handled errors
51      */

52     protected Logger handledErrorsLogger;
53
54     /**
55      * Error handling node for the ResourceNotFoundException
56      * (deprecated)
57      */

58     private HandleErrorsNode error404;
59
60     /**
61      * Error handling node for all other exceptions
62      */

63     private HandleErrorsNode error500;
64
65     public void enableLogging(Logger logger) {
66         super.enableLogging(logger);
67         this.handledErrorsLogger = logger.getChildLogger("handled-errors");
68     }
69
70     /**
71      * The component manager is used to create notifying builders.
72      */

73     public void compose(ComponentManager manager) {
74         this.manager = manager;
75     }
76
77     void set404Handler(ProcessingNode node) {
78         this.error404 = (HandleErrorsNode) node;
79     }
80
81     void set500Handler(ProcessingNode node) {
82         this.error500 = (HandleErrorsNode) node;
83     }
84
85     /**
86      * @return true if has no error handler nodes set
87      */

88     public boolean isEmpty() {
89         return this.error404 == null && this.error500 == null;
90     }
91
92     public boolean isInternal() {
93         return this.error500 != null && this.error500.isInternal();
94     }
95
96     public boolean isExternal() {
97         return this.error500 != null && this.error500.isExternal();
98     }
99
100     /**
101      * Handle error.
102      */

103     public boolean invokeErrorHandler(Exception JavaDoc ex,
104                                       Environment env,
105                                       InvokeContext context)
106     throws Exception JavaDoc {
107         return prepareErrorHandler(ex, env, context) != null;
108     }
109
110     /**
111      * Prepare error handler for the internal pipeline error handling.
112      *
113      * <p>If building pipeline only, error handling pipeline will be
114      * built and returned. If building and executing pipeline,
115      * error handling pipeline will be built and executed.</p>
116      */

117     public ProcessingPipeline prepareErrorHandler(Exception JavaDoc ex,
118                                                   Environment env,
119                                                   InvokeContext context)
120     throws Exception JavaDoc {
121         boolean internal = !env.isExternal() && !env.isInternalRedirect();
122
123         if (internal && !isInternal()) {
124             // Propagate exception on internal request: No internal handler.
125
throw ex;
126         } else if (!internal && !isExternal()) {
127             // Propagate exception on external request: No external handler.
128
throw ex;
129         } else if (!internal && error404 != null && ex instanceof ResourceNotFoundException) {
130             // Invoke 404-specific handler: Only on external requests. Deprecated.
131
return prepareErrorHandler(error404, ex, env, context);
132         } else if (error500 != null) {
133             // Invoke global handler
134
return prepareErrorHandler(error500, ex, env, context);
135         }
136
137         // Exception was not handled in this error handler, propagate.
138
throw ex;
139     }
140
141     /**
142      * Handle error using specified error handler processing node.
143      */

144     public boolean invokeErrorHandler(ProcessingNode node,
145                                       Exception JavaDoc ex,
146                                       Environment env,
147                                       InvokeContext context)
148     throws Exception JavaDoc {
149         return prepareErrorHandler(node, ex, env, context) != null;
150     }
151
152     /**
153      * Prepare (or execute) error handler using specified error handler
154      * processing node.
155      *
156      * <p>If building pipeline only, error handling pipeline will be
157      * built and returned. If building and executing pipeline,
158      * error handling pipeline will be built and executed.</p>
159      */

160     private ProcessingPipeline prepareErrorHandler(ProcessingNode node,
161                                                    Exception JavaDoc ex,
162                                                    Environment env,
163                                                    InvokeContext context)
164     throws Exception JavaDoc {
165         if (ex instanceof ResourceNotFoundException) {
166             this.handledErrorsLogger.error(ex.getMessage());
167         } else {
168             this.handledErrorsLogger.error(ex.getMessage(), ex);
169         }
170
171         try {
172             prepare(context, env, ex);
173
174             // Create error context
175
InvokeContext errorContext = new InvokeContext(context.isBuildingPipelineOnly());
176             errorContext.enableLogging(getLogger());
177             errorContext.setRedirector(context.getRedirector());
178             errorContext.compose(this.manager);
179             try {
180                 // Process error handling node
181
if (node.invoke(env, errorContext)) {
182                     // Exception was handled.
183
return errorContext.getProcessingPipeline();
184                 }
185             } finally {
186                 errorContext.dispose();
187             }
188         } catch (Exception JavaDoc e) {
189             getLogger().error("An exception occured while handling errors at " + node.getLocation(), e);
190             // Rethrow it: It will either be handled by the parent sitemap or by the environment (e.g. Cocoon servlet)
191
throw e;
192         }
193
194         // Exception was not handled in this error handler, propagate.
195
throw ex;
196     }
197
198     /**
199      * Build notifying object
200      */

201     private void prepare(InvokeContext context, Environment env, Exception JavaDoc ex)
202     throws IOException JavaDoc, ComponentException {
203         Map JavaDoc objectModel = env.getObjectModel();
204         if (objectModel.get(Constants.NOTIFYING_OBJECT) == null) {
205             // error has not been processed by another handler before
206

207             // Try to reset the response to avoid mixing already produced output
208
// and error page.
209
if (!context.isBuildingPipelineOnly()) {
210                 env.tryResetResponse();
211             }
212
213             // Create a Notifying
214
NotifyingBuilder notifyingBuilder = (NotifyingBuilder) this.manager.lookup(NotifyingBuilder.ROLE);
215             Notifying currentNotifying = null;
216             try {
217                 currentNotifying = notifyingBuilder.build(this, ex);
218             } finally {
219                 this.manager.release(notifyingBuilder);
220             }
221
222             // Add it to the object model
223
objectModel.put(Constants.NOTIFYING_OBJECT, currentNotifying);
224
225             // Also add the exception
226
objectModel.put(ObjectModelHelper.THROWABLE_OBJECT, ex);
227         }
228     }
229 }
230
Popular Tags