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

For more information, please explore the Attic.

Coverage Report - org.apache.shale.test.mock.MockValueBinding
 
Classes in this File Line Coverage Branch Coverage Complexity
MockValueBinding
100%
70/70
N/A
3.933
 
 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.test.mock;
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import javax.faces.application.Application;
 25  
 import javax.faces.component.StateHolder;
 26  
 import javax.faces.context.ExternalContext;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.el.EvaluationException;
 29  
 import javax.faces.el.PropertyNotFoundException;
 30  
 import javax.faces.el.PropertyResolver;
 31  
 import javax.faces.el.ReferenceSyntaxException;
 32  
 import javax.faces.el.ValueBinding;
 33  
 import javax.faces.el.VariableResolver;
 34  
 
 35  
 
 36  
 /**
 37  
  * <p>Mock implementation of <code>ValueBinding</code>.</p>
 38  
  */
 39  
 
 40  
 public class MockValueBinding extends ValueBinding implements StateHolder {
 41  
 
 42  
 
 43  
     // ------------------------------------------------------------ Constructors
 44  
 
 45  
 
 46  
     /**
 47  
      * <p>Construct a default instance.</p>
 48  
      */
 49  
     public MockValueBinding() {
 50  
 
 51  
         this(null, null);
 52  
 
 53  
     }
 54  
 
 55  
 
 56  
     /**
 57  
      * <p>Construct a new value binding for the specified expression.</p>
 58  
      *
 59  
      * @param application Application instance to be wrapped
 60  
      * @param ref Expression to be wrapped
 61  
      */
 62  30
     public MockValueBinding(Application application, String ref) {
 63  
 
 64  30
         this.application = application;
 65  30
         if (ref != null) {
 66  30
             if (ref.startsWith("#{") && ref.endsWith("}")) {
 67  3
                 ref = ref.substring(2, ref.length() - 1);
 68  
             }
 69  
         }
 70  30
         this.ref = ref;
 71  
 
 72  30
     }
 73  
 
 74  
 
 75  
     // ----------------------------------------------------- Mock Object Methods
 76  
 
 77  
 
 78  
     /**
 79  
      * <p>Return the expression string for this value binding.</p>
 80  
      */
 81  
     public String ref() {
 82  
 
 83  
         return this.ref;
 84  
 
 85  
     }
 86  
 
 87  
 
 88  
     // ------------------------------------------------------ Instance Variables
 89  
 
 90  
 
 91  
     /**
 92  
      * <p>The <code>Application</code> instance for this application.</p>
 93  
      */
 94  
     private transient Application application; // Restored as necessary
 95  
 
 96  
 
 97  
     /**
 98  
      * <p>The expression this value binding will evaluate.</p>
 99  
      */
 100  
     private String ref;
 101  
 
 102  
 
 103  
     // ---------------------------------------------------- ValueBinding Methods
 104  
 
 105  
 
 106  
     /** {@inheritDoc} */
 107  
     public Object getValue(FacesContext context)
 108  
         throws EvaluationException, PropertyNotFoundException {
 109  
 
 110  24
         if (context == null) {
 111  
             throw new NullPointerException();
 112  
         }
 113  24
         List names = parse(ref);
 114  
 
 115  
         // Resolve the variable name
 116  24
         VariableResolver vr = application().getVariableResolver();
 117  24
         String name = (String) names.get(0);
 118  24
         Object base = vr.resolveVariable(context, name);
 119  24
         if (names.size() < 2) {
 120  15
             return (base);
 121  
         }
 122  
 
 123  
         // Resolve the property names
 124  9
         PropertyResolver pr = application().getPropertyResolver();
 125  18
         for (int i = 1; i < names.size(); i++) {
 126  9
             base = pr.getValue(base, (String) names.get(i));
 127  
         }
 128  
 
 129  
         // Return the resolved value
 130  9
         return (base);
 131  
 
 132  
     }
 133  
 
 134  
 
 135  
     /** {@inheritDoc} */
 136  
     public void setValue(FacesContext context, Object value)
 137  
         throws EvaluationException, PropertyNotFoundException {
 138  
 
 139  6
         if (context == null) {
 140  
             throw new NullPointerException();
 141  
         }
 142  6
         List names = parse(ref);
 143  
 
 144  
         // Resolve the variable name
 145  6
         VariableResolver vr = application().getVariableResolver();
 146  6
         String name = (String) names.get(0);
 147  6
         Object base = vr.resolveVariable(context, name);
 148  6
         if (names.size() < 2) {
 149  3
             if ("applicationScope".equals(name)
 150  
                 || "requestScope".equals(name)
 151  
                 || "sessionScope".equals(name)) {
 152  
                 throw new ReferenceSyntaxException("Cannot set '"
 153  
                                                    + name + "'");
 154  
             }
 155  3
             Map map = econtext().getRequestMap();
 156  3
             if (map.containsKey(name)) {
 157  2
                 map.put(name, value);
 158  2
                 return;
 159  
             }
 160  1
             map = econtext().getSessionMap();
 161  1
             if ((map != null) && (map.containsKey(name))) {
 162  
                 map.put(name, value);
 163  
                 return;
 164  
             }
 165  1
             map = econtext().getApplicationMap();
 166  1
             if (map.containsKey(name)) {
 167  
                 map.put(name, value);
 168  
                 return;
 169  
             }
 170  1
             econtext().getRequestMap().put(name, value);
 171  1
             return;
 172  
         }
 173  
 
 174  
         // Resolve the property names
 175  3
         PropertyResolver pr = application().getPropertyResolver();
 176  3
         for (int i = 1; i < (names.size() - 1); i++) {
 177  
             // System.out.println("  property=" + names.get(i));
 178  
             base = pr.getValue(base, (String) names.get(i));
 179  
         }
 180  
 
 181  
         // Update the last property
 182  3
         pr.setValue(base, (String) names.get(names.size() - 1), value);
 183  
 
 184  3
     }
 185  
 
 186  
 
 187  
     /** {@inheritDoc} */
 188  
     public boolean isReadOnly(FacesContext context)
 189  
         throws PropertyNotFoundException {
 190  
 
 191  
         if (context == null) {
 192  
             throw new NullPointerException();
 193  
         }
 194  
         List names = parse(ref);
 195  
 
 196  
         // Resolve the variable name
 197  
         VariableResolver vr = application().getVariableResolver();
 198  
         String name = (String) names.get(0);
 199  
         Object base = vr.resolveVariable(context, name);
 200  
         if (names.size() < 2) {
 201  
             return true;
 202  
         }
 203  
 
 204  
         // Resolve the property names
 205  
         PropertyResolver pr = application().getPropertyResolver();
 206  
         for (int i = 1; i < names.size() - 1; i++) {
 207  
             base = pr.getValue(base, (String) names.get(i));
 208  
         }
 209  
 
 210  
         // Return the read only state of the final property
 211  
         return pr.isReadOnly(base, (String) names.get(names.size() - 1));
 212  
 
 213  
     }
 214  
 
 215  
 
 216  
     /** {@inheritDoc} */
 217  
     public Class getType(FacesContext context)
 218  
         throws PropertyNotFoundException {
 219  
 
 220  
         if (context == null) {
 221  
             throw new NullPointerException();
 222  
         }
 223  
         List names = parse(ref);
 224  
 
 225  
         // Resolve the variable name
 226  
         VariableResolver vr = application().getVariableResolver();
 227  
         String name = (String) names.get(0);
 228  
         Object base = vr.resolveVariable(context, name);
 229  
         if (names.size() < 2) {
 230  
             return base.getClass();
 231  
         }
 232  
 
 233  
         // Resolve the property names
 234  
         PropertyResolver pr = application().getPropertyResolver();
 235  
         for (int i = 1; i < names.size() - 1; i++) {
 236  
             base = pr.getValue(base, (String) names.get(i));
 237  
         }
 238  
 
 239  
         // Return the type of the final property
 240  
         return pr.getType(base, (String) names.get(names.size() - 1));
 241  
 
 242  
     }
 243  
 
 244  
     /** {@inheritDoc} */
 245  
     public String getExpressionString() {
 246  
 
 247  
         return "#{" + ref + "}";
 248  
 
 249  
     }
 250  
 
 251  
 
 252  
     // ----------------------------------------------------- StateHolder Methods
 253  
 
 254  
 
 255  
     /** {@inheritDoc} */
 256  
     public Object saveState(FacesContext context) {
 257  
 
 258  
         Object[] values = new Object[1];
 259  
         values[0] = ref;
 260  
         return values;
 261  
 
 262  
     }
 263  
 
 264  
 
 265  
     /** {@inheritDoc} */
 266  
     public void restoreState(FacesContext context, Object state) {
 267  
 
 268  
         Object[] values = (Object[]) state;
 269  
         ref = (String) values[0];
 270  
 
 271  
     }
 272  
 
 273  
 
 274  
     /**
 275  
      * <p>Flag indicating that this value is transient.</p>
 276  
      */
 277  30
     private boolean transientFlag = false;
 278  
 
 279  
 
 280  
     /** {@inheritDoc} */
 281  
     public boolean isTransient() {
 282  
 
 283  
         return this.transientFlag;
 284  
 
 285  
     }
 286  
 
 287  
 
 288  
     /** {@inheritDoc} */
 289  
     public void setTransient(boolean transientFlag) {
 290  
 
 291  
         this.transientFlag = transientFlag;
 292  
 
 293  
     }
 294  
 
 295  
 
 296  
     // --------------------------------------------------------- Private Methods
 297  
 
 298  
 
 299  
     /**
 300  
      * <p>Return the relevant <code>Application</code> instance.</p>
 301  
      */
 302  
     private Application application() {
 303  
 
 304  42
         if (application == null) {
 305  
             application = FacesContext.getCurrentInstance().getApplication();
 306  
         }
 307  42
         return (application);
 308  
 
 309  
     }
 310  
 
 311  
 
 312  
     /**
 313  
      * <p>Return the relevant <code>ExternalContext</code> instance.</p>
 314  
      */
 315  
     private ExternalContext econtext() {
 316  
 
 317  6
         return (FacesContext.getCurrentInstance().getExternalContext());
 318  
 
 319  
     }
 320  
 
 321  
 
 322  
     /**
 323  
      * <p>Return a list of the expression elements in this expression.</p>
 324  
      *
 325  
      * @param ref Expression to be parsed
 326  
      */
 327  
     private List parse(String ref) {
 328  
 
 329  30
         List names = new ArrayList();
 330  30
         StringBuffer expr = new StringBuffer(ref);
 331  30
         boolean isBlockOn = false;
 332  434
         for (int i = expr.length() - 1; i > -1; i--) {
 333  404
             if (expr.charAt(i) == ' ') {
 334  2
                 expr.deleteCharAt(i);
 335  2
             } else if (expr.charAt(i) == ']') {
 336  2
                 expr.deleteCharAt(i);
 337  2
             } else if (expr.charAt(i) == '[') {
 338  2
                 expr.deleteCharAt(i);
 339  2
             } else if (expr.charAt(i) == '\'') {
 340  4
                 if (!isBlockOn) {
 341  2
                     expr.deleteCharAt(i);
 342  2
                 } else {
 343  2
                     names.add(0, expr.substring(i + 1));
 344  2
                     expr.delete(i, expr.length());
 345  
                 }
 346  4
                 isBlockOn = !isBlockOn;
 347  4
             } else if (expr.charAt(i) == '.' && !isBlockOn) {
 348  10
                 names.add(0, expr.substring(i + 1));
 349  10
                 expr.delete(i, expr.length());
 350  
             }
 351  
         }
 352  
 
 353  30
         if (expr.length() > 0) {
 354  30
             names.add(0, expr.toString());
 355  
         }
 356  
 
 357  30
         if (names.size() < 1) {
 358  
             throw new ReferenceSyntaxException("No expression in '"
 359  
                     + ref + "'");
 360  
         }
 361  72
         for (int i = 0; i < names.size(); i++) {
 362  42
             String name = (String) names.get(i);
 363  42
             if (name.length() < 1) {
 364  
                 throw new ReferenceSyntaxException("Invalid expression '"
 365  
                         + ref + "'");
 366  
             }
 367  
         }
 368  30
         return (names);
 369  
 
 370  
     }
 371  
 
 372  
 
 373  
 }