aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java')
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java105
1 files changed, 71 insertions, 34 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java b/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java
index cdda364d..03127892 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/UberspectImpl.java
@@ -19,6 +19,7 @@ package org.apache.velocity.util.introspection;
* under the License.
*/
+import org.apache.commons.lang3.Conversion;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
@@ -42,6 +43,7 @@ import org.slf4j.Logger;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
@@ -69,7 +71,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
/**
* the conversion handler
*/
- protected ConversionHandler conversionHandler;
+ protected TypeConversionHandler conversionHandler;
/**
* runtime services
@@ -86,7 +88,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
introspector = new Introspector(log, conversionHandler);
}
- public ConversionHandler getConversionHandler()
+ public TypeConversionHandler getConversionHandler()
{
return conversionHandler;
}
@@ -95,51 +97,86 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
* sets the runtime services
* @param rs runtime services
*/
+ @SuppressWarnings("deprecation")
public void setRuntimeServices(RuntimeServices rs)
{
rsvc = rs;
log = rsvc.getLog("introspection");
- String conversionHandlerClass = rs.getString(RuntimeConstants.CONVERSION_HANDLER_CLASS);
- if (conversionHandlerClass == null || conversionHandlerClass.equals("none"))
+ Object conversionHandlerInstance = rs.getProperty(RuntimeConstants.CONVERSION_HANDLER_INSTANCE);
+ if (conversionHandlerInstance == null)
{
- conversionHandler = null;
- }
- else
- {
- Object o = null;
-
- try
+ String conversionHandlerClass = rs.getString(RuntimeConstants.CONVERSION_HANDLER_CLASS);
+ if (conversionHandlerClass != null && !conversionHandlerClass.equals("none"))
{
- o = ClassUtils.getNewInstance(conversionHandlerClass);
- }
- catch (ClassNotFoundException cnfe )
- {
- String err = "The specified class for ConversionHandler (" + conversionHandlerClass
+ try
+ {
+ conversionHandlerInstance = ClassUtils.getNewInstance(conversionHandlerClass);
+ }
+ catch (ClassNotFoundException cnfe )
+ {
+ String err = "The specified class for ConversionHandler (" + conversionHandlerClass
+ ") does not exist or is not accessible to the current classloader.";
- log.error(err);
- throw new VelocityException(err, cnfe);
- }
- catch (InstantiationException ie)
- {
- throw new VelocityException("Could not instantiate class '" + conversionHandlerClass + "'", ie);
+ log.error(err);
+ throw new VelocityException(err, cnfe);
+ }
+ catch (InstantiationException ie)
+ {
+ throw new VelocityException("Could not instantiate class '" + conversionHandlerClass + "'", ie);
+ }
+ catch (IllegalAccessException ae)
+ {
+ throw new VelocityException("Cannot access class '" + conversionHandlerClass + "'", ae);
+ }
}
- catch (IllegalAccessException ae)
+ }
+
+ if (conversionHandlerInstance != null)
+ {
+ if (conversionHandlerInstance instanceof ConversionHandler)
{
- throw new VelocityException("Cannot access class '" + conversionHandlerClass + "'", ae);
- }
+ log.warn("The ConversionHandler interface is deprecated - see the TypeConversionHandler interface");
+ final ConversionHandler ch = (ConversionHandler)conversionHandlerInstance;
+ conversionHandler = new TypeConversionHandler()
+ {
+ @Override
+ public boolean isExplicitlyConvertible(Type formal, Class actual, boolean possibleVarArg)
+ {
+ Class formalClass = IntrospectionUtils.getTypeClass(formal);
+ if (formalClass != null) return ch.isExplicitlyConvertible(formalClass, actual, possibleVarArg);
+ else return false;
+ }
- if (!(o instanceof ConversionHandler))
+ @Override
+ public Converter getNeededConverter(Type formal, Class actual)
+ {
+ Class formalClass = IntrospectionUtils.getTypeClass(formal);
+ if (formalClass != null) return ch.getNeededConverter(formalClass, actual);
+ else return null;
+ }
+
+ @Override
+ public void addConverter(Type formal, Class actual, Converter converter)
+ {
+ Class formalClass = IntrospectionUtils.getTypeClass(formal);
+ if (formalClass != null) ch.addConverter(formalClass, actual, converter);
+ else throw new UnsupportedOperationException("This conversion handler doesn't know how to handle Type: " + formal.getTypeName());
+ }
+ };
+ }
+ else if (!(conversionHandlerInstance instanceof TypeConversionHandler))
{
- String err = "The specified class for ResourceManager (" + conversionHandlerClass
- + ") does not implement " + ConversionHandler.class.getName()
+ String err = "The specified class or provided instance for the conversion handler (" + conversionHandlerInstance.getClass().getName()
+ + ") does not implement " + TypeConversionHandler.class.getName()
+ "; Velocity is not initialized correctly.";
log.error(err);
throw new VelocityException(err);
}
-
- conversionHandler = (ConversionHandler) o;
+ else
+ {
+ conversionHandler = (TypeConversionHandler)conversionHandlerInstance;
+ }
}
}
@@ -256,7 +293,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
Method m = introspector.getMethod(obj.getClass(), methodName, args);
if (m != null)
{
- return new VelMethodImpl(m, false, getNeededConverters(m.getParameterTypes(), args));
+ return new VelMethodImpl(m, false, getNeededConverters(m.getGenericParameterTypes(), args));
}
Class cls = obj.getClass();
@@ -269,7 +306,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
{
// and create a method that knows to wrap the value
// before invoking the method
- return new VelMethodImpl(m, true, getNeededConverters(m.getParameterTypes(), args));
+ return new VelMethodImpl(m, true, getNeededConverters(m.getGenericParameterTypes(), args));
}
}
// watch for classes, to allow calling their static methods (VELOCITY-102)
@@ -278,7 +315,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
m = introspector.getMethod((Class)obj, methodName, args);
if (m != null)
{
- return new VelMethodImpl(m, false, getNeededConverters(m.getParameterTypes(), args));
+ return new VelMethodImpl(m, false, getNeededConverters(m.getGenericParameterTypes(), args));
}
}
return null;
@@ -288,7 +325,7 @@ public class UberspectImpl implements Uberspect, RuntimeServicesAware
* get the list of needed converters to adapt passed argument types to method types
* @return null if not conversion needed, otherwise an array containing needed converters
*/
- private Converter[] getNeededConverters(Class[] expected, Object[] provided)
+ private Converter[] getNeededConverters(Type[] expected, Object[] provided)
{
if (conversionHandler == null) return null;
// var args are not handled here - CB TODO