1 //
2 //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
3 //All rights reserved.
4 //
5 //Redistribution and use in source and binary forms, with or without modification,
6 //are permitted provided that the following conditions are met:
7 //
8 //* Redistributions of source code must retain the above copyright notice,
9 //this list of conditions and the following disclaimer.
10 //* Redistributions in binary form must reproduce the above copyright notice,
11 //this list of conditions and the following disclaimer in the documentation
12 //and/or other materials provided with the distribution.
13 //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
14 //nor the names of its contributors may be used to endorse or promote products
15 //derived from this software without specific prior written permission.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 //POSSIBILITY OF SUCH DAMAGE.
27 //
28
29 package org.objectledge.web.mvc;
30
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Map;
34
35 import org.jcontainer.dna.Configuration;
36 import org.jcontainer.dna.Logger;
37 import org.objectledge.ComponentInitializationError;
38 import org.objectledge.context.Context;
39 import org.objectledge.pipeline.ErrorHandlingPipeline;
40 import org.objectledge.pipeline.ProcessingException;
41 import org.objectledge.pipeline.Valve;
42 import org.objectledge.templating.TemplatingContext;
43 import org.objectledge.utils.StackTrace;
44
45 /**
46 * The valve that redirects to a configured view in case of exception.
47 *
48 * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
49 */
50 public class ExceptionRedirectorValve implements Valve
51 {
52 /*** logger the logger */
53 private Logger logger;
54
55 /*** error view */
56 private String errorView;
57
58 /*** error log level */
59 private String errorLevel;
60
61 /*** exception - view mapping */
62 private Map exceptionViewMap;
63
64 /*** exception - log level mapping */
65 private Map exceptionLoggingLevelMap;
66
67 /***
68 * Component constructor.
69 *
70 * @param config the configuration.
71 * @param logger the logger.
72 */
73 public ExceptionRedirectorValve(Configuration config, Logger logger)
74 {
75 this.logger = logger;
76 Object sessions = null;
77 exceptionViewMap = new HashMap();
78 exceptionLoggingLevelMap = new HashMap();
79
80 try
81 {
82 errorView = config.getChild("error_view").getValue("Error");
83 errorLevel = config.getChild("error_level").getValue("ERROR");
84 Configuration[] exception = config.getChildren("exception");
85 for (int i = 0; i < exception.length; i++)
86 {
87 String name = exception[i].getAttribute("class");
88 String view = exception[i].getAttribute("view");
89 String level = exception[i].getAttribute("level");
90 Class clazz = Class.forName(name);
91 exceptionViewMap.put(clazz, view);
92 exceptionLoggingLevelMap.put(clazz, level);
93 }
94 if (!exceptionViewMap.containsKey(Throwable.class))
95 {
96 exceptionViewMap.put(Throwable.class, errorView);
97 exceptionLoggingLevelMap.put(Throwable.class, errorLevel);
98 }
99 }
100 ///CLOVER:OFF
101 catch (Exception e)
102 {
103 throw new ComponentInitializationError(e);
104 }
105 ///CLOVER:ON
106 }
107
108 /***
109 * {@inheritDoc}
110 */
111 public void process(Context context) throws ProcessingException
112 {
113 MVCContext mvcContext = MVCContext.getMVCContext(context);
114 Throwable t = (Throwable)context.getAttribute(ErrorHandlingPipeline.PIPELINE_EXCEPTION);
115 if (t != null)
116 {
117
118 Class leafException = null;
119 Iterator i = exceptionViewMap.keySet().iterator();
120 while (i.hasNext())
121 {
122 Class temp = (Class)i.next();
123 if (temp.isAssignableFrom(t.getClass()))
124 {
125 if (leafException == null || leafException.isAssignableFrom(temp))
126 {
127 leafException = temp;
128 }
129 }
130 }
131 log((String)exceptionLoggingLevelMap.get(leafException), t);
132 String view = (String)exceptionViewMap.get(leafException);
133 TemplatingContext templatingContext = TemplatingContext.getTemplatingContext(context);
134 if (templatingContext != null)
135 {
136 templatingContext.put("originalView", mvcContext.getView());
137 templatingContext.put("stackTrace", new StackTrace(t).toString());
138 }
139 mvcContext.setView(view);
140 }
141 }
142
143 private void log(String verbosity, Throwable t)
144 {
145 if (verbosity.equals("WARN"))
146 {
147 logger.warn("Exception occured during processing", t);
148 return;
149 }
150 if (verbosity.equals("INFO"))
151 {
152 logger.info("Exception occured during processing", t);
153 return;
154 }
155 if (verbosity.equals("DEBUG"))
156 {
157 logger.debug("Exception occured during processing", t);
158 return;
159 }
160 if (verbosity.equals("TRACE"))
161 {
162 logger.trace("Exception occured during processing", t);
163 return;
164 }
165 logger.error("Exception occured during processing", t);
166 }
167 }