Coverage Report - org.apache.myfaces.el.FlashELResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
FlashELResolver
0%
0/114
0%
0/64
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.el;
 20  
 
 21  
 import javax.el.ELContext;
 22  
 import javax.el.ELException;
 23  
 import javax.el.ELResolver;
 24  
 import javax.el.PropertyNotFoundException;
 25  
 import javax.el.PropertyNotWritableException;
 26  
 import javax.faces.context.ExternalContext;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.context.Flash;
 29  
 import java.beans.FeatureDescriptor;
 30  
 import java.util.ArrayList;
 31  
 import java.util.Iterator;
 32  
 
 33  
 /**
 34  
  * Resolver for Flash object 
 35  
  * 
 36  
  * @author Leonardo Uribe (latest modification by $Author$)
 37  
  * @version $Revision$ $Date$
 38  
  */
 39  
 public class FlashELResolver extends ELResolver
 40  
 {
 41  
 
 42  
     private final static String FLASH = "flash";
 43  
 
 44  
     private final static String KEEP = "keep";
 45  
 
 46  
     private final static String NOW = "now";
 47  
 
 48  
     public FlashELResolver()
 49  
     {
 50  0
         super();
 51  0
     }
 52  
 
 53  
     @Override
 54  
     public void setValue(ELContext context, Object base, Object property,
 55  
             Object value) throws NullPointerException,
 56  
             PropertyNotFoundException, PropertyNotWritableException,
 57  
             ELException
 58  
     {
 59  0
         if (property == null)
 60  
         {
 61  0
             throw new PropertyNotFoundException();
 62  
         }
 63  0
         if (!(property instanceof String))
 64  
         {
 65  0
             return;
 66  
         }
 67  
 
 68  0
         String strProperty = property.toString();
 69  
 
 70  0
         if (FLASH.equals(strProperty))
 71  
         {
 72  0
             throw new PropertyNotWritableException();
 73  
         }
 74  0
         else if (base instanceof Flash)
 75  
         {
 76  0
             context.setPropertyResolved(true);
 77  
             try
 78  
             {
 79  0
                 ((Flash) base).put(strProperty, value);
 80  
             }
 81  0
             catch (UnsupportedOperationException e)
 82  
             {
 83  0
                 throw new PropertyNotWritableException(e);
 84  0
             }
 85  
         }
 86  0
     }
 87  
 
 88  
     @Override
 89  
     public boolean isReadOnly(ELContext context, Object base, Object property)
 90  
             throws NullPointerException, PropertyNotFoundException, ELException
 91  
     {
 92  
 
 93  0
         if (property == null)
 94  
         {
 95  0
             throw new PropertyNotFoundException();
 96  
         }
 97  0
         if (!(property instanceof String))
 98  
         {
 99  0
             return false;
 100  
         }
 101  
 
 102  0
         String strProperty = property.toString();
 103  
 
 104  0
         if (FLASH.equals(strProperty))
 105  
         {
 106  0
             context.setPropertyResolved(true);
 107  0
             return true;
 108  
         }
 109  0
         else if (base instanceof Flash)
 110  
         {
 111  0
             context.setPropertyResolved(true);
 112  
         }
 113  
 
 114  0
         return false;
 115  
     }
 116  
 
 117  
     @Override
 118  
     public Object getValue(ELContext elContext, Object base, Object property)
 119  
             throws NullPointerException, PropertyNotFoundException, ELException
 120  
     {
 121  
 
 122  0
         if (property == null)
 123  
         {
 124  0
             throw new PropertyNotFoundException();
 125  
         }
 126  0
         if (!(property instanceof String))
 127  
         {
 128  0
             return null;
 129  
         }
 130  
 
 131  0
         String strProperty = property.toString();
 132  
 
 133  0
         if (base == null)
 134  
         {
 135  0
             if (FLASH.equals(strProperty))
 136  
             {
 137  0
                 FacesContext facesContext = facesContext(elContext);
 138  0
                 if (facesContext == null)
 139  
                 {
 140  0
                     return null;
 141  
                 }
 142  0
                 ExternalContext externalContext = facesContext.getExternalContext();
 143  0
                 if (externalContext == null)
 144  
                 {
 145  0
                     return null;
 146  
                 }
 147  
 
 148  
                 //Access to flash object
 149  0
                 elContext.setPropertyResolved(true);
 150  0
                 Flash flash = externalContext.getFlash();
 151  
                 //This is just to make sure after this point
 152  
                 //we are not in "keep" promotion.
 153  0
                 setDoKeepPromotion(false, facesContext);
 154  
                 
 155  
                 // Note that after this object is returned, Flash.get() and Flash.put()
 156  
                 // methods are called from javax.el.MapELResolver, since 
 157  
                 // Flash is instance of Map.
 158  0
                 return flash;
 159  
             }
 160  
         }
 161  0
         else if (base instanceof Flash)
 162  
         {
 163  0
             FacesContext facesContext = facesContext(elContext);
 164  0
             if (facesContext == null)
 165  
             {
 166  0
                 return null;
 167  
             }
 168  0
             ExternalContext externalContext = facesContext.getExternalContext();
 169  0
             if (externalContext == null)
 170  
             {
 171  0
                 return null;
 172  
             }
 173  0
             Flash flash = (Flash) base;
 174  0
             if (KEEP.equals(strProperty))
 175  
             {
 176  0
                 setDoKeepPromotion(true, facesContext);
 177  
                 // Since we returned a Flash instance getValue will 
 178  
                 // be called again but this time the property name
 179  
                 // to be resolved will be called, so we can do keep
 180  
                 // promotion.
 181  0
                 elContext.setPropertyResolved(true);
 182  0
                 return base;
 183  
             }
 184  0
             else if (NOW.equals(strProperty))
 185  
             {
 186  
                 //Prevent invalid syntax #{flash.keep.now.someKey}
 187  0
                 if (!isDoKeepPromotion(facesContext))
 188  
                 {
 189  
                     // According to the javadoc of Flash.putNow() and 
 190  
                     // Flash.keep(), this is an alias to requestMap, used
 191  
                     // as a "buffer" to promote vars to flash scope using
 192  
                     // "keep" method
 193  0
                     elContext.setPropertyResolved(true);
 194  0
                     return externalContext.getRequestMap();
 195  
                 }
 196  
             }
 197  0
             else if (isDoKeepPromotion(facesContext))
 198  
             {
 199  
                 //Resolve property calling get or keep
 200  0
                 elContext.setPropertyResolved(true);
 201  
                 //promote it to flash scope
 202  0
                 flash.keep(strProperty);
 203  
                 //Obtain the value on requestMap if any
 204  0
                 Object value = externalContext.getRequestMap().get(strProperty);
 205  0
                 return value;
 206  
             }
 207  
             else
 208  
             {
 209  
                 //Just get the value
 210  0
                 elContext.setPropertyResolved(true);
 211  0
                 return flash.get(strProperty);
 212  
             }
 213  
         }
 214  0
         return null;
 215  
     }
 216  
     
 217  
     /**
 218  
      * This var indicate if we are inside a keep operation
 219  
      * or not. We go into keep status in two cases:
 220  
      * 
 221  
      * - A direct call to Flash.keep(String key)
 222  
      * - A lookup to keep map using a value expression #{flash.keep.someKey}.
 223  
      *   This occur when the ELResolver try to get the keep object.
 224  
      *   
 225  
      * Note that when "keep" is resolved by FlashELResolver,
 226  
      * we need a way to comunicate that the current lookup is 
 227  
      * for keep promotion.
 228  
      * 
 229  
      * This var do the job.
 230  
      */
 231  
     private static final String KEEP_STATUS_KEY = "org.apache.myfaces.el.FlashELResolver.KEEP_STATUS";
 232  
 
 233  
     private static boolean isDoKeepPromotion(FacesContext facesContext)
 234  
     {
 235  0
         Boolean doKeepPromotion = (Boolean) facesContext.getAttributes().get(KEEP_STATUS_KEY);
 236  
 
 237  0
         if (doKeepPromotion == null)
 238  
         {
 239  0
             doKeepPromotion = false;
 240  
         }
 241  
 
 242  0
         return doKeepPromotion;
 243  
     }
 244  
 
 245  
     private static void setDoKeepPromotion(boolean value, FacesContext facesContext)
 246  
     {
 247  0
         facesContext.getAttributes().put(KEEP_STATUS_KEY, Boolean.valueOf(value));
 248  0
     }
 249  
     
 250  
     // get the FacesContext from the ELContext
 251  
     protected FacesContext facesContext(ELContext context)
 252  
     {
 253  0
         return (FacesContext) context.getContext(FacesContext.class);
 254  
     }
 255  
 
 256  
     protected ExternalContext externalContext(ELContext context)
 257  
     {
 258  0
         return facesContext(context).getExternalContext();
 259  
     }
 260  
 
 261  
     @Override
 262  
     public Class<?> getType(ELContext context, Object base, Object property)
 263  
             throws NullPointerException, PropertyNotFoundException, ELException
 264  
     {
 265  
 
 266  0
         if (property == null)
 267  
         {
 268  0
             throw new PropertyNotFoundException();
 269  
         }
 270  0
         if (!(property instanceof String))
 271  
         {
 272  0
             return null;
 273  
         }
 274  
 
 275  0
         String strProperty = property.toString();
 276  
 
 277  0
         if (FLASH.equals(strProperty))
 278  
         {
 279  0
             context.setPropertyResolved(true);
 280  
         }
 281  0
         else if (base instanceof Flash)
 282  
         {
 283  0
             context.setPropertyResolved(true);
 284  0
             Object obj = ((Flash) base).get(property);
 285  0
             return (obj != null) ? obj.getClass() : null;
 286  
         }
 287  
 
 288  0
         return null;
 289  
     }
 290  
 
 291  
     @Override
 292  
     public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
 293  
             Object base)
 294  
     {
 295  0
         ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>(1);
 296  
 
 297  0
         descriptors.add(makeDescriptor(FLASH,
 298  
                 "Represents the current flash scope", Object.class));
 299  
 
 300  0
         if (base instanceof Flash)
 301  
         {
 302  0
             Iterator itr = ((Flash) base).keySet().iterator();
 303  
             Object key;
 304  
             FeatureDescriptor desc;
 305  0
             while (itr.hasNext())
 306  
             {
 307  0
                 key = itr.next();
 308  0
                 desc = makeDescriptor(key.toString(), key.toString(), key.getClass());
 309  0
                 descriptors.add(desc);
 310  
             }
 311  
         }
 312  0
         return descriptors.iterator();
 313  
     }
 314  
 
 315  
     protected FeatureDescriptor makeDescriptor(String name, String description,
 316  
             Class<?> elResolverType)
 317  
     {
 318  0
         FeatureDescriptor fd = new FeatureDescriptor();
 319  0
         fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
 320  0
         fd.setValue(ELResolver.TYPE, elResolverType);
 321  0
         fd.setName(name);
 322  0
         fd.setDisplayName(name);
 323  0
         fd.setShortDescription(description);
 324  0
         fd.setExpert(false);
 325  0
         fd.setHidden(false);
 326  0
         fd.setPreferred(true);
 327  0
         return fd;
 328  
     }
 329  
 
 330  
     @Override
 331  
     public Class<?> getCommonPropertyType(ELContext context, Object base)
 332  
     {
 333  0
         if (base == null)
 334  
         {
 335  0
             return null;
 336  
         }
 337  
 
 338  0
         if (base instanceof Flash)
 339  
         {
 340  0
             return Object.class;
 341  
         }
 342  0
         else if (FLASH.equals(base.toString()))
 343  
         {
 344  0
             return Object.class;
 345  
         }
 346  
 
 347  0
         return null;
 348  
     }
 349  
 
 350  
 }