Package org.jboss.portletbridge.richfaces

Source Code of org.jboss.portletbridge.richfaces.RichFacesStrategy

/**
*
*/
package org.jboss.portletbridge.richfaces;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

import javax.faces.FacesException;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.portlet.MimeResponse;
import javax.portlet.PortletContext;
import javax.portlet.PortletSession;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.faces.BridgeException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ajax4jsf.application.AjaxViewHandler;
import org.ajax4jsf.context.AjaxContext;
import org.ajax4jsf.context.ViewResources;
import org.ajax4jsf.request.MultipartRequest;
import org.ajax4jsf.resource.FacesResourceContext;
import org.ajax4jsf.resource.InternetResource;
import org.ajax4jsf.resource.InternetResourceBuilder;
import org.ajax4jsf.resource.ResourceContext;
import org.ajax4jsf.resource.ResourceLifecycle;
import org.ajax4jsf.resource.ResourceNotFoundException;
import org.ajax4jsf.resource.ServletResourceContext;
import org.ajax4jsf.webapp.WebXml;
import org.ajax4jsf.xml.serializer.Method;
import org.ajax4jsf.xml.serializer.OutputPropertiesFactory;
import org.ajax4jsf.xml.serializer.Serializer;
import org.ajax4jsf.xml.serializer.SerializerFactory;
import org.ajax4jsf.xml.serializer.TreeWalker;
import org.jboss.portletbridge.BridgeConfig;
import org.jboss.portletbridge.BridgeStrategy;
import org.jboss.portletbridge.BufferedMimeResponseWrapper;
import org.jboss.portletbridge.RequestScopeManager;
import org.jboss.portletbridge.StateId;
import org.jboss.portletbridge.component.UIPortletAjaxViewRoot;
import org.jboss.portletbridge.context.AbstractExternalContext;
import org.jboss.portletbridge.context.PortletBridgeContext;
import org.jboss.portletbridge.renderkit.portlet.PortletAjaxViewRootRenderer;
import org.jboss.portletbridge.util.BridgeLogger;
import org.richfaces.component.FileUploadConstants;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
* @author asmirnov
*
*/
public class RichFacesStrategy extends BridgeStrategy {

  private static final String XML_CONTENT = "text/xml;charset=UTF-8";

  private static final String HTML_EPILOG = "</body></html>";

  private static final byte[] HTML_EPILOG_BYTES = HTML_EPILOG.getBytes();

  private static final String HTML_BODY = "</head><body>";

  private static final byte[] HTML_BODY_BYTES = HTML_BODY.getBytes();

  private static final String HTML_PROLOG = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>";

  private static final byte[] HTML_PROLOG_BYTES = HTML_PROLOG.getBytes();

  private static final Logger log = BridgeLogger.BRIDGE.getLogger();

  public static final String RICHFACES_RESOURCE = "org.jboss.portletbridge.richfaces.Resource";

  public static final String AJAX4JSF_FILTER = "org.ajax4jsf.Filter";
  public static final String SEAM_FILTER = "org.jboss.seam.servlet.SeamFilter";
  public static final String PARAM_CREATE_TEMP_FILES = "createTempFiles";
  public static final String PARAM_MAX_REQUEST_SIZE = "maxRequestSize";

  private final ResourceLifecycle lifecycle;

  private final PortletXMLFilter xmlFilter;

  private InternetResourceBuilder resourceBuilder;

  private boolean uploadToTempDir = false;

  private int uploadLimit = 0;

  public RichFacesStrategy(BridgeConfig config) {
    super(config);
    // Assert richfaces classes.
    AjaxContext.class.getName();
    lifecycle = new ResourceLifecycle();
    xmlFilter = new PortletXMLFilter();
    PortletContext portletContext = config.getPortletConfig()
        .getPortletContext();
    xmlFilter.init(portletContext);
    resourceBuilder = InternetResourceBuilder.getInstance();
    if (!(resourceBuilder instanceof PortletResourceBuilder)) {
      resourceBuilder = new PortletResourceBuilder(resourceBuilder);
      InternetResourceBuilder.setInstance(resourceBuilder);
    }
    WebXml webXml = (WebXml) portletContext
        .getAttribute(WebXml.CONTEXT_ATTRIBUTE);
    portletContext.setAttribute(WebXml.CONTEXT_ATTRIBUTE,
        new PortletWebXml(webXml));

    Map<String, String> filterInitParams = config
        .getFilterInitParams(AJAX4JSF_FILTER);

    if (filterInitParams == null) {
      // then check to see if the init params are on the seam filter
      // config
      filterInitParams = config.getFilterInitParams(SEAM_FILTER);
    }

    if (filterInitParams != null) {
      String uploadToTempDirStr = filterInitParams
          .get(PARAM_CREATE_TEMP_FILES);
      this.uploadToTempDir = uploadToTempDirStr != null
          && uploadToTempDirStr.toLowerCase().equals("true");
      String maxRequestSizeStr = filterInitParams
          .get(PARAM_MAX_REQUEST_SIZE);
      if (maxRequestSizeStr != null) {
        try {
          uploadLimit = Integer.parseInt(maxRequestSizeStr);
        } catch (NumberFormatException nfe) {
          log.warning("invalid Filter init parameter value in web.xml: "
              + PARAM_MAX_REQUEST_SIZE
              + " - "
              + maxRequestSizeStr);
        }
      }
    }

  }

