Search in sources :

Example 1 with TagValueExpression

use of org.apache.myfaces.view.facelets.el.TagValueExpression in project myfaces by apache.

the class TagAttributeImpl method getValueExpression.

/**
 * Create a ValueExpression, using this attribute's literal value and the passed expected type.
 *
 * See ExpressionFactory#createValueExpression(jakarta.el.ELContext, java.lang.String, java.lang.Class)
 * See ValueExpression
 * @param ctx
 *            FaceletContext to use
 * @param type
 *            expected return type
 * @return ValueExpression instance
 */
@Override
public ValueExpression getValueExpression(FaceletContext ctx, Class type) {
    AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
    // volatile reads are atomic, so take the tuple to later comparison.
    Object[] localCachedExpression = cachedExpression;
    if (actx.isAllowCacheELExpressions() && localCachedExpression != null && localCachedExpression.length == 2) {
        // If the expected type is the same return the cached one
        if (localCachedExpression[0] == null && type == null) {
            // If #{cc} recalculate the composite component level
            if ((this.capabilities & EL_CC) != 0) {
                UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
                if (cc != null) {
                    Location location = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
                    if (location != null) {
                        return ((LocationValueExpression) localCachedExpression[1]).apply(actx.getFaceletCompositionContext().getCompositeComponentLevel(), location);
                    }
                }
                return ((LocationValueExpression) localCachedExpression[1]).apply(actx.getFaceletCompositionContext().getCompositeComponentLevel());
            }
            return (ValueExpression) localCachedExpression[1];
        } else if (localCachedExpression[0] != null && localCachedExpression[0].equals(type)) {
            // If #{cc} recalculate the composite component level
            if ((this.capabilities & EL_CC) != 0) {
                UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
                if (cc != null) {
                    Location location = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
                    if (location != null) {
                        return ((LocationValueExpression) localCachedExpression[1]).apply(actx.getFaceletCompositionContext().getCompositeComponentLevel(), location);
                    }
                }
                return ((LocationValueExpression) localCachedExpression[1]).apply(actx.getFaceletCompositionContext().getCompositeComponentLevel());
            }
            return (ValueExpression) localCachedExpression[1];
        }
    }
    actx.beforeConstructELExpression();
    try {
        ExpressionFactory f = ctx.getExpressionFactory();
        ValueExpression valueExpression = f.createValueExpression(ctx, this.value, type);
        if (actx.getFaceletCompositionContext().isWrapTagExceptionsAsContextAware()) {
            valueExpression = new ContextAwareTagValueExpression(this, valueExpression);
        } else {
            valueExpression = new TagValueExpression(this, valueExpression);
        }
        // (see MYFACES-2561 for details)
        if ((this.capabilities & EL_CC) != 0) {
            // In MYFACES-4099 it was found that #{cc} could happen outside a composite component. In that
            // case, getLocation() will point to the template. To solve the problem, it is better to get
            // the location of the composite component from the stack directly, but only when the path
            // is different.
            Location currentLocation = getLocation();
            UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
            if (cc != null) {
                Location ccLocation = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
                if (ccLocation != null && !ccLocation.getPath().equals(currentLocation.getPath())) {
                    // #{cc} from a template called from inside a composite component, disable caching on
                    // this expression. The reason is we need to change the Location object used as
                    // reference as the one in the stack, and that depends on the template hierarchy.
                    // cacheable = false;
                    currentLocation = ccLocation;
                }
            }
            valueExpression = new LocationValueExpression(currentLocation, valueExpression, actx.getFaceletCompositionContext().getCompositeComponentLevel());
        } else if ((this.capabilities & EL_RESOURCE) != 0) {
            valueExpression = new ResourceLocationValueExpression(getLocation(), valueExpression);
        }
        if (actx.isAllowCacheELExpressions() && !actx.isAnyFaceletsVariableResolved()) {
            cachedExpression = new Object[] { type, valueExpression };
        }
        return valueExpression;
    } catch (Exception e) {
        throw new TagAttributeException(this, e);
    } finally {
        actx.afterConstructELExpression();
    }
}
Also used : TagAttributeException(jakarta.faces.view.facelets.TagAttributeException) ExpressionFactory(jakarta.el.ExpressionFactory) ContextAwareTagValueExpression(org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression) TagValueExpression(org.apache.myfaces.view.facelets.el.TagValueExpression) ResourceLocationValueExpression(org.apache.myfaces.view.facelets.el.ResourceLocationValueExpression) UIComponent(jakarta.faces.component.UIComponent) AbstractFaceletContext(org.apache.myfaces.view.facelets.AbstractFaceletContext) TagAttributeException(jakarta.faces.view.facelets.TagAttributeException) ELException(jakarta.el.ELException) ResourceLocationValueExpression(org.apache.myfaces.view.facelets.el.ResourceLocationValueExpression) ContextAwareTagValueExpression(org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression) ValueExpression(jakarta.el.ValueExpression) LocationValueExpression(org.apache.myfaces.view.facelets.el.LocationValueExpression) TagValueExpression(org.apache.myfaces.view.facelets.el.TagValueExpression) ContextAwareTagValueExpression(org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression) Location(jakarta.faces.view.Location) ResourceLocationValueExpression(org.apache.myfaces.view.facelets.el.ResourceLocationValueExpression) LocationValueExpression(org.apache.myfaces.view.facelets.el.LocationValueExpression)

Aggregations

ELException (jakarta.el.ELException)1 ExpressionFactory (jakarta.el.ExpressionFactory)1 ValueExpression (jakarta.el.ValueExpression)1 UIComponent (jakarta.faces.component.UIComponent)1 Location (jakarta.faces.view.Location)1 TagAttributeException (jakarta.faces.view.facelets.TagAttributeException)1 AbstractFaceletContext (org.apache.myfaces.view.facelets.AbstractFaceletContext)1 ContextAwareTagValueExpression (org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression)1 LocationValueExpression (org.apache.myfaces.view.facelets.el.LocationValueExpression)1 ResourceLocationValueExpression (org.apache.myfaces.view.facelets.el.ResourceLocationValueExpression)1 TagValueExpression (org.apache.myfaces.view.facelets.el.TagValueExpression)1