Coverage Report - org.apache.myfaces.application.viewstate.ClientSideStateCacheImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ClientSideStateCacheImpl
0%
0/47
0%
0/38
4.429
 
 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.application.viewstate;
 20  
 
 21  
 import javax.faces.context.ExternalContext;
 22  
 import javax.faces.context.FacesContext;
 23  
 
 24  
 import org.apache.myfaces.application.StateCache;
 25  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 26  
 import org.apache.myfaces.shared.util.WebConfigParamUtils;
 27  
 
 28  
 class ClientSideStateCacheImpl extends StateCache<Object, Object>
 29  
 {
 30  
     
 31  
     /**
 32  
      * Define the time in minutes where the view state is valid when
 33  
      * client side state saving is used. By default it is set to 0
 34  
      * (infinite).
 35  
      */
 36  
     @JSFWebConfigParam(since="2.1.9, 2.0.15", defaultValue="0", group="state")
 37  
     public static final String INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT = 
 38  
             "org.apache.myfaces.CLIENT_VIEW_STATE_TIMEOUT";
 39  0
     public static final Long INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT = 0L;
 40  
     
 41  
     private static final int STATE_PARAM = 0;
 42  
     private static final int VIEWID_PARAM = 1;
 43  
     private static final int TIMESTAMP_PARAM = 2;
 44  
     
 45  0
     private static final Object[] EMPTY_STATES = new Object[]{null, null};
 46  
     
 47  
     private Long _clientViewStateTimeout;
 48  
     
 49  
     private CsrfSessionTokenFactory csrfSessionTokenFactory;
 50  
     
 51  
     public ClientSideStateCacheImpl()
 52  0
     {
 53  0
         FacesContext facesContext = FacesContext.getCurrentInstance();
 54  
         
 55  0
         String csrfRandomMode = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
 56  
                 RANDOM_KEY_IN_CSRF_SESSION_TOKEN_PARAM, 
 57  
                 RANDOM_KEY_IN_CSRF_SESSION_TOKEN_PARAM_DEFAULT);
 58  0
         if (RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM.equals(csrfRandomMode))
 59  
         {
 60  0
             csrfSessionTokenFactory = new SecureRandomCsrfSessionTokenFactory(facesContext);
 61  
         }
 62  
         else
 63  
         {
 64  0
             csrfSessionTokenFactory = new RandomCsrfSessionTokenFactory(facesContext);
 65  
         }
 66  0
     }
 67  
 
 68  
     @Override
 69  
     public Object saveSerializedView(FacesContext facesContext,
 70  
             Object serializedView)
 71  
     {
 72  
         // The state in this case the state is saved on the token sent to
 73  
         // the client (isWriteStateAfterRenderViewRequired() is set to true).
 74  
         // No additional operation is required here.
 75  0
         return encodeSerializedState(facesContext, serializedView);
 76  
     }
 77  
 
 78  
     @Override
 79  
     public Object restoreSerializedView(FacesContext facesContext,
 80  
             String viewId, Object viewState)
 81  
     {
 82  0
         Object[] state = (Object[]) viewState;
 83  0
         long clientViewStateTimeout = getClientViewStateTimeout(facesContext.getExternalContext());
 84  
         
 85  0
         if (clientViewStateTimeout > 0L)
 86  
         {
 87  0
             Long timeStamp = (Long) state[TIMESTAMP_PARAM];
 88  0
             if (timeStamp == null)
 89  
             {
 90  
                 //If no timestamp, state is invalid.
 91  0
                 return null;
 92  
             }
 93  0
             long passedTime = (System.currentTimeMillis() - timeStamp.longValue()) / 60000;
 94  
             
 95  0
             if (passedTime > clientViewStateTimeout)
 96  
             {
 97  
                 //expire
 98  0
                 return null;
 99  
             }
 100  
         }
 101  
         
 102  0
         String restoredViewId = (String) state[VIEWID_PARAM];
 103  
         
 104  0
         if (viewId != null && !viewId.equals(restoredViewId))
 105  
         {
 106  
             //invalid viewId, expire
 107  0
             return null;
 108  
         }
 109  
         
 110  
         //return the state
 111  0
         if (state[STATE_PARAM] == null)
 112  
         {
 113  0
             return EMPTY_STATES;
 114  
         }
 115  
         else
 116  
         {
 117  0
             Object serializedView = state[STATE_PARAM];
 118  0
             if (serializedView instanceof Object[] &&
 119  
             ((Object[])serializedView).length == 2 &&
 120  
             ((Object[])serializedView)[0] == null &&
 121  
             ((Object[])serializedView)[1] == null)
 122  
             {
 123  
                 // Remember inside the state null is stored as an empty array.
 124  0
                 return null;
 125  
             }
 126  
             
 127  0
             return state[STATE_PARAM];
 128  
         }
 129  
     }
 130  
 
 131  
     @Override
 132  
     public Object encodeSerializedState(FacesContext facesContext,
 133  
             Object serializedView)
 134  
     {
 135  0
         Object[] state = null;
 136  
         
 137  0
         if (getClientViewStateTimeout(facesContext.getExternalContext()).longValue() > 0L)
 138  
         {
 139  0
             state = new Object[3];
 140  0
             state[TIMESTAMP_PARAM] = System.currentTimeMillis();
 141  
         }
 142  
         else
 143  
         {
 144  0
             state = new Object[2];
 145  
         }
 146  
         
 147  0
         if (serializedView == null)
 148  
         {
 149  0
             state[STATE_PARAM] = EMPTY_STATES;
 150  
         }
 151  0
         else if (serializedView instanceof Object[] &&
 152  
             ((Object[])serializedView).length == 2 &&
 153  
             ((Object[])serializedView)[0] == null &&
 154  
             ((Object[])serializedView)[1] == null)
 155  
         {
 156  
             // The generated state can be considered zero, set it as null
 157  
             // into the map.
 158  0
             state[STATE_PARAM] = null;
 159  
         }
 160  
         else
 161  
         {
 162  0
             state[STATE_PARAM] = serializedView;
 163  
         }
 164  
 
 165  0
         state[VIEWID_PARAM] = facesContext.getViewRoot().getViewId();
 166  
         
 167  0
         return state;
 168  
     }
 169  
 
 170  
     @Override
 171  
     public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
 172  
     {
 173  0
         return true;
 174  
     }
 175  
 
 176  
     /**
 177  
      * @return the _clientViewStateTimeout
 178  
      */
 179  
     protected Long getClientViewStateTimeout(ExternalContext context)
 180  
     {
 181  0
         if (_clientViewStateTimeout == null)
 182  
         {
 183  0
             _clientViewStateTimeout = WebConfigParamUtils.getLongInitParameter(
 184  
                     context, INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT,
 185  
                     INIT_PARAM_CLIENT_VIEW_STATE_TIMEOUT_DEFAULT);
 186  0
             if (_clientViewStateTimeout.longValue() < 0L)
 187  
             {
 188  0
                 _clientViewStateTimeout = 0L;
 189  
             }
 190  
         }
 191  0
         return _clientViewStateTimeout;
 192  
     }
 193  
 
 194  
     @Override
 195  
     public String createCryptographicallyStrongTokenFromSession(FacesContext context)
 196  
     {
 197  0
         return csrfSessionTokenFactory.createCryptographicallyStrongTokenFromSession(context);
 198  
     }
 199  
 }