Search in sources :

Example 1 with ExpressionCacheKey

use of org.thymeleaf.cache.ExpressionCacheKey in project thymeleaf by thymeleaf.

the class OGNLShortcutExpression method getObjectProperty.

private static Object getObjectProperty(final ICache<ExpressionCacheKey, Object> expressionCache, final String propertyName, final Object target) {
    final Class<?> currClass = OgnlRuntime.getTargetClass(target);
    final ExpressionCacheKey cacheKey = computeMethodCacheKey(currClass, propertyName);
    Method readMethod = null;
    if (expressionCache != null) {
        readMethod = (Method) expressionCache.get(cacheKey);
    }
    if (readMethod == null) {
        final BeanInfo beanInfo;
        try {
            beanInfo = Introspector.getBeanInfo(currClass);
        } catch (final IntrospectionException e) {
            // Something went wrong during introspection - wash hands, just let OGNL decide what to do
            throw new OGNLShortcutExpressionNotApplicableException();
        }
        final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        if (propertyDescriptors != null) {
            for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                if (propertyDescriptor.getName().equals(propertyName)) {
                    readMethod = propertyDescriptor.getReadMethod();
                    if (readMethod != null && expressionCache != null) {
                        expressionCache.put(cacheKey, readMethod);
                    }
                    break;
                }
            }
        }
    }
    if (readMethod == null) {
        // The property name does not match any getter methods - better let OGNL decide what to do
        throw new OGNLShortcutExpressionNotApplicableException();
    }
    try {
        return readMethod.invoke(target, NO_PARAMS);
    } catch (final IllegalAccessException e) {
        // Oops! we better let OGNL take care of this its own way...
        throw new OGNLShortcutExpressionNotApplicableException();
    } catch (final InvocationTargetException e) {
        // Oops! we better let OGNL take care of this its own way...
        throw new OGNLShortcutExpressionNotApplicableException();
    }
}
Also used : PropertyDescriptor(java.beans.PropertyDescriptor) ExpressionCacheKey(org.thymeleaf.cache.ExpressionCacheKey) BeanInfo(java.beans.BeanInfo) IntrospectionException(java.beans.IntrospectionException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with ExpressionCacheKey

use of org.thymeleaf.cache.ExpressionCacheKey in project thymeleaf by thymeleaf.

the class OGNLShortcutExpression method evaluate.

Object evaluate(final IEngineConfiguration configuration, final Map<String, Object> context, final Object root) throws Exception {
    final ICacheManager cacheManager = configuration.getCacheManager();
    final ICache<ExpressionCacheKey, Object> expressionCache = (cacheManager == null ? null : cacheManager.getExpressionCache());
    Object target = root;
    for (final String propertyName : this.expressionLevels) {
        // If target is null, we will mimic what OGNL does in these cases...
        if (target == null) {
            throw new OgnlException("source is null for getProperty(null, \"" + propertyName + "\")");
        }
        // For the best integration possible, we will ask OGNL which property accessor it would use for
        // this target object, and then depending on the result apply our equivalent or just default to
        // OGNL evaluation if it is a custom property accessor we do not implement.
        final Class<?> targetClass = OgnlRuntime.getTargetClass(target);
        final PropertyAccessor ognlPropertyAccessor = OgnlRuntime.getPropertyAccessor(targetClass);
        // Depending on the returned OGNL property accessor, we will try to apply ours
        if (target instanceof Class<?>) {
            // Because of the way OGNL works, the "OgnlRuntime.getTargetClass(...)" of a Class object is the class
            // object itself, so we might be trying to apply a PropertyAccessor to a Class instead of a real object,
            // something we avoid by means of this shortcut
            target = getObjectProperty(expressionCache, propertyName, target);
        } else if (OGNLContextPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getContextProperty(propertyName, context, target);
        } else if (ObjectPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getObjectProperty(expressionCache, propertyName, target);
        } else if (MapPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getMapProperty(propertyName, (Map<?, ?>) target);
        } else if (ListPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getListProperty(expressionCache, propertyName, (List<?>) target);
        } else if (SetPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getSetProperty(expressionCache, propertyName, (Set<?>) target);
        } else if (IteratorPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getIteratorProperty(expressionCache, propertyName, (Iterator<?>) target);
        } else if (EnumerationPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getEnumerationProperty(expressionCache, propertyName, (Enumeration<?>) target);
        } else if (ArrayPropertyAccessor.class.equals(ognlPropertyAccessor.getClass())) {
            target = getArrayProperty(expressionCache, propertyName, (Object[]) target);
        } else {
            // default to normal OGNL evaluation.
            throw new OGNLShortcutExpressionNotApplicableException();
        }
    }
    return target;
}
Also used : EnumerationPropertyAccessor(ognl.EnumerationPropertyAccessor) PropertyAccessor(ognl.PropertyAccessor) ListPropertyAccessor(ognl.ListPropertyAccessor) ObjectPropertyAccessor(ognl.ObjectPropertyAccessor) MapPropertyAccessor(ognl.MapPropertyAccessor) ArrayPropertyAccessor(ognl.ArrayPropertyAccessor) EnumerationPropertyAccessor(ognl.EnumerationPropertyAccessor) IteratorPropertyAccessor(ognl.IteratorPropertyAccessor) SetPropertyAccessor(ognl.SetPropertyAccessor) ExpressionCacheKey(org.thymeleaf.cache.ExpressionCacheKey) MapPropertyAccessor(ognl.MapPropertyAccessor) OgnlException(ognl.OgnlException) Iterator(java.util.Iterator) List(java.util.List) SetPropertyAccessor(ognl.SetPropertyAccessor) ICacheManager(org.thymeleaf.cache.ICacheManager)

Aggregations

ExpressionCacheKey (org.thymeleaf.cache.ExpressionCacheKey)2 BeanInfo (java.beans.BeanInfo)1 IntrospectionException (java.beans.IntrospectionException)1 PropertyDescriptor (java.beans.PropertyDescriptor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 Iterator (java.util.Iterator)1 List (java.util.List)1 ArrayPropertyAccessor (ognl.ArrayPropertyAccessor)1 EnumerationPropertyAccessor (ognl.EnumerationPropertyAccessor)1 IteratorPropertyAccessor (ognl.IteratorPropertyAccessor)1 ListPropertyAccessor (ognl.ListPropertyAccessor)1 MapPropertyAccessor (ognl.MapPropertyAccessor)1 ObjectPropertyAccessor (ognl.ObjectPropertyAccessor)1 OgnlException (ognl.OgnlException)1 PropertyAccessor (ognl.PropertyAccessor)1 SetPropertyAccessor (ognl.SetPropertyAccessor)1 ICacheManager (org.thymeleaf.cache.ICacheManager)1