I'm working on an existing JSF component where the encodeEnd
method ends with:
// popComponentFromEL(context);
The Javadoc for UIComponent#popComponentFromEL(FacesContext context)
tells me:
Pop the current
UIComponent
from theFacesContext
attributes map so that the previousUIComponent
, if any, becomes the current component.
When and why would you need or want that?
I've found that none of the other components in the same library are using it.
That's the counterpart of pushComponentToEL()
whose Javadoc explains this more elaborately.
pushComponentToEL
public final void pushComponentToEL(FacesContext context, UIComponent component)
Push the current UIComponent this to the
FacesContext
attribute map using the keyCURRENT_COMPONENT
saving the previousUIComponent
associated withCURRENT_COMPONENT
for a subsequent call topopComponentFromEL(javax.faces.context.FacesContext)
.This method and
popComponentFromEL()
form the basis for the contract that enables the EL Expression "#{component}
" to resolve to the "current" component that is being processed in the lifecycle. The requirements for whenpushComponentToEL()
andpopComponentFromEL()
must be called are specified as needed in the javadoc for this class. AfterpushComponentToEL()
returns, a call togetCurrentComponent(javax.faces.context.FacesContext)
must return thisUIComponent
instance untilpopComponentFromEL()
is called, after which point the previousUIComponent
instance will be returned fromgetCurrentComponent()
Basically, this approach
public void encodeXxx(FacesContext context) {
try {
pushComponentToEL(context, this);
// ...
}
finally {
popComponentFromEL(context);
}
}
allows you during the // ...
process to grab this
component using #{component}
in EL, or UIComponent#getCurrentComponent()
in a managed bean.
One of well known examples is this construct:
<h:inputText ... styleClass="#{component.valid ? 'valid' : 'error'}" />
where #{component.valid}
basically refers UIInput#isValid()
.