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

For more information, please explore the Attic.

View Javadoc

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.lang.reflect.Method;
21  import java.util.ArrayList;
22  import java.util.List;
23  import javax.el.ELContext;
24  import javax.el.ELException;
25  import javax.el.ELResolver;
26  import javax.el.MethodExpression;
27  import javax.el.MethodInfo;
28  import javax.faces.context.FacesContext;
29  
30  /***
31   * <p>Mock implementation of <code>MethodExpression</code>.</p>
32   */
33  public class MockMethodExpression extends MethodExpression {
34      
35  
36      // ------------------------------------------------------------ Constructors
37  
38  
39      /***
40       * Serial version UID.
41       */
42      private static final long serialVersionUID = 5694105394290316715L;
43  
44  
45      /***
46       * <p>Construct a new expression for the specified expression string.</p>
47       *
48       * @param expression Expression string to be evaluated
49       * @param signature Parameter signature of the method to be called
50       * @param expectedType Expected type of the result
51       */
52      public MockMethodExpression(String expression, Class[] signature, Class expectedType) {
53  
54          if (expression == null) {
55              throw new NullPointerException("Expression string cannot be null");
56          }
57          this.expression = expression;
58          this.signature = signature;
59          this.expectedType = expectedType;
60          parse();
61  
62      }
63  
64  
65      // ------------------------------------------------------ Instance Variables
66  
67  
68      /***
69       * <p>The parsed elements of this expression.</p>
70       */
71      private String[] elements = null;
72  
73  
74      /***
75       * <p>The expected result type for <code>getValue()</code> calls.</p>
76       */
77      private Class expectedType = null;
78  
79  
80      /***
81       * <p>The original expression string used to create this expression.</p>
82       */
83      private String expression = null;
84  
85  
86      /***
87       * <p>The method signature of the method to be called.</p>
88       */
89      private Class[] signature = null;
90  
91  
92      // ------------------------------------------------------ Expression Methods
93  
94  
95      /***
96       * <p>Return <code>true</code> if this expression is equal to the
97       * specified expression.</p>
98       *
99       * @param obj Object to be compared
100      */
101     public boolean equals(Object obj) {
102 
103         if ((obj != null) & (obj instanceof MethodExpression)) {
104             return expression.equals(((MethodExpression) obj).getExpressionString());
105         } else {
106             return false;
107         }
108 
109     }
110 
111 
112     /***
113      * <p>Return the original String used to create this expression,
114      * unmodified.</p>
115      */
116     public String getExpressionString() {
117 
118         return this.expression;
119 
120     }
121 
122 
123     /***
124      * <p>Return the hash code for this expression.</p>
125      */
126     public int hashCode() {
127 
128         return this.expression.hashCode();
129 
130     }
131 
132 
133     /***
134      * <p>Return <code>true</code> if the expression string for this expression
135      * contains only literal text.</p>
136      */
137     public boolean isLiteralText() {
138 
139         return (expression.indexOf("${") < 0) && (expression.indexOf("#{") < 0);
140 
141     }
142 
143 
144     // ------------------------------------------------ MethodExpression Methods
145 
146 
147     /***
148      * <p>Evaluate the expression relative to the specified context,
149      * and return information about the actual implementation method.</p>
150      *
151      * @param context ELContext for this evaluation
152      */
153     public MethodInfo getMethodInfo(ELContext context) {
154 
155         if (context == null) {
156             throw new NullPointerException();
157         }
158         return new MethodInfo(elements[elements.length - 1], expectedType, signature);
159 
160     }
161 
162 
163     /***
164      * <p>Evaluate the expression relative to the specified ocntext,
165      * and return the result after coercion to the expected result type.</p>
166      *
167      * @param context ELContext for this evaluation
168      * @param params Parameters for this method call
169      */
170     public Object invoke(ELContext context, Object[] params) {
171 
172         if (context == null) {
173             throw new NullPointerException();
174         }
175         if (isLiteralText()) {
176             return expression;
177         }
178 
179         FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
180         ELResolver resolver = fcontext.getApplication().getELResolver();
181         Object base = null;
182         for (int i = 0; i < elements.length - 1; i++) {
183             base = resolver.getValue(context, base, elements[i]);
184         }
185 
186         try {
187             Method method = base.getClass().getMethod(elements[elements.length - 1], signature);
188             Object result = method.invoke(base, params);
189             return fcontext.getApplication().getExpressionFactory().coerceToType(result, expectedType);
190         } catch (RuntimeException e) {
191             throw e;
192         } catch (Exception e) {
193             throw new ELException(e);
194         }
195 
196     }
197 
198 
199     // --------------------------------------------------------- Private Methods
200 
201 
202     /***
203      * <p>Parse the expression string into its constituent elemetns.</p>
204      */
205     private void parse() {
206 
207         if (isLiteralText()) {
208             elements = new String[0];
209             return;
210         }
211 
212         if (expression.startsWith("${") || expression.startsWith("#{")) {
213             if (expression.endsWith("}")) {
214                 String temp = expression.substring(2, expression.length() - 1).replaceAll(" ", "");
215                 List names = new ArrayList();
216                 while (temp.length() > 0) {
217                     int period= temp.indexOf(".");
218                     if (period >= 0) {
219                         names.add(temp.substring(0, period));
220                         temp = temp.substring(period + 1);
221                     } else {
222                         names.add(temp);
223                         temp = "";
224                     }
225                 }
226                 elements = (String[]) names.toArray(new String[names.size()]);
227             } else {
228                 throw new IllegalArgumentException(expression);
229             }
230         } else {
231             throw new IllegalArgumentException(expression);
232         }
233 
234     }
235 
236 
237 }