raise before navigate event
---------------------------
Key: SEAMFACES-21
URL:
https://jira.jboss.org/browse/SEAMFACES-21
Project: Seam Faces
Issue Type: Feature Request
Components: JSF CDI Integration
Affects Versions: 3.0.0.Alpha2
Reporter: Dan Allen
Fix For: 3.0.0.Alpha3
One of the system event candidates that was overlooked in JSF 2.0 was a before navigation
event, which would get fired just before the call to NavigationHandler#handleNavigation().
This is a very interesting transition and would open up a lot of possibilities for
application developers, because JSF really don't accommodate this extension well.
(Seam 2 had some functionality for setting context variables before navigation, but IMHO
it would be far more powerful if we just raised an event so that the developer could
execute any sort of logic before navigation).
Forget even making a JSF system event out of it. Let's just raise it using CDI events
(since we are bridging the JSF events anyway).
I propose that we introduce the event qualifier:
@Qualifier
@Target( { FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface FacesNavigation {
}
and the event object would be the NavigationCase.
public void preNavigate(@Observes @Before @FacesNavigation NavigationCase nc) {
nc.getParameters().put("foo", Arrays.asList("bar"));
}
This can be combined with @Before and @View for filtering the event. We may even want
@ToView to filter both the current and target view. Not sure how fine-grained to get.
Here's a rough sketch of how this might be implemented. Unfortunately, this exposes
the nastiness of the ConfigurableNavigationHandler in JSF 2.0, but at least we can
leverage the NavigationCase resolution method we added for ourselves.
public class SeamNavigationHandler extends ConfigurableNavigationHandler {
private final NavigationHandler delegate;
public SeamNavigationHandler(NavigationHandler delegate)
{
this.delegate = delegate;
}
@Override
public NavigationCase getNavigationCase(FacesContext context, String fromAction, String
outcome)
{
if (delegate instanceof ConfigurableNavigationHandler) {
return ((ConfigurableNavigationHandler) delegate).getNavigationCase(context,
fromAction, outcome);
}
// I guess
return null;
}
@Override
public Map<String, Set<NavigationCase>> getNavigationCases()
{
if (delegate instanceof ConfigurableNavigationHandler) {
return ((ConfigurableNavigationHandler) delegate).getNavigationCases();
}
// I guess
return null;
}
@Override
public void handleNavigation(FacesContext context, String fromAction, String outcome)
{
if (delegate instanceof ConfigurableNavigationHandler) {
// we need to perform the resolution before JSF gets it so that we know where we
are headed
NavigationCase navigationCase = ((ConfigurableNavigationHandler)
delegate).getNavigationCase(context, fromAction, outcome);
if (navigationCase != null) {
// this is solved elsewhere in Seam Faces, so just use that same hook
BeanManager beanManager = ...;
beanManager.fireEvent(navigationCase, new AnnotationLiteral<Before>()
{}, new AnnotationLiteral<FacesNavigation>() {}, new
ViewLiteral(context.getViewRoot().getViewId())));
}
}
delegate.handleNavigation(context, fromAction, outcome);
}
}
We could support short-circuiting the view handler by checking for
context.getResponseComplete() (redirect occurred) or if the view root changed (render
occurred), but that might be abusing this hook.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira