Coverage Report - org.seasar.teeda.core.application.ViewHandlerImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ViewHandlerImpl
64%
103/161
59%
61/104
4
 
 1  
 /*
 2  
  * Copyright 2004-2011 the Seasar Foundation and the Others.
 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,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.teeda.core.application;
 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.StateManager;
 26  
 import javax.faces.application.ViewHandler;
 27  
 import javax.faces.component.UIViewRoot;
 28  
 import javax.faces.context.ExternalContext;
 29  
 import javax.faces.context.FacesContext;
 30  
 import javax.faces.internal.FacesConfigOptions;
 31  
 import javax.faces.internal.RenderPreparableUtil;
 32  
 import javax.faces.render.RenderKitFactory;
 33  
 import javax.portlet.PortletURL;
 34  
 import javax.portlet.RenderResponse;
 35  
 import javax.servlet.ServletRequest;
 36  
 import javax.servlet.ServletResponse;
 37  
 import javax.servlet.http.HttpServletResponse;
 38  
 import javax.servlet.http.HttpSession;
 39  
 import javax.servlet.jsp.jstl.core.Config;
 40  
 
 41  
 import org.seasar.framework.util.AssertionUtil;
 42  
 import org.seasar.framework.util.StringUtil;
 43  
 import org.seasar.teeda.core.JsfConstants;
 44  
 import org.seasar.teeda.core.config.webapp.element.ServletMappingElement;
 45  
 import org.seasar.teeda.core.config.webapp.element.WebappConfig;
 46  
 import org.seasar.teeda.core.portlet.FacesPortlet;
 47  
 import org.seasar.teeda.core.util.PortletUtil;
 48  
 import org.seasar.teeda.core.util.ServletExternalContextUtil;
 49  
 import org.seasar.teeda.core.util.StateManagerUtil;
 50  
 import org.seasar.teeda.core.util.WebappConfigUtil;
 51  
 
 52  
 /**
 53  
  * @author higa
 54  
  * @author shot
 55  
  */
 56  
 public class ViewHandlerImpl extends ViewHandler {
 57  
 
 58  31
     public ViewHandlerImpl() {
 59  31
     }
 60  
 
 61  
     public Locale calculateLocale(FacesContext context) {
 62  3
         AssertionUtil.assertNotNull("context", context);
 63  2
         Locale supportedLocale = getLocaleFromSupportedLocales(context);
 64  2
         if (supportedLocale != null) {
 65  1
             return supportedLocale;
 66  
         }
 67  1
         Locale defaultLocale = getLocaleFromDefaultLocale(context);
 68  1
         if (defaultLocale != null) {
 69  1
             return defaultLocale;
 70  
         }
 71  0
         return Locale.getDefault();
 72  
     }
 73  
 
 74  
     protected Locale getLocaleFromSupportedLocales(FacesContext context) {
 75  4
         Application app = context.getApplication();
 76  4
         for (Iterator locales = context.getExternalContext()
 77  6
                 .getRequestLocales(); locales.hasNext();) {
 78  4
             Locale locale = (Locale) locales.next();
 79  4
             for (Iterator supportedLocales = app.getSupportedLocales(); supportedLocales
 80  5
                     .hasNext();) {
 81  3
                 Locale supportedLocale = (Locale) supportedLocales.next();
 82  3
                 if (isMatchLocale(locale, supportedLocale)) {
 83  2
                     return supportedLocale;
 84  
                 }
 85  
             }
 86  
         }
 87  2
         return null;
 88  
     }
 89  
 
 90  
     protected Locale getLocaleFromDefaultLocale(FacesContext context) {
 91  3
         Locale defaultLocale = context.getApplication().getDefaultLocale();
 92  3
         for (Iterator locales = context.getExternalContext()
 93  4
                 .getRequestLocales(); locales.hasNext();) {
 94  3
             Locale reqLocale = (Locale) locales.next();
 95  3
             if (isMatchLocale(reqLocale, defaultLocale)) {
 96  2
                 return defaultLocale;
 97  
             }
 98  
         }
 99  1
         return null;
 100  
     }
 101  
 
 102  
     protected boolean isMatchLocale(Locale reqLocale, Locale jsfLocale) {
 103  11
         if (reqLocale == null && jsfLocale == null) {
 104  1
             return true;
 105  10
         } else if (reqLocale == null || jsfLocale == null) {
 106  1
             return false;
 107  
         }
 108  9
         if (reqLocale.equals(jsfLocale)) {
 109  5
             return true;
 110  
         }
 111  4
         return reqLocale.getLanguage().equals(jsfLocale.getLanguage())
 112  
                 && StringUtil.isEmpty(jsfLocale.getCountry());
 113  
     }
 114  
 
 115  
     public String calculateRenderKitId(FacesContext context) {
 116  5
         AssertionUtil.assertNotNull("context", context);
 117  4
         String renderKitId = context.getApplication().getDefaultRenderKitId();
 118  4
         if (renderKitId == null) {
 119  2
             renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
 120  
         }
 121  4
         return renderKitId;
 122  
     }
 123  
 
 124  
     public UIViewRoot createView(FacesContext context, String viewId) {
 125  3
         AssertionUtil.assertNotNull("context", context);
 126  2
         Locale locale = null;
 127  2
         String renderKitId = null;
 128  2
         UIViewRoot viewRoot = context.getViewRoot();
 129  2
         if (viewRoot != null) {
 130  1
             locale = viewRoot.getLocale();
 131  1
             renderKitId = viewRoot.getRenderKitId();
 132  
         } else {
 133  1
             locale = calculateLocale(context);
 134  1
             renderKitId = calculateRenderKitId(context);
 135  
         }
 136  2
         viewRoot = (UIViewRoot) context.getApplication().createComponent(
 137  
                 UIViewRoot.COMPONENT_TYPE);
 138  2
         viewRoot.setViewId(viewId);
 139  2
         viewRoot.setLocale(locale);
 140  2
         viewRoot.setRenderKitId(renderKitId);
 141  2
         return viewRoot;
 142  
     }
 143  
 
 144  
     public String getActionURL(FacesContext context, String viewId) {
 145  4
         AssertionUtil.assertNotNull("context", context);
 146  3
         AssertionUtil.assertNotNull("viewId", viewId);
 147  
 
 148  
         // PortletSupport
 149  2
         if (PortletUtil.isRender(context)) {
 150  0
             RenderResponse response = (RenderResponse) context
 151  
                     .getExternalContext().getResponse();
 152  0
             PortletURL url = response.createActionURL();
 153  0
             url.setParameter(FacesPortlet.VIEW_ID, viewId);
 154  0
             return url.toString();
 155  
         }
 156  
 
 157  2
         String path = getViewIdPath(context, viewId);
 158  2
         if (path != null && path.startsWith("/")) {
 159  2
             return context.getExternalContext().getRequestContextPath() + path;
 160  
         } else {
 161  0
             return path;
 162  
         }
 163  
     }
 164  
 
 165  
     public String getResourceURL(FacesContext context, String path) {
 166  4
         AssertionUtil.assertNotNull("context", context);
 167  3
         AssertionUtil.assertNotNull("path", path);
 168  2
         if (path.startsWith("/")) {
 169  1
             return context.getExternalContext().getRequestContextPath() + path;
 170  
         } else {
 171  1
             return path;
 172  
         }
 173  
     }
 174  
 
 175  
     public void renderView(FacesContext context, UIViewRoot viewRoot)
 176  
             throws IOException, FacesException {
 177  0
         AssertionUtil.assertNotNull("context", context);
 178  0
         AssertionUtil.assertNotNull("viewRoot", viewRoot);
 179  0
         RenderPreparableUtil.encodeBeforeForComponent(context, viewRoot);
 180  
 
 181  0
         ExternalContext externalContext = context.getExternalContext();
 182  
 
 183  
         // really need this? 2.5.2.2 on JSF 1.1 and 7.5.2 on JSF(confused....)
 184  0
         ensureResponseLocaleSet(externalContext, viewRoot);
 185  0
         ensureRequestLocaleSet(externalContext, viewRoot);
 186  
         try {
 187  0
             String viewId = convertViewIdIfNeed(context);
 188  0
             context.getViewRoot().setViewId(viewId);
 189  0
             externalContext.dispatch(viewId);
 190  
         } finally {
 191  
             // PortletSupport
 192  0
             if (!PortletUtil.isPortlet(context)) {
 193  0
                 storeResponseCharacterEncoding(externalContext);
 194  
             }
 195  
         }
 196  0
     }
 197  
 
 198  
     // TODO redirect need when viewId could not be identified?
 199  
     public UIViewRoot restoreView(FacesContext context, String viewId) {
 200  1
         AssertionUtil.assertNotNull("context", context);
 201  1
         Application app = context.getApplication();
 202  1
         String renderKitId = calculateRenderKitId(context);
 203  1
         StateManager stateManager = app.getStateManager();
 204  1
         return stateManager.restoreView(context, viewId, renderKitId);
 205  
     }
 206  
 
 207  
     public void writeState(FacesContext context) throws IOException {
 208  1
         AssertionUtil.assertNotNull("context", context);
 209  1
         if (StateManagerUtil.isSavingStateInClient(context)) {
 210  0
             context.getResponseWriter().writeText(JsfConstants.STATE_MARKER,
 211  
                     null);
 212  
         }
 213  1
     }
 214  
 
 215  
     protected String getViewIdPath(FacesContext context, String viewId) {
 216  6
         if (!viewId.startsWith("/")) {
 217  0
             throw new IllegalArgumentException();
 218  
         }
 219  
 
 220  
         // PortletSupport
 221  6
         if (PortletUtil.isPortlet(context)) {
 222  0
             return viewId;
 223  
         }
 224  
 
 225  6
         WebappConfig webappConfig = getWebappConfig(context);
 226  6
         String urlPattern = getUrlPattern(webappConfig, context);
 227  6
         if (urlPattern != null) {
 228  4
             if (urlPattern.startsWith("*.")) {
 229  2
                 urlPattern = urlPattern.substring(1, urlPattern.length());
 230  2
                 if (viewId.endsWith(urlPattern)) {
 231  0
                     return viewId;
 232  
                 } else {
 233  2
                     int index = viewId.lastIndexOf(".");
 234  2
                     if (index >= 0) {
 235  1
                         return viewId.substring(0, index) + urlPattern;
 236  
                     } else {
 237  1
                         return viewId + urlPattern;
 238  
                     }
 239  
                 }
 240  
             } else {
 241  2
                 if (urlPattern.endsWith("/*")) {
 242  0
                     urlPattern = urlPattern.substring(0,
 243  
                             urlPattern.length() - 2);
 244  
                 }
 245  2
                 return urlPattern + viewId;
 246  
             }
 247  
         } else {
 248  2
             return viewId;
 249  
         }
 250  
     }
 251  
 
 252  
     protected String getUrlPattern(WebappConfig webappConfig,
 253  
             FacesContext context) {
 254  8
         String servletPath = context.getExternalContext()
 255  
                 .getRequestServletPath();
 256  8
         String pathInfo = context.getExternalContext().getRequestPathInfo();
 257  8
         List servletMappings = webappConfig.getServletMappingElements();
 258  8
         for (Iterator itr = servletMappings.iterator(); itr.hasNext();) {
 259  7
             ServletMappingElement servletMapping = (ServletMappingElement) itr
 260  
                     .next();
 261  7
             String urlPattern = servletMapping.getUrlPattern();
 262  7
             if ((isExtensionMapping(urlPattern) && pathInfo == null)
 263  
                     || (!isExtensionMapping(urlPattern) && pathInfo != null)) {
 264  5
                 if (isExtensionMapping(urlPattern)) {
 265  2
                     String extension = urlPattern.substring(1, urlPattern
 266  
                             .length());
 267  2
                     if (servletPath.endsWith(extension)
 268  
                             || servletPath.equals(urlPattern)) {
 269  2
                         return urlPattern;
 270  
                     }
 271  
                 } else {
 272  3
                     urlPattern = urlPattern.substring(0,
 273  
                             urlPattern.length() - 2);
 274  3
                     if (servletPath.equals(urlPattern)) {
 275  3
                         return urlPattern;
 276  
                     }
 277  
                 }
 278  
             }
 279  
         }
 280  3
         return null;
 281  
     }
 282  
 
 283  
     protected String convertViewIdIfNeed(FacesContext context) {
 284  0
         WebappConfig webappConfig = getWebappConfig(context);
 285  0
         ExternalContext externalContext = context.getExternalContext();
 286  0
         String viewId = context.getViewRoot().getViewId();
 287  
         // PortletSupport
 288  0
         if (PortletUtil.isPortlet(context)) {
 289  0
             return viewId;
 290  
         }
 291  0
         String urlPattern = getUrlPattern(webappConfig, context);
 292  0
         if (urlPattern != null && isExtensionMapping(urlPattern)) {
 293  0
             String defaultSuffix = externalContext
 294  
                     .getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
 295  0
             String suffix = defaultSuffix != null ? defaultSuffix
 296  
                     : ViewHandler.DEFAULT_SUFFIX;
 297  0
             if (!viewId.endsWith(suffix)) {
 298  0
                 int dot = viewId.lastIndexOf('.');
 299  0
                 if (dot == -1) {
 300  0
                     viewId = viewId + suffix;
 301  
                 } else {
 302  0
                     viewId = viewId.substring(0, dot) + suffix;
 303  
                 }
 304  
             }
 305  
         }
 306  0
         return viewId;
 307  
     }
 308  
 
 309  
     protected WebappConfig getWebappConfig(FacesContext context) {
 310  6
         return WebappConfigUtil.getWebappConfig(context);
 311  
     }
 312  
 
 313  
     protected void ensureResponseLocaleSet(ExternalContext externalContext,
 314  
             UIViewRoot viewRoot) {
 315  0
         if (externalContext.getResponse() instanceof ServletResponse) {
 316  0
             ServletResponse res = (ServletResponse) externalContext
 317  
                     .getResponse();
 318  0
             res.setLocale(viewRoot.getLocale());
 319  
         }
 320  0
     }
 321  
 
 322  
     protected void ensureRequestLocaleSet(ExternalContext externalContext,
 323  
             UIViewRoot viewRoot) {
 324  
         //TODO Config#set(...) seems not to support Portlet API
 325  0
         if (externalContext.getRequest() instanceof ServletRequest) {
 326  0
             Config.set((ServletRequest) externalContext.getRequest(),
 327  
                     Config.FMT_LOCALE, viewRoot.getLocale());
 328  
         }
 329  0
     }
 330  
 
 331  
     protected void storeResponseCharacterEncoding(
 332  
             ExternalContext externalContext) {
 333  
         // Portlet: RenderRequest does not have getCharacterEncoding()
 334  0
         final String pathInfo = externalContext.getRequestPathInfo();
 335  0
         if (!pathInfo.endsWith(FacesConfigOptions.getDefaultSuffix())) {
 336  0
             return;
 337  
         }
 338  0
         if (externalContext.getResponse() instanceof ServletResponse) {
 339  0
             ServletResponse res = (ServletResponse) externalContext
 340  
                     .getResponse();
 341  0
             if (!ServletExternalContextUtil.isHttpServletResponse(res)) {
 342  0
                 return;
 343  
             }
 344  0
             HttpServletResponse httpRes = ServletExternalContextUtil
 345  
                     .getResponse(externalContext);
 346  0
             HttpSession session = (HttpSession) externalContext
 347  
                     .getSession(false);
 348  0
             if (session != null) {
 349  0
                 final String enc = httpRes.getCharacterEncoding();
 350  0
                 session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, enc);
 351  
             }
 352  
         }
 353  0
     }
 354  
 
 355  
     private static boolean isExtensionMapping(String urlPattern) {
 356  17
         return (urlPattern != null) && (urlPattern.startsWith("*."));
 357  
     }
 358  
 }