You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2010/01/22 05:59:45 UTC

svn commit: r901997 - in /geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el: BeanELResolver.java CompositeELResolver.java ELContext.java ELResolver.java MethodExpression.java ValueExpression.java

Author: xuhaihong
Date: Fri Jan 22 04:59:44 2010
New Revision: 901997

URL: http://svn.apache.org/viewvc?rev=901997&view=rev
Log:
Implement BeanELResolver/CompositeELResolver.invoke method

Modified:
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/BeanELResolver.java
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/CompositeELResolver.java
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELContext.java
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELResolver.java
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/MethodExpression.java
    geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ValueExpression.java

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/BeanELResolver.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/BeanELResolver.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/BeanELResolver.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/BeanELResolver.java Fri Jan 22 04:59:44 2010
@@ -22,6 +22,7 @@
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -32,6 +33,7 @@
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 
+
 public class BeanELResolver extends ELResolver {
 
 	private final boolean readOnly;
@@ -345,7 +347,107 @@
 	}
 
     public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
-        // TODO Auto-generated method stub
-        return null;
+        if (context == null) {
+            throw new NullPointerException("ELContext could not be nulll");
+        }
+        // Why static invocation is not supported
+        if(base == null || method == null) {
+            return null;
+        }
+        if (params == null) {
+            params = new Object[0];
+        }
+        ExpressionFactory expressionFactory = (ExpressionFactory) context.getContext(ExpressionFactory.class);
+        if (expressionFactory == null) {
+            expressionFactory = ExpressionFactory.newInstance();
+        }
+        String methodName = (String) expressionFactory.coerceToType(method, String.class);
+        if (methodName.length() == 0) {
+            throw new MethodNotFoundException("The parameter method could not be zero-length");
+        }
+        Class<?> targetClass = base.getClass();
+        if (methodName.equals("<init>") || methodName.equals("<cinit>")) {
+            throw new MethodNotFoundException(method + " is not found in target class " + targetClass.getName());
+        }
+        Method targetMethod = null;
+        if (paramTypes == null) {
+            int paramsNumber = params.length;
+            for (Method m : targetClass.getMethods()) {
+                if (m.getName().equals(methodName) && m.getParameterTypes().length == paramsNumber) {
+                    targetMethod = m;
+                    break;
+                }
+            }
+            if (targetMethod == null) {
+                for (Method m : targetClass.getMethods()) {
+                    if (m.getName().equals(methodName) && m.isVarArgs() && paramsNumber >= (m.getParameterTypes().length - 1)) {
+                        targetMethod = m;
+                        break;
+                    }
+                }
+            }
+        } else {
+            try {
+                targetMethod = targetClass.getMethod(methodName, paramTypes);
+            } catch (SecurityException e) {
+                throw new ELException(e);
+            } catch (NoSuchMethodException e) {
+                throw new MethodNotFoundException(e);
+            }
+        }
+        if (targetMethod == null) {
+            throw new MethodNotFoundException(method + " is not found in target class " + targetClass.getName());
+        }
+        if (paramTypes == null) {
+            paramTypes = targetMethod.getParameterTypes();
+        }
+        //Initial check whether the types and parameter values length
+        if (targetMethod.isVarArgs()) {
+            if (paramTypes.length - 1 > params.length) {
+                throw new IllegalArgumentException("Inconsistent number between argument types and values");
+            }
+        } else if (paramTypes.length != params.length) {
+            throw new IllegalArgumentException("Inconsistent number between argument types and values");
+        }
+        try {
+            Object[] finalParamValues = new Object[paramTypes.length];
+            int iCurrentIndex = 0;
+            for (int iLoopSize = paramTypes.length - 1; iCurrentIndex < iLoopSize; iCurrentIndex++) {
+                finalParamValues[iCurrentIndex] = expressionFactory.coerceToType(params[iCurrentIndex],paramTypes[iCurrentIndex]);
+            }
+            /**
+             * Not sure it is over-designed. Do not find detailed description about how the parameter values are passed if the method is of variable arguments.
+             * It might be an array directly passed or each parameter value passed one by one.
+             */
+            if (targetMethod.isVarArgs()) {
+                // varArgsClassType should be an array type
+                Class<?> varArgsClassType = paramTypes[iCurrentIndex];
+                // 1. If there is no parameter value left for the variable argment, create a zero-length array
+                // 2. If there is only one parameter value left for the variable argment, and it has the same array type with the varArgsClass, pass in directly
+                // 3. Eles, create an array of varArgsClass type, and add all the left coerced parameter values
+                if (iCurrentIndex == params.length) {
+                    finalParamValues[iCurrentIndex] = Array.newInstance(varArgsClassType.getComponentType(), 0);
+                } else if (iCurrentIndex == params.length - 1 && varArgsClassType == params[iCurrentIndex].getClass()
+                        && varArgsClassType.getClassLoader() == params[iCurrentIndex].getClass().getClassLoader()) {
+                    finalParamValues[iCurrentIndex] = paramTypes[iCurrentIndex];
+                } else {
+                    Object targetArray = Array.newInstance(varArgsClassType.getComponentType(), params.length - iCurrentIndex);
+                    Class<?> componentClassType = varArgsClassType.getComponentType();
+                    for (int i = 0, iLoopSize = params.length - iCurrentIndex; i < iLoopSize; i++) {
+                        Array.set(targetArray, i, expressionFactory.coerceToType(iCurrentIndex + i, componentClassType));
+                    }
+                    finalParamValues[iCurrentIndex] = targetArray;
+                }
+            } else {
+                finalParamValues[iCurrentIndex] = expressionFactory.coerceToType(params[iCurrentIndex], paramTypes[iCurrentIndex]);
+            }
+            Object retValue = targetMethod.invoke(base, finalParamValues);
+            context.setPropertyResolved(true);
+            return retValue;
+        }  catch (IllegalAccessException e) {
+            throw new ELException(e);
+        } catch (InvocationTargetException e) {
+            throw new ELException(e.getCause());
+        }
     }
 }

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/CompositeELResolver.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/CompositeELResolver.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/CompositeELResolver.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/CompositeELResolver.java Fri Jan 22 04:59:44 2010
@@ -199,7 +199,31 @@
 	}
 
     public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
