KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > myfaces > application > jsp > JspViewHandlerImpl


1 /*
2  * Copyright 2004 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.myfaces.application.jsp;
17
18 import java.io.IOException JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Locale JavaDoc;
22
23 import javax.faces.FacesException;
24 import javax.faces.application.Application;
25 import javax.faces.application.ViewHandler;
26 import javax.faces.component.UIViewRoot;
27 import javax.faces.context.ExternalContext;
28 import javax.faces.context.FacesContext;
29 import javax.faces.render.RenderKitFactory;
30 import javax.portlet.PortletURL;
31 import javax.portlet.RenderResponse;
32 import javax.servlet.ServletResponse JavaDoc;
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.http.HttpServletResponse JavaDoc;
35 import javax.servlet.http.HttpSession JavaDoc;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.myfaces.portlet.MyFacesGenericPortlet;
40 import org.apache.myfaces.portlet.PortletUtil;
41 import org.apache.myfaces.util.DebugUtils;
42 import org.apache.myfaces.webapp.webxml.ServletMapping;
43 import org.apache.myfaces.webapp.webxml.WebXml;
44
45 /**
46  * @author Thomas Spiegl (latest modification by $Author: matzew $)
47  * @version $Revision: 1.35 $ $Date: 2005/03/10 15:44:59 $
48  * $Log: JspViewHandlerImpl.java,v $
49  * Revision 1.35 2005/03/10 15:44:59 matzew
50  * Patch for supporting Strut-Faces form Mike Traum (MYFACES-121)
51  *
52  * Revision 1.34 2005/02/10 20:31:21 matzew
53  * organized import statements
54  *
55  * Revision 1.33 2005/02/10 20:24:17 matzew
56  * closed MYFACES-101 in Jira; Thanks to Stan Silvert (JBoss Group)
57  *
58  * Revision 1.32 2005/01/27 02:38:44 svieujot
59  * Remove portlet-api dependency while keeping portlet support.
60  *
61  * Revision 1.31 2005/01/26 17:03:12 matzew
62  * MYFACES-86. portlet support provided by Stan Silver (JBoss Group)
63  *
64  * Revision 1.30 2004/10/13 11:50:59 matze
65  * renamed packages to org.apache
66  *
67  * Revision 1.29 2004/10/05 08:22:55 manolito
68  * #1031187 [PATCH] JspViewHandlerImpl: Remove dep on ServletRequest
69  *
70  * Revision 1.28 2004/09/02 09:04:14 manolito
71  * typing errors in comments
72  *
73  * Revision 1.27 2004/09/01 18:32:55 mwessendorf
74  * Organize Imports
75  *
76  * Revision 1.26 2004/08/11 23:09:35 o_rossmueller
77  * handle character encoding as described in section 2.5.2.2 of JSF 1.1
78  *
79  * Revision 1.25 2004/08/11 22:56:30 o_rossmueller
80  * handle character encoding as described in section 2.5.2.2 of JSF 1.1
81  *
82  * Revision 1.24 2004/07/16 08:34:01 manolito
83  * cosmetic change
84  *
85  * Revision 1.23 2004/07/10 06:35:08 mwessendorf
86  * is defaultRenderKitId set in faces-config.xml ?
87  *
88  * Revision 1.22 2004/07/01 22:05:20 mwessendorf
89  * ASF switch
90  *
91  * Revision 1.21 2004/05/18 12:02:14 manolito
92  * getActionURL and getResourceURL must not call encodeActionURL or encodeResourceURL
93  *
94  * Revision 1.20 2004/05/12 01:41:31 o_rossmueller
95  * fix #951896: added state params to link URLs for ALLOW_JAVASCRIPT=false
96  *
97  * Revision 1.19 2004/04/27 07:37:56 manolito
98  * bugfix: handleCharacterEncoding must be called before any request parameters are retrieved
99  *
100  * Revision 1.18 2004/04/05 09:16:24 manolito
101  * javadoc header
102  *
103  */

