Package org.jboss.portletbridge

Source Code of org.jboss.portletbridge.AjaxPortletBridge

/******************************************************************************
* JBoss, a division of Red Hat                                               *
* Copyright 2006, Red Hat Middleware, LLC, and individual                    *
* contributors as indicated by the @authors tag. See the                     *
* copyright.txt in the distribution for a full listing of                    *
* individual contributors.                                                   *
*                                                                            *
* This is free software; you can redistribute it and/or modify it            *
* under the terms of the GNU Lesser General Public License as                *
* published by the Free Software Foundation; either version 2.1 of           *
* the License, or (at your option) any later version.                        *
*                                                                            *
* This software is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of             *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           *
* Lesser General Public License for more details.                            *
*                                                                            *
* You should have received a copy of the GNU Lesser General Public           *
* License along with this software; if not, write to the Free                *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA         *
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.                   *
******************************************************************************/
package org.jboss.portletbridge;

import org.ajax4jsf.context.AjaxContext;
import org.ajax4jsf.xml.serializer.*;
import org.jboss.portletbridge.application.PortletStateHolder;
import org.jboss.portletbridge.application.PortletStateHolder.WindowIDRetriver;
import org.jboss.portletbridge.application.PortletWindowState;
import org.jboss.portletbridge.context.AbstractExternalContext;
import org.jboss.portletbridge.context.InitFacesContext;
import org.jboss.portletbridge.context.PortalActionURL;
import org.jboss.portletbridge.context.PortletBridgeContext;
import org.jboss.portletbridge.richfaces.RichFacesHelper;
import org.jboss.portletbridge.util.BridgeLogger;
import org.jboss.portletbridge.util.FacesConfig;
import org.jboss.portletbridge.util.PortletXML;
import org.jboss.portletbridge.util.WebXML;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;

