OK, so here's the approach in summary:

First, you'll need some way of mapping the view ID derived from the request URL to an actual Facelets view (.xhtml file or whatever). I have an XML file that defines regular expressions to match against the URL and substitution patterns to build the view path, but you may be able to use something simpler. Given that, you can get Facelets to load the view while preserving the original view ID in the component tree.

Create a sub-class of FaceletsViewHandler and override the buildView() method. Copy the implementation from the Facelets sources and look for the block that loads the Facelet. You need to change that to load the path you derived from the original view ID, like this:

        // grab our FaceletFactory and create a Facelet
        Facelet f = null;
        FaceletFactory.setInstance(this.localFaceletFactory);
        try {
            String viewPath = myMappingFunction(
                                viewToRender.getViewId());
            f = this.localFaceletFactory.getFacelet(viewPath);
        } finally {
            FaceletFactory.setInstance(null);
        }

The rest of the buildView implementation stays the same as in the Facelets distribution. The only slight glitch is the reference above to localFaceletFactory; since faceletFactory is private in the base FaceletViewHandler class, you have to override createFaceletFactory() like this:

protected FaceletFactory createFaceletFactory(com.sun.facelets.compiler.Compiler compiler) {
        localFaceletFactory = super.createFaceletFactory(compiler);
        return localFaceletFactory;
    }

in order to get a reference to the facelet factory to use in buildView().

If you need more help getting this working, ping me off-list (since it's a bit off-topic to get into any further here).

HTH,

L.

David G. Friedman wrote:
I've been playing with Facelets so I'm all ears. Feel free to backchannel me or 
to move this to the facelets list if you
prefer.

Regards,
David

-----Original Message-----
From: news [mailto:[EMAIL PROTECTED] Behalf Of Laurie Harper
Sent: Thursday, January 12, 2006 10:52 PM
To: users@myfaces.apache.org
Subject: Re: How to override the MyFaces 1.1.1 taglib listener
registration?


David, I have a solution for this based on subclassing
FaceletsViewHandler; the trick is to map the view ID to a view, load the
view to create the component tree, but retain the view ID. It's a little
tricky -- and can't be done in a way that's portable, so if you're not
using Facelets my solution wont work for you. But if you are using
Facelets, and would like the details, let me know.

L.

David G. Friedman wrote:
I don't have control over that option with my hosting provider.  I just have 
JSF (MyFaces) to work with to make
everything dynamic.  I tried creating the new UIViewRoot with the 
/hostname/whatever path then resetting it back to
/whatever before returning it with CreateViewRoot but that didn't work.  It 
doesn't find the file now so at least I
know
ViewHandler.createView() isn't the correct place for my logic. *shrug*

Regards,
David

-----Original Message-----
From: Jesse Alexander (KBSA 21)
[mailto:[EMAIL PROTECTED]
Sent: Thursday, January 12, 2006 1:57 PM
To: MyFaces Discussion
Subject: RE: How to override the MyFaces 1.1.1 taglib listener
registration?


Why not use an apache webserver with its url-rewriting capabilities?

hth
Alexander

-----Original Message-----
From: David G. Friedman [mailto:[EMAIL PROTECTED]
Sent: Thursday, January 12, 2006 5:55 PM
To: MyFaces Discussion
Subject: RE: How to override the MyFaces 1.1.1 taglib listener registration?

Ronald,

I want to virtual host so the path /hello maps internally to /hostname/hello.  
I'm trying to do some sort of internal
redirect WITHOUT having to put dummy/stub files in the main /WEBAPP folder 
which would then include the relevant
virtual
host file(s).  So, this kind of cancels out Facelets or Shale/Clay for that 
very purpose.  I've tried making another
ViewHandler.createView(context, "hostname" + viewId) but that ALSO changes the 
submitted path to
/hostname/whatever.jsf
instead of retaining it as /whatever.jsf.

Now, I'm thinking I can use the servletContextListener to put my own 
ExternalContext in there so when the JSP calls
ExternalContext.dispatch(), I can override that method to invoke 
"/localhost/filename" since I won't have a generic
"/filename" setup.

I'm open to new ideas and suggestions.  I wonder sometimes why I go for the 
complicated stuff when I program
application
services. *sigh*

Regards,
David

-----Original Message-----
From: "R. Müller" [mailto:[EMAIL PROTECTED]
Sent: Thursday, January 12, 2006 5:14 AM
To: MyFaces Discussion
Subject: Re: How to override the MyFaces 1.1.1 taglib listener
registration?


Hi David,

why you want to override - define your own in the web.xml !

<listener>
<listener-class>myServletContextListener</listener-class>
</listener>

You have to implement the 'javax.servlet.ServletContextListener' -
Interface with the following two methods :

public void contextInitialized(ServletContextEvent e);
public void contextDestroyed(ServletContextEvent e);

The same if want to listen for sessions. You have to additionally
implement the 'javax.servlet.http.HttpSessionListener'-Interface with

public void sessionCreated(HttpSessionEvent e);
public void sessionDestroyed(HttpSessionEvent e);

regards

Ronald

David G. Friedman wrote:
In the MyFaces taglib, it has the listener declaration (which works in my 
Tomcat 5.0.28 :

<listener>
    
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>

Is there any way to override this other than:

a) Edit the taglib file to change it.

b) make my own 
/WEB-INF/classes/org/apache/myfaces/webapp/StartupServletContextListener.java 
file?

Regards,
David








Reply via email to