104 public class JspViewHandlerImpl
105         extends ViewHandler
106 {
107     private static final Log log = LogFactory.getLog(JspViewHandlerImpl.class);
108     public static final String JavaDoc FORM_STATE_MARKER = "<!--@@JSF_FORM_STATE_MARKER@@-->";
109     public static final int FORM_STATE_MARKER_LEN = FORM_STATE_MARKER.length();
110
111
112     public JspViewHandlerImpl()
113     {
114         if (log.isTraceEnabled()) log.trace("New ViewHandler instance created");
115     }
116
117     public Locale JavaDoc calculateLocale(FacesContext facesContext)
118     {
119         Iterator JavaDoc locales = facesContext.getExternalContext().getRequestLocales();
120         while (locales.hasNext())
121         {
122             Locale JavaDoc locale = (Locale JavaDoc)locales.next();
123             for (Iterator JavaDoc it = facesContext.getApplication().getSupportedLocales(); it.hasNext();)
124             {
125                 Locale JavaDoc supportLocale = (Locale JavaDoc)it.next();
126                 // higher priority to a language match over an exact match
127
// that occures further down (see Jstl Reference 1.0 8.3.1)
128
if (locale.getLanguage().equals(supportLocale.getLanguage()) &&
129                     (supportLocale.getCountry() == null ||
130                      supportLocale.getCountry().length() == 0))
131                 {
132                     return supportLocale;
133                 }
134                 else if (supportLocale.equals(locale))
135                 {
136                     return supportLocale;
137                 }
138             }
139         }
140
141         Locale JavaDoc defaultLocale = facesContext.getApplication().getDefaultLocale();
142         return defaultLocale != null ? defaultLocale : Locale.getDefault();
143     }
144
145     public String JavaDoc calculateRenderKitId(FacesContext facesContext)
146     {
147         String JavaDoc renderKitId = facesContext.getApplication().getDefaultRenderKitId();
148         return (renderKitId!=null) ? renderKitId : RenderKitFactory.HTML_BASIC_RENDER_KIT;
149         //TODO: how to calculate from client?
150
}
151
152     /**
153      */

154     public UIViewRoot createView(FacesContext facesContext, String JavaDoc viewId)
155     {
156         Locale JavaDoc currentLocale = null;
157         String JavaDoc currentRenderKitId = null;
158         UIViewRoot uiViewRoot = facesContext.getViewRoot();
159         if (uiViewRoot != null)
160         {
161             //Remember current locale and renderKitId
162
currentLocale = uiViewRoot.getLocale();
163             currentRenderKitId = uiViewRoot.getRenderKitId();
164         }
165
166         uiViewRoot = (UIViewRoot)facesContext.getApplication().createComponent(UIViewRoot.COMPONENT_TYPE);
167         uiViewRoot.setViewId(viewId);
168
169         if (currentLocale != null)
170         {
171             //set old locale
172
uiViewRoot.setLocale(currentLocale);
173         }
174         else
175         {
176             //calculate locale
177
uiViewRoot.setLocale(calculateLocale(facesContext));
178         }
179
180         if (currentRenderKitId != null)
181         {
182             //set old renderKit
183
uiViewRoot.setRenderKitId(currentRenderKitId);
184         }
185         else
186         {
187             //calculate renderKit
188
uiViewRoot.setRenderKitId(calculateRenderKitId(facesContext));
189         }
190
191         if (log.isTraceEnabled()) log.trace("Created view " + viewId);
192         return uiViewRoot;
193     }
194
195     public String JavaDoc getActionURL(FacesContext facesContext, String JavaDoc viewId)
196     {
197         if (PortletUtil.isRenderResponse(facesContext))
198         {
199             RenderResponse response = (RenderResponse)facesContext.getExternalContext().getResponse();
200             PortletURL url = response.createActionURL();
201             url.setParameter(MyFacesGenericPortlet.VIEW_ID, viewId);
202             return url.toString();
203         }
204         
205         String JavaDoc path = getViewIdPath(facesContext, viewId);
206         if (path.length() > 0 && path.charAt(0) == '/')
207         {
208             return facesContext.getExternalContext().getRequestContextPath() + path;
209         }
210         else
211         {
212             return path;
213         }
214     }
215
216     public String JavaDoc getResourceURL(FacesContext facesContext, String JavaDoc path)
217     {
218         if (path.length() > 0 && path.charAt(0) == '/')
219         {
220             return facesContext.getExternalContext().getRequestContextPath() + path;
221         }
222         else
223         {
224             return path;
225         }
226     }
227
228     public void renderView(FacesContext facesContext, UIViewRoot viewToRender)
229             throws IOException JavaDoc, FacesException
230     {
231         if (viewToRender == null)
232         {
233             log.fatal("viewToRender must not be null");
234             throw new NullPointerException JavaDoc("viewToRender must not be null");
235         }
236
237         ExternalContext externalContext = facesContext.getExternalContext();
238
239         String JavaDoc viewId = facesContext.getViewRoot().getViewId();
240
241         if (PortletUtil.isPortletRequest(facesContext)) {
242             externalContext.dispatch(viewId);
243             return;
244         }
245         
246         ServletMapping servletMapping = getServletMapping(externalContext);
247         if (servletMapping.isExtensionMapping())
248         {
249             String JavaDoc defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
250             String JavaDoc suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
251             DebugUtils.assertError(suffix.charAt(0) == '.',
252                                    log, "Default suffix must start with a dot!");
253             if (!viewId.endsWith(suffix))
254             {
255                 int dot = viewId.lastIndexOf('.');
256                 if (dot == -1)
257                 {
258                     if (log.isTraceEnabled()) log.trace("Current viewId has no extension, appending default suffix " + suffix);
259                     viewId = viewId + suffix;
260                 }
261                 else
262                 {
263                     if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
264                     viewId = viewId.substring(0, dot) + suffix;
265                 }
266                 facesContext.getViewRoot().setViewId(viewId);
267             }
268         }
269
270         if (log.isTraceEnabled()) log.trace("Dispatching to " + viewId);
271
272         // handle character encoding as of section 2.5.2.2 of JSF 1.1
273
if (externalContext.getResponse() instanceof ServletResponse JavaDoc) {
274             ServletResponse JavaDoc response = (ServletResponse JavaDoc) externalContext.getResponse();
275             response.setLocale(viewToRender.getLocale());
276         }
277         
278         // TODO: 2.5.2.2 for Portlet? What do I do?
279

280         externalContext.dispatch(viewId);
281
282         // handle character encoding as of section 2.5.2.2 of JSF 1.1
283
if (externalContext.getRequest() instanceof HttpServletRequest JavaDoc) {
284             HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) externalContext.getResponse();
285             HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) externalContext.getRequest();
286             HttpSession JavaDoc session = request.getSession(false);
287
288             if (session != null) {
289                 session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, response.getCharacterEncoding());
290             }
291         }
292
293     }
294
295
296     public UIViewRoot restoreView(FacesContext facesContext, String JavaDoc viewId)
297     {
298         Application application = facesContext.getApplication();
299         ViewHandler applicationViewHandler = application.getViewHandler();
300         String JavaDoc renderKitId = applicationViewHandler.calculateRenderKitId(facesContext);
301         UIViewRoot viewRoot = application.getStateManager().restoreView(facesContext,
302                                                                         viewId,
303                                                                         renderKitId);
304         return viewRoot;
305     }
306
307     /**
308      * Writes a state marker that is replaced later by one or more hidden form
309      * inputs.
310      * @param facesContext
311      * @throws IOException
312      */