import javax.el.ELContext;
import javax.el.ELContextEvent;
import javax.el.ELContextListener;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.webapp.FacesServlet;
import javax.portlet.*;
import javax.portlet.faces.Bridge;
import javax.portlet.faces.BridgeException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.security.Principal;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* @author asmirnov
*/
public class AjaxPortletBridge implements Bridge, ELContextListener,
    BridgeConfig {

  public static final String VIEWID_HISTORY_PREFIX = Bridge.VIEWID_HISTORY
      + ".";
  private static final Logger log = BridgeLogger.BRIDGE.getLogger();
  private static final String EXCEPTION_HANDLER_CLASS_PARAMETER = ExceptionHandler.class
      .getName();
  public static final String AJAX_NAMESPACE_PARAMETER = "org.ajax4jsf.portlet.NAMESPACE";
  public static final String VIEW_ID_PARAMETERS = "org.jboss.portletbridge.VIEW_ID_PARAMETERS";
  private boolean initialized = false;
  private PortletConfig portletConfig;
  private ExceptionHandler exceptionHandler;
  private Lifecycle lifecycle;
  private FacesContextFactory facesContextFactory;
  private List<String> facesServletMappings;
  private Set<ExcludedRequestAttribute> excludedAttributes;
  private boolean preserveActionParams;
  private Map<String, String> defaultViewIdMap;
  private PortletStateHolder stateHolder;
  private Map<Class<? extends Throwable>, String> errorPages;

  public RichFacesHelper richFacesHelper;
  public boolean RICHFACES_ENABLED;
  private Application application;
  private Set<String> userRoles;

  static {
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.portlet.faces.Bridge#destroy()
   */
  public void destroy() {
    if (log.isLoggable(Level.FINE)) {
      log.fine("Destroy portletbridge "
          + getPortletConfig().getPortletName());
    }
    this.lifecycle = null;
    this.facesContextFactory = null;
    this.stateHolder = null;
    this.initialized = false;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.portlet.faces.Bridge#init(javax.portlet.PortletConfig)
   */
  @SuppressWarnings("unchecked")
  public void init(PortletConfig config) throws BridgeException {
    if (null == config) {
      throw new NullPointerException(
          "No PortletConfig at the bridge initialization");
    }
    if (initialized) {
      throw new BridgeException("JSF portlet bridge already initialized");
    }
    String portletName = config.getPortletName();
    if (log.isLoggable(Level.FINE)) {
      log.fine("Start portletbridge initialization for " + portletName);
    }
    this.portletConfig = config;
    PortletContext portletContext = config.getPortletContext();
    // add locales to faces application
    stateHolder = PortletStateHolder.init(portletContext);
    initFaces(portletContext);
    transferLocales(config);
    exceptionHandler = createExceptionHandler(portletContext);
    // Parse web.xml for a Faces Servlet mappings.
    WebXML webXml = new WebXML();
    webXml.parse(portletContext);
    this.facesServletMappings = webXml.getFacesServletMappings();
    if (null == facesServletMappings || facesServletMappings.size() == 0) {
      throw new BridgeException("Unable to get Faces Servlet mapping");
    }
    errorPages = webXml.getErrorViews();
    // Get defined role names from portlet.xml
    PortletXML portletXML = new PortletXML();
    portletXML.parse(portletContext);
    userRoles = portletXML.getUserRoles(portletName);
    // Get all excluded request attributes names.
    this.excludedAttributes = new HashSet<ExcludedRequestAttribute>();
    String bridgeParametersPrefix = Bridge.BRIDGE_PACKAGE_PREFIX
        + portletName + ".";
    List<String> excluded = (List<String>) portletContext
        .getAttribute(bridgeParametersPrefix
            + Bridge.EXCLUDED_REQUEST_ATTRIBUTES);
    if (null != excluded) {
      for (String name : excluded) {
        excludedAttributes.add(new ExcludedRequestAttribute(name));
      }
    }
    FacesConfig facesConfig = new FacesConfig();
    facesConfig.parse(portletContext);
    excluded = facesConfig.getExcludedAttributes();
    if (null != excluded) {
      for (String name : excluded) {
        excludedAttributes.add(new ExcludedRequestAttribute(name));
      }
    }
    // Get preserve action parameters flag
    Boolean preserveParams = (Boolean) portletContext
        .getAttribute(bridgeParametersPrefix
            + Bridge.PRESERVE_ACTION_PARAMS);
    this.preserveActionParams = Boolean.TRUE.equals(preserveParams);
    // Get devault view's Map.
    this.defaultViewIdMap = (Map<String, String>) portletContext
        .getAttribute(bridgeParametersPrefix
            + Bridge.DEFAULT_VIEWID_MAP);
    if (null == this.defaultViewIdMap || 0 == this.defaultViewIdMap.size()) {
      throw new BridgeException("No JSF view id's defined in portlet");
    }
    // Initialization done.
    initialized = true;
    if (log.isLoggable(Level.FINE)) {
      log.fine("Done portletbridge initialization for " + portletName);
    }
  }

  protected void initFaces(PortletContext portletContext) {
    try {
      // get faces lifecycle instance. Name of the Lifecycle can be
      // changed by the init parameter, as described in the JSR 301
      // PLT
      // 3.2
      LifecycleFactory factory = (LifecycleFactory) FactoryFinder
          .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
      String lifecycleId = portletContext
          .getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
      if (null == lifecycleId) {
        lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
      }
      if (log.isLoggable(Level.FINE)) {
        log.fine("Create instance of a JSF lifecycle " + lifecycleId);
      }
      this.lifecycle = factory.getLifecycle(lifecycleId);
      // get faces context factory instance
      this.facesContextFactory = (FacesContextFactory) FactoryFinder
          .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
      this.lifecycle.getPhaseListeners();
      // add this (as ELContextListener) to listener to populate new
      // context
      ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder
          .getFactory(FactoryFinder.APPLICATION_FACTORY);
      application = appFactory.getApplication();

      application.addELContextListener(this);
      try {
        richFacesHelper = new RichFacesHelper();
        RICHFACES_ENABLED = true;
      } catch (NoClassDefFoundError e) {
        // Do nothing, no Richfaces classes available.
        richFacesHelper = null;
        RICHFACES_ENABLED = false;
      }
      if (RICHFACES_ENABLED) {
        String renderKitId;
        if (null == (renderKitId = application.getDefaultRenderKitId())) {
          renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
        }
        RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
            .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
        FacesContext context = new InitFacesContext(application,
            portletContext);
        RenderKit renderKit = renderKitFactory.getRenderKit(context,
            renderKitId);
        renderKit
            .addRenderer(
                UIViewRoot.COMPONENT_FAMILY,
                UIViewRoot.COMPONENT_TYPE,
                richFacesHelper.getViewRootRenderer());
        context.release();
      }
    } catch (FacesException e) {
      throw new BridgeException("JSF Initialization error", e);
    }
  }

  private Application getApplication() {
    return application;
  }

  protected void transferLocales(PortletConfig config) {
    // Try to set locales from portlet.xml into faces application
    try {
      Class c = Class
          .forName("org.jboss.portal.portlet.impl.jsr168.api.PortletConfigImpl");
      java.lang.reflect.Method method = c
          .getMethod("getSupportedLocales");
      Object retobj = method.invoke(config, null);
      Enumeration portletLocales = (Enumeration) retobj;
      Collection facesLocales = new ArrayList();

      while (portletLocales.hasMoreElements()) {
        facesLocales.add(portletLocales.nextElement());
      }
      getApplication().setSupportedLocales(facesLocales);

    } catch (ClassNotFoundException e) {
      if (log.isLoggable(Level.FINE)) {
        log
            .fine("Unable to set portlet locales into faces application");
      }
    } catch (IllegalAccessException e) {
      if (log.isLoggable(Level.SEVERE)) {
        log.severe("Error while setting locales in faces application");
      }
    } catch (NoSuchMethodException e) {

    } catch (InvocationTargetException e) {

    }

  }

  protected ExceptionHandler createExceptionHandler(
      PortletContext portletContext) {
    String exceptionHandlerClassName = portletContext
        .getInitParameter(EXCEPTION_HANDLER_CLASS_PARAMETER);
    ExceptionHandler handler = null;
    if (null != exceptionHandlerClassName) {
      ClassLoader classLoader = Thread.currentThread()
          .getContextClassLoader();
      if (null == classLoader) {
        classLoader = this.getClass().getClassLoader();
      }
      try {
        Class<? extends ExceptionHandler> exceptionHandlerClass = classLoader
            .loadClass(exceptionHandlerClassName).asSubclass(
                ExceptionHandler.class);
        handler = exceptionHandlerClass.newInstance();
      } catch (ClassNotFoundException e) {
        handler = new ExceptionHandlerImpl();
      } catch (InstantiationException e) {
        handler = new ExceptionHandlerImpl();
      } catch (IllegalAccessException e) {
        handler = new ExceptionHandlerImpl();
      }
    } else {
      handler = new ExceptionHandlerImpl();
    }
    return handler;
  }

  public void doFacesRequest(ActionRequest request, ActionResponse response)
      throws BridgeException {
    if (null == request) {
      throw new NullPointerException("Request parameter is null");
    }
    if (null == response) {
      throw new NullPointerException("Response parameter is null");
    }
    if (!isInitialized()) {
      throw new BridgeException("JSF Portlet bridge is not initialized");
    }
    if (log.isLoggable(Level.FINE)) {
      log.fine("Start bridge action request processing for portlet "
          + getPortletName());
    }
    initRequest(request, response, Bridge.PortletPhase.ActionPhase);
    StateId stateId = getStateHolder()
        .getStateId(getPortletName(), request);
    PortletWindowState windowState = new PortletWindowState() {

      @Override
      public BridgeConfig getBridgeConfig() {
        return AjaxPortletBridge.this;
      }

    };
    PortletBridgeContext bridgeContext = createBridgeContext(request,
        windowState);
    bridgeContext.setStateId(stateId);
    FacesContext facesContext = getFacesContext(request, response);
    try {
      execute(facesContext);
      // save request scope variables and Faces Messages.
      if (!facesContext.getResponseComplete()) {
        // Setup portlet modes from parameters.
        Map<String, String[]> viewIdParameters = (Map<String, String[]>) facesContext
            .getExternalContext().getRequestMap().get(
                VIEW_ID_PARAMETERS);
        if (null != viewIdParameters && viewIdParameters.size() > 0) {
          processPortletParameters(response, stateId, facesContext,
              facesContext.getViewRoot().getViewId(),
              viewIdParameters);
        }
        // Save view state for a render phases.
        facesContext.getApplication().getStateManager().saveView(
            facesContext);
        windowState.saveRequest(facesContext);
      } else {
        windowState.reset();
        windowState.saveSeamConversationId(facesContext);
        String redirectViewId = bridgeContext.getRedirectViewId();
        if (null != redirectViewId) {
          windowState.setViewId(redirectViewId);
          // Save redirect request parameters.
          Map<String, String[]> newRequestParameters = bridgeContext
              .getRedirectRequestParameters();
          windowState.setRequestParameters(newRequestParameters);
          processPortletParameters(response, stateId, facesContext,
              redirectViewId, newRequestParameters);
        }
      }
      // TODO - detect portlet mode changes ( by the viewId parameter. )
      // viewId history should be updated at the render response only.
      // facesContext.getExternalContext().getSessionMap().put(
      // VIEWID_HISTORY_PREFIX+request.getPortletMode().toString(),
      // windowState.getViewId());
      // getStateHolder().addWindowState(stateId, windowState);
      // response.setRenderParameter(PortletStateHolder.STATE_ID_PARAMETER,
      // stateId);
    } catch (Exception e) {
      // handle exception.
      exceptionHandler.processActionException(facesContext, windowState,
          e);
    } finally {
      getStateHolder().addWindowState(stateId, windowState);
      response.setRenderParameter(PortletStateHolder.STATE_ID_PARAMETER,
          stateId.toString());
      facesContext.release();
    }
  }

  public void processPortletParameters(ActionResponse response,
      StateId stateId, FacesContext facesContext, String redirectViewId,
      Map<String, String[]> newRequestParameters)
      throws MalformedURLException, PortletModeException {
    for (Entry<String, String[]> entry : newRequestParameters.entrySet()) {
      String key = entry.getKey();
      if (Bridge.PORTLET_MODE_PARAMETER.equals(key)) {
        String portletModeName = entry.getValue()[0];
        PortletMode mode = new PortletMode(portletModeName);
        PortalActionURL historyViewId = new PortalActionURL(
            redirectViewId);
        stateId.setMode(mode);
        historyViewId.setParameter(
            PortletStateHolder.STATE_ID_PARAMETER, stateId
                .toString());
        historyViewId.setParameter(Bridge.PORTLET_MODE_PARAMETER,
            portletModeName);
        facesContext.getExternalContext().getSessionMap().put(
            VIEWID_HISTORY_PREFIX + portletModeName,
            historyViewId.toString());
        response.setPortletMode(mode);
      } else if (Bridge.PORTLET_WINDOWSTATE_PARAMETER.equals(key)) {
        try {
          WindowState state = new WindowState(entry.getValue()[0]);
          response.setWindowState(state);
        } catch (WindowStateException e) {
          // only valid modes supported.
        }

      }
    }
  }

  private PortletBridgeContext createBridgeContext(PortletRequest request,
      PortletWindowState windowState) {
    PortletBridgeContext bridgeContext = windowState.createBridgeContext();
    request.setAttribute(PortletBridgeContext.REQUEST_PARAMETER_NAME,
        bridgeContext);
    bridgeContext.setInitialRequestAttributeNames(request
        .getAttributeNames());
    return bridgeContext;
  }

  public void doFacesRequest(RenderRequest request, RenderResponse response)
      throws BridgeException {
    if (null == request) {
      throw new NullPointerException("Request parameter is null");
    }
    if (null == response) {
      throw new NullPointerException("Response parameter is null");
    }
    if (!isInitialized()) {
      throw new BridgeException("JSF Portlet bridge is not initialized");
    }

    if (log.isLoggable(Level.FINE)) {
      log.fine("Start bridge render request processing for portlet "
          + getPortletName());
    }
    BufferedRenderResponseWrapper wrappedResponse = new BufferedRenderResponseWrapper(
        response);

    initRequest(request, wrappedResponse, Bridge.PortletPhase.RenderPhase);
    String namespace = wrappedResponse.getNamespace();
    StateId stateId = getStateHolder().getStateId(getPortletName(),
        request, namespace);

    PortletWindowState windowState = getStateHolder().getWindowState(
        stateId);
    if (null == windowState) {
      windowState = new PortletWindowState() {

        @Override
        public BridgeConfig getBridgeConfig() {
          return AjaxPortletBridge.this;
        }

      };
      getStateHolder().addWindowState(stateId, windowState);
    }
    PortletBridgeContext bridgeContext = createBridgeContext(request,
        windowState);
    bridgeContext.setStateId(stateId);

    FacesContext facesContext = getFacesContext(request, wrappedResponse);


    try {
      windowState.restoreRequest(facesContext, true);
      // If we're using RichFaces, setup proper parameters for this render
      // request
      if (RICHFACES_ENABLED) {
        setupAjaxParams(facesContext, stateId.toString(), namespace);
      }
      // set portletbridge title if its set.
      ResourceBundle bundle = portletConfig.getResourceBundle(request
          .getLocale());
      if (bundle != null) {
        String title = null;
        try {
          title = bundle.getString("javax.portlet.title");
          wrappedResponse.setTitle(title);
        } catch (Exception e) {
          // Ignore MissingResourceException
        }
      }

      try {

        renderResponse(facesContext, windowState);
        // TODO - detect redirect case. Reset response, clear request
        // variables as far as Seam state.
        // Perform new render phase with a new ViewId.
        String redirectViewId = bridgeContext.getRedirectViewId();
        if (null != redirectViewId) {
          windowState.reset();
          windowState.setViewId(redirectViewId);

          Map<String, String[]> redirectParams = bridgeContext
              .getRedirectRequestParameters();

          // release old FacesContext.
          facesContext.release();
          // Reset attributes to initial state
          Set<String> initialAttributes = bridgeContext
              .getInitialRequestAttributeNames();
          List<String> currentAttributes = Collections.list(request
              .getAttributeNames());
          currentAttributes.removeAll(initialAttributes);
          for (Object newAttribute : currentAttributes) {
            request.removeAttribute((String) newAttribute);
          }
          if (redirectParams != null) {
            windowState.setRequestParameters(redirectParams);
          }

          // Create new FacesContext
          facesContext = getFacesContext(request, wrappedResponse);
          ViewHandler viewHandler = facesContext.getApplication()
              .getViewHandler();
          UIViewRoot viewRoot = viewHandler.createView(facesContext,
              redirectViewId);
          facesContext.setViewRoot(viewRoot);
          renderResponse(facesContext, windowState);
        }
        windowState.setViewId(facesContext.getViewRoot().getViewId());
      } catch (Exception e) {
        wrappedResponse.reset();
        log.log(Level.SEVERE, "Error processing execute lifecycle", e);
        exceptionHandler.processRenderException(facesContext,
            windowState, e);
      }
      // Set important Portal parameters to window state.
      String viewId = facesContext.getViewRoot().getViewId();
      //
      String actionURL = facesContext.getApplication().getViewHandler()
          .getActionURL(facesContext, viewId);
      actionURL = facesContext.getExternalContext().encodeActionURL(
          actionURL);
      windowState.setPortalActionURL(new PortalActionURL(actionURL));

      PortletURL portletURL = wrappedResponse.createRenderURL();
      portletURL.setParameter(PortletStateHolder.STATE_ID_PARAMETER,
          stateId.toString());
      String renderUrl = portletURL.toString();
      windowState.setPortalRenderURL(new PortalActionURL(renderUrl));
      windowState.setNamespace(namespace);
      windowState.setPortletLocale(request.getLocale());
      // TODO - encode request attributes, portlet mode and windowId, as
      // required by JSR-301 5.3.3
      String portletModeName = request.getPortletMode().toString();
      PortalActionURL historyViewId = new PortalActionURL(viewId);
      historyViewId.setParameter(PortletStateHolder.STATE_ID_PARAMETER,
          stateId.toString());
      historyViewId.setParameter(Bridge.PORTLET_MODE_PARAMETER,
          portletModeName);
      facesContext.getExternalContext().getSessionMap().put(
          VIEWID_HISTORY_PREFIX + portletModeName,
          historyViewId.toString());
      // writer.println("</div>");
      windowState.saveSeamConversationId(facesContext);
      // PortletSession portletSession = request.getPortletSession(true);
      PortletSession portletSession = (PortletSession) facesContext
          .getExternalContext().getSession(true);
      WindowIDRetriver idRetriver = (WindowIDRetriver) portletSession
          .getAttribute(PortletStateHolder.WINDOW_ID_RETRIVER);

      if (null != idRetriver) {
        windowState.setWindowId(idRetriver.getWindowID());
      }
      PortletBridgePrincipal security = new PortletBridgePrincipal(request,userRoles);
      // TODO - get user roles, defined in the portletbridge.xml ( ???
      // parse it ??? ), and store all values for a
      // "isUserInRole(roleName)" calls
      portletSession.setAttribute(
          AbstractExternalContext.PORTAL_USER_PRINCIPAL,
          security, PortletSession.APPLICATION_SCOPE);
      if (log.isLoggable(Level.FINE)) {
        log.fine("Finish rendering portletbridge for namespace "
            + namespace);
      }
      // Disable portletbridge caching.
      // TODO - detect ajax components on page, static views can be
      // cached.
      wrappedResponse.setProperty(RenderResponse.EXPIRATION_CACHE, "0");

      if (RICHFACES_ENABLED) {
        richFacesHelper
            .getCurrentInstance();
        Object headEvents = request.getAttribute(AjaxContext.HEAD_EVENTS_PARAMETER);

        if (headEvents != null) {
          Node[] nodes = (Node[]) headEvents;

          Properties xhtmlProperties = OutputPropertiesFactory
              .getDefaultMethodProperties(Method.XHTML);
          Serializer serializer = SerializerFactory
              .getSerializer(xhtmlProperties);

          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();
        }
      }

      wrappedResponse.writeBufferedData();
    } catch (Exception e) {
      throw new BridgeException(e);
    } finally {
      facesContext.release();
    }
  }

  private void setupAjaxParams(FacesContext facesContext, String stateId,
      String namespace) {
    Map<String, Object> commonAjaxParameters = richFacesHelper
        .getCurrentInstance(facesContext).getCommonAjaxParameters();
    commonAjaxParameters
        .put(PortletStateHolder.STATE_ID_PARAMETER, stateId);
    commonAjaxParameters.put(AjaxPortletBridge.AJAX_NAMESPACE_PARAMETER,
        namespace);
  }

  /**
   * @param facesContext
   * @param windowState
   * @throws FacesException
   */
  private void renderResponse(FacesContext facesContext,
      PortletWindowState windowState) throws FacesException {
    if (null == facesContext.getViewRoot()) {
      execute(facesContext);
      // TODO - detect redirect case.
    }
    //
    if (!facesContext.getResponseComplete()) {
      render(facesContext);
    }
  }

  /**
   * @param request
   * @param response
   * @param actionPhase
   * @return initialized bridge context instance.
   * @throws BridgeException
   */
  protected void initRequest(PortletRequest request,
      PortletResponse response, PortletPhase actionPhase)
      throws BridgeException {
    request.setAttribute(Bridge.PORTLET_LIFECYCLE_PHASE, actionPhase);
    // Check viewId history sessions attributes
    Map<String, String> viewIdMap = getDefaultViewIdMap();
    String firstMode = viewIdMap.keySet().iterator().next();
    PortletSession portletSession = request.getPortletSession();
    if (null == portletSession.getAttribute(VIEWID_HISTORY_PREFIX
        + firstMode)) {
      // Fill viewId's history attributes by default values.
      for (Entry<String, String> entry : viewIdMap.entrySet()) {
        portletSession.setAttribute(VIEWID_HISTORY_PREFIX
            + entry.getKey(), encodeModeParam(entry.getKey(),entry.getValue()));
      }
    }
  }

  /**
   * Encode mode parameter into viewId.
   * @param mode
   * @param viewId
   * @return
   */
  private String encodeModeParam(String mode, String viewId) {
    try {
      PortalActionURL viewIdUrl = new PortalActionURL(viewId);
      viewIdUrl.addParameter(Bridge.PORTLET_MODE_PARAMETER, mode);
      return viewIdUrl.toString();
    } catch (MalformedURLException e) {
      throw new BridgeException("Malformed ViewId",e);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#getPortletConfig()
   */
  public PortletConfig getPortletConfig() {
    return portletConfig;
  }

  protected Object getContext() {
    // TODO Auto-generated method stub
    return portletConfig.getPortletContext();
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.jboss.portletbridge.BridgeConfig#getInitParameter(java.lang.String)
   */
  public String getInitParameter(String name) {
    String initParameter = portletConfig.getInitParameter(name);
    if (null == initParameter) {
      initParameter = portletConfig.getPortletContext().getInitParameter(
          name);
    }
    return initParameter;
  }

  /**
   * @return the initialized
   */
  protected boolean isInitialized() {
    return initialized;
  }

  /**
   * @return the exceptionHandler
   */
  protected ExceptionHandler getExceptionHandler() {
    return exceptionHandler;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#getFacesServletMappings()
   */
  public List<String> getFacesServletMappings() {
    return facesServletMappings;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#getExcludedAttributes()
   */
  public Set<ExcludedRequestAttribute> getExcludedAttributes() {
    return excludedAttributes;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#getPortletName()
   */
  public String getPortletName() {
    return portletConfig.getPortletName();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#isPreserveActionParams()
   */
  public boolean isPreserveActionParams() {
    return preserveActionParams;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jboss.portletbridge.BridgeConfig#getDefaultViewIdMap()
   */
  public Map<String, String> getDefaultViewIdMap() {
    return defaultViewIdMap;
  }

  /**
   * @return the stateHolder
   */
  protected PortletStateHolder getStateHolder() {
    return stateHolder;
  }

  public void contextCreated(ELContextEvent event) {
    // Add the portletConfig to the ELContext
    ELContext elContext = event.getELContext();
    if (elContext.getContext(PortletConfig.class) == null) {
      elContext.putContext(PortletConfig.class, portletConfig);
    }
  }

  /**
   * Get currenf JSF lifecycle instance.
   *
   * @return
   */
  public Lifecycle getFacesLifecycle() {
    return this.lifecycle;
  }

  /**
   * Create new faces context instance.
   *
   * @param request
   * @param response
   * @return new instance of faces context.
   */
  protected FacesContext getFacesContext(Object request, Object response) {
    FacesContext facesContext = this.facesContextFactory.getFacesContext(
        getContext(), request, response, getFacesLifecycle());
    return facesContext;
  }

  protected void execute(FacesContext context) throws FacesException {
    getFacesLifecycle().execute(context);
  }

  protected void render(FacesContext context) throws FacesException {
    getFacesLifecycle().render(context);
  }

  /**
   * @return the errorPages
   */
  public Map<Class<? extends Throwable>, String> getErrorPages() {
    return errorPages;
  }
}
TOP

Related Classes of org.jboss.portletbridge.AjaxPortletBridge

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.