use of org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression 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();
}
}
Aggregations