313     public void writeState(FacesContext facesContext) throws IOException JavaDoc
314     {
315         if (facesContext.getApplication().getStateManager().isSavingStateInClient(facesContext))
316         {
317             facesContext.getResponseWriter().write(FORM_STATE_MARKER);
318         }
319     }
320
321
322     protected String JavaDoc getViewIdPath(FacesContext facescontext, String JavaDoc viewId)
323     {
324         if (viewId == null)
325         {
326             log.error("ViewId must not be null");
327             throw new NullPointerException JavaDoc("ViewId must not be null");
328         }
329         if (!viewId.startsWith("/"))
330         {
331             log.error("ViewId must start with '/' (viewId = " + viewId + ")");
332             throw new IllegalArgumentException JavaDoc("ViewId must start with '/' (viewId = " + viewId + ")");
333         }
334
335         if (PortletUtil.isPortletRequest(facescontext))
336         {
337             return viewId;
338         }
339         
340         ServletMapping servletMapping = getServletMapping(facescontext.getExternalContext());
341
342         if (servletMapping.isExtensionMapping())
343         {
344             // extension mapping
345
String JavaDoc urlpattern = servletMapping.getUrlPattern();
346             if (urlpattern.startsWith("*"))
347             {
348                 urlpattern = urlpattern.substring(1, urlpattern.length());
349             }
350             if (viewId.endsWith(urlpattern))
351             {
352                 return viewId;
353             }
354             else
355             {
356                 int idx = viewId.lastIndexOf(".");
357                 if (idx >= 0)
358                 {
359                     return viewId.substring(0, idx) + urlpattern;
360                 }
361                 else
362                 {
363                     return viewId + urlpattern;
364                 }
365
366             }
367         }
368         else
369         {
370             // prefix mapping
371
String JavaDoc urlpattern = servletMapping.getUrlPattern();
372             if (urlpattern.endsWith("/*"))
373             {
374                 urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
375             }
376             return urlpattern + viewId;
377         }
378     }
379
380     private static ServletMapping getServletMapping(ExternalContext externalContext)
381     {
382         String JavaDoc servletPath = externalContext.getRequestServletPath();
383         String JavaDoc requestPathInfo = externalContext.getRequestPathInfo();
384
385         WebXml webxml = WebXml.getWebXml(externalContext);
386         List JavaDoc mappings = webxml.getFacesServletMappings();
387
388         boolean isExtensionMapping = (requestPathInfo == null);
389
390         for (int i = 0, size = mappings.size(); i < size; i++)
391         {
392             ServletMapping servletMapping = (ServletMapping) mappings.get(i);
393             if (servletMapping.isExtensionMapping() == isExtensionMapping)
394             {
395                 String JavaDoc urlpattern = servletMapping.getUrlPattern();
396                 if (isExtensionMapping)
397                 {
398                     String JavaDoc extension = urlpattern.substring(1, urlpattern.length());
399                     if (servletPath.endsWith(extension))
400                     {
401                         return servletMapping;
402                     }
403                 }
404                 else
405                 {
406                     urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
407                     // servletPath starts with "/" except in the case where the
408
// request is matched with the "/*" pattern, in which case
409
// it is the empty string (see Servlet Sepc 2.3 SRV4.4)
410
if (servletPath.equals(urlpattern))
411                     {
412                         return servletMapping;
413                     }
414                 }
415             }
416         }
417
418         // handle cases as best possible where servletPath is not a faces servlet,
419
// such as when coming through struts-faces
420
if (mappings.size() > 0) {
421             return (ServletMapping) mappings.get(0);
422         }
423         else {
424             log.error("no faces servlet mappings found");
425             throw new IllegalArgumentException JavaDoc("could not find pathMapping for servletPath = " + servletPath +
426                       " requestPathInfo = " + requestPathInfo);
427         }
428     }
429
430
431 }
432
Popular Tags