1 16 package org.apache.myfaces.application.jsp; 17 18 import java.io.IOException ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Locale ; 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 ; 33 import javax.servlet.http.HttpServletRequest ; 34 import javax.servlet.http.HttpServletResponse ; 35 import javax.servlet.http.HttpSession ; 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 104 public class JspViewHandlerImpl 105 extends ViewHandler 106 { 107 private static final Log log = LogFactory.getLog(JspViewHandlerImpl.class); 108 public static final String 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 calculateLocale(FacesContext facesContext) 118 { 119 Iterator locales = facesContext.getExternalContext().getRequestLocales(); 120 while (locales.hasNext()) 121 { 122 Locale locale = (Locale )locales.next(); 123 for (Iterator it = facesContext.getApplication().getSupportedLocales(); it.hasNext();) 124 { 125 Locale supportLocale = (Locale )it.next(); 126 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 defaultLocale = facesContext.getApplication().getDefaultLocale(); 142 return defaultLocale != null ? defaultLocale : Locale.getDefault(); 143 } 144 145 public String calculateRenderKitId(FacesContext facesContext) 146 { 147 String renderKitId = facesContext.getApplication().getDefaultRenderKitId(); 148 return (renderKitId!=null) ? renderKitId : RenderKitFactory.HTML_BASIC_RENDER_KIT; 149 } 151 152 154 public UIViewRoot createView(FacesContext facesContext, String viewId) 155 { 156 Locale currentLocale = null; 157 String currentRenderKitId = null; 158 UIViewRoot uiViewRoot = facesContext.getViewRoot(); 159 if (uiViewRoot != null) 160 { 161 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 uiViewRoot.setLocale(currentLocale); 173 } 174 else 175 { 176 uiViewRoot.setLocale(calculateLocale(facesContext)); 178 } 179 180 if (currentRenderKitId != null) 181 { 182 uiViewRoot.setRenderKitId(currentRenderKitId); 184 } 185 else 186 { 187 uiViewRoot.setRenderKitId(calculateRenderKitId(facesContext)); 189 } 190 191 if (log.isTraceEnabled()) log.trace("Created view " + viewId); 192 return uiViewRoot; 193 } 194 195 public String getActionURL(FacesContext facesContext, String 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 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 getResourceURL(FacesContext facesContext, String 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 , FacesException 230 { 231 if (viewToRender == null) 232 { 233 log.fatal("viewToRender must not be null"); 234 throw new NullPointerException ("viewToRender must not be null"); 235 } 236 237 ExternalContext externalContext = facesContext.getExternalContext(); 238 239 String 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 defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME); 250 String 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 if (externalContext.getResponse() instanceof ServletResponse ) { 274 ServletResponse response = (ServletResponse ) externalContext.getResponse(); 275 response.setLocale(viewToRender.getLocale()); 276 } 277 278 280 externalContext.dispatch(viewId); 281 282 if (externalContext.getRequest() instanceof HttpServletRequest ) { 284 HttpServletResponse response = (HttpServletResponse ) externalContext.getResponse(); 285 HttpServletRequest request = (HttpServletRequest ) externalContext.getRequest(); 286 HttpSession 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 viewId) 297 { 298 Application application = facesContext.getApplication(); 299 ViewHandler applicationViewHandler = application.getViewHandler(); 300 String renderKitId = applicationViewHandler.calculateRenderKitId(facesContext); 301 UIViewRoot viewRoot = application.getStateManager().restoreView(facesContext, 302 viewId, 303 renderKitId); 304 return viewRoot; 305 } 306 307 313 public void writeState(FacesContext facesContext) throws IOException 314 { 315 if (facesContext.getApplication().getStateManager().isSavingStateInClient(facesContext)) 316 { 317 facesContext.getResponseWriter().write(FORM_STATE_MARKER); 318 } 319 } 320 321 322 protected String getViewIdPath(FacesContext facescontext, String viewId) 323 { 324 if (viewId == null) 325 { 326 log.error("ViewId must not be null"); 327 throw new NullPointerException ("ViewId must not be null"); 328 } 329 if (!viewId.startsWith("/")) 330 { 331 log.error("ViewId must start with '/' (viewId = " + viewId + ")"); 332 throw new IllegalArgumentException ("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 String 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 String 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 servletPath = externalContext.getRequestServletPath(); 383 String requestPathInfo = externalContext.getRequestPathInfo(); 384 385 WebXml webxml = WebXml.getWebXml(externalContext); 386 List 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 urlpattern = servletMapping.getUrlPattern(); 396 if (isExtensionMapping) 397 { 398 String 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 if (servletPath.equals(urlpattern)) 411 { 412 return servletMapping; 413 } 414 } 415 } 416 } 417 418 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 ("could not find pathMapping for servletPath = " + servletPath + 426 " requestPathInfo = " + requestPathInfo); 427 } 428 } 429 430 431 } 432 | Popular Tags |