2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

Coverage Report - org.apache.shale.faces.ShalePropertyResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
ShalePropertyResolver
0% 
0% 
6.889
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to you under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.shale.faces;
 19  
 
 20  
 import java.beans.Beans;
 21  
 import java.util.Map;
 22  
 import javax.faces.el.EvaluationException;
 23  
 import javax.faces.el.PropertyNotFoundException;
 24  
 import javax.faces.el.PropertyResolver;
 25  
 import javax.naming.Context;
 26  
 import javax.naming.Name;
 27  
 import javax.naming.NameNotFoundException;
 28  
 import javax.naming.NamingException;
 29  
 import org.apache.shale.util.LoadBundle;
 30  
 
 31  
 /**
 32  
  * <p>Shale-specific PropertyResolver for evaluating JavaServer Faces
 33  
  * value binding and method binding expressions.  The following special
 34  
  * processing is performed, based on recognizing the type of the base
 35  
  * object:</p>
 36  
  * <ul>
 37  
  * <li><strong>javax.naming.Context</strong> - Treats the property "name"
 38  
  *     as a String (or <code>javax.naming.Name</code>) suitable for passing
 39  
  *     to the <code>lookup()</code> method of the <code>Context</code>.
 40  
  *     The Context has no way to describe whether it is read only or not,
 41  
  *     so <code>isReadOnly()</code> returns <code>false</code>.</li>
 42  
  * <li><strong>org.apache.shale.util.LoadBundle</strong> - Special handling
 43  
  *     as follows, based on the requested property name:
 44  
  *     <ul>
 45  
  *     <li><code>map</code> - Delegates to the original resolver's handling
 46  
  *         of the <code>map</code> property.  This is for backwards compatibility
 47  
  *         with applications depending on this behavior from the 1.0.0
 48  
  *         version of the class.</li>
 49  
  *     <li>Any other property is considered to be a resource bundle key, which
 50  
  *         will be used to look up the corresponding value from the underlying
 51  
  *         resource bundle, using the <code>Locale</code> from the current
 52  
  *         view for selecting the appropriate translation.</li>
 53  
  *     </ul></li>
 54  
  * </ul>
 55  
  * <p>All other evaluations are delegated to the previous implementation
 56  
  * that was passed to our constructor.</p>
 57  
  *
 58  
  * $Id: ShalePropertyResolver.java 464373 2006-10-16 04:21:54Z rahul $
 59  
  */
 60  
 public class ShalePropertyResolver extends PropertyResolver {
 61  
 
 62  
 
 63  
     // ------------------------------------------------------------- Constructor
 64  
 
 65  
 
 66  
     /**
 67  
      * <p>Construct a new {@link ShalePropertyResolver} instance.</p>
 68  
      *
 69  
      *
 70  
      * @param original Original resolver to delegate to.
 71  
      */
 72  0
     public ShalePropertyResolver(PropertyResolver original) {
 73  
 
 74  0
         this.original = original;
 75  
 
 76  0
     }
 77  
 
 78  
 
 79  
     // ------------------------------------------------------ Instance Variables
 80  
 
 81  
 
 82  
     /**
 83  
      * <p>The original <code>PropertyResolver</code> passed to our constructor.</p>
 84  
      */
 85  0
     private PropertyResolver original = null;
 86  
 
 87  
 
 88  
     // ------------------------------------------------ PropertyResolver Methods
 89  
 
 90  
 
 91  
     /**
 92  
      * <p>For a base object of type <code>Context</code>, look up and return
 93  
      * the named object corresponding to the specified property name from
 94  
      * this <code>Context</code>.</p>
 95  
      *
 96  
      * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
 97  
      * treat the property expression as follows:</p>
 98  
      * <ul>
 99  
      * <li>If the property name is <code>map</code>, call the corresponding
 100  
      *     property getter and return that value.</li>
 101  
      * <li>Otherwise, treat the property name as a message key, and look up
 102  
      *     and return the corresponding value from the <code>Map</code> that
 103  
      *     is returned by the <code>getMap()</code> call.</li>
 104  
      * </ul>
 105  
      *
 106  
      * @param base Base object from which to return a property
 107  
      * @param property Property to be returned
 108  
      *
 109  
      * @exception EvaluationException if an evaluation error occurs
 110  
      * @exception PropertyNotFoundException if there is no such named
 111  
      *  object in this context
 112  
      */
 113  
     public Object getValue(Object base, Object property)
 114  
       throws EvaluationException, PropertyNotFoundException {
 115  
 
 116  0
         if (base instanceof Context) {
 117  0
             Context context = (Context) base;
 118  
             try {
 119  0
                 if (property instanceof Name) {
 120  0
                     return context.lookup((Name) property);
 121  
                 } else {
 122  0
                     return context.lookup(property.toString());
 123  
                 }
 124  0
             } catch (NameNotFoundException e) {
 125  
                 // Mimic standard JSF/JSP behavior when base is a Map
 126  
                 // by returning null
 127  0
                 return null;
 128  0
             } catch (NamingException e) {
 129  0
                 throw new EvaluationException(e);
 130  
             }
 131  0
         } else if (base instanceof LoadBundle && !"basename".equals(property)) {
 132  0
             Map map = ((LoadBundle) base).getMap();
 133  0
             if ("map".equals(property)) {
 134  0
                 return map;
 135  
             } else {
 136  0
                 return map.get(property);
 137  
             }
 138  
         } else {
 139  0
             return original.getValue(base, property);
 140  
         }
 141  
 
 142  
     }
 143  
 
 144  
 
 145  
     /**
 146  
      * <p>For a base object of type <code>Context</code>, replace any previous
 147  
      * binding for the named object corresponding to the specified property
 148  
      * name into this <code>Context</code>.</p>
 149  
      *
 150  
      * <p>(Since 1.0.1) For a base object of type <code>LoadBundle</code>,
 151  
      * throw an exception since all properties of this object are read only.</p>
 152  
      *
 153  
      * @param base Base object in which to store a property
 154  
      * @param property Property to be stored
 155  
      * @param value Value to be stored
 156  
      *
 157  
      * @exception EvaluationException if an evaluation error occurs
 158  
      * @exception PropertyNotFoundException if there is no such named
 159  
      *  object in this context
 160  
      */
 161  
     public void setValue(Object base, Object property, Object value) {
 162  
 
 163  0
         if (base instanceof Context) {
 164  0
             Context context = (Context) base;
 165  
             try {
 166  
                 // Mimic standard JSF/JSP behavior when base is a Map
 167  
                 // by calling rebind() instead of bind()
 168  0
                 if (property instanceof Name) {
 169  0
                     context.rebind((Name) property, value);
 170  
                 } else {
 171  0
                     context.rebind(property.toString(), value);
 172  
                 }
 173  0
             } catch (NamingException e) {
 174  0
                 throw new EvaluationException(e);
 175  0
             }
 176  0
         } else if (base instanceof LoadBundle && !"basename".equals(property)) {
 177  0
             throw new PropertyNotFoundException("" + value);
 178  
         } else {
 179  0
             original.setValue(base, property, value);
 180  
         }
 181  
 
 182  0
     }
 183  
 
 184  
 
 185  
     /**
 186  
      * <p>For a <code>Context</code> base object, arbitrarily return
 187  
      * <code>false</code> because we cannot determine if a <code>Context</code>
 188  
      * is read only or not.</p>
 189  
      *
 190  
      * <p>(Since 1.0.1) For a <code>LoadBundle</code> base object,
 191  
      * return <code>true</code> because all pseudo-properties of
 192  
      * this bundle are considered to be read only.</p>
 193  
      *
 194  
      * @param base Base object from which to return read only state
 195  
      * @param property Property to be checked
 196  
      *
 197  
      * @exception EvaluationException if an evaluation error occurs
 198  
      * @exception PropertyNotFoundException if there is no such named
 199  
      *  object in this context
 200  
      */
 201  
     public boolean isReadOnly(Object base, Object property)
 202  
       throws EvaluationException, PropertyNotFoundException {
 203  
 
 204  0
         if (base instanceof Context) {
 205  
             // Mimic standard JSF/JSP behavior when base is a Map
 206  
             // by returning false if we cannot tell any better
 207  0
             return false;
 208  0
         } else if (base instanceof LoadBundle && !"basename".equals(property)) {
 209  
             // All properties of this object are considered read only
 210  0
             return true;
 211  
         } else {
 212  0
             return original.isReadOnly(base, property);
 213  
         }
 214  
 
 215  
     }
 216  
 
 217  
 
 218  
     /**
 219  
      * <p>For a <code>Context</code>, look up and return the type of the
 220  
      * named object corresponding to the specified property name from this
 221  
      * <code>Context</code>.</p>
 222  
      *
 223  
      * <p>(Since 1.0.1) For a <code>LoadBundle</code>, look up and return
 224  
      * the corresponding object type at runtime, or return <code>Object</code>
 225  
      * for the type to be looked up at design time.</p>
 226  
      *
 227  
      * @param base Base object from which to return a property type
 228  
      * @param property Property whose type is to be returned
 229  
      *
 230  
      * @exception EvaluationException if an evaluation error occurs
 231  
      * @exception PropertyNotFoundException if there is no such named
 232  
      *  object in this context
 233  
      */
 234  
     public Class getType(Object base, Object property)
 235  
       throws EvaluationException, PropertyNotFoundException {
 236  
 
 237  0
         if (base instanceof Context) {
 238  0
             Context context = (Context) base;
 239  
             Object value;
 240  
             try {
 241  0
                 if (property instanceof Name) {
 242  0
                     value = context.lookup((Name) property);
 243  
                 } else {
 244  0
                     value = context.lookup(property.toString());
 245  
                 }
 246  0
             } catch (NameNotFoundException e) {
 247  
                 // Mimic standard JSF/JSP behavior when base is a Map
 248  
                 // by returning null
 249  0
                 return null;
 250  0
             } catch (NamingException e) {
 251  0
                 throw new EvaluationException(e);
 252  0
             }
 253  0
             if (value == null) {
 254  0
                 return null;
 255  
             } else {
 256  0
                 return value.getClass();
 257  
             }
 258  0
         } else if (base instanceof LoadBundle && !"basename".equals(property)) {
 259  0
             LoadBundle lb = (LoadBundle) base;
 260  0
             if ("map".equals(property)) {
 261  0
                 return Map.class;
 262  0
             } else if (Beans.isDesignTime()) {
 263  0
                 return Object.class;
 264  
             } else {
 265  0
                 Object value = lb.getMap().get(property);
 266  0
                 if (value != null) {
 267  0
                     return value.getClass();
 268  
                 } else {
 269  0
                     return null;
 270  
                 }
 271  
             }
 272  
         } else {
 273  0
             return original.getType(base, property);
 274  
         }
 275  
 
 276  
     }
 277  
 
 278  
 
 279  
     /**
 280  
      * <p>Convert an index into a corresponding string, and delegate.</p>
 281  
      *
 282  
      * @param base Base object from which to return a property
 283  
      * @param index Index to be returned
 284  
      *
 285  
      * @exception EvaluationException if an evaluation error occurs
 286  
      * @exception PropertyNotFoundException if there is no such named
 287  
      *  object in this context
 288  
      */
 289  
     public Object getValue(Object base, int index)
 290  
       throws EvaluationException, PropertyNotFoundException {
 291  
 
 292  0
         if (base instanceof Context) {
 293  0
             return getValue(base, "" + index);
 294  0
         } else if (base instanceof LoadBundle && !"basename".equals(base)) {
 295  0
             return getValue(base, "" + index);
 296  
         } else {
 297  0
             return original.getValue(base, index);
 298  
         }
 299  
 
 300  
     }
 301  
 
 302  
 
 303  
     /**
 304  
      * <p>Convert an index into a corresponding string, and delegate.</p>
 305  
      *
 306  
      * @param base Base object into which to store a property
 307  
      * @param index Index to be stored
 308  
      * @param value Value to be stored
 309  
      *
 310  
      * @exception EvaluationException if an evaluation error occurs
 311  
      * @exception PropertyNotFoundException if there is no such named
 312  
      *  object in this context
 313  
      */
 314  
     public void setValue(Object base, int index, Object value)
 315  
       throws EvaluationException, PropertyNotFoundException {
 316  
 
 317  0
         if (base instanceof Context) {
 318  0
             setValue(base, "" + index, value);
 319  0
         } else if (base instanceof LoadBundle) {
 320  0
             setValue(base, "" + index, value);
 321  
         } else {
 322  0
             original.setValue(base, index, value);
 323  
         }
 324  
 
 325  0
     }
 326  
 
 327  
 
 328  
     /**
 329  
      * <p>Convert an index into a corresponding string, and delegate.</p>
 330  
      *
 331  
      * @param base Base object from which to check a property
 332  
      * @param index Index to be checked
 333  
      *
 334  
      * @exception EvaluationException if an evaluation error occurs
 335  
      * @exception PropertyNotFoundException if there is no such named
 336  
      *  object in this context
 337  
      */
 338  
     public boolean isReadOnly(Object base, int index)
 339  
       throws EvaluationException, PropertyNotFoundException {
 340  
 
 341  0
         if (base instanceof Context) {
 342  0
             return isReadOnly(base, "" + index);
 343  0
         } else if (base instanceof LoadBundle) {
 344  0
             return isReadOnly(base, "" + index);
 345  
         } else {
 346  0
             return original.isReadOnly(base, index);
 347  
         }
 348  
 
 349  
     }
 350  
 
 351  
 
 352  
     /**
 353  
      * <p>Convert an index into a corresponding string, and delegate.</p>
 354  
      *
 355  
      * @param base Base object from which to return a property type
 356  
      * @param index Index whose type is to be returned
 357  
      *
 358  
      * @exception EvaluationException if an evaluation error occurs
 359  
      * @exception PropertyNotFoundException if there is no such named
 360  
      *  object in this context
 361  
      */
 362  
     public Class getType(Object base, int index)
 363  
       throws EvaluationException, PropertyNotFoundException {
 364  
 
 365  0
         if (base instanceof Context) {
 366  0
             return getType(base, "" + index);
 367  0
         } else if (base instanceof LoadBundle) {
 368  0
             return getType(base, "" + index);
 369  
         } else {
 370  0
             return original.getType(base, index);
 371  
         }
 372  
 
 373  
     }
 374  
 
 375  
 
 376  
 }