Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/myfaces/el/MethodBindingImpl.java


1   /*
2    * Copyright 2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.myfaces.el;
17  
18  import org.apache.myfaces.el.ValueBindingImpl.NotVariableReferenceException;
19  
20  import org.apache.commons.beanutils.MethodUtils;
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  import javax.faces.application.Application;
25  import javax.faces.component.StateHolder;
26  import javax.faces.context.FacesContext;
27  import javax.faces.el.*;
28  import javax.faces.event.AbortProcessingException;
29  import javax.faces.validator.ValidatorException;
30  import javax.servlet.jsp.el.ELException;
31  import java.lang.reflect.InvocationTargetException;
32  import java.lang.reflect.Method;
33  
34  
35  /**
36   * @author Anton Koinov (latest modification by $Author: oros $)
37   * @version $Revision: 278654 $ $Date: 2005-09-04 20:32:35 -0400 (Sun, 04 Sep 2005) $
38   */
39  public class MethodBindingImpl extends MethodBinding
40      implements StateHolder
41  {
42      static final Log log = LogFactory.getLog(MethodBindingImpl.class);
43  
44      //~ Instance fields -------------------------------------------------------
45  
46      ValueBindingImpl _valueBinding;
47      Class[]          _argClasses;
48  
49      //~ Constructors ----------------------------------------------------------
50  
51      public MethodBindingImpl(Application application, String reference,
52          Class[] argClasses)
53      {
54          // Note: using ValueBindingImpl, istead of creating a common subclass,
55          //       to share single Expression cache
56          // Note: we can trim() reference, since string-binding mixed
57          //       expressions are not allowed for MethodBindings
58          _valueBinding = new ValueBindingImpl(application, reference.trim());
59          _argClasses = argClasses;
60      }
61  
62      //~ Methods ---------------------------------------------------------------
63  
64      public String getExpressionString()
65      {
66          return _valueBinding._expressionString;
67      }
68  
69      public Class getType(FacesContext facesContext)
70      {
71          if (facesContext == null) {
72              throw new NullPointerException("facesContext");
73          }
74          try
75          {
76              Object[] baseAndProperty = resolveToBaseAndProperty(facesContext);
77              Object base = baseAndProperty[0];
78              Object property = baseAndProperty[1];
79  
80              Class returnType = base.getClass().getMethod(property.toString(), _argClasses).getReturnType();
81  
82              if (returnType.getName().equals("void")) {
83                  // the spec document says: "if type is void return null"
84                  // but the RI returns Void.class, so let's follow the RI
85                  return Void.class;
86              }
87              return returnType;
88          }
89          catch (ReferenceSyntaxException e)
90          {
91              throw e;
92          }
93          catch (IndexOutOfBoundsException e)
94          {
95              // ArrayIndexOutOfBoundsException also here
96              throw new PropertyNotFoundException("Expression: "
97                  + getExpressionString(), e);
98          }
99          catch (Exception e)
100         {
101             throw new EvaluationException("Cannot get type for expression "
102                 + getExpressionString(), e);
103         }
104     }
105 
106     public Object invoke(FacesContext facesContext, Object[] args)
107         throws EvaluationException, MethodNotFoundException
108     {
109         if (facesContext == null) {
110             throw new NullPointerException("facesContext");
111         }
112         try
113         {
114             Object[] baseAndProperty = resolveToBaseAndProperty(facesContext);
115             Object base = baseAndProperty[0];
116             Object property = baseAndProperty[1];
117 
118             Method m = base.getClass().getMethod(property.toString(), _argClasses);
119 
120             // Check if the concrete class of this method is accessible and if not
121             // search for a public interface that declares this method
122             m = MethodUtils.getAccessibleMethod(m);
123             if (m == null)
124             {
125                 throw new MethodNotFoundException(
126                     getExpressionString() + " (not accessible!)");
127             }
128 
129             return m.invoke(base, args);
130         }
131         catch (ReferenceSyntaxException e)
132         {
133             throw e;
134         }
135         catch (IndexOutOfBoundsException e)
136         {
137             // ArrayIndexOutOfBoundsException also here
138             throw new PropertyNotFoundException("Expression: "
139                 + getExpressionString(), e);
140         }
141         catch (InvocationTargetException e)
142         {
143             Throwable cause = e.getCause();
144             if (cause != null)
145             {
146                 if (cause instanceof ValidatorException ||
147                     cause instanceof AbortProcessingException)
148                 {
149                     throw new EvaluationException(cause);
150                 }
151                 else
152                 {
153                     throw new EvaluationException("Exception while invoking expression "
154                         + getExpressionString(), cause);
155                 }
156             }
157             else
158             {
159                 throw new EvaluationException("Exception while invoking expression "
160                     + getExpressionString(), e);
161             }
162         }
163         catch (Exception e)
164         {
165             throw new EvaluationException("Exception while invoking expression "
166                 + getExpressionString(), e);
167         }
168     }
169 
170     protected Object[] resolveToBaseAndProperty(FacesContext facesContext)
171         throws ELException
172     {
173         if (facesContext == null)
174         {
175             throw new NullPointerException("facesContext");
176         }
177 
178         try
179         {
180             Object base = _valueBinding.resolveToBaseAndProperty(facesContext);
181 
182             if (!(base instanceof Object[]))
183             {
184                 String errorMessage = "Expression not a valid method binding: "
185                     + getExpressionString();
186                 throw new ReferenceSyntaxException(errorMessage);
187             }
188 
189             return (Object[]) base;
190         }
191         catch (NotVariableReferenceException e)
192         {
193             throw new ReferenceSyntaxException("Expression: "
194                 + getExpressionString(), e);
195         }
196     }
197 
198     public String toString()
199     {
200         return _valueBinding.toString();
201     }
202 
203     //~ StateHolder implementation --------------------------------------------
204 
205     private boolean _transient = false;
206 
207     /**
208      * Empty constructor, so that new instances can be created when restoring
209      * state.
210      */
211     public MethodBindingImpl()
212     {
213         _valueBinding = null;
214         _argClasses = null;
215     }
216 
217     public Object saveState(FacesContext facescontext)
218     {
219         return new Object[] { _valueBinding.saveState(facescontext),
220             _argClasses};
221     }
222 
223     public void restoreState(FacesContext facescontext, Object obj)
224     {
225         Object[] ar = (Object[]) obj;
226         _valueBinding = new ValueBindingImpl();
227         _valueBinding.restoreState(facescontext, ar[0]);
228         _argClasses = (Class[]) ar[1];
229     }
230 
231     public boolean isTransient()
232     {
233         return _transient;
234     }
235 
236     public void setTransient(boolean flag)
237     {
238         _transient = flag;
239     }
240 
241 }