Problem
A viewId is applicationwide resolved. The Resolve happens only once and not every Time

Task
Migrating a JSF 1.2 (Sun.RI) application to JSF2.0(Myfaces). This Application has an overwritten FacesViewHandler with custom FacletContext, DefaultFaceletFactory, DefaultFactory and a custom ResourceResolver.
We serve custom content for a viewId based on session data
Example:
The browser wanted viewId order.jsf and the app resolves this viewId to order_advanced.jsf. But in the browser there is only order.jsf visible.

This was easy to achieve. We use a MappingBean for mapping the viewIds. This MappingBean is instantiated when the session starts, and the Resolver use this Mapping Bean.

What we have:

  1. Our Mapping Beans are in place and fully functional.
  2. Custom ResourceResolver

    @Override
    public URL resolveUrl(final String path) {
    
        final PageMappingBean pmb = (PageMappingBean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(
                                    "pageMappingBean");
        URL returnURL = _resolver.resolveUrl(pmb != null ? pmb.mapUrl(path) : path);
    
    
        return returnURL;
    }
    

Observation
Accessing a viewid, which is mapped, works for the first session. It is mapped and resolved.
Starting a new session with a different mapping does not resolve the viewid any more.

This is due to the method (From Myfaces)

public Facelet getFacelet(String uri){
     URL url = (URL) _relativeLocations.get(uri);
    if (url == null)
    {
        url = resolveURL(_baseUrl, uri);
        if (url != null)
        {
            Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
            newLoc.put(uri, url);
            _relativeLocations = newLoc;
        }
        else
        {
            throw new IOException("'" + uri + "' not found.");
        }
    }
    return this.getFacelet(url);
}

in class 'DefaultFaceletFactory'

Question
How can we override the above method in Myfaces (Productive and testing environment). As mentioned above we had done this for JSF1.2 but in JSF 2.0 there is the additional VDL layer.

Or is there an other way to solve the problem?

Note
FacesFlow could possibly be a solution for our problem, but it can not be used in WAS8.0 application server, we are not allowed to:-(
For Mojarra(RI) we have a solution. There it is possible to set the context-param com.sun.faces.faceletFactory. This solution is working for us but can only be used in developing environment. Production and Testing is based on Myfaces.

For now we have dropped the idea of having an applicationscoped FaceletFactory. We are using dynamic resolution of facelets:

<ui:component xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html">
     <ui:include src="#{faceletMapper.map('/pagetoload.xhtml')}"/>
</ui:component>
有帮助吗?

解决方案

We do not longer use a custom FacletFactory. We are extending our facelets dynamically now. Outr Mapping Bean is just a normal bean which decide which facelet would be included

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top