Package org.jboss.seam.ui.facelet

Source Code of org.jboss.seam.ui.facelet.FaceletsRenderer$RenderingContext

package org.jboss.seam.ui.facelet;

import static org.jboss.seam.ScopeType.STATELESS;
import static org.jboss.seam.annotations.Install.BUILT_IN;

import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;

import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.ResourceLoader;
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.mock.MockExternalContext;
import org.jboss.seam.mock.MockFacesContext;
import org.jboss.seam.ui.util.JSF;

import com.sun.facelets.Facelet;
import com.sun.facelets.impl.DefaultFaceletFactory;
import com.sun.facelets.impl.DefaultResourceResolver;

/**
*
* Implementation of Renderer using Facelets
*
* Especially useful for sending email using Seam Mail
*
* @author Pete Muir
* @author Norman Richards
*
*/

@Scope(STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.faces.renderer")
@AutoCreate
@Install(value = true, precedence = BUILT_IN, classDependencies="com.sun.facelets.Facelet")
public class FaceletsRenderer extends Renderer
{
   /**
    * Sets up and tears down the rendering (FacesContext, ExternalContext) using
    * Seam's mock contexts if JSF is not currently running.  Also switches out the
    * ViewRoot for the duration.  Any output written to the ResponseWriter is
    * buffered.
    *
    * @author Pete Muir
    *
    */
   protected abstract class RenderingContext
   {
     
      public RenderingContext(String viewId)
      {
         this.viewId = viewId;
      }
     
      private String viewId;
     
      private ClassLoader originalClassLoader;
      private ResponseWriter originalResponseWriter;
      private UIViewRoot originalViewRoot;
      private StringWriter writer = new StringWriter();
     
      /**
       * Call to execute the process method inside the RenderingContext
       */
      public void run()
      {
         try
         {
            init();
            process();
         }
         finally
         {
            cleanup();
         }
      }
     
      private void init()
      {
         // Make sure we are using the correct ClassLoader
         originalClassLoader = Thread.currentThread().getContextClassLoader();
         Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        
         // If a FacesContext isn't available, set one up
         if (FacesContext.getCurrentInstance() == null)
         {
            MockFacesContext mockFacesContext = new MockFacesContext(new MockExternalContext())
                     .setCurrent();
            mockFacesContext.createViewRoot();
         }
        
         FacesContext facesContext = FacesContext.getCurrentInstance();
        
         // Wrap the ResponseWriter
         originalResponseWriter = facesContext.getResponseWriter();
         facesContext.setResponseWriter(facesContext.getRenderKit().createResponseWriter(writer,
                  null, null));
        
         // Create a new UIViewRoot
         originalViewRoot = facesContext.getViewRoot();
         UIViewRoot viewRoot = new UIViewRoot();
         viewRoot.setRenderKitId(facesContext.getApplication().getViewHandler().calculateRenderKitId(facesContext));
         viewRoot.setViewId(viewId);
         viewRoot.setLocale(originalViewRoot.getLocale());
         facesContext.setViewRoot(viewRoot);
      }
     
      private void cleanup()
      {
         FacesContext facesContext = FacesContext.getCurrentInstance();
         if (originalResponseWriter != null)
         {
            facesContext.setResponseWriter(originalResponseWriter);
         }
         if (originalViewRoot != null)
         {
            facesContext.setViewRoot(originalViewRoot);
         }
         Thread.currentThread().setContextClassLoader(originalClassLoader);      
      }
     
      /**
       * Return any output written to the ResponseWriter as a String
       */
      public String getOutput()
      {
         return writer.getBuffer().toString();
      }
     
      /**
       * Override to execute within a RenderingContext
       */
      protected abstract void process();
     
   }
  
   /**
    * Render the viewId, anything written to the JSF ResponseWriter is
    * returned
    */
   @Override
   public String render(final String viewId)
   {
      RenderingContext context = new RenderingContext(viewId) {
        
         @Override
         public void process()
         {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            try
            {
               renderFacelet(facesContext, faceletForURL(resourceURL(viewId)));
            }
            catch (IOException e)
            {
               throw new RuntimeException("Error rendering view", e);
            }
         }
        
      };
      context.run();
     
      return context.getOutput();
   }

   /**
    * Get a viewId as a URL
    */
   protected URL resourceURL(String viewId)
   {

      URL url = ResourceLoader.instance().getResource(viewId);

      if (url == null)
      {
         throw new IllegalArgumentException("resource doesn't exist: " + viewId);
      }

      return url;
   }

   /**
    * Get a Facelet for a URL
    */
   protected Facelet faceletForURL(URL url) throws IOException
   {
      return new DefaultFaceletFactory(FaceletCompiler.instance(), new DefaultResourceResolver())
               .getFacelet(url);
   }

   /**
    * Render a Facelet
    */
   protected void renderFacelet(FacesContext facesContext, Facelet facelet) throws IOException
   {
      UIViewRoot root = facesContext.getViewRoot();
      facelet.apply(facesContext, root);
      JSF.renderChildren(facesContext, root)
   }
  
}
TOP

Related Classes of org.jboss.seam.ui.facelet.FaceletsRenderer$RenderingContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.