Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.component » [javadoc | source]
    1   /*
    2    * $Id: MethodBindingMethodExpressionAdapter.java,v 1.7 2007/04/27 22:00:12 ofung Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40    
   41   package javax.faces.component;
   42   
   43   import java.io.Serializable;
   44   
   45   import javax.faces.component.StateHolder;
   46   import javax.faces.context.FacesContext;
   47   import javax.faces.el.EvaluationException;
   48   import javax.faces.el.ReferenceSyntaxException;
   49   import javax.faces.el.MethodBinding;
   50   
   51   import javax.el.MethodExpression;
   52   import javax.el.MethodInfo;
   53   import javax.el.ELException;
   54   import javax.el.ELContext;
   55   import javax.el.ExpressionFactory;
   56   import javax.el.ValueExpression;
   57   
   58   import java.util.Arrays;
   59   import java.lang.reflect.Method;
   60   
   61   /**
   62    * <p>Wrap a MethodExpression instance and expose it as a MethodBinding</p>
   63    *
   64    */
   65    class MethodBindingMethodExpressionAdapter extends MethodBinding implements StateHolder, 
   66       Serializable {
   67   
   68       private static final long serialVersionUID = 7334926223014401689L;
   69   
   70       private MethodExpression methodExpression= null;
   71       private boolean tranzient;
   72   
   73       public MethodBindingMethodExpressionAdapter() {} // for StateHolder
   74       
   75        MethodBindingMethodExpressionAdapter(MethodExpression methodExpression) {
   76           this.methodExpression = methodExpression;    
   77       }
   78   
   79       public Object invoke(FacesContext context, Object params[])
   80           throws javax.faces.el.EvaluationException, javax.faces.el.MethodNotFoundException {
   81   	assert(null != methodExpression);
   82           if ( context == null ) {
   83               throw new NullPointerException("FacesConext -> null");
   84           }
   85           
   86   	Object result = null;
   87   	try {
   88   	    result = methodExpression.invoke(context.getELContext(),
   89   					     params);
   90   	}
   91   	catch (javax.el.MethodNotFoundException e) {
   92   	    throw new javax.faces.el.MethodNotFoundException(e);
   93   	}
   94   	catch (javax.el.PropertyNotFoundException e) {
   95   	    throw new EvaluationException(e);
   96   	}
   97   	catch (ELException e) {
   98               Throwable cause = e.getCause();
   99               if (cause == null) {
  100                   cause = e;
  101               }
  102               throw new EvaluationException(cause);
  103   	} catch (NullPointerException e) {
  104   	    throw new javax.faces.el.MethodNotFoundException(e);
  105   	}
  106   	return result;
  107       }
  108   
  109       public Class getType(FacesContext context) throws javax.faces.el.MethodNotFoundException {
  110   	assert(null != methodExpression);
  111   	if (context == null) {
  112   	        throw new NullPointerException("FacesConext -> null");
  113       }
  114   	Class result = null;
  115           if ( context == null ) {
  116               throw new NullPointerException();
  117           }
  118           
  119   	try {
  120   	    MethodInfo mi = 
  121   		methodExpression.getMethodInfo(context.getELContext());
  122   	    result = mi.getReturnType();
  123   	}
  124   	catch (javax.el.PropertyNotFoundException e) {
  125   	    throw new javax.faces.el.MethodNotFoundException(e);
  126   	}
  127   	catch (javax.el.MethodNotFoundException e) {
  128   	    throw new javax.faces.el.MethodNotFoundException(e);
  129   	}
  130   	catch (ELException e) {
  131   	    throw new javax.faces.el.MethodNotFoundException(e);
  132   	}
  133   	return result;
  134       }
  135       
  136      
  137       public String getExpressionString() {
  138   	assert(null != methodExpression);
  139           return methodExpression.getExpressionString();
  140       }
  141   
  142       public boolean equals(Object other) {
  143           if (this == other) {
  144               return true;       
  145           }
  146           if (other instanceof MethodBindingMethodExpressionAdapter) {
  147               return methodExpression.equals(((MethodBindingMethodExpressionAdapter) other).getWrapped());                        
  148           } else if (other instanceof MethodBinding) {
  149               MethodBinding binding = (MethodBinding) other;
  150               
  151               // We'll need to do a little leg work to determine
  152               // if the MethodBinding is equivalent to the 
  153               // wrapped MethodExpression
  154               String expr = binding.getExpressionString();
  155               int idx = expr.indexOf('.');
  156               String target = expr.substring(0, idx).substring(2);
  157               String t = expr.substring(idx + 1);
  158               String method = t.substring(0, (t.length() - 1));
  159               
  160               FacesContext context = FacesContext.getCurrentInstance();
  161               ELContext elContext = context.getELContext();
  162               MethodInfo controlInfo = methodExpression.getMethodInfo(elContext);
  163               
  164               // ensure the method names are the same
  165               if (!controlInfo.getName().equals(method)) {
  166                   return false;
  167               }
  168               
  169               // Using the target, create an expression and evaluate
  170               // it.           
  171               ExpressionFactory factory = context.getApplication().getExpressionFactory();
  172               ValueExpression ve = factory.createValueExpression(elContext,
  173                                                                  "#{" + target + '}',
  174                                                                  Object.class);
  175               if (ve == null) {
  176                   return false;                                                               
  177               }
  178               
  179               Object result = ve.getValue(elContext);
  180               
  181               if (result == null) {
  182                   return false;
  183               }
  184               
  185               // Get all of the methods with the matching name and try
  186               // to find a match based on controlInfo's return and parameter
  187               // types
  188               Class type = binding.getType(context);
  189               Method[] methods = result.getClass().getMethods();
  190               for (Method meth : methods) {
  191                   if (meth.getName().equals(method)
  192                        && type.equals(controlInfo.getReturnType())
  193                        && Arrays.equals(meth.getParameterTypes(), 
  194                                         controlInfo.getParamTypes())) {
  195                       return true;                      
  196                   }
  197               }
  198           }
  199           
  200           return false;
  201           
  202       }
  203   
  204       public int hashCode() {
  205   	assert(null != methodExpression);
  206   
  207   	return methodExpression.hashCode();
  208       }
  209   
  210   
  211       public boolean isTransient() {
  212           return this.tranzient;
  213       }
  214       
  215       public void setTransient(boolean tranzient) {
  216           this.tranzient = tranzient;
  217       }
  218       
  219       public Object saveState(FacesContext context){
  220   	Object result = null;
  221   	if (!tranzient) {
  222   	    if (methodExpression instanceof StateHolder) {
  223   		Object [] stateStruct = new Object[2];
  224   		
  225   		// save the actual state of our wrapped methodExpression
  226   		stateStruct[0] = ((StateHolder)methodExpression).saveState(context);
  227   		// save the class name of the methodExpression impl
  228   		stateStruct[1] = methodExpression.getClass().getName();
  229   
  230   		result = stateStruct;
  231   	    }
  232   	    else {
  233   		result = methodExpression;
  234   	    }
  235   	}
  236   
  237   	return result;
  238   	
  239       }
  240   
  241       public void restoreState(FacesContext context, Object state) {
  242   	// if we have state
  243   	if (null == state) {
  244   	    return;
  245   	}
  246   	
  247   	if (!(state instanceof MethodExpression)) {
  248   	    Object [] stateStruct = (Object []) state;
  249   	    Object savedState = stateStruct[0];
  250   	    String className = stateStruct[1].toString();
  251   	    MethodExpression result = null;
  252   	    
  253   	    Class toRestoreClass = null;
  254   	    if (null != className) {
  255   		try {
  256   		    toRestoreClass = loadClass(className, this);
  257   		}
  258   		catch (ClassNotFoundException e) {
  259   		    throw new IllegalStateException(e.getMessage());
  260   		}
  261   		
  262   		if (null != toRestoreClass) {
  263   		    try {
  264   			result = 
  265   			    (MethodExpression) toRestoreClass.newInstance();
  266   		    }
  267   		    catch (InstantiationException e) {
  268   			throw new IllegalStateException(e.getMessage());
  269   		    }
  270   		    catch (IllegalAccessException a) {
  271   			throw new IllegalStateException(a.getMessage());
  272   		    }
  273   		}
  274   		
  275   		if (null != result && null != savedState) {
  276   		    // don't need to check transient, since that was
  277   		    // done on the saving side.
  278   		    ((StateHolder)result).restoreState(context, savedState);
  279   		}
  280   		methodExpression = result;
  281   	    }
  282   	}
  283   	else {
  284   	    methodExpression = (MethodExpression) state;
  285   	}
  286       }
  287       
  288       public MethodExpression getWrapped() {
  289           return methodExpression;
  290       }
  291   
  292       //
  293       // Helper methods for StateHolder
  294       //
  295   
  296       private static Class loadClass(String name, 
  297               Object fallbackClass) throws ClassNotFoundException {
  298           ClassLoader loader =
  299               Thread.currentThread().getContextClassLoader();
  300           if (loader == null) {
  301               loader = fallbackClass.getClass().getClassLoader();
  302           }
  303           return Class.forName(name, true, loader);
  304       }
  305    
  306   
  307   
  308   }

Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.component » [javadoc | source]