  private void finishResponse(FacesContext facesContext,
      BufferedMimeResponseWrapper wrappedResponse) {
    try {
      Map<String, Object> requestMap = facesContext.getExternalContext()
          .getRequestMap();
      if (!Boolean.TRUE.equals(requestMap
          .get(AjaxViewHandler.RESOURCES_PROCESSED))) {

        ViewResources viewResources = new ViewResources();

        viewResources.initialize(facesContext);
        viewResources.processHeadResources(facesContext);

        requestMap.put(AjaxContext.HEAD_EVENTS_PARAMETER,
            viewResources.getHeadEvents());

        // Mark as processed.
        requestMap.put(AjaxViewHandler.RESOURCES_PROCESSED,
            Boolean.TRUE);
      }
      AjaxContext ajaxContext = AjaxContext
          .getCurrentInstance(facesContext);
      if (ajaxContext.isAjaxRequest(facesContext)) {
        writeAjaxContent(facesContext, wrappedResponse);
      } else {
        writeContent(facesContext, wrappedResponse);
      }
    } catch (Exception e) {
      throw new BridgeException(e);
    }
  }

  private void writeAjaxContent(FacesContext facesContext,
      BufferedMimeResponseWrapper wrappedResponse) throws IOException,
      SAXException {
    xmlFilter.writeContent(facesContext, wrappedResponse);
  }

  private void writeContent(FacesContext facesContext,
      BufferedMimeResponseWrapper wrappedResponse) throws IOException,
      SAXException {
    writeHeadEvents(facesContext, wrappedResponse);
    wrappedResponse.writeBufferedData();
  }

  private void writeHeadEvents(FacesContext facesContext,
      BufferedMimeResponseWrapper wrappedResponse) throws IOException,
      SAXException {
    Object headEvents = facesContext.getExternalContext().getRequestMap()
        .get(AjaxContext.HEAD_EVENTS_PARAMETER);
    if (headEvents != null) {
      Node[] nodes = (Node[]) headEvents;

      Properties xhtmlProperties = OutputPropertiesFactory
          .getDefaultMethodProperties(Method.XHTML);
      Serializer serializer = SerializerFactory
          .getSerializer(xhtmlProperties);
      MimeResponse response = wrappedResponse.getResponse();
      if (wrappedResponse.isUseWriter()) {
        serializer.setWriter(response.getWriter());
      } else {
        serializer.setOutputStream(response.getPortletOutputStream());
      }

      ContentHandler contentHandler = serializer.asContentHandler();
      TreeWalker treeWalker = new TreeWalker(contentHandler);

      contentHandler.startDocument();

      for (Node node : nodes) {
        treeWalker.traverseFragment(node);
      }

      contentHandler.endDocument();
    }
  }

  public void init(FacesContext context, RenderKitFactory renderKitFactory) {
    PortletAjaxViewRootRenderer ajaxRenderer = new PortletAjaxViewRootRenderer();
    Iterator<String> renderKitIds = renderKitFactory.getRenderKitIds();
    while (renderKitIds.hasNext()) {
      String renderKitId = renderKitIds.next();
      RenderKit renderKit = renderKitFactory.getRenderKit(context,
          renderKitId);
      renderKit.addRenderer(UIViewRoot.COMPONENT_FAMILY,
          UIViewRoot.COMPONENT_TYPE, ajaxRenderer);
    }
    context.getApplication().addComponent(UIViewRoot.COMPONENT_TYPE,
        UIPortletAjaxViewRoot.class.getName());
  }

  public void beforeRenderRequest(FacesContext facesContext) {
    AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
    StateId stateId = PortletBridgeContext.getCurrentInstance(facesContext)
        .getStateId();
    ajaxContext.getCommonAjaxParameters().put(
        RequestScopeManager.STATE_ID_PARAMETER, stateId.toString());
  }

  public RenderResponse createResponseWrapper(RenderResponse response) {
    return new BufferedRenderResponseWrapper(response);
  }

  public ResourceResponse createResponseWrapper(ResourceResponse response) {
    return new BufferedResourceResponseWrapper(response);
  }

  public void afterRenderRequest(FacesContext facesContext,
      RenderResponse wrappedResponse) {
    finishResponse(facesContext,
        (BufferedMimeResponseWrapper) wrappedResponse);

  }

  public void afterResourceRequest(FacesContext facesContext,
      ResourceResponse wrappedResponse) {
    finishResponse(facesContext,
        (BufferedMimeResponseWrapper) wrappedResponse);
  }

