Coverage Report - org.apache.myfaces.lifecycle.ClientConfig
 
Classes in this File Line Coverage Branch Coverage Complexity
ClientConfig
0%
0/39
0%
0/34
5.75
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.lifecycle;
 20  
 
 21  
 
 22  
 import javax.faces.context.FacesContext;
 23  
 import java.io.Serializable;
 24  
 import javax.servlet.http.Cookie;
 25  
 import javax.servlet.http.HttpServletResponse;
 26  
 import java.util.Map;
 27  
 
 28  
 /**
 29  
  * Contains information about whether the user has
 30  
  * JavaScript enabled on his client, etc.
 31  
  * It also contains the windowhandler html which gets sent to
 32  
  * the browser to detect the current windowId.
 33  
  *
 34  
  * This allows the 'customisation' of this html file to e.g.
 35  
  * adopt the background colour to avoid screen flickering.
 36  
  *
 37  
  * Please note that all subclasses of ClientConfig should also
 38  
  * be @SessionScoped as well!
 39  
  */
 40  0
 public class ClientConfig implements Serializable
 41  
 {
 42  
     private static final long serialVersionUID = 581351549574404793L;
 43  
 
 44  
     /** We will set a cookie with this very name if a noscript link got clicked by the user */
 45  
     public static final String COOKIE_NAME_NOSCRIPT_ENABLED = "mfNoScriptEnabled";
 46  
 
 47  0
     private volatile Boolean javaScriptEnabled = null;
 48  
 
 49  
     protected String windowHandlerHtml;
 50  
 
 51  
     /** lazily initiated via {@link #getUserAgent(javax.faces.context.FacesContext)} */
 52  0
     private volatile String userAgent = null;
 53  
 
 54  
     /**
 55  
      * The location of the default windowhandler resource
 56  
      */
 57  
     //private static final String DEFAULT_WINDOW_HANDLER_HTML_FILE = "static/windowhandler.html";
 58  
 
 59  
     /**
 60  
      * Defaults to <code>true</code>.
 61  
      * @return if the user has JavaScript enabled
 62  
      */
 63  
     public boolean isJavaScriptEnabled()
 64  
     {
 65  0
         if (javaScriptEnabled == null)
 66  
         {
 67  0
             synchronized(this)
 68  
             {
 69  
                 // double lock checking idiom on volatile variable works since java5
 70  0
                 if (javaScriptEnabled == null)
 71  
                 {
 72  
                     // no info means that it is default -> true
 73  0
                     javaScriptEnabled = Boolean.TRUE;
 74  
 
 75  0
                     FacesContext facesContext = FacesContext.getCurrentInstance();
 76  0
                     if (facesContext != null)
 77  
                     {
 78  0
                         Cookie cookie = (Cookie) facesContext.getExternalContext().
 79  
                                 getRequestCookieMap().get(COOKIE_NAME_NOSCRIPT_ENABLED);
 80  0
                         if (cookie!= null)
 81  
                         {
 82  0
                             javaScriptEnabled = Boolean.parseBoolean((String) cookie.getValue());
 83  
                         }
 84  
                     }
 85  
                 }
 86  0
             }
 87  
         }
 88  0
         return javaScriptEnabled;
 89  
     }
 90  
 
 91  
     /**
 92  
      * Set it to <code>false</code> if you don't like to use the
 93  
      * JavaScript based client side windowhandler. In this case
 94  
      * the request will be returned directly.
 95  
      * @param javaScriptEnabled
 96  
      */
 97  
     public void setJavaScriptEnabled(boolean javaScriptEnabled)
 98  
     {
 99  0
         this.javaScriptEnabled = javaScriptEnabled;
 100  
 
 101  
         // and now also store this information inside a cookie!
 102  0
         FacesContext facesContext = FacesContext.getCurrentInstance();
 103  0
         if (facesContext != null)
 104  
         {
 105  0
             Object r = facesContext.getExternalContext().getResponse();
 106  0
             if (r instanceof HttpServletResponse)
 107  
             {
 108  0
                 Cookie cookie = new Cookie(COOKIE_NAME_NOSCRIPT_ENABLED, "" + javaScriptEnabled);
 109  0
                 cookie.setPath("/"); // for all the server
 110  0
                 HttpServletResponse response = (HttpServletResponse) r;
 111  0
                 response.addCookie(cookie);
 112  
             }
 113  
         }
 114  0
     }
 115  
 
 116  
     /**
 117  
      * For branding the whole windowhandler page - e.g. not only change the
 118  
      * background color, add some images and empty menu structure
 119  
      * or the language of the message text - you can just copy the content of the
 120  
      * {@link #DEFAULT_WINDOW_HANDLER_HTML_FILE} and adopt it to your needs.
 121  
      *
 122  
      * The reason for this is to minimize visual side effects on browsers who do
 123  
      * not properly support html5 localstorage.
 124  
      *
 125  
      * @return the location of the <i>windowhandler.html</i> resource
 126  
      *         which should be sent to the users browser.
 127  
      */
 128  
     /*
 129  
     public String getWindowHandlerResourceLocation()
 130  
     {
 131  
         return DEFAULT_WINDOW_HANDLER_HTML_FILE;
 132  
     }*/
 133  
 
 134  
     /**
 135  
      * This might return different windowhandlers based on user settings like
 136  
      * his language, an affiliation, etc
 137  
      * @return a String containing the whole windowhandler.html file.
 138  
      * @throws IOException
 139  
      */
 140  
     /*
 141  
     public String getWindowHandlerHtml() throws IOException
 142  
     {
 143  
         if (FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Development) 
 144  
                 && windowHandlerHtml != null)
 145  
         {
 146  
             // use cached windowHandlerHtml except in Development
 147  
             return windowHandlerHtml;
 148  
         }
 149  
 
 150  
         InputStream is = ClassUtils.getContextClassLoader().getResourceAsStream(
 151  
                 getWindowHandlerResourceLocation());
 152  
         StringBuffer sb = new StringBuffer();
 153  
         try
 154  
         {
 155  
             byte[] buf = new byte[16 * 1024];
 156  
             int bytesRead;
 157  
             while ((bytesRead = is.read(buf)) != -1)
 158  
             {
 159  
                 String sbuf = new String(buf, 0, bytesRead);
 160  
                 sb.append(sbuf);
 161  
             }
 162  
         }
 163  
         finally
 164  
         {
 165  
             is.close();
 166  
         }
 167  
 
 168  
         windowHandlerHtml = sb.toString();
 169  
 
 170  
         return windowHandlerHtml;
 171  
     }*/
 172  
 
 173  
 
 174  
     /**
 175  
      * This information will get stored as it cannot
 176  
      * change during the session anyway.
 177  
      * @return the UserAgent of the request.
 178  
      */
 179  
     public String getUserAgent(FacesContext facesContext)
 180  
     {
 181  0
         if (userAgent == null)
 182  
         {
 183  0
             synchronized (this)
 184  
             {
 185  0
                 if (userAgent == null)
 186  
                 {
 187  0
                     Map<String, String[]> requestHeaders =
 188  
                             facesContext.getExternalContext().getRequestHeaderValuesMap();
 189  
 
 190  0
                     if (requestHeaders != null &&
 191  
                             requestHeaders.containsKey("User-Agent"))
 192  
                     {
 193  0
                         String[] userAgents = requestHeaders.get("User-Agent");
 194  0
                         userAgent = userAgents.length > 0 ? userAgents[0] : null;
 195  
                     }
 196  
                 }
 197  0
             }
 198  
         }
 199  
 
 200  0
         return userAgent;
 201  
     }
 202  
 
 203  
     /**
 204  
      * Users can overload this method to define in which scenarios a request should result
 205  
      * in an 'intercepted' page with proper windowId detection. This can e.g. contain
 206  
      * blacklisting some userAgents.
 207  
      * By default the following User-Agents will be served directly:
 208  
      * <ul>
 209  
      *     <li>.*bot.*</li>
 210  
      *     <li>.*Bot.*</li>
 211  
      *     <li>.*Slurp.*</li>
 212  
      *     <li>.*Crawler.*</li>
 213  
      * </ul>
 214  
      * @return <code>true</code> if the Request should get 'intercepted' and the intermediate
 215  
      *        windowhandler.html page should get rendered first. By returning <code>false</code>
 216  
      *        the requested page will get rendered intermediately.
 217  
      * @see #getUserAgent(javax.faces.context.FacesContext) for determining the UserAgent
 218  
      */
 219  
     public boolean isClientSideWindowHandlerRequest(FacesContext facesContext)
 220  
     {
 221  0
         if (!isJavaScriptEnabled())
 222  
         {
 223  0
             return false;
 224  
         }
 225  
 
 226  0
         String userAgent = getUserAgent(facesContext);
 227  
 
 228  0
         if (userAgent != null &&
 229  
             ( userAgent.indexOf("bot")     >= 0 || // Googlebot, etc
 230  
               userAgent.indexOf("Bot")     >= 0 || // BingBot, etc
 231  
               userAgent.indexOf("Slurp")   >= 0 || // Yahoo Slurp
 232  
               userAgent.indexOf("Crawler") >= 0    // various other Crawlers
 233  
             ) )
 234  
         {
 235  0
             return false;
 236  
         }
 237  
 
 238  0
         return true;
 239  
     }
 240  
 
 241  
 }