5 Replies Latest reply on Jan 2, 2007 7:34 PM by markcollette

    Seam debug page with ICEfaces

    markcollette

      Hi, I work at ICEsoft, on both Facelets and Seam integration. I ran into an issue with the Seam debug screen, as it works with ICEfaces. Basically, none of the stock JSF components were rendering properly, because org.jboss.seam.debug.jsf.SeamDebugPhaseListener diretly uses Facelets, without using the ViewHandler mechanisms, which ICEfaces relies upon.

      I think that the easiest approach will be to make a Seam com.sun.facelets.impl.ResourceResolver that knows how to get at the debug.xhtml file, and just use the existing facelets.RESOURCE_RESOLVER parameter to access it. No phase listener would be necessary, and the existing ViewHandler mechanisms would operate as usual to show the debug screen.

      Some sort of chaining of ResourceResolvers should be done, so that apps with an existing ResourceResolver will work. My preference would be for Facelets core to alter its use of the facelets.RESOURCE_RESOLVER parameter, to treat it as an ordered list of ResourceResolvers, much like how the facelets.LIBRARIES and facelets.DECORATORS parameters work.

      In the immediate term, to simplify my proof of concept code, I will add a second parameter called seam.RESOURCE_RESOLVER which org.jboss.seam.debug.jsf.SeamDebugResourceResolver will delegate to.

      So, to recap, here are some configuration examples:

      Current way, with a custom ResourceResolver:

      web.xml

      <context-param>
       <param-name>facelets.RESOURCE_RESOLVER</param-name>
       <param-value>com.mycompany.CustomResourceResolver</param-value>
      </context-param>
      


      Short-term solution, with Seam debug ResourceResolver, and no other custom ResourceResolver:

      web.xml
      <context-param>
       <param-name>facelets.RESOURCE_RESOLVER</param-name>
       <param-value>org.jboss.seam.debug.jsf.SeamDebugResourceResolver</param-value>
      </context-param>
      


      Short-term solution, with Seam debug ResourceResolver, and a custom
      ResourceResolver:

      web.xml
      <context-param>
       <param-name>facelets.RESOURCE_RESOLVER</param-name>
       <param-value>org.jboss.seam.debug.jsf.SeamDebugResourceResolver</param-value>
      </context-param>
      <context-param>
       <param-name>seam.RESOURCE_RESOLVER</param-name>
       <param-value>com.mycompany.CustomResourceResolver</param-value>
      </context-param>
      


      Potential long-term solution, with Seam debug ResourceResolver, and a custom ResourceResolver, chained:

      web.xml
      <context-param>
       <param-name>facelets.RESOURCE_RESOLVER</param-name>
      
      <param-value>org.jboss.seam.debug.jsf.SeamDebugResourceResolver;com.mycompany.CustomResourceResolver</param-value>
      </context-param>
      


      To try out the proof-of-concept method (short-term), do the following:

      1. Disable the SeamDebugPhaseListener by commenting out the lifecycle
      phase-listener block in src\debug\META-INF\faces-config.xml

      2. Copy and paste the following Java source code, and save it to src\debug\org\jboss\seam\debug\jsf\SeamDebugResourceResolver.java

      3. Tell the web app about SeamDebugResourceResolver. I added the following
      block to both examples\dvdstore\resources\WEB-INF\web.xml and examples\hibernate\resources\WEB-INF\web.xml

      <context-param>
       <param-name>facelets.RESOURCE_RESOLVER</param-name>
       <param-value>org.jboss.seam.debug.jsf.SeamDebugResourceResolver</param-value>
      </context-param>
      

      4. Rebuild Seam so that the change to the phase-listener will take effect.

      5. Build and deploy the web apps



      ##############################
      SeamDebugResourceResolver.java
      ##############################

      package org.jboss.seam.debug.jsf;
      
      import java.io.IOException;
      import java.net.URL;
      
      import javax.faces.context.FacesContext;
      import org.jboss.seam.core.Init;
      
      import com.sun.facelets.impl.ResourceResolver;
      import com.sun.facelets.impl.DefaultResourceResolver;
      
      /**
       * Intercepts any request for a path like /debug.xxx and renders
       * the Seam debug page using facelets.
       *
       * @author Mark Collette
       */
      public class SeamDebugResourceResolver implements ResourceResolver
      {
       private final static String PARAM_RESOURCE_RESOLVER = "seam.RESOURCE_RESOLVER";
      
       private ResourceResolver delegate;
      
       public SeamDebugResourceResolver()
       {
       delegate = buildDelegateResourceResolver();
       }
      
       public URL resolveUrl(String path)
       {
       System.out.println("SeamDebugResourceResolver.resolveUrl() path: " + path);
       if ( path!=null && path.startsWith("/debug.") && Init.instance().isDebug() )
       {
       URL url = SeamDebugResourceResolver.class.getClassLoader().getResource("META-INF/debug.xhtml");
       System.out.println("SeamDebugResourceResolver.resolveUrl() url: " + url);
       return url;
       }
       return delegate.resolveUrl(path);
       }
      
       private ResourceResolver buildDelegateResourceResolver()
       {
       FacesContext ctx = FacesContext.getCurrentInstance();
      
       ResourceResolver resourceResolver = null;
       String paramResourceResolver =
       ctx.getExternalContext().getInitParameter(PARAM_RESOURCE_RESOLVER);
       if( paramResourceResolver != null && paramResourceResolver.length() > 0 )
       {
       try
       {
       Class resourceResolverClass = Class.forName(
       paramResourceResolver,
       true,
       Thread.currentThread().getContextClassLoader());
       resourceResolver = (ResourceResolver) resourceResolverClass.newInstance();
       }
       catch(Exception e)
       {
       throw new RuntimeException("Problem initializing Seam delegate ResourceResolver: " + paramResourceResolver, e);
       }
       }
       if( resourceResolver == null )
       resourceResolver = new DefaultResourceResolver();
       return resourceResolver;
       }
      }



        • 1. Re: Seam debug page with ICEfaces
          gavin.king

          Thanks Mark, that's great but ... is there anyway to do this from faces-config.xml instead of web.xml? I would like the debug page to be automagically installed by the jboss-seam-debug.jar, instead of having to futz with web.xml.

          • 2. Re: Seam debug page with ICEfaces
            markcollette

            Hmm, some random musings from me, about your question ... :)

            I'm not aware of any other way of telling Facelets where to get at a resource, besides via the ResourceResolver. The thing is, I'm not sure that ResourceResolvers should be automagically configured anyway, since the web app developer would probably want to control the sequence of the chain of delegation.

            And the problem with the SeamDebugPhaseListener approach is that anyone using their own ViewHandler, not just ICEfaces with its ViewHandlers, may have problems. And what if content is being rendered to some non-HTML front-end? Then they might not be able to access the debug page anyway with the existing approach.

            Is there some way of faces-config.xml saving away some state somewhere, that the Facelets DefaultResourceResolver could then retrieve, that would then tell it how to find your debug.xhtml file? Alternatively, maybe your PhaseListener could programatically call some static method in Facelets, that could tell the DefaultResourceResolver about a Seam delegate that can find the debug.xhtml file. I guess that's more of a question for the Facelets Dev newsgroup, but maybe you'd have some clout with them to have that done?


            Oh, and I should probably mention, that what I've described here in this thread won't actually make the debug page work with the ICEfaces 1.5.1 release, but should make the next release work.

            • 3. Re: Seam debug page with ICEfaces
              gavin.king

              Let's wait til Jacob gets back (his IM status says "snowboarding in montana") and see what he has to say ;-)

              • 4. Re: Seam debug page with ICEfaces

                This will have to be for the next release, your workaround will probably work fine for now, but I'm re-working configuration loading and adding things to the taglib.xml for Facelets 1.2

                • 5. Re: Seam debug page with ICEfaces
                  markcollette

                   

                  "hookomjj" wrote:
                  This will have to be for the next release, your workaround will probably work fine for now, but I'm re-working configuration loading and adding things to the taglib.xml for Facelets 1.2


                  By next release, do you mean in Facelets 1.2.x, or 1.1.13?