Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]

    1   /*
    2    * $Id: MethodExpressionMethodBindingAdapter.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 javax.el.MethodExpression;
   44   import javax.el.ELException;
   45   import javax.el.ELContext;
   46   import javax.el.MethodInfo;
   47   import javax.faces.el.MethodBinding;
   48   import javax.faces.context.FacesContext;
   49   import javax.faces.component.StateHolder;
   50   import javax.el.ELContext;
   51   import javax.el.ExpressionFactory;
   52   import javax.el.ValueExpression;
   53   
   54   import java.util.Arrays;
   55   import java.lang.reflect.Method;
   56   import java.io.Serializable;
   57   
   58   /**
   59    * <p>Wrap a MethodBinding instance and expose it as a
   60    * MethodExpression.</p>
   61    */
   62   
   63    class MethodExpressionMethodBindingAdapter extends MethodExpression implements Serializable, StateHolder {
   64   
   65       private static final long serialVersionUID = -1822420567946048452L;
   66   
   67       public MethodExpressionMethodBindingAdapter() {} // for StateHolder
   68   
   69       private MethodBinding binding = null;
   70   
   71        MethodExpressionMethodBindingAdapter(MethodBinding binding) {
   72   	assert(null != binding);
   73   	this.binding = binding;
   74       }
   75   
   76       //
   77       // Methods from MethodExpression
   78       //
   79   
   80       private transient MethodInfo info = null;
   81   
   82       public MethodInfo getMethodInfo(ELContext context) throws ELException {
   83   	assert(null != binding);
   84   	
   85   	if (context == null) {
   86   	    throw new NullPointerException("ELContext -> null");
   87       }
   88   
   89   	if (null == info) {
   90   	    FacesContext facesContext = (FacesContext) 
   91   		context.getContext(FacesContext.class);
   92   	    if (null != facesContext) {
   93   		try {
   94   		    //PENDING - we should find a way to provide more information
   95   		    info = new MethodInfo(null, binding.getType(facesContext), null);
   96   		}
   97   		catch (Exception e) {
   98   		    throw new ELException(e);
   99   		}
  100   	    }
  101   	}
  102   		
  103   	return info;
  104       }
  105       
  106       public Object invoke(ELContext context, Object[] params) throws ELException {
  107   	assert(null != binding);
  108   	
  109   	if (context == null) {
  110   	    throw new NullPointerException("ELContext -> null");
  111       }
  112   
  113   	Object result = null;
  114   	FacesContext facesContext = (FacesContext) 
  115   	    context.getContext(FacesContext.class);
  116   	if (null != facesContext) {
  117   	    try {
  118   		result = binding.invoke(facesContext, params);
  119   	    }
  120   	    catch (Exception e) {
  121   		throw new ELException(e);
  122   	    }
  123   	}
  124   	return result;
  125       }
  126   
  127       public String getExpressionString() {
  128   	assert(null != binding);
  129   	return binding.getExpressionString();
  130   	
  131       }
  132   
  133       public boolean isLiteralText() {
  134           assert (binding != null);
  135           String expr = binding.getExpressionString();
  136           return (!(expr.startsWith("#{")
  137               && expr.endsWith("}")));    
  138       }
  139   
  140       public boolean equals(Object other) {              
  141           
  142           if (other == this) {
  143               return true;
  144           }
  145           
  146           if (other instanceof MethodExpressionMethodBindingAdapter) {
  147               MethodBinding ob = ((MethodExpressionMethodBindingAdapter) other).getWrapped();
  148               return (binding.equals(ob));
  149           } else if (other instanceof MethodExpression) {
  150               MethodExpression expression = (MethodExpression) other;
  151               
  152               // We'll need to do a little leg work to determine
  153               // if the MethodBinding is equivalent to the 
  154               // wrapped MethodExpression
  155               String expr = binding.getExpressionString();
  156               int idx = expr.indexOf('.');
  157               String target = expr.substring(0, idx).substring(2);
  158               String t = expr.substring(idx + 1);
  159               String method = t.substring(0, (t.length() - 1));
  160               
  161               FacesContext context = FacesContext.getCurrentInstance();
  162               ELContext elContext = context.getELContext();
  163               MethodInfo controlInfo = expression.getMethodInfo(elContext);
  164               
  165               // ensure the method names are the same
  166               if (!controlInfo.getName().equals(method)) {
  167                   return false;
  168               }
  169               
  170               // Using the target, create an expression and evaluate
  171               // it.           
  172               ExpressionFactory factory = context.getApplication().getExpressionFactory();
  173               ValueExpression ve = factory.createValueExpression(elContext,
  174                                                                  "#{" + target + '}',
  175                                                                  Object.class);
  176               if (ve == null) {
  177                   return false;
  178               }                
  179                                                 
  180               Object result = ve.getValue(elContext);
  181               
  182               if (result == null) {
  183                   return false;
  184               }
  185               
  186               
  187               // Get all of the methods with the matching name and try
  188               // to find a match based on controlInfo's return and parameter
  189               // types
  190               Method[] methods = result.getClass().getMethods();
  191               for (Method meth : methods) {
  192                   if (meth.getName().equals(method)
  193                        && meth.getReturnType().equals(controlInfo.getReturnType())
  194                        && Arrays.equals(meth.getParameterTypes(), 
  195                                         controlInfo.getParamTypes())) {
  196                       return true;                      
  197                   }
  198               }
  199           }
  200           return false;
  201           
  202       }
  203   
  204       public int hashCode() {
  205   	assert(null != binding);
  206   
  207   	return binding.hashCode();
  208       }
  209       
  210       public String getDelimiterSyntax() {
  211          // PENDING (visvan) Implementation
  212           return "";
  213       }
  214       
  215       // 
  216       // Methods from StateHolder
  217       //
  218   
  219       
  220   
  221       public Object saveState(FacesContext context) {
  222           if (context == null) {
  223               throw new NullPointerException();
  224           }
  225   	Object result = null;
  226   	if (!tranzient) {
  227   	    if (binding instanceof StateHolder) {
  228   		Object [] stateStruct = new Object[2];
  229   		
  230   		// save the actual state of our wrapped binding
  231   		stateStruct[0] = ((StateHolder)binding).saveState(context);
  232   		// save the class name of the binding impl
  233   		stateStruct[1] = binding.getClass().getName();
  234   
  235   		result = stateStruct;
  236   	    }
  237   	    else {
  238   		result = binding;
  239   	    }
  240   	}
  241   
  242   	return result;
  243       }
  244   
  245       public void restoreState(FacesContext context, Object state) {
  246           if (context == null) {
  247               throw new NullPointerException();
  248           }
  249   	// if we have state
  250   	if (null == state) {
  251   	    return;
  252   	}
  253   	
  254   	if (!(state instanceof MethodBinding)) {
  255   	    Object [] stateStruct = (Object []) state;
  256   	    Object savedState = stateStruct[0];
  257   	    String className = stateStruct[1].toString();
  258   	    MethodBinding result = null;
  259   	    
  260   	    Class toRestoreClass = null;
  261   	    if (null != className) {
  262   		try {
  263   		    toRestoreClass = loadClass(className, this);
  264   		}
  265   		catch (ClassNotFoundException e) {
  266   		    throw new IllegalStateException(e.getMessage());
  267   		}
  268   		
  269   		if (null != toRestoreClass) {
  270   		    try {
  271   			result = 
  272   			    (MethodBinding) toRestoreClass.newInstance();
  273   		    }
  274   		    catch (InstantiationException e) {
  275   			throw new IllegalStateException(e.getMessage());
  276   		    }
  277   		    catch (IllegalAccessException a) {
  278   			throw new IllegalStateException(a.getMessage());
  279   		    }
  280   		}
  281   		
  282   		if (null != result && null != savedState) {
  283   		    // don't need to check transient, since that was
  284   		    // done on the saving side.
  285   		    ((StateHolder)result).restoreState(context, savedState);
  286   		}
  287   		binding = result;
  288   	    }
  289   	}
  290   	else {
  291   	    binding = (MethodBinding) state;
  292   	}
  293       }
  294   
  295       private boolean tranzient = false;
  296   
  297       public boolean isTransient() {
  298   	return tranzient;
  299       }
  300   
  301       public void setTransient(boolean newTransientMethod) {
  302   	tranzient = newTransientMethod;
  303       }
  304   
  305       //
  306       // Helper methods for StateHolder
  307       //
  308   
  309       private static Class loadClass(String name, 
  310               Object fallbackClass) throws ClassNotFoundException {
  311           ClassLoader loader =
  312               Thread.currentThread().getContextClassLoader();
  313           if (loader == null) {
  314               loader = fallbackClass.getClass().getClassLoader();
  315           }
  316            return Class.forName(name, true, loader);
  317       }
  318    
  319   
  320       // 
  321       // methods used by classes aware of this class's wrapper nature
  322       //
  323   
  324       public MethodBinding getWrapped() {
  325   	return binding;
  326       }
  327   
  328   }

Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]