You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ra...@apache.org on 2009/08/01 02:36:52 UTC
svn commit: r799779 [2/3] - in
/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl: ./
context/ parser/ scripting/ util/ util/introspection/
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java Sat Aug 1 00:36:51 2009
@@ -104,7 +104,7 @@
context.setBindings(new SimpleBindings(vars), ScriptContext.ENGINE_SCOPE);
}
- public Map getVars() {
+ public Map<String,Object> getVars() {
return new JexlContextWrapper(context);
}
};
@@ -137,7 +137,7 @@
* Current implementation only gives access to ENGINE_SCOPE binding.
*/
@SuppressWarnings("unchecked")
- private static class JexlContextWrapper implements Map {
+ private static class JexlContextWrapper implements Map<String,Object> {
private final ScriptContext context;
@@ -180,7 +180,7 @@
return bnd.keySet();
}
- public Object put(final Object key, final Object value) {
+ public Object put(final String key, final Object value) {
Bindings bnd = context.getBindings(ScriptContext.ENGINE_SCOPE);
return bnd.put(String.valueOf(key), value);
}
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/AbstractExecutor.java Sat Aug 1 00:36:51 2009
@@ -14,16 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.commons.jexl.util;
+import org.apache.commons.jexl.util.introspection.MethodKey;
+import org.apache.commons.jexl.util.introspection.VelMethod;
+import org.apache.commons.jexl.util.introspection.VelPropertySet;
+import org.apache.commons.jexl.util.introspection.VelPropertyGet;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
/**
* Abstract class that is used to execute an arbitrary
* method that is introspected. This is the superclass
- * for the GetExecutor and PropertyExecutor.
+ * for all other AbstractExecutor classes.
*
* @since 1.0
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
@@ -31,35 +32,53 @@
* @version $Id$
*/
public abstract class AbstractExecutor {
- /** Empty parameters list for method matching. */
- protected static final Object[] EMPTY_PARAMS = {};
+ /** A marker for invocation failures in tryInvoke. */
+ public static final Object TRY_FAILED = new Object() {
+ @Override
+ public String toString() {
+ return "tryExecute failed";
+ }
+ };
+
/**
- * Method to be executed.
+ * A helper to initialize the marker methods (array.get, list.get, etc...).
+ * @param clazz the class to introspect
+ * @param name the name of the method
+ * @param parms the parameters
+ * @return the method
*/
- protected final Method method;
+ static java.lang.reflect.Method initMarker(Class<?> clazz, String name, Class<?>... parms) {
+ try {
+ return clazz.getMethod(name, parms);
+ } catch (Exception xnever) {
+ throw new Error(xnever);
+ }
+ }
/**
- * Default and sole constructor.
- * @param theMethod the method held by this executor
+ * Creates an arguments array.
+ * @param args the list of arguments
+ * @return the arguments array
*/
- protected AbstractExecutor(Method theMethod) {
- method = theMethod;
+ static Object[] makeArgs(Object... args) {
+ return args;
}
+ /** The class this executor applies to. */
+ protected final Class<?> objectClass;
+ /** Method to be executed. */
+ protected final java.lang.reflect.Method method;
+
/**
- * Execute method against context.
- *
- * @param o The owner.
- * @return The return value.
- * @throws IllegalAccessException Method is inaccessible.
- * @throws InvocationTargetException Method body throws an exception.
- */
- public Object execute(Object o)
- throws IllegalAccessException, InvocationTargetException {
- return method == null? null : method.invoke(o, (Object[]) null);
+ * Default and sole constructor.
+ * @param theClass the class this executor applies to
+ * @param theMethod the method held by this executor
+ */
+ protected AbstractExecutor(Class<?> theClass, java.lang.reflect.Method theMethod) {
+ objectClass = theClass;
+ method = theMethod;
}
-
/**
* Tell whether the executor is alive by looking
* at the value of the method.
@@ -71,10 +90,188 @@
}
/**
- * Gets the method to be executed.
- * @return Method The method to be executed.
+ * Specifies if this executor is cacheable and able to be reused for this
+ * class of object it was returned for.
+ *
+ * @return true if can be reused for this class, false if not
+ */
+ public boolean isCacheable() {
+ return method != null;
+ }
+
+ /**
+ * Gets the method to be executed or used as a marker.
+ * @return Method The method used by execute in derived classes.
*/
- public final Method getMethod() {
+ public final java.lang.reflect.Method getMethod() {
return method;
}
- }
\ No newline at end of file
+
+ /**
+ * Gets the method name used.
+ * @return method name
+ */
+ public final String getMethodName() {
+ return method.getName();
+ }
+
+ /**
+ * Abstract class that is used to execute an arbitrary 'get' method.
+ */
+ public abstract static class Get extends AbstractExecutor implements VelPropertyGet {
+ /**
+ * Default and sole constructor.
+ * @param theClass the class this executor applies to
+ * @param theMethod the method held by this executor
+ */
+ protected Get(Class<?> theClass, java.lang.reflect.Method theMethod) {
+ super(theClass, theMethod);
+ }
+
+ /** {@inheritDoc} */
+ public final Object invoke(Object o) throws Exception {
+ return execute(o);
+ }
+
+ /**
+ * Gets the property value from an object.
+ *
+ * @param o The object to get the property from.
+ * @return The property value.
+ * @throws IllegalAccessException Method is inaccessible.
+ * @throws InvocationTargetException Method body throws an exception.
+ */
+ public abstract Object execute(Object o)
+ throws IllegalAccessException, InvocationTargetException;
+
+ /**
+ * Tries to reuse this executor, checking that it is compatible with
+ * the actual set of arguments.
+ * @param o The object to get the property from.
+ * @param property The property to get from the object.
+ * @return The property value or TRY_FAILED if checking failed.
+ */
+ public Object tryExecute(Object o, Object property) {
+ return TRY_FAILED;
+ }
+ }
+
+ /**
+ * Abstract class that is used to execute an arbitrary 'set' method.
+ */
+ public abstract static class Set extends AbstractExecutor implements VelPropertySet {
+ /**
+ * Default and sole constructor.
+ * @param theClass the class this executor applies to
+ * @param theMethod the method held by this executor
+ */
+ protected Set(Class<?> theClass, java.lang.reflect.Method theMethod) {
+ super(theClass, theMethod);
+ }
+
+ /** {@inheritDoc} */
+ public Object invoke(Object o, Object arg) throws Exception {
+ return execute(o, arg);
+ }
+
+ /**
+ * Sets the property value of an object.
+ *
+ * @param o The object to set the property in.
+ * @param arg The value.
+ * @return The return value.
+ * @throws IllegalAccessException Method is inaccessible.
+ * @throws InvocationTargetException Method body throws an exception.
+ */
+ public abstract Object execute(Object o, Object arg)
+ throws IllegalAccessException, InvocationTargetException;
+
+ /**
+ * Tries to reuse this executor, checking that it is compatible with
+ * the actual set of arguments.
+ * @param o The object to invoke the method from.
+ * @param property The property to set in the object.
+ * @param arg The value to use as the property value.
+ * @return The return value or TRY_FAILED if checking failed.
+ */
+ public Object tryExecute(Object o, Object property, Object arg) {
+ return TRY_FAILED;
+ }
+
+ }
+
+
+
+ /**
+ * Abstract class that is used to execute an arbitrary method.
+ */
+ public abstract static class Method extends AbstractExecutor implements VelMethod {
+ /**
+ * A helper class to pass the method & parameters.
+ */
+ protected static final class Parameter {
+ /** The method. */
+ private final java.lang.reflect.Method method;
+ /** The method key. */
+ private final MethodKey key;
+ /** Creates an instance.
+ * @param m the method
+ * @param k the method key
+ */
+ public Parameter(java.lang.reflect.Method m, MethodKey k) {
+ method = m;
+ key = k;
+ }
+ }
+ /** The method key discovered from the arguments. */
+ protected final MethodKey key;
+ /**
+ * Creates a new instance.
+ * @param c the class this executor applies to
+ * @param km the method and MethodKey to encapsulate.
+ */
+ protected Method(Class<?> c, Parameter km) {
+ super(c, km.method);
+ key = km.key;
+ }
+
+ /** {@inheritDoc} */
+ public final Object invoke(Object o, Object[] args) throws Exception {
+ return execute(o, args);
+ }
+
+ /**
+ * Returns the return type of the method invoked.
+ * @return return type
+ */
+ public final Class<?> getReturnType() {
+ return method.getReturnType();
+ }
+
+ /**
+ * Invokes the method to be executed.
+ *
+ * @param o the object to invoke the method upon
+ * @param args the method arguments
+ * @return the result of the method invocation
+ * @throws IllegalAccessException Method is inaccessible.
+ * @throws InvocationTargetException Method body throws an exception.
+ */
+ public abstract Object execute(Object o, Object[] args)
+ throws IllegalAccessException, InvocationTargetException;
+
+ /**
+ * Tries to reuse this executor, checking that it is compatible with
+ * the actual set of arguments.
+ * @param o the object to invoke the method upon
+ * @param name the method name
+ * @param args the method arguments
+ * @return the result of the method invocation or INVOKE_FAILED if checking failed.
+ */
+ public Object tryExecute(String name, Object o, Object[] args){
+ return TRY_FAILED;
+ }
+
+ }
+
+}
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java Sat Aug 1 00:36:51 2009
@@ -17,13 +17,10 @@
package org.apache.commons.jexl.util;
-
-
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.lang.reflect.Array;
-
/**
* <p>
* An Iterator wrapper for an Object[]. This will
@@ -44,41 +41,29 @@
* @version $Id$
*/
public class ArrayIterator implements Iterator<Object> {
- /**
- * The objects to iterate over.
- */
+ /** The objects to iterate over. */
private final Object array;
-
- /**
- * The current position and size in the array.
- */
- private int pos;
-
- /**
- * The size of the array.
- */
+ /** The size of the array. */
private final int size;
+ /** The current position and size in the array. */
+ private int pos;
/**
* Creates a new iterator instance for the specified array.
- *
* @param arr The array for which an iterator is desired.
*/
public ArrayIterator(Object arr) {
- /*
- * if this isn't an array, then throw. Note that this is
- * for internal use - so this should never happen - if it does
- * we screwed up.
- */
-
- if (!arr.getClass().isArray()) {
- throw new IllegalArgumentException("Programmer error :"
- + " internal ArrayIterator invoked w/o array");
+ if (arr == null) {
+ array = null;
+ pos = 0;
+ size = 0;
+ } else if (!arr.getClass().isArray()) {
+ throw new IllegalArgumentException(arr.getClass() + " is not an array");
+ } else {
+ array = arr;
+ pos = 0;
+ size = Array.getLength(array);
}
-
- array = arr;
- pos = 0;
- size = Array.getLength(array);
}
/**
@@ -89,12 +74,8 @@
public Object next() {
if (pos < size) {
return Array.get(array, pos++);
- }
-
- /*
- * we screwed up...
- */
-
+ }
+ // we screwed up...
throw new NoSuchElementException("No more elements: " + pos
+ " / " + size);
}
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java Sat Aug 1 00:36:51 2009
@@ -31,13 +31,14 @@
/**
* Create the wrapper.
- * @param array {@link #array}
+ * @param anArray {@link #array}
*/
- // CSOFF: HiddenField
- public ArrayListWrapper(Object array) {
- this.array = array;
+ public ArrayListWrapper(Object anArray) {
+ if (!anArray.getClass().isArray()) {
+ throw new IllegalArgumentException(anArray.getClass() + " is not an array");
+ }
+ this.array = anArray;
}
- // CSON: HiddenField
/** {@inheritDoc} */
@Override
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.lang.reflect.InvocationTargetException;
+/**
+ * Specialized executor to get a boolean property from an object.
+ */
+public final class BooleanGetExecutor extends AbstractExecutor.Get {
+ /** The property. */
+ private final String property;
+ /**
+ * Creates an instance by attempting discovery of the get method.
+ * @param is the introspector
+ * @param clazz the class to introspect
+ * @param identifier the property to get
+ */
+ public BooleanGetExecutor(Introspector is, Class<?> clazz, String identifier) {
+ super(clazz, discover(is, clazz, identifier));
+ property = identifier;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(Object o)
+ throws IllegalAccessException, InvocationTargetException {
+ return method == null ? null : method.invoke(o, (Object[]) null);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(Object o, Object identifier) {
+ if (o != null && method != null
+ // ensure method name matches the property name
+ && property.equals(identifier)
+ && objectClass.equals(o.getClass())) {
+ try {
+ return method.invoke(o, (Object[]) null);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+ /**
+ * Discovers the method for a {@link BooleanGet}.
+ * <p>The method to be found should be named "is{P,p}property and return a boolean.</p>
+ *@param is the introspector
+ *@param clazz the class to find the get method from
+ *@param property the the property name
+ *@return the method if found, null otherwise
+ */
+ static java.lang.reflect.Method discover(Introspector is, final Class<?> clazz, String property) {
+ java.lang.reflect.Method m = PropertyGetExecutor.discoverGet(is, "is", clazz, property);
+ return (m != null && m.getReturnType() == Boolean.TYPE) ? m : null;
+ }
+
+}
\ No newline at end of file
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanGetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl.util;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Specialized executor to get a property from an object.
+ * <p>Duck as in duck-typing for an interface like:
+ * <code>
+ * interface Get {
+ * Object get(Object key);
+ * }
+ * </code>
+ * </p>
+ */
+/**
+ * Specialized executor to get a property from an object.
+ * <p>Duck as in duck-typing for classes that implement an get(object) method.</p>
+ */
+public final class DuckGetExecutor extends AbstractExecutor.Get {
+ /** The property. */
+ private final Object property;
+
+ /**
+ * Creates an instance by attempting discovery of the get method.
+ * @param is the introspector
+ * @param clazz the class to introspect
+ * @param identifier the property to get
+ */
+ public DuckGetExecutor(Introspector is, Class<?> clazz, Object identifier) {
+ super(clazz, discover(is, clazz, identifier));
+ property = identifier;
+ }
+
+ /**
+ * Get the property from the object.
+ * @param o the object.
+ * @return object.get(property)
+ * @throws IllegalAccessException Method is inaccessible.
+ * @throws InvocationTargetException Method body throws an exception.
+ */
+ @Override
+ public Object execute(Object o)
+ throws IllegalAccessException, InvocationTargetException {
+ Object[] args = {property};
+ return method == null ? null : method.invoke(o, args);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(Object o, Object identifier) {
+ if (o != null && method != null
+ // ensure method name matches the property name
+ && property.equals(identifier)
+ && objectClass.equals(o.getClass())) {
+ try {
+ Object[] args = {property};
+ return method.invoke(o, args);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+ /**
+ * Discovers a method for a {@link GetExecutor.DuckGet}.
+ *@param is the introspector
+ *@param clazz the class to find the get method from
+ *@param identifier the key to use as an argument to the get method
+ *@return the method if found, null otherwise
+ */
+ private static java.lang.reflect.Method discover(Introspector is,
+ final Class<?> clazz, Object identifier) {
+ return is.getMethod(clazz, "get", makeArgs(identifier));
+ }
+}
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckGetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl.util;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Specialized executor to set a property of an object.
+ * <p>Duck as in duck-typing for an interface like:
+ * <code>
+ * interface Set {
+ * Object put(Object property, Object value);
+ * }
+ * </code>
+ * </p>
+ */
+public final class DuckSetExecutor extends AbstractExecutor.Set {
+ /** The property. */
+ private final Object property;
+
+ /**
+ * Creates an instance.
+ *@param is the introspector
+ *@param clazz the class to find the set method from
+ *@param identifier the key to use as 1st argument to the set method
+ *@param arg the value to use as 2nd argument to the set method
+ */
+ public DuckSetExecutor(Introspector is, Class<?> clazz, Object identifier, Object arg) {
+ super(clazz, discover(is, clazz, identifier, arg));
+ property = identifier;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(Object o, Object arg)
+ throws IllegalAccessException, InvocationTargetException {
+ Object[] pargs = {property, arg};
+ if (method != null) {
+ method.invoke(o, pargs);
+ }
+ return arg;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(Object o, Object identifier, Object arg) {
+ if (o != null && method != null
+ // ensure method name matches the property name
+ && property.equals(identifier)
+ && objectClass.equals(o.getClass())) {
+ try {
+ Object[] args = {property, arg};
+ return method.invoke(o, args);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+ /**
+ * Discovers the method for a {@link DuckSet}.
+ *@param is the introspector
+ *@param clazz the class to find the set method from
+ *@param identifier the key to use as 1st argument to the set method
+ *@param arg the value to use as 2nd argument to the set method
+ *@return the method if found, null otherwise
+ */
+ private static java.lang.reflect.Method discover(Introspector is,
+ Class<?> clazz, Object identifier, Object arg) {
+ return is.getMethod(clazz, "put", makeArgs(identifier, arg));
+ }
+}
\ No newline at end of file
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/DuckSetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java Sat Aug 1 00:36:51 2009
@@ -23,10 +23,10 @@
/**
* An Iterator wrapper for an Enumeration.
- *
* @since 1.0
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @version $Id$
+ * @param <T> the type of object this iterator returns
*/
public class EnumerationIterator<T> implements Iterator<T> {
/**
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Introspector.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Introspector.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Introspector.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Introspector.java Sat Aug 1 00:36:51 2009
@@ -16,40 +16,245 @@
*/
package org.apache.commons.jexl.util;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+
import org.apache.commons.jexl.util.introspection.Uberspect;
import org.apache.commons.jexl.util.introspection.UberspectImpl;
-import org.apache.commons.jexl.util.introspection.UberspectLoggable;
+import org.apache.commons.jexl.util.introspection.MethodKey;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
- * Little class to manage a Velocity uberspector (Vel 1.4+) for instrospective
- * services.
- *
- * @since 1.0
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- * @version $Id$
+ * Default introspection services.
+ * <p>Finding methods as well as property getters & setters.</p>
*/
-public class Introspector {
+public class Introspector {
+ /** The default uberspector that handles all introspection patterns. */
+ private static volatile Uberspect uberSpect;
+ /** The logger to use for all warnings & errors. */
+ protected final Log rlog;
+ /** The (low level) introspector to use for introspection services. */
+ protected final org.apache.commons.jexl.util.introspection.Introspector introspector;
+
/**
- * The uberspector from Velocity that handles all introspection patterns.
+ * Gets the default instance of Uberspect.
+ * <p>This is lazily initialized to avoid building a default instance if there
+ * is no use for it. The main reason for not using the default Uberspect instance is to
+ * be able to use a (low level) introspector created with a given logger
+ * instead of the default one.</p>
+ * @return Uberspect the default uberspector instance.
*/
- private static final Uberspect uberSpect;
+ // CSOFF: DoubleCheckedLocking
+ public static Uberspect getUberspect() {
+ // uses a double-locking pattern since java5 memory model allows it
+ if (uberSpect == null) {
+ synchronized (Uberspect.class) {
+ if (uberSpect == null) {
+ Log logger = LogFactory.getLog(Introspector.class);
+ uberSpect = new UberspectImpl(logger);
+ }
+ }
+ }
+ return uberSpect;
+ }
+ // CSON: DoubleCheckedLocking
- static {
+ /**
+ * Creates a new instance of Uberspect.
+ * @param logger the logger used by this Uberspect.
+ * @return the new instance
+ */
+ public static Uberspect getUberspect(Log logger) {
+ return new UberspectImpl(logger);
+ }
+
+ /**
+ * Creates an introspector.
+ * @param log the logger to use for warnings.
+ * @param is the low level introspector.
+ */
+ public Introspector(Log log, org.apache.commons.jexl.util.introspection.Introspector is) {
+ rlog = log;
+ introspector = is;
+ }
- Log logger = LogFactory.getLog(Introspector.class);
+ /**
+ * Coerce an Object to an Integer.
+ * @param arg the Object to coerce
+ * @return an Integer if it can be converted, null otherwise
+ */
+ protected Integer toInteger(Object arg) {
+ if (arg == null) {
+ return null;
+ }
+ if (arg instanceof Number) {
+ return ((Number) arg).intValue();
+ }
+ try {
+ return Integer.parseInt(arg.toString());
+ } catch(NumberFormatException xnumber) {
+ return null;
+ }
+ }
- uberSpect = new UberspectImpl();
- ((UberspectLoggable) uberSpect).setRuntimeLogger(logger);
+ /**
+ * Coerce an Object to a String.
+ * @param arg the Object to coerce
+ * @return a String if it can be converted, null otherwise
+ */
+ protected String toString(Object arg) {
+ return arg == null? null : arg.toString();
}
/**
- * For now, expose the raw uberspector to the AST.
+ * Gets the method defined by <code>name</code> and
+ * <code>params</code> for the Class <code>c</code>.
+ *
+ * @param c Class in which the method search is taking place
+ * @param name Name of the method being searched for
+ * @param params An array of Objects (not Classes) that describe the
+ * the parameters
*
- * @return Uberspect The Velocity uberspector.
+ * @return The desired Method object.
+ * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
+ * CSOFF: RedundantThrows
*/
- public static Uberspect getUberspect() {
- return uberSpect;
+ protected final Method getMethod(Class<?> c, String name, Object[] params) throws IllegalArgumentException {
+ return introspector.getMethod(c, new MethodKey(name, params));
+ }
+
+ /**
+ * Gets the method defined by <code>key</code> and for the Class <code>c</code>.
+ *
+ * @param c Class in which the method search is taking place
+ * @param key MethodKey of the method being searched for
+ *
+ * @return The desired Method object.
+ * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
+ * CSOFF: RedundantThrows
+ */
+ protected final Method getMethod(Class<?> c, MethodKey key) throws IllegalArgumentException {
+ return introspector.getMethod(c, key);
+ }
+
+ /**
+ * Returns a general constructor.
+ * @param ctorHandle the object
+ * @param args contrusctor arguments
+ * @return a {@link java.lang.reflect.Constructor}
+ */
+ public final Constructor<?> getConstructor(Object ctorHandle, Object[] args) {
+ String className = null;
+ if (ctorHandle instanceof Class<?>) {
+ className = ((Class<?>) ctorHandle).getName();
+ } else if (ctorHandle != null) {
+ className = ctorHandle.toString();
+ } else {
+ return null;
+ }
+ return introspector.getConstructor(new MethodKey(className, args));
+ }
+
+ /**
+ * Returns a general method.
+ * @param obj the object
+ * @param name the method name
+ * @param args method arguments
+ * @return a {@link AbstractExecutor.Method}.
+ */
+ public final AbstractExecutor.Method getMethodExecutor(Object obj, String name, Object[] args) {
+ AbstractExecutor.Method me = new MethodExecutor(this, obj, name, args);
+ return me.isAlive()? me : null;
}
+
+ /**
+ * Return a property getter.
+ * @param obj the object to get the property from.
+ * @param identifier property name
+ * @return a {@link AbstractExecutor.Get}.
+ */
+ public final AbstractExecutor.Get getGetExecutor(Object obj, Object identifier) {
+ final Class<?> claz = obj.getClass();
+ final String property = toString(identifier);
+ Method method;
+ AbstractExecutor.Get executor;
+ // first try for a getFoo() type of property (also getfoo() )
+ if (property != null) {
+ executor = new PropertyGetExecutor(this, claz, property);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ }
+ // look for boolean isFoo()
+ if (property != null) {
+ executor = new BooleanGetExecutor(this, claz, property);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ }
+ // let's see if we are a map...
+ executor = new MapGetExecutor(this, claz, identifier);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ // if that didn't work, look for get("foo")
+ executor = new DuckGetExecutor(this, claz, identifier);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ // let's see if we can convert the identifier to an int,
+ // if obj is an array or a list, we can still do something
+ Integer index = toInteger(identifier);
+ if (index != null) {
+ executor = new ListGetExecutor(this, claz, index);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return a property setter.
+ * @param obj the object to get the property from.
+ * @param identifier property name (or identifier)
+ * @param arg value to set
+ * @return a {@link AbstractExecutor.Set}.
+ */
+ public final AbstractExecutor.Set getSetExecutor(final Object obj, final Object identifier, Object arg) {
+ final Class<?> claz = obj.getClass();
+ final String property = toString(identifier);
+ AbstractExecutor.Set executor;
+ // first try for a setFoo() type of property (also setfoo() )
+ if (property != null) {
+ executor = new PropertySetExecutor(this, claz, property, arg);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ }
+ // let's see if we are a map...
+ executor = new MapSetExecutor(this, claz, identifier, arg);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ // if that didn't work, look for get("foo")
+ executor = new DuckSetExecutor(this, claz, property, arg);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ // let's see if we can convert the identifier to an int,
+ // if obj is an array or a list, we can still do something
+ Integer index = toInteger(identifier);
+ if (index != null) {
+ executor = new ListSetExecutor(this, claz, index, arg);
+ if (executor.isAlive()) {
+ return executor;
+ }
+ }
+ return null;
+ }
+
}
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.util.List;
+import java.lang.reflect.Array;
+/**
+ * Specialized executor to get a property from a List or array.
+ */
+public final class ListGetExecutor extends AbstractExecutor.Get {
+ /** The java.lang.reflect.Array.get method used as an active marker in ListGet. */
+ private static final java.lang.reflect.Method ARRAY_GET =
+ initMarker(Array.class, "get", Object.class, Integer.TYPE);
+ /** The java.util.list.get method used as an active marker in ListGet. */
+ private static final java.lang.reflect.Method LIST_GET =
+ initMarker(List.class, "get", Integer.TYPE);
+ /** The property. */
+ private final Integer property;
+
+ /**
+ * Creates an instance checking for the List interface or Array capability.
+ * @param is the introspector
+ * @param clazz the class to introspect
+ * @param index the index to use in list.get(index)
+ */
+ public ListGetExecutor(Introspector is, Class<?> clazz, Integer index) {
+ super(clazz, discover(clazz));
+ property = index;
+ }
+
+ /**
+ * Get the property from the list or array.
+ * @param list the List/array.
+ * @return list.get(index)
+ */
+ @Override
+ public Object execute(final Object list) {
+ if (method == ARRAY_GET) {
+ return java.lang.reflect.Array.get(list, property);
+ } else {
+ return ((List<?>) list).get(property);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(final Object list, Object index) {
+ if (method == discover(list.getClass())
+ && objectClass.equals(list.getClass())
+ && index instanceof Integer) {
+ if (method == ARRAY_GET) {
+ return java.lang.reflect.Array.get(list, property);
+ } else {
+ return ((List<?>) list).get(property);
+ }
+ }
+ return TRY_FAILED;
+ }
+
+
+ /**
+ * Finds the method to perform the get on a list of array.
+ * @param clazz the class to introspect
+ * @return a marker method, list.get or array.get
+ */
+ static java.lang.reflect.Method discover(Class<?> clazz) {
+ //return discoverList(false, clazz, property);
+ if (clazz.isArray()) {
+ return ARRAY_GET;
+ }
+ if (List.class.isAssignableFrom(clazz)) {
+ return LIST_GET;
+ }
+ return null;
+ }
+}
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListGetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.util.List;
+import java.lang.reflect.Array;
+/**
+ * Specialized executor to set a property in a List or array.
+ */
+public final class ListSetExecutor extends AbstractExecutor.Set {
+ /** The java.lang.reflect.Array.get method used as an active marker in ListGet. */
+ private static final java.lang.reflect.Method ARRAY_SET =
+ initMarker(Array.class, "set", Object.class, Integer.TYPE, Object.class);
+ /** The java.util.list.set method used as an active marker in ListSet. */
+ private static final java.lang.reflect.Method LIST_SET =
+ initMarker(List.class, "set", Integer.TYPE, Object.class);
+ /** The property. */
+ private final Integer property;
+
+ /**
+ * Creates an instance checking for the List interface or Array capability.
+ * @param is the introspector
+ * @param clazz the class that might implement the map interface
+ * @param index the index to use in list.set(index,value)
+ * @param value the value to use in list.set(index,value)
+ */
+ public ListSetExecutor(Introspector is, Class<?> clazz, Integer index, Object value) {
+ super(clazz, discover(clazz));
+ property = index;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(final Object list, Object arg) {
+ if (method == ARRAY_SET) {
+ java.lang.reflect.Array.set(list, property, arg);
+ } else {
+ ((List<Object>) list).set(property, arg);
+ }
+ return arg;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(final Object list, Object index, Object arg) {
+ if (method == discover(list.getClass())
+ && objectClass.equals(list.getClass())
+ && index instanceof Integer) {
+ Integer idx = (Integer) index;
+ if (method == ARRAY_SET) {
+ java.lang.reflect.Array.set(list, idx, arg);
+ } else {
+ ((List<Object>) list).set(idx, arg);
+ }
+ }
+ return TRY_FAILED;
+ }
+
+
+ /**
+ * Finds the method to perform 'set' on a list of array.
+ * @param clazz the class to introspect
+ * @return a marker method, list.set or array.set
+ */
+ static java.lang.reflect.Method discover(Class<?> clazz) {
+ if (clazz.isArray()) {
+ // we could verify if the call can be performed but it does not change
+ // the fact we would fail...
+ // Class<?> formal = clazz.getComponentType();
+ // Class<?> actual = arg == null? Object.class : arg.getClass();
+ // if (IntrospectionUtils.isMethodInvocationConvertible(formal, actual, false)) {
+ return ARRAY_SET;
+ // }
+ }
+ if (List.class.isAssignableFrom(clazz)) {
+ return LIST_SET;
+ }
+ return null;
+ }
+}
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ListSetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java Sat Aug 1 00:36:51 2009
@@ -18,70 +18,54 @@
package org.apache.commons.jexl.util;
import java.util.Map;
-import java.lang.reflect.Method;
-import org.apache.commons.logging.Log;
-
-
-/**
- * GetExecutor that is smart about Maps. If it detects one, it does not
- * use Reflection but a cast to access the getter.
- *
- * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
- * @version $Id$
+ /**
+ * Specialized executor to get a property from a Map.
*/
-public class MapGetExecutor extends AbstractExecutor {
- /** A one argument signature to find method. */
- private static final Class<?>[] OBJECT_PARM = new Class<?>[]{Object.class};
- /** the property to get. */
- private final String property;
+public final class MapGetExecutor extends AbstractExecutor.Get {
+ /** The java.util.map.get method used as an active marker in MapGet. */
+ private static final java.lang.reflect.Method MAP_GET =
+ initMarker(Map.class, "get", Object.class);
+ /** The property. */
+ private final Object property;
/**
- * Creates the instance.
- * @param rlog The logger.
- * @param clazz the class to execute the get on.
- * @param aProperty the property or key to get.
+ * Creates an instance checking for the Map interface.
+ * @param is the introspector
+ * @param clazz the class that might implement the map interface
+ * @param key the key to use in map.get(key)
*/
- public MapGetExecutor(final Log rlog, final Class<?> clazz, final String aProperty) {
- super(aProperty != null? discover(rlog, clazz, aProperty) : null);
- this.property = aProperty;
+ public MapGetExecutor(Introspector is, Class<?> clazz, Object key) {
+ super(clazz, discover(clazz));
+ property = key;
}
/**
- * Finds the method for a MapGetExecutor.
- *
- * @param rlog The logger.
- * @param clazz The class being analyzed.
- * @param property The boolean property.
- * @return The method.
+ * Get the property from the map.
+ * @param map the map.
+ * @return map.get(property)
*/
- private static Method discover(final Log rlog, final Class<?> clazz, final String property) {
- Method m = null;
- Class<?>[] interfaces = clazz.getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- if (interfaces[i].equals(Map.class)) {
- try {
- m = Map.class.getMethod("get", OBJECT_PARM);
- // pass through application level runtime exceptions
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- rlog.error("While looking for get('" + property + "') method:", e);
- }
- break;
- }
- }
- return m;
+ @Override
+ public Object execute(final Object map) {
+ return ((Map<Object, ?>) map).get(property);
}
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(final Object map, Object key) {
+ if (objectClass.equals(map.getClass())
+ && (key == null || property.getClass().equals(key.getClass()))) {
+ return ((Map<Object, ?>) map).get(key);
+ }
+ return TRY_FAILED;
+ }
- /**
- * Get the property from the map.
- * @param o the map.
- * @return o.get(property)
+ /**
+ * Finds the method to perform 'get' on a map.
+ * @param clazz the class to introspect
+ * @return a marker method, map.get
*/
- @Override
- public Object execute(final Object o) {
- return ((Map<String,?>) o).get(property);
+ static java.lang.reflect.Method discover(Class<?> clazz) {
+ return (Map.class.isAssignableFrom(clazz))? MAP_GET : null;
}
-}
\ No newline at end of file
+}
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.util.Map;
+import java.lang.reflect.InvocationTargetException;
+/**
+ * Specialized executor to set a property in a Map.
+ */
+public final class MapSetExecutor extends AbstractExecutor.Set {
+ /** The java.util.map.put method used as an active marker in MapSet. */
+ private static final java.lang.reflect.Method MAP_SET = initMarker(Map.class, "put", Object.class, Object.class);
+ /** The property. */
+ private final Object property;
+
+ /**
+ * Creates an instance checking for the Map interface.
+ *@param is the introspector
+ *@param clazz the class that might implement the map interface
+ *@param key the key to use as argument in map.put(key,value)
+ *@param value the value to use as argument in map.put(key,value)
+ */
+ public MapSetExecutor(Introspector is, Class<?> clazz, Object key, Object value) {
+ super(clazz, discover(clazz));
+ property = key;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(final Object map, Object value)
+ throws IllegalAccessException, InvocationTargetException {
+ ((Map<Object, Object>) map).put(property, value);
+ return value;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(final Object map, Object key, Object value) {
+ if (objectClass.equals(map.getClass())
+ && (key == null || property.getClass().equals(key.getClass()))) {
+ return ((Map<Object, Object>) map).put(key, value);
+ }
+ return TRY_FAILED;
+ }
+
+ /**
+ * Finds the method to perform 'set' on a map.
+ * @param clazz the class to introspect
+ * @return a marker method, map.get
+ */
+ static java.lang.reflect.Method discover(Class<?> clazz) {
+ return (Map.class.isAssignableFrom(clazz))? MAP_SET : null;
+ }
+}
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapSetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import org.apache.commons.jexl.util.introspection.MethodKey;
+
+/**
+ * Specialized executor to invoke a method on an object.
+ */
+public final class MethodExecutor extends AbstractExecutor.Method {
+ /** Whether this method handles varargs. */
+ private final boolean isVarArgs;
+ /**
+ * Creates a new instance.
+ * @param is the introspector used to discover the method
+ * @param obj the object to find the method in
+ * @param name the method name
+ * @param args the method arguments
+ */
+ public MethodExecutor(Introspector is, Object obj, String name, Object[] args) {
+ super(obj.getClass(), discover(is, obj, name, args));
+ isVarArgs = method != null && isVarArgMethod(method);
+ }
+
+ /**
+ * Invokes the method to be executed.
+ * @param o the object to invoke the method upon
+ * @param args the method arguments
+ * @return the result of the method invocation
+ * @throws IllegalAccessException Method is inaccessible.
+ * @throws InvocationTargetException Method body throws an exception.
+ */
+ @Override
+ public Object execute(Object o, Object[] args)
+ throws IllegalAccessException, InvocationTargetException {
+ if (isVarArgs) {
+ Class<?>[] formal = method.getParameterTypes();
+ int index = formal.length - 1;
+ Class<?> type = formal[index].getComponentType();
+ if (args.length >= index) {
+ args = handleVarArg(type, index, args);
+ }
+ }
+ if (method.getDeclaringClass() == ArrayListWrapper.class && o.getClass().isArray()) {
+ return method.invoke(new ArrayListWrapper(o), args);
+ } else {
+ return method.invoke(o, args);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(String name, Object o, Object[] args) {
+ MethodKey tkey = new MethodKey(name, args);
+ // let's assume that invocation will fly if the declaring class is the
+ // same and arguments have the same type
+ if (objectClass.equals(o.getClass()) && tkey.equals(key)) {
+ try {
+ return execute(o, args);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+
+ /**
+ * Discovers a method for a {@link MethodExecutor}.
+ * <p>
+ * If the object is an array, an attempt will be made to find the
+ * method in a List (see {@link ArrayListWrapper})
+ * </p>
+ * <p>
+ * If the object is a class, an attempt will be made to find the
+ * method as a static method of that class.
+ * </p>
+ * @param is the introspector used to discover the method
+ * @param obj the object to introspect
+ * @param method the name of the method to find
+ * @param args the method arguments
+ * @return a filled up parameter (may contain a null method)
+ */
+ private static Parameter discover(Introspector is,
+ Object obj, String method, Object[] args) {
+ final Class<?> clazz = obj.getClass();
+ final MethodKey key = new MethodKey(method, args);
+ java.lang.reflect.Method m = is.getMethod(clazz, key);
+ if (m == null && clazz.isArray()) {
+ // check for support via our array->list wrapper
+ m = is.getMethod(ArrayListWrapper.class, key);
+ }
+ if (m == null && obj instanceof Class<?>) {
+ m = is.getMethod((Class<?>) obj, key);
+ }
+ return new Parameter(m, key);
+ }
+
+ /**
+ * Reassembles arguments if the method is a vararg method.
+ * @param type The vararg class type (aka component type
+ * of the expected array arg)
+ * @param index The index of the vararg in the method declaration
+ * (This will always be one less than the number of
+ * expected arguments.)
+ * @param actual The actual parameters being passed to this method
+ * @return The actual parameters adjusted for the varargs in order
+ * to fit the method declaration.
+ */
+ protected Object[] handleVarArg(Class<?> type, int index, Object[] actual) {
+ // if no values are being passed into the vararg
+ if (actual.length == index) {
+ // create an empty array of the expected type
+ actual = new Object[]{Array.newInstance(type, 0)};
+ } else if (actual.length == index + 1) {
+ // if one value is being passed into the vararg
+ // make sure the last arg is an array of the expected type
+ if (MethodKey.isInvocationConvertible(type,
+ actual[index].getClass(),
+ false)) {
+ // create a 1-length array to hold and replace the last param
+ Object lastActual = Array.newInstance(type, 1);
+ Array.set(lastActual, 0, actual[index]);
+ actual[index] = lastActual;
+ }
+ } else if (actual.length > index + 1) {
+ // if multiple values are being passed into the vararg
+ // put the last and extra actual in an array of the expected type
+ int size = actual.length - index;
+ Object lastActual = Array.newInstance(type, size);
+ for (int i = 0; i < size; i++) {
+ Array.set(lastActual, i, actual[index + i]);
+ }
+
+ // put all into a new actual array of the appropriate size
+ Object[] newActual = new Object[index + 1];
+ for (int i = 0; i < index; i++) {
+ newActual[i] = actual[i];
+ }
+ newActual[index] = lastActual;
+
+ // replace the old actual array
+ actual = newActual;
+ }
+ return actual;
+ }
+
+ /**
+ * Determines if a method can accept a variable number of arguments.
+ * @param m a the method to check
+ * @return true if method is vararg, false otherwise
+ */
+ private static boolean isVarArgMethod(java.lang.reflect.Method m) {
+ Class<?>[] formal = m.getParameterTypes();
+ if (formal == null || formal.length == 0) {
+ return false;
+ } else {
+ Class<?> last = formal[formal.length - 1];
+ // if the last arg is an array, then
+ // we consider this a varargs method
+ return last.isArray();
+ }
+ }
+}
+
+
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MethodExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Specialized executor to get a property from an object.
+ */
+public final class PropertyGetExecutor extends AbstractExecutor.Get {
+ /** A static signature for method(). */
+ private static final Object[] EMPTY_PARAMS = {};
+ /** The property. */
+ private final String property;
+
+ /**
+ * Creates an instance by attempting discovery of the get method.
+ * @param is the introspector
+ * @param clazz the class to introspect
+ * @param identifier the property to get
+ */
+ public PropertyGetExecutor(Introspector is, Class<?> clazz, String identifier) {
+ super(clazz, discover(is, clazz, identifier));
+ property = identifier;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(Object o)
+ throws IllegalAccessException, InvocationTargetException {
+ return method == null ? null : method.invoke(o, (Object[]) null);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(Object o, Object identifier) {
+ if (o != null && method != null
+ && property.equals(identifier)
+ && objectClass.equals(o.getClass())) {
+ try {
+ return method.invoke(o, (Object[]) null);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+ /**
+ * Discovers the method for a {@link PropertyGet}.
+ * <p>The method to be found should be named "get{P,p}property.</p>
+ *@param is the introspector
+ *@param clazz the class to find the get method from
+ *@param property the property name to find
+ *@return the method if found, null otherwise
+ */
+ static java.lang.reflect.Method discover(Introspector is,
+ final Class<?> clazz, String property) {
+ return discoverGet(is, "get", clazz, property);
+ }
+
+
+ /**
+ * Base method for boolean & object property get.
+ * @param is the introspector
+ * @param which "is" or "get" for boolean or object
+ * @param clazz The class being examined.
+ * @param property The property being addressed.
+ * @return The {get,is}{p,P}roperty method if one exists, null otherwise.
+ */
+ static java.lang.reflect.Method discoverGet(Introspector is,
+ String which, Class<?> clazz, String property) {
+ // this is gross and linear, but it keeps it straightforward.
+ java.lang.reflect.Method method = null;
+ final int start = which.length(); // "get" or "is" so 3 or 2 for char case switch
+ // start with get<Property>
+ StringBuilder sb = new StringBuilder(which);
+ sb.append(property);
+ // uppercase nth char
+ char c = sb.charAt(start);
+ sb.setCharAt(start, Character.toUpperCase(c));
+ method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
+ //lowercase nth char
+ if (method == null) {
+ sb.setCharAt(start, Character.toLowerCase(c));
+ method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
+ }
+ return method;
+ }
+}
+
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyGetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.util;
+import java.lang.reflect.InvocationTargetException;
+/**
+ * Specialized executor to set a property in an object.
+ */
+public final class PropertySetExecutor extends AbstractExecutor.Set {
+ /** Index of the first character of the set{p,P}roperty. */
+ private static final int SET_START_INDEX = 3;
+ /** The property. */
+ private final String property;
+
+ /**
+ * Creates an instance by attempting discovery of the set method.
+ * @param is the introspector
+ * @param clazz the class to introspect
+ * @param identifier the property to set
+ * @param arg the value to set into the property
+ */
+ public PropertySetExecutor(Introspector is, Class<?> clazz, String identifier, Object arg) {
+ super(clazz, discover(is, clazz, identifier, arg));
+ property = identifier;
+
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(Object o, Object arg)
+ throws IllegalAccessException, InvocationTargetException {
+ Object[] pargs = {arg};
+ if (method != null) {
+ method.invoke(o, pargs);
+ }
+ return arg;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Object tryExecute(Object o, Object identifier, Object arg) {
+ if (o != null && method != null
+ // ensure method name matches the property name
+ && property.equals(identifier)
+ // object class should be same as executor's method declaring class
+ && objectClass.equals(o.getClass())
+ // we are guaranteed the method has one parameter since it is a set(x)
+ && (arg == null || method.getParameterTypes()[0].equals(arg.getClass()))) {
+ try {
+ return execute(o, arg);
+ } catch (InvocationTargetException xinvoke) {
+ return TRY_FAILED; // fail
+ } catch (IllegalAccessException xill) {
+ return TRY_FAILED;// fail
+ }
+ }
+ return TRY_FAILED;
+ }
+
+
+ /**
+ * Discovers the method for a {@link PropertySet}.
+ * <p>The method to be found should be named "set{P,p}property.</p>
+ *@param is the introspector
+ *@param clazz the class to find the get method from
+ *@param property the name of the property to set
+ *@param arg the value to assign to the property
+ *@return the method if found, null otherwise
+ */
+ private static java.lang.reflect.Method discover(Introspector is,
+ final Class<?> clazz, String property, Object arg) {
+ // first, we introspect for the set<identifier> setter method
+ Object[] params = {arg};
+ StringBuilder sb = new StringBuilder("set");
+ sb.append(property);
+ // uppercase nth char
+ char c = sb.charAt(SET_START_INDEX);
+ sb.setCharAt(SET_START_INDEX, Character.toUpperCase(c));
+ java.lang.reflect.Method method = is.getMethod(clazz, sb.toString(), params);
+ // lowercase nth char
+ if (method == null) {
+ sb.setCharAt(SET_START_INDEX, Character.toLowerCase(c));
+ method = is.getMethod(clazz, sb.toString(), params);
+ }
+
+ return method;
+ }
+}
+
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertySetExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java?rev=799779&r1=799778&r2=799779&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java Sat Aug 1 00:36:51 2009
@@ -24,11 +24,12 @@
import org.apache.commons.logging.Log;
/**
- * Taken from the Velocity tree so we can be self-sufficient.
+ * Originally taken from the Velocity tree so we can be self-sufficient.
*
* A cache of introspection information for a specific class instance.
- * Keys objects by an agregation of the method name and the names of classes
+ * Keys objects by an agregation of the method name and the classes
* that make up the parameters.
+ * @see MethodKey
*
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
* @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
@@ -38,7 +39,7 @@
* @version $Id$
* @since 1.0
*/
-public class ClassMap {
+final class ClassMap {
/** cache of methods. */
private final MethodCache methodCache;
@@ -63,14 +64,13 @@
/**
* Find a Method using the method name and parameter objects.
*
- * @param name The method name to look up.
- * @param params An array of parameters for the method.
+ * @param key the method key
* @return A Method object representing the method to invoke or null.
- * @throws MethodMap.AmbiguousException When more than one method is a match for the parameters.
+ * @throws MethodKey.AmbiguousException When more than one method is a match for the parameters.
*/
- public Method findMethod(final String name, final Object[] params)
- throws MethodMap.AmbiguousException {
- return methodCache.get(name, params);
+ public Method findMethod(final MethodKey key)
+ throws MethodKey.AmbiguousException {
+ return methodCache.get(key);
}
/**
@@ -154,7 +154,7 @@
* @version $Id$
* <p>
* It stores the association between:
- * - a key made of a method name & an array of argument types. (@see MethodCache.MethodKey)
+ * - a key made of a method name & an array of argument types.
* - a method.
* </p>
* <p>
@@ -237,24 +237,12 @@
* If nothing is found, then we must actually go
* and introspect the method from the MethodMap.
*</p>
- * @param name The method name to look up.
- * @param params An array of parameters for the method.
- * @return A Method object representing the method to invoke or null.
- * @throws MethodMap.AmbiguousException When more than one method is a match for the parameters.
- */
- Method get(final String name, final Object[] params)
- throws MethodMap.AmbiguousException {
- return get(new MethodKey(name, params));
- }
-
- /**
- * Finds a Method using a MethodKey.
* @param methodKey the method key
- * @return a method
- * @throws MethodMap.AmbiguousException if method resolution is ambiguous
+ * @return A Method object representing the method to invoke or null.
+ * @throws MethodKey.AmbiguousException When more than one method is a match for the parameters.
*/
Method get(final MethodKey methodKey)
- throws MethodMap.AmbiguousException {
+ throws MethodKey.AmbiguousException {
synchronized (methodMap) {
Method cacheEntry = cache.get(methodKey);
// We looked this up before and failed.
@@ -271,7 +259,7 @@
} else {
cache.put(methodKey, CACHE_MISS);
}
- } catch (MethodMap.AmbiguousException ae) {
+ } catch (MethodKey.AmbiguousException ae) {
// that's a miss :-)
cache.put(methodKey, CACHE_MISS);
throw ae;
@@ -311,137 +299,4 @@
}
}
}
-
- /**
- * A method key for the introspector cache.
- * <p>
- * This replaces the original key scheme which used to build the key
- * by concatenating the method name and parameters class names as one string
- * with the exception that primitive types were converted to their object class equivalents.
- * </p>
- * <p>
- * The key is still based on the same information, it is just wrapped in an object instead.
- * Primitive type classes are converted to they object equivalent to make a key;
- * int foo(int) and int foo(Integer) do generate the same key.
- * </p>
- * A key can be constructed either from arguments (array of objects) or from parameters
- * (array of class).
- * Roughly 3x faster than string key to access the map & uses less memory.
- */
- static final class MethodKey {
- /** The hash code. */
- private final int hashCode;
- /** The method name. */
- private final String method;
- /** The parameters. */
- private final Class<?>[] params;
- /** A marker for empty parameter list. */
- private static final Class<?>[] NOARGS = new Class<?>[0];
- /** The hash code constants. */
- private static final int HASH = 37;
-
- /** Creates a MethodKey from a method.
- * Used to store information in the method map.
- * @param aMethod the method to build the key from
- */
- MethodKey(Method aMethod) {
- this(aMethod.getName(), aMethod.getParameterTypes());
- }
-
- /** Creates a MethodKey from a method name and a set of arguments (objects).
- * Used to query the method map.
- * @param aMethod the method name
- * @param args the arguments instances to match the method signature
- */
- MethodKey(String aMethod, Object[] args) {
- // !! keep this in sync with the other ctor (hash code) !!
- this.method = aMethod;
- int hash = this.method.hashCode();
- final int size;
- // CSOFF: InnerAssignment
- if (args != null && (size = args.length) > 0) {
- // CSON: InnerAssignment
- this.params = new Class<?>[size];
- for (int p = 0; p < size; ++p) {
- // ctor(Object) : {
- Object arg = args[p];
- // no need to go thru primitive type conversion since these are objects
- Class<?> parm = arg == null ? Object.class : arg.getClass();
- // }
- hash = (HASH * hash) + parm.hashCode();
- this.params[p] = parm;
- }
- } else {
- this.params = NOARGS;
- }
- this.hashCode = hash;
- }
-
- /** Creates a MethodKey from a method name and a set of parameters (classes).
- * Used to store information in the method map. ( @see MethodKey#primitiveClass )
- * @param aMethod the method name
- * @param args the argument classes to match the method signature
- */
- MethodKey(String aMethod, Class<?>[] args) {
- // !! keep this in sync with the other ctor (hash code) !!
- this.method = aMethod;
- int hash = this.method.hashCode();
- final int size;
- // CSOFF: InnerAssignment
- if (args != null && (size = args.length) > 0) {
- // CSON: InnerAssignment
- this.params = new Class<?>[size];
- for (int p = 0; p < size; ++p) {
- // ctor(Class): {
- Class<?> parm = MethodCache.primitiveClass(args[p]);
- // }
- hash = (HASH * hash) + parm.hashCode();
- this.params[p] = parm;
- }
- } else {
- this.params = NOARGS;
- }
- this.hashCode = hash;
- }
-
- /**
- * Gets this key's method name.
- * @return the method name
- */
- String getMethod() {
- return method;
- }
-
- /**
- * Gets this key's method parameter classes.
- * @return the parameters
- */
- Class<?>[] getParameters() {
- return params;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- @Override
- public boolean equals(Object arg) {
- if (arg instanceof MethodKey) {
- MethodKey key = (MethodKey) arg;
- return method.equals(key.method) && java.util.Arrays.equals(params, key.params);
- }
- return false;
- }
-
- @Override
- /** Compatible with original string key. */
- public String toString() {
- StringBuilder builder = new StringBuilder(method);
- for (Class<?> c : params) {
- builder.append(c.getName());
- }
- return builder.toString();
- }
- }
}
\ No newline at end of file
Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java?rev=799779&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java Sat Aug 1 00:36:51 2009
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl.util.introspection;
+
+/**
+ * A little class to abstract debugging info.
+ */
+public interface DebugInfo {
+ /** A default debug info with (oviously) no information. */
+ DebugInfo NONE = new DebugInfo() {
+ public String debugString() {
+ return "?@?:?";
+ }
+ };
+ /**
+ * Formats this information.
+ * @return a human readable string.
+ */
+ String debugString();
+}
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/DebugInfo.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL