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

For more information, please explore the Attic.

Coverage Report - org.apache.shale.test.el.MockValueExpression
 
Classes in this File Line Coverage Branch Coverage Complexity
MockValueExpression
100%
43/43
N/A
4.182
 
 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.el;
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.List;
 22  
 import javax.el.ELContext;
 23  
 import javax.el.ELResolver;
 24  
 import javax.el.ValueExpression;
 25  
 import javax.faces.context.FacesContext;
 26  
 
 27  
 /**
 28  
  * <p>Mock implementation of <code>ValueExpression</code>.</p>
 29  
  *
 30  
  * <p>This implementation supports a limited subset of overall expression functionality:</p>
 31  
  * <ul>
 32  
  * <li>A literal string that contains no expression delimiters.</li>
 33  
  * <li>An expression that starts with "#{" or "${", and ends with "}".</li>
 34  
  * </ul>
 35  
  */
 36  
 public class MockValueExpression extends ValueExpression {
 37  
     
 38  
 
 39  
     // ------------------------------------------------------------ Constructors
 40  
 
 41  
 
 42  
     /**
 43  
      * Serial version UID.
 44  
      */
 45  
     private static final long serialVersionUID = -8649071428507512623L;
 46  
 
 47  
 
 48  
     /**
 49  
      * <p>Construct a new expression for the specified expression string.</p>
 50  
      *
 51  
      * @param expression Expression string to be evaluated
 52  
      * @param expectedType Expected type of the result
 53  
      */
 54  1
     public MockValueExpression(String expression, Class expectedType) {
 55  
 
 56  1
         if (expression == null) {
 57  
             throw new NullPointerException("Expression string cannot be null");
 58  
         }
 59  1
         this.expression = expression;
 60  1
         this.expectedType = expectedType;
 61  1
         parse();
 62  
 
 63  1
     }
 64  
 
 65  
 
 66  
     // ------------------------------------------------------ Instance Variables
 67  
 
 68  
 
 69  
     /**
 70  
      * <p>The parsed elements of this expression.</p>
 71  
      */
 72  1
     private String[] elements = null;
 73  
 
 74  
 
 75  
     /**
 76  
      * <p>The expected result type for <code>getValue()</code> calls.</p>
 77  
      */
 78  1
     private Class expectedType = null;
 79  
 
 80  
 
 81  
     /**
 82  
      * <p>The original expression string used to create this expression.</p>
 83  
      */
 84  1
     private String expression = null;
 85  
 
 86  
 
 87  
     // ------------------------------------------------------ Expression Methods
 88  
 
 89  
 
 90  
     /**
 91  
      * <p>Return <code>true</code> if this expression is equal to the
 92  
      * specified expression.</p>
 93  
      *
 94  
      * @param obj Object to be compared
 95  
      */
 96  
     public boolean equals(Object obj) {
 97  
 
 98  
         if ((obj != null) & (obj instanceof ValueExpression)) {
 99  
             return expression.equals(((ValueExpression) obj).getExpressionString());
 100  
         } else {
 101  
             return false;
 102  
         }
 103  
 
 104  
     }
 105  
 
 106  
 
 107  
     /**
 108  
      * <p>Return the original String used to create this expression,
 109  
      * unmodified.</p>
 110  
      */
 111  
     public String getExpressionString() {
 112  
 
 113  
         return this.expression;
 114  
 
 115  
     }
 116  
 
 117  
 
 118  
     /**
 119  
      * <p>Return the hash code for this expression.</p>
 120  
      */
 121  
     public int hashCode() {
 122  
 
 123  
         return this.expression.hashCode();
 124  
 
 125  
     }
 126  
 
 127  
 
 128  
     /**
 129  
      * <p>Return <code>true</code> if the expression string for this expression
 130  
      * contains only literal text.</p>
 131  
      */
 132  
     public boolean isLiteralText() {
 133  
 
 134  2
         return (expression.indexOf("${") < 0) && (expression.indexOf("#{") < 0);
 135  
 
 136  
     }
 137  
 
 138  
 
 139  
     // ------------------------------------------------- ValueExpression Methods
 140  
 
 141  
 
 142  
     /**
 143  
      * <p>Return the type that the result of this expression will
 144  
      * be coerced to.</p>
 145  
      */
 146  
     public Class getExpectedType() {
 147  
 
 148  1
         return this.expectedType;
 149  
 
 150  
     }
 151  
 
 152  
 
 153  
     /**
 154  
      * <p>Evaluate this expression relative to the specified context,
 155  
      * and return the most general type that is acceptable for the
 156  
      * value passed in a <code>setValue()</code> call.</p>
 157  
      *
 158  
      * @param context ELContext for this evaluation
 159  
      */
 160  
     public Class getType(ELContext context) {
 161  
 
 162  
         if (context == null) {
 163  
             throw new NullPointerException();
 164  
         }
 165  
         Object value = getValue(context);
 166  
         if (value == null) {
 167  
             return null;
 168  
         } else {
 169  
             return value.getClass();
 170  
         }
 171  
 
 172  
     }
 173  
 
 174  
 
 175  
     /**
 176  
      * <p>Evaluate this expression relative to the specified context,
 177  
      * and return the result.</p>
 178  
      *
 179  
      * @param context ELContext for this evaluation
 180  
      */
 181  
     public Object getValue(ELContext context) {
 182  
 
 183  1
         if (context == null) {
 184  
             throw new NullPointerException();
 185  
         }
 186  1
         if (isLiteralText()) {
 187  
             return expression;
 188  
         }
 189  
 
 190  2
         FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
 191  1
         ELResolver resolver = fcontext.getApplication().getELResolver();
 192  1
         Object base = null;
 193  3
         for (int i = 0; i < elements.length; i++) {
 194  2
             base = resolver.getValue(context, base, elements[i]);
 195  
         }
 196  1
         return fcontext.getApplication().getExpressionFactory().coerceToType(base, getExpectedType());
 197  
 
 198  
     }
 199  
 
 200  
 
 201  
     /**
 202  
      * <p>Evaluate this expression relative to the specified context,
 203  
      * and return <code>true</code> if a call to <code>setValue()</code>
 204  
      * will always fail.</p>
 205  
      *
 206  
      * @param context ELContext for this evaluation
 207  
      */
 208  
     public boolean isReadOnly(ELContext context) {
 209  
 
 210  
         if (context == null) {
 211  
             throw new NullPointerException();
 212  
         }
 213  
         if (isLiteralText()) {
 214  
             return true;
 215  
         }
 216  
 
 217  
         FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
 218  
         ELResolver resolver = fcontext.getApplication().getELResolver();
 219  
         Object base = null;
 220  
         for (int i = 0; i < elements.length - 1; i++) {
 221  
             base = resolver.getValue(context, base, elements[i]);
 222  
         }
 223  
         return resolver.isReadOnly(context, base, elements[elements.length - 1]);
 224  
 
 225  
     }
 226  
 
 227  
 
 228  
 
 229  
     /**
 230  
      * <p>Evaluate this expression relative to the specified context,
 231  
      * and set the result to the specified value.</p>
 232  
      *
 233  
      * @param context ELContext for this evaluation
 234  
      * @param value Value to which the result should be set
 235  
      */
 236  
     public void setValue(ELContext context, Object value) {
 237  
 
 238  
         if (context == null) {
 239  
             throw new NullPointerException();
 240  
         }
 241  
 
 242  
         FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
 243  
         ELResolver resolver = fcontext.getApplication().getELResolver();
 244  
         Object base = null;
 245  
         for (int i = 0; i < elements.length - 1; i++) {
 246  
             base = resolver.getValue(context, base, elements[i]);
 247  
         }
 248  
         resolver.setValue(context, base, elements[elements.length - 1], value);
 249  
 
 250  
     }
 251  
 
 252  
 
 253  
     // --------------------------------------------------------- Private Methods
 254  
 
 255  
 
 256  
     /**
 257  
      * <p>Parse the expression string into its constituent elemetns.</p>
 258  
      */
 259  
     private void parse() {
 260  
 
 261  1
         if (isLiteralText()) {
 262  
             elements = new String[0];
 263  
             return;
 264  
         }
 265  
 
 266  1
         if (expression.startsWith("${") || expression.startsWith("#{")) {
 267  1
             if (expression.endsWith("}")) {               
 268  1
                 List names = new ArrayList();
 269  1
                 StringBuffer expr = new StringBuffer(expression.substring(2, expression.length() - 1).replaceAll(" ", ""));
 270  1
                 boolean isBlockOn = false;
 271  38
                 for (int i = expr.length() - 1; i > -1; i--) {
 272  37
                     if (expr.charAt(i) == ' ') {
 273  
                         expr.deleteCharAt(i);
 274  
                     } else if (expr.charAt(i) == ']') {
 275  1
                         expr.deleteCharAt(i);
 276  1
                     } else if (expr.charAt(i) == '[') {
 277  1
                         expr.deleteCharAt(i);
 278  1
                     } else if (expr.charAt(i) == '\'') {
 279  2
                         if (!isBlockOn) {
 280  1
                             expr.deleteCharAt(i);
 281  1
                         } else {
 282  1
                             names.add(0, expr.substring(i + 1));
 283  1
                             expr.delete(i, expr.length());
 284  
                         }
 285  2
                         isBlockOn = !isBlockOn;
 286  2
                     } else if (expr.charAt(i) == '.' && !isBlockOn) {
 287  
                         names.add(0, expr.substring(i + 1));
 288  
                         expr.delete(i, expr.length());
 289  
                     }
 290  
                 }
 291  1
                 if (expr.length() > 0) {
 292  1
                     names.add(0, expr.toString());
 293  
                 }
 294  
 
 295  1
                 elements = (String[]) names.toArray(new String[names.size()]);
 296  1
             } else {
 297  
                 throw new IllegalArgumentException(expression);
 298  
             }
 299  
         } else {
 300  
             throw new IllegalArgumentException(expression);
 301  
         }
 302  
 
 303  1
     }
 304  
 
 305  
 
 306  
 }