  @Override
  public boolean serveResource(ResourceRequest request,
      ResourceResponse response) throws BridgeException {
    String resourceKey = request.getResourceID();
    if (null != resourceKey) {

      try {
        InternetResource resource = resourceBuilder
            .getResourceForKey(resourceKey);
        ResourceContext resourceContext = getResourceContext(resource,
            request, response);
        Object resourceData = resourceBuilder
            .getResourceDataForKey(resourceKey);
        resourceContext.setResourceData(resourceData);
        try {
          // TODO - cache ?
          request.setAttribute(RICHFACES_RESOURCE, resource);
          lifecycle.send(resourceContext, resource);
          request.removeAttribute(RICHFACES_RESOURCE);
        } catch (IOException e) {
          throw new BridgeException(e);
        } finally {
          resourceContext.release();
        }
        return true;

      } catch (ResourceNotFoundException e) {
        return false;
      }
    } else { // Handle File Upload
        if(isMultipartContent(request)) {
        String uid = request
                .getParameter(FileUploadConstants.UPLOAD_FILES_ID);
        MultipartRequest multipartRequest;
        // RichFaces 3.3.1 & 3.3.3 uses different signatures in
        // constructor, so use reflection to create instance.
        try {
          try {
            Constructor<MultipartRequest> constructor = MultipartRequest.class
                    .getConstructor(HttpServletRequest.class,
                            boolean.class, int.class, String.class);
            multipartRequest = constructor.newInstance(
                    new ResourceRequestWrapper(request),
                    uploadToTempDir, uploadLimit, uid);
          } catch (NoSuchMethodException e) {
            // 3.3.1, add temp dir parameter.
            Constructor<MultipartRequest> constructor = MultipartRequest.class
                    .getConstructor(HttpServletRequest.class,
                            boolean.class, String.class, int.class,
                            String.class);
            multipartRequest = constructor.newInstance(
                    new ResourceRequestWrapper(request),
                    uploadToTempDir, null, uploadLimit, uid);
          }
        } catch (Exception e) {
          throw new BridgeException(
                  "Cannot create MultipartRequest instance", e);
        }
        request.setAttribute(
                FileUploadConstants.FILE_UPLOAD_REQUEST_ATTRIBUTE_NAME,
                multipartRequest);
        return false;
        }
      }
    return false;
  }

  public static final String MULTIPART = "multipart/";

  public static final boolean isMultipartContent(ResourceRequest request) {
    String contentType = request.getContentType();
    if (contentType == null) {
      return false;
    }
    if (contentType.toLowerCase().startsWith(MULTIPART)) {
      return true;
    }
    return false;
  }

  /**
   * @param resource
   * @param request
   * @param response
   * @return
   * @throws ServletException
   * @throws FacesException
   */
  protected ResourceContext getResourceContext(InternetResource resource,
      ResourceRequest request, ResourceResponse response)
      throws FacesException {
    FacesContext facesContext = null;
    ResourceContext resourceContext;
    if (resource.requireFacesContext()) {
      facesContext = config.createFacesContext(request, response);
      resourceContext = new PortletFacesResourceContext(facesContext);
    } else {
      resourceContext = new PortletResourceContext(config
          .getPortletConfig().getPortletContext(), request, response);
    }
    resourceContext.setCacheEnabled(true);
    return resourceContext;
  }

  @Override
  public int getPortletSessionScopeForName(String name) {
    return PortletSession.PORTLET_SCOPE;
  }

  @Override
  public void beforeActionRequest(FacesContext facesContext) {
    // TODO Auto-generated method stub
  }

  @Override
  public void afterActionRequestExecute(FacesContext facesContext) {
    // TODO Auto-generated method stub
  }

  @Override
  public void afterActionRequest(FacesContext facesContext) {
    // TODO Auto-generated method stub

  }

  @Override
  public void beforeEventRequest(FacesContext facesContext) {
    // TODO Auto-generated method stub

  }

  @Override
  public void afterEventRequest(FacesContext facesContext) {
    // TODO Auto-generated method stub
  }

  @Override
  public void beforeResourceRequest(FacesContext facesContext) {
    AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
    StateId stateId = PortletBridgeContext.getCurrentInstance(facesContext)
        .getStateId();
    ajaxContext.getCommonAjaxParameters().put(
        RequestScopeManager.STATE_ID_PARAMETER, stateId.toString());

    if (ajaxContext.isAjaxRequest(facesContext)) {
      // Set XML response.
      Object response = facesContext.getExternalContext().getResponse();
      Object request = facesContext.getExternalContext().getRequest();
      // PBR-134 see forum post for IE8 fix
      if (!isMultipartContent((ResourceRequest) request)) {
        if (response instanceof MimeResponse) {
          MimeResponse mimeResponse = (MimeResponse) response;
          mimeResponse.setContentType(XML_CONTENT);
        }
      }

    }
  }

  @Override
  public void afterResourceRequestExecute(FacesContext facesContext) {
    // DO nothing.
  }

}
TOP

Related Classes of org.jboss.portletbridge.richfaces.RichFacesStrategy

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.