1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.webapp;
20
21 import java.io.IOException;
22 import java.lang.reflect.Method;
23 import java.lang.reflect.InvocationTargetException;
24 import java.util.List;
25
26 import javax.faces.FactoryFinder;
27 import javax.faces.FacesException;
28 import javax.faces.context.FacesContext;
29 import javax.faces.context.FacesContextFactory;
30 import javax.faces.lifecycle.Lifecycle;
31 import javax.faces.lifecycle.LifecycleFactory;
32 import javax.servlet.Servlet;
33 import javax.servlet.ServletConfig;
34 import javax.servlet.ServletException;
35 import javax.servlet.ServletRequest;
36 import javax.servlet.ServletResponse;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42
43
44
45
46
47
48
49 public final class FacesServlet
50 implements Servlet
51 {
52 private static final Log log = LogFactory.getLog(FacesServlet.class);
53 public static final String CONFIG_FILES_ATTR = "javax.faces.CONFIG_FILES";
54 public static final String LIFECYCLE_ID_ATTR = "javax.faces.LIFECYCLE_ID";
55
56 private static final String SERVLET_INFO = "FacesServlet of the MyFaces API implementation";
57 private static final String ERROR_HANDLING_PARAMETER = "org.apache.myfaces.ERROR_HANDLING";
58 private static final String ERROR_HANDLER_PARAMETER = "org.apache.myfaces.ERROR_HANDLER";
59 private static final String ERROR_HANDLING_EXCEPTION_LIST = "org.apache.myfaces.errorHandling.exceptionList";
60
61 private ServletConfig _servletConfig;
62 private FacesContextFactory _facesContextFactory;
63 private Lifecycle _lifecycle;
64
65 public FacesServlet()
66 {
67 super();
68 }
69
70 public void destroy()
71 {
72 _servletConfig = null;
73 _facesContextFactory = null;
74 _lifecycle = null;
75 if(log.isTraceEnabled()) log.trace("destroy");
76 }
77
78 public ServletConfig getServletConfig()
79 {
80 return _servletConfig;
81 }
82
83 public String getServletInfo()
84 {
85 return SERVLET_INFO;
86 }
87
88 private String getLifecycleId()
89 {
90 String lifecycleId = _servletConfig.getServletContext().getInitParameter(LIFECYCLE_ID_ATTR);
91 return lifecycleId != null ? lifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
92 }
93
94 public void init(ServletConfig servletConfig)
95 throws ServletException
96 {
97 if(log.isTraceEnabled()) log.trace("init begin");
98 _servletConfig = servletConfig;
99 _facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
100
101
102
103
104 LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
105 _lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
106 if(log.isTraceEnabled()) log.trace("init end");
107 }
108
109 public void service(ServletRequest request,
110 ServletResponse response)
111 throws IOException,
112 ServletException
113 {
114
115 HttpServletRequest httpRequest = ((HttpServletRequest) request);
116 String pathInfo = httpRequest.getPathInfo();
117
118
119 if (pathInfo != null
120 && (pathInfo.startsWith("/WEB-INF") || pathInfo
121 .startsWith("/META-INF")))
122 {
123 StringBuffer buffer = new StringBuffer();
124
125 buffer.append(" Someone is trying to access a secure resource : ").append(pathInfo);
126 buffer.append("\n remote address is ").append(httpRequest.getRemoteAddr());
127 buffer.append("\n remote host is ").append(httpRequest.getRemoteHost());
128 buffer.append("\n remote user is ").append(httpRequest.getRemoteUser());
129 buffer.append("\n request URI is ").append(httpRequest.getRequestURI());
130
131 log.warn(buffer.toString());
132
133
134
135 ((HttpServletResponse) response)
136 .sendError(HttpServletResponse.SC_NOT_FOUND);
137 return;
138 }
139
140 if(log.isTraceEnabled()) log.trace("service begin");
141 FacesContext facesContext = prepareFacesContext(request, response);
142 try {
143 _lifecycle.execute(facesContext);
144
145 if (!handleQueuedExceptions(facesContext))
146 {
147 _lifecycle.render(facesContext);
148 }
149 }
150 catch (Exception e)
151 {
152 handleLifecycleException(facesContext, e);
153 }
154 catch (Throwable e)
155 {
156 handleLifecycleThrowable(facesContext, e);
157 }
158 finally
159 {
160 facesContext.release();
161 }
162 if(log.isTraceEnabled()) log.trace("service end");
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176
177 private boolean handleQueuedExceptions(FacesContext facesContext) throws IOException, ServletException {
178 List li = (List)
179 facesContext.getExternalContext().getRequestMap().get(ERROR_HANDLING_EXCEPTION_LIST);
180
181 if(li != null && li.size()>=1) {
182
183
184
185 boolean errorHandling = getBooleanValue(facesContext.getExternalContext().getInitParameter(ERROR_HANDLING_PARAMETER), true);
186
187 if(errorHandling) {
188 String errorHandlerClass = facesContext.getExternalContext().getInitParameter(ERROR_HANDLER_PARAMETER);
189 if(errorHandlerClass != null) {
190 try {
191 Class clazz = Class.forName(errorHandlerClass);
192
193 Object errorHandler = clazz.newInstance();
194
195 Method m = clazz.getMethod("handleExceptionList", new Class[]{FacesContext.class,Exception.class});
196 m.invoke(errorHandler, new Object[]{facesContext, li});
197 }
198 catch(ClassNotFoundException ex) {
199 throw new ServletException("Error-Handler : " +errorHandlerClass+ " was not found. Fix your web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
200 } catch (IllegalAccessException ex) {
201 throw new ServletException("Constructor of error-Handler : " +errorHandlerClass+ " is not accessible. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
202 } catch (InstantiationException ex) {
203 throw new ServletException("Error-Handler : " +errorHandlerClass+ " could not be instantiated. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
204 } catch (NoSuchMethodException ex) {
205
206
207 throw (FacesException) li.get(0);
208 } catch (InvocationTargetException ex) {
209 throw new ServletException("Excecution of method handleException in Error-Handler : " +errorHandlerClass+ " threw an exception. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
210 }
211 }
212 else {
213 _ErrorPageWriter.handleExceptionList(facesContext, li);
214 }
215 }
216 else {
217 _ErrorPageWriter.throwException((Exception) li.get(0));
218 }
219 return true;
220 }
221 return false;
222 }
223
224 private void handleLifecycleException(FacesContext facesContext, Exception e) throws IOException, ServletException {
225
226 boolean errorHandling = getBooleanValue(facesContext.getExternalContext().getInitParameter(ERROR_HANDLING_PARAMETER), true);
227
228 if(errorHandling) {
229 String errorHandlerClass = facesContext.getExternalContext().getInitParameter(ERROR_HANDLER_PARAMETER);
230 if(errorHandlerClass != null) {
231 try {
232 Class clazz = Class.forName(errorHandlerClass);
233
234 Object errorHandler = clazz.newInstance();
235
236 Method m = clazz.getMethod("handleException", new Class[]{FacesContext.class,Exception.class});
237 m.invoke(errorHandler, new Object[]{facesContext, e});
238 }
239 catch(ClassNotFoundException ex) {
240 throw new ServletException("Error-Handler : " +errorHandlerClass+ " was not found. Fix your web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
241 } catch (IllegalAccessException ex) {
242 throw new ServletException("Constructor of error-Handler : " +errorHandlerClass+ " is not accessible. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
243 } catch (InstantiationException ex) {
244 throw new ServletException("Error-Handler : " +errorHandlerClass+ " could not be instantiated. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
245 } catch (NoSuchMethodException ex) {
246 log.error("Error-Handler : " +errorHandlerClass+ " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
247
248 handleLifecycleThrowable(facesContext, e);
249 } catch (InvocationTargetException ex) {
250 throw new ServletException("Excecution of method handleException in Error-Handler : " +errorHandlerClass+ " threw an exception. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
251 }
252 }
253 else {
254 _ErrorPageWriter.handleException(facesContext, e);
255 }
256 }
257 else {
258 _ErrorPageWriter.throwException(e);
259 }
260 }
261
262 private void handleLifecycleThrowable(FacesContext facesContext, Throwable e) throws IOException, ServletException {
263
264 boolean errorHandling = getBooleanValue(facesContext.getExternalContext().getInitParameter(ERROR_HANDLING_PARAMETER), true);
265
266 if(errorHandling) {
267 String errorHandlerClass = facesContext.getExternalContext().getInitParameter(ERROR_HANDLER_PARAMETER);
268 if(errorHandlerClass != null) {
269 try {
270 Class clazz = Class.forName(errorHandlerClass);
271
272 Object errorHandler = clazz.newInstance();
273
274 Method m = clazz.getMethod("handleThrowable", new Class[]{FacesContext.class,Throwable.class});
275 m.invoke(errorHandler, new Object[]{facesContext, e});
276 }
277 catch(ClassNotFoundException ex) {
278 throw new ServletException("Error-Handler : " +errorHandlerClass+ " was not found. Fix your web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
279 } catch (IllegalAccessException ex) {
280 throw new ServletException("Constructor of error-Handler : " +errorHandlerClass+ " is not accessible. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
281 } catch (InstantiationException ex) {
282 throw new ServletException("Error-Handler : " +errorHandlerClass+ " could not be instantiated. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
283 } catch (NoSuchMethodException ex) {
284 throw new ServletException("Error-Handler : " +errorHandlerClass+ " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
285 } catch (InvocationTargetException ex) {
286 throw new ServletException("Excecution of method handleException in Error-Handler : " +errorHandlerClass+ " threw an exception. Error-Handler is specified in web.xml-parameter : "+ERROR_HANDLER_PARAMETER,ex);
287 }
288 }
289 else {
290 _ErrorPageWriter.handleThrowable(facesContext, e);
291 }
292 }
293 else {
294 _ErrorPageWriter.throwException(e);
295 }
296 }
297
298 private static boolean getBooleanValue(String initParameter, boolean defaultVal) {
299
300 if(initParameter == null || initParameter.trim().length()==0)
301 return defaultVal;
302
303 return (initParameter.equalsIgnoreCase("on") || initParameter.equals("1") || initParameter.equalsIgnoreCase("true"));
304 }
305
306 private FacesContext prepareFacesContext(ServletRequest request, ServletResponse response) {
307 FacesContext facesContext
308 = _facesContextFactory.getFacesContext(_servletConfig.getServletContext(),
309 request,
310 response,
311 _lifecycle);
312 return facesContext;
313 }
314 }