-        // TODO Auto-generated method stub
+        if (context == null) {
+            throw new NullPointerException("ELContext could not be null");
+        }
+        if (method == null || base == null) {
+            return null;
+        }
+        ExpressionFactory expressionFactory = (ExpressionFactory) context.getContext(ExpressionFactory.class);
+        if (expressionFactory == null) {
+            expressionFactory = ExpressionFactory.newInstance();
+        }
+        String targetMethod = (String) expressionFactory.coerceToType(method, String.class);
+        if (targetMethod.length() == 0) {
+            throw new ELException(new NoSuchMethodException());
+        }
+        context.setPropertyResolved(false);
+        if (context.getContext(ExpressionFactory.class) == null) {
+            context.putContext(ExpressionFactory.class, ExpressionFactory.newInstance());
+        }
+        Object retValue = null;
+        for (ELResolver resolver : resolvers) {
+            retValue = resolver.invoke(context, base, targetMethod, paramTypes, params);
+            if (context.isPropertyResolved()) {
+                return retValue;
+            }
+        }
         return null;
     }
 }

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELContext.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELContext.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELContext.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELContext.java Fri Jan 22 04:59:44 2010
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,55 +27,72 @@
 public abstract class ELContext {
 
     private Locale locale;
-    
+
     private Map<Class<?>, Object> map;
-    
+
     private boolean resolved;
-    
+
+    private static ExpressionFactory expressionFactory;
+
+    private static boolean useCachedExpressionFactory;
+
+    static{
+        useCachedExpressionFactory = Boolean.valueOf(System.getProperty("org.apache.geronimo.spec.el.useCachedExpressionFactory","true"));
+        if (useCachedExpressionFactory) {
+            try {
+                expressionFactory = ExpressionFactory.newInstance();
+            } catch (Exception e) {
+            }
+        }
+    }
+
     /**
-     * 
+     *
      */
     public ELContext() {
         this.resolved = false;
+        if (useCachedExpressionFactory) {
+            putContext(ExpressionFactory.class, expressionFactory);
+        }
     }
-    
+
     public Object getContext(Class key) {
         if (this.map == null) {
             return null;
         }
         return this.map.get(key);
     }
-    
+
     public void putContext(Class key, Object contextObject) throws NullPointerException {
         if (key == null || contextObject == null) {
             throw new NullPointerException();
         }
-        
+
         if (this.map == null) {
             this.map = new HashMap<Class<?>, Object>();
         }
-        
+
         this.map.put(key, contextObject);
     }
-    
+
     public void setPropertyResolved(boolean resolved) {
         this.resolved = resolved;
     }
-    
+
     public boolean isPropertyResolved() {
         return this.resolved;
     }
-    
+
     public abstract ELResolver getELResolver();
 
     public abstract FunctionMapper getFunctionMapper();
-    
+
     public abstract VariableMapper getVariableMapper();
-    
+
     public Locale getLocale() {
         return this.locale;
     }
-    
+
     public void setLocale(Locale locale) {
         this.locale = locale;
     }

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELResolver.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELResolver.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELResolver.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ELResolver.java Fri Jan 22 04:59:44 2010
@@ -70,4 +70,5 @@
     public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
         return null;
     }
+
 }

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/MethodExpression.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/MethodExpression.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/MethodExpression.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/MethodExpression.java Fri Jan 22 04:59:44 2010
@@ -27,7 +27,6 @@
     public abstract Object invoke(ELContext context, Object[] params) throws NullPointerException, PropertyNotFoundException, MethodNotFoundException, ELException;
 
     public boolean isParameterProvided() {
-        //TODO
         return false;
     }
 }

Modified: geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ValueExpression.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ValueExpression.java?rev=901997&r1=901996&r2=901997&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ValueExpression.java (original)
+++ geronimo/specs/trunk/geronimo-el_2.2_spec/src/main/java/javax/el/ValueExpression.java Fri Jan 22 04:59:44 2010
@@ -32,8 +32,7 @@
 
     public abstract Object getValue(ELContext context) throws NullPointerException, PropertyNotFoundException, ELException;
 
-    public ValueReference getValueReference(ELContext context) {
-        //TODO
+    public ValueReference getValueReference(ELContext context){
         return null;
     }
 }