public RequestParameterMapFactory(BridgeContext bridgeContext) {

    PortletRequest portletRequest = bridgeContext.getPortletRequest();

    if (portletRequest instanceof ClientDataRequest) {
      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;
      String contentType = clientDataRequest.getContentType();

      // Note that ICEfaces ace:fileEntry cannot rely on RequestParameterValuesMapImpl because it
      // relies on its
      // own mechanism for handling file upload.
      Product iceFaces = ProductMap.getInstance().get(ProductConstants.ICEFACES);

      if ((contentType != null)
          && contentType.toLowerCase().startsWith(BridgeConstants.MULTIPART_CONTENT_TYPE_PREFIX)
          && !iceFaces.isDetected()) {
        RequestParameterMapMultiPartImpl requestParameterMapMultiPartImpl =
            new RequestParameterMapMultiPartImpl(bridgeContext, clientDataRequest);
        requestParameterMap = requestParameterMapMultiPartImpl;
        requestParameterValuesMap =
            new RequestParameterValuesMapMultiPartImpl(requestParameterMapMultiPartImpl);
      } else {
        requestParameterMap = new RequestParameterMapImpl(bridgeContext);
        requestParameterValuesMap = new RequestParameterValuesMapImpl(bridgeContext);
      }
    } else {
      requestParameterMap = new RequestParameterMapImpl(bridgeContext);
      requestParameterValuesMap = new RequestParameterValuesMapImpl(bridgeContext);
    }
  }
  protected boolean isICEfacesLegacyMode(ClientDataRequest clientDataRequest) {

    if (iceFacesLegacyMode == null) {

      iceFacesLegacyMode = Boolean.FALSE;

      String requestContentType = clientDataRequest.getContentType();

      if ((requestContentType != null)
          && requestContentType
              .toLowerCase()
              .startsWith(BridgeConstants.MULTIPART_CONTENT_TYPE_PREFIX)) {

        Product iceFaces = ProductMap.getInstance().get(ProductConstants.ICEFACES);

        if (iceFaces.isDetected()
            && ((iceFaces.getMajorVersion() == 2)
                || ((iceFaces.getMajorVersion() == 3) && (iceFaces.getMinorVersion() == 0)))) {

          iceFacesLegacyMode = Boolean.TRUE;
        }
      }
    }

    return iceFacesLegacyMode;
  }
/** @author Neil Griffin */
public class BeanManagerFactoryImpl extends BeanManagerFactory {

  // Private Constants
  private static final boolean MOJARRA_DETECTED =
      ProductMap.getInstance()
          .get(ProductConstants.JSF)
          .getTitle()
          .equals(ProductConstants.MOJARRA);

  // Private Data Members
  List<ConfiguredManagedBean> configuredManagedBeans;

  public BeanManagerFactoryImpl() {
    ApplicationConfig applicationConfig = ApplicationConfigUtil.getApplicationConfig();
    FacesConfig facesConfig = applicationConfig.getFacesConfig();
    this.configuredManagedBeans = facesConfig.getConfiguredManagedBeans();
  }

  @Override
  public BeanManager getBeanManager() {

    BeanManager beanManager = null;

    if (MOJARRA_DETECTED) {
      beanManager = new BeanManagerMojarraImpl(configuredManagedBeans);
    } else {
      beanManager = new BeanManagerImpl(configuredManagedBeans);
    }

    return beanManager;
  }

  public BeanManagerFactory getWrapped() {

    // Since this is the factory instance provided by the bridge, it will never wrap another
    // factory.
    return null;
  }
}
/** @author Neil Griffin */
public class ExternalContextImpl extends ExternalContextCompat_2_2_Impl {

  // Logger
  private static final Logger logger = LoggerFactory.getLogger(ExternalContextImpl.class);

  // Private Constants
  private static final boolean LIFERAY_PORTAL_DETECTED =
      ProductMap.getInstance().get(ProductConstants.LIFERAY_PORTAL).isDetected();
  private static final boolean RICHFACES_DETECTED =
      ProductMap.getInstance().get(ProductConstants.RICHFACES).isDetected();
  private static final String ORG_RICHFACES_EXTENSION = "org.richfaces.extension";

  // Pre-initialized Data Members
  private ApplicationMap applicationMap;
  private BeanManager beanManager;
  private Map<String, Object> requestAttributeMap;
  private Iterator<Locale> requestLocales;
  private Map<String, Object> sessionMap;

  // Lazily-Initialized Data Members
  private String authType;
  private BridgeAfterViewContentRequest bridgeAfterViewContentRequest;
  private BridgeAfterViewContentResponse bridgeAfterViewContentResponse;
  private Map<String, String> initParameterMap;
  private String remoteUser;
  private Map<String, Object> requestCookieMap;
  private Locale requestLocale;
  private Principal userPrincipal;

  public ExternalContextImpl(
      PortletContext portletContext,
      PortletRequest portletRequest,
      PortletResponse portletResponse) {

    super(portletContext, portletRequest, portletResponse);

    BeanManagerFactory beanManagerFactory =
        (BeanManagerFactory) FactoryExtensionFinder.getFactory(BeanManagerFactory.class);
    this.beanManager = beanManagerFactory.getBeanManager();

    try {
      boolean requestChanged = false;
      boolean responseChanged = false;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }

  @Override
  public void dispatch(String path) throws IOException {

    // Indicate that JSP AFTER_VIEW_CONTENT processing has been de-activated. This will make it
    // possible for the
    // Mojarra JspViewHandlingStrategy#executePageToBuildView(FacesContext, UIViewRoot) method to
    // successfully call
    // {@link ExternalContextImpl#setResponse(Object)} in order to undo the
    // ViewHandlerResponseWrapper and restore
    // the original PortletResponse.
    bridgeContext.setProcessingAfterViewContent(false);

    logger.debug("De-activated JSP AFTER_VIEW_CONTENT");

    bridgeContext.dispatch(path);
  }

  /** @see ExternalContext#encodeNamespace(String) */
  @Override
  public String encodeNamespace(String name) {

    if (name == null) {
      return bridgeContext.getResponseNamespace();
    } else if (RICHFACES_DETECTED && (name.equals(ORG_RICHFACES_EXTENSION))) {

      // http://issues.liferay.com/browse/FACES-1416
      return name;
    } else {
      return bridgeContext.getResponseNamespace() + name;
    }
  }

  /** @see ExternalContext#encodeResourceURL(String) */
  @Override
  public String encodeResourceURL(String url) {
    return bridgeContext.encodeResourceURL(url).toString();
  }

  @Override
  public void log(String message) {
    portletContext.log(message);
  }

  @Override
  public void log(String message, Throwable exception) {
    portletContext.log(message, exception);
  }

  @Override
  public void redirect(String url) throws IOException {
    bridgeContext.redirect(url);
  }

  /**
   * In order to increase runtime performance, this method caches values of objects that are
   * typically called more than once during the JSF lifecycle. Other values will be cached lazily,
   * or might not be cached since their getter methods may never get called.
   *
   * @param requestChanged Flag indicating that this method is being called because {@link
   *     #setRequest(Object)} was called.
   * @param responseChanged Flag indicating that this method is being called because {@link
   *     #setResponse(Object)} was called.
   */
  protected void preInitializeObjects(boolean requestChanged, boolean responseChanged) {

    if (requestChanged) {
      bridgeContext.setPortletRequest(portletRequest);
    }

    if (responseChanged) {
      bridgeContext.setPortletResponse(portletResponse);
    }

    // Retrieve the portlet lifecycle phase.
    portletPhase = bridgeContext.getPortletRequestPhase();

    // Determines whether or not methods annotated with the &#064;PreDestroy annotation are
    // preferably invoked
    // over the &#064;BridgePreDestroy annotation.
    String preferPreDestroyInitParam =
        getInitParameter(BridgeConfigConstants.PARAM_PREFER_PRE_DESTROY1);

    if (preferPreDestroyInitParam == null) {

      // Backward compatibility
      preferPreDestroyInitParam = getInitParameter(BridgeConfigConstants.PARAM_PREFER_PRE_DESTROY2);
    }

    boolean preferPreDestroy = BooleanHelper.toBoolean(preferPreDestroyInitParam, true);

    // Initialize the application map.
    applicationMap = new ApplicationMap(portletContext, beanManager, preferPreDestroy);

    // Determines whether or not JSF @ManagedBean classes annotated with @RequestScoped should be
    // distinct for
    // each portlet when running under Liferay Portal.
    boolean distinctRequestScopedManagedBeans = false;

    if (LIFERAY_PORTAL_DETECTED) {
      distinctRequestScopedManagedBeans =
          BooleanHelper.toBoolean(
              getInitParameter(BridgeConfigConstants.PARAM_DISTINCT_REQUEST_SCOPED_MANAGED_BEANS),
              false);
    }

    // Initialize the request attribute map.
    Set<String> removedAttributeNames = null;
    BridgeRequestScope bridgeRequestScope = bridgeContext.getBridgeRequestScope();

    if (bridgeRequestScope != null) {
      removedAttributeNames = bridgeRequestScope.getRemovedAttributeNames();
    } else {
      removedAttributeNames = new HashSet<String>();
    }

    requestAttributeMap =
        new RequestAttributeMap(
            portletRequest,
            beanManager,
            bridgeContext.getPortletContainer().getResponseNamespace(),
            preferPreDestroy,
            distinctRequestScopedManagedBeans,
            removedAttributeNames);

    // Initialize the session map.
    sessionMap =
        new SessionMap(
            portletRequest.getPortletSession(),
            beanManager,
            PortletSession.PORTLET_SCOPE,
            preferPreDestroy);

    // Initialize the init parameter map.
    initParameterMap = Collections.unmodifiableMap(new InitParameterMap(portletContext));

    // Initialize the request context path.
    requestContextPath = portletRequest.getContextPath();

    // Initialize the request locales.
    requestLocales = new LocaleIterator(portletRequest.getLocales());
  }

  @Override
  public Map<String, Object> getApplicationMap() {
    return applicationMap;
  }

  @Override
  public String getAuthType() {

    if (authType == null) {
      authType = portletRequest.getAuthType();
    }

    return authType;
  }

  @Override
  public Object getContext() {
    return portletContext;
  }

  @Override
  public boolean isUserInRole(String role) {
    return portletRequest.isUserInRole(role);
  }

  @Override
  public String getInitParameter(String name) {
    return bridgeContext.getInitParameter(name);
  }

  @Override
  public Map<String, String> getInitParameterMap() {
    return initParameterMap;
  }

  @Override
  public String getRemoteUser() {

    if (remoteUser == null) {
      remoteUser = portletRequest.getRemoteUser();
    }

    return remoteUser;
  }

  @Override
  public Object getRequest() {

    // If JSP AFTER_VIEW_CONTENT processing has been activated by the
    // JspViewDeclarationLanguage#buildView(FacesContext, UIViewRoot) method, then return a
    // ServletRequest that
    // wraps/decorates the current PortletRequest. This is necessary because the MyFaces
    // JspViewDeclarationLanguage#buildView(FacesContext, UIViewRoot) method has a Servlet API
    // dependency due to
    // explicit casts to HttpServletRequest.
    if (bridgeContext.isProcessingAfterViewContent()) {

      if ((bridgeAfterViewContentRequest == null)
          || (bridgeAfterViewContentRequest.getWrapped() != portletRequest)) {

        BridgeWriteBehindSupportFactory bridgeWriteBehindSupportFactory =
            (BridgeWriteBehindSupportFactory)
                FactoryExtensionFinder.getFactory(BridgeWriteBehindSupportFactory.class);
        bridgeAfterViewContentRequest =
            bridgeWriteBehindSupportFactory.getBridgeAfterViewContentRequest(portletRequest);
      }

      return bridgeAfterViewContentRequest;
    } else {
      return portletRequest;
    }
  }

  @Override
  public void setRequest(Object request) {
    this.portletRequest = (PortletRequest) request;

    try {
      boolean requestChanged = true;
      boolean responseChanged = false;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }

  @Override
  public String getRequestCharacterEncoding() {

    if (portletRequest instanceof ClientDataRequest) {
      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;
      String requestCharacterEncoding = clientDataRequest.getCharacterEncoding();

      if (manageIncongruities) {

        try {
          incongruityContext.setRequestCharacterEncoding(requestCharacterEncoding);
        } catch (Exception e) {
          logger.error(e);
        }
      }

      return requestCharacterEncoding;
    } else {

      if (manageIncongruities) {
        return incongruityContext.getRequestCharacterEncoding();
      } else {

        // The Mojarra 2.x {@link MultiViewHandler#initView(FacesContext)} method expects a null
        // value to be
        // returned, so throwing an IllegalStateException is not an option.
        return null;
      }
    }
  }

  @Override
  public void setRequestCharacterEncoding(String encoding)
      throws UnsupportedEncodingException, IllegalStateException {

    // Although the JSF API's ViewHandler.initView(FacesContext) method will call this method during
    // the portlet
    // RENDER_PHASE, the RenderRequest does not implement the ClientDataRequest interface, which
    // means it does not
    // have a setCharacterEncoding(String) method, therefore this should only be done in the case of
    // a
    // ClientDataRequest.
    if (portletRequest instanceof ClientDataRequest) {
      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;

      try {
        clientDataRequest.setCharacterEncoding(encoding);
      } catch (IllegalStateException e) {
        // TestPage141: setRequestCharacterEncodingActionTest -- exception is to be ignored
      }
    } else {

      if (manageIncongruities) {
        incongruityContext.setRequestCharacterEncoding(encoding);
      } else {
        // TestPage140: setRequestCharacterEncodingRenderTest expects this to be a no-op so throwing
        // an
        // IllegalStateException is not an option.
      }
    }
  }

  @Override
  public String getRequestContentType() {

    if (portletRequest instanceof ClientDataRequest) {
      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;

      // If using ICEfaces 3.0.x/2.0.x then need to return the legacy value.
      // http://issues.liferay.com/browse/FACES-1228
      String requestContentType = null;

      if (isICEfacesLegacyMode(clientDataRequest)) {
        requestContentType = clientDataRequest.getResponseContentType();
      } else {
        requestContentType = clientDataRequest.getContentType();
      }

      if (manageIncongruities) {
        incongruityContext.setRequestContentType(requestContentType);
      }

      return requestContentType;
    } else {

      if (manageIncongruities) {
        return incongruityContext.getRequestContentType();
      } else {

        // TestPage166: getRequestContentTypeEventTest expects this condition to return null so
        // throwing an
        // IllegalStateException is not an option.
        return null;
      }
    }
  }

  @Override
  public String getRequestContextPath() {
    return requestContextPath;
  }

  @Override
  public Map<String, Object> getRequestCookieMap() {

    if (requestCookieMap == null) {
      requestCookieMap = new RequestCookieMap(portletRequest.getCookies());
    }

    return requestCookieMap;
  }

  @Override
  public Map<String, String> getRequestHeaderMap() {
    return bridgeContext.getRequestHeaderMap();
  }

  @Override
  public Map<String, String[]> getRequestHeaderValuesMap() {
    return bridgeContext.getRequestHeaderValuesMap();
  }

  @Override
  public Locale getRequestLocale() {

    if (requestLocale == null) {
      requestLocale = portletRequest.getLocale();
    }

    return requestLocale;
  }

  @Override
  public Iterator<Locale> getRequestLocales() {
    return requestLocales;
  }

  @Override
  public Map<String, Object> getRequestMap() {
    return requestAttributeMap;
  }

  @Override
  public Map<String, String> getRequestParameterMap() {
    return bridgeContext.getRequestParameterMap();
  }

  @Override
  public Iterator<String> getRequestParameterNames() {
    return getRequestParameterMap().keySet().iterator();
  }

  @Override
  public Map<String, String[]> getRequestParameterValuesMap() {
    return bridgeContext.getRequestParameterValuesMap();
  }

  /**
   * This method returns the relative path to the viewId that is to be rendered.
   *
   * @see javax.faces.context.ExternalContext#getRequestPathInfo()
   */
  @Override
  public String getRequestPathInfo() {
    return bridgeContext.getRequestPathInfo();
  }

  /** Section 6.1.3.1 of the JSR 329 spec describes the logic for this method. */
  @Override
  public String getRequestServletPath() {
    return bridgeContext.getRequestServletPath();
  }

  @Override
  public URL getResource(String path) throws MalformedURLException {
    return portletContext.getResource(path);
  }

  @Override
  public InputStream getResourceAsStream(String path) {
    return portletContext.getResourceAsStream(path);
  }

  @Override
  public Set<String> getResourcePaths(String path) {
    return portletContext.getResourcePaths(path);
  }

  @Override
  public Object getResponse() {

    // If JSP AFTER_VIEW_CONTENT processing has been activated by the
    // JspViewDeclarationLanguage#buildView(FacesContext, UIViewRoot) method, then return a
    // ServletResponse that is
    // able to handle the AFTER_VIEW_CONTENT feature. This is necessary because the Mojarra
    // JspViewHandlingStrategy#getWrapper(ExternalContext) method has a Servlet API dependency due
    // to explicit casts
    // to HttpServletResponse. Additionally, the MyFaces
    // JspViewDeclarationLanguage#buildView(FacesContext,
    // UIViewRoot) method has an explicit cast to HttpServletResponse.
    if (bridgeContext.isProcessingAfterViewContent()) {

      if (facesImplementationServletResponse == null) {

        if ((bridgeAfterViewContentResponse == null)
            || (bridgeAfterViewContentResponse.getWrapped() != portletResponse)) {
          BridgeWriteBehindSupportFactory bridgeWriteBehindSupportFactory =
              (BridgeWriteBehindSupportFactory)
                  FactoryExtensionFinder.getFactory(BridgeWriteBehindSupportFactory.class);
          bridgeAfterViewContentResponse =
              bridgeWriteBehindSupportFactory.getBridgeAfterViewContentResponse(
                  portletResponse, getRequestLocale());
        }

        return bridgeAfterViewContentResponse;
      } else {
        return facesImplementationServletResponse;
      }
    } else {

      if (isBridgeFlashServletResponseRequired()) {
        return createFlashHttpServletResponse();
      } else {
        return portletResponse;
      }
    }
  }

  @Override
  public void setResponse(Object response) {

    // Assume that the JSP_AFTER_VIEW_CONTENT feature is deactivated.
    facesImplementationServletResponse = null;

    // If JSP AFTER_VIEW_CONTENT processing has been activated by the bridge's
    // ViewDeclarationLanguageJspImpl#buildView(FacesContext, UIViewRoot) method, then wrap the
    // specified response
    // object with a ServletResponse that is able to handle the AFTER_VIEW_CONTENT feature. This is
    // necessary
    // because the Mojarra JspViewHandlingStrategy#getWrapper(ExternalContext) method has a Servlet
    // API dependency
    // due to explicit casts to HttpServletResponse.
    if (bridgeContext.isProcessingAfterViewContent()) {

      // If the specified response is of type HttpServletResponseWrapper, then it is almost certain
      // that Mojarra's
      // JspViewHandlingStrategy#executePageToBuildView(FacesContext, UIViewRoot) method is
      // attempting to wrap the
      // bridge's response object (that it originally got by calling the
      // ExternalContext#getResponse() method)
      // with it's ViewHandlerResponseWrapper, which extends HttpServletResponseWrapper.
      if (response instanceof HttpServletResponseWrapper) {

        this.facesImplementationServletResponse = (ServletResponse) response;

        HttpServletResponseWrapper httpServletResponseWrapper =
            (HttpServletResponseWrapper) response;
        ServletResponse wrappedServletResponse = httpServletResponseWrapper.getResponse();

        if (wrappedServletResponse instanceof BridgeAfterViewContentResponse) {
          BridgeAfterViewContentResponse bridgeAfterViewContentPreResponse =
              (BridgeAfterViewContentResponse) wrappedServletResponse;
          PortletResponse wrappedPortletResponse = bridgeAfterViewContentPreResponse.getWrapped();

          BridgeWriteBehindSupportFactory bridgeWriteBehindSupportFactory =
              (BridgeWriteBehindSupportFactory)
                  FactoryExtensionFinder.getFactory(BridgeWriteBehindSupportFactory.class);
          BridgeWriteBehindResponse bridgeWriteBehindResponse =
              bridgeWriteBehindSupportFactory.getBridgeWriteBehindResponse(
                  (MimeResponse) wrappedPortletResponse, facesImplementationServletResponse);

          // Note: See comments in BridgeContextImpl#dispatch(String) regarding Liferay's inability
          // to
          // accept a wrapped response. This is indeed supported in Pluto.
          this.portletResponse = (PortletResponse) bridgeWriteBehindResponse;
        } else {

          // Since we're unable to determine the wrapped PortletResponse, the following line will
          // throw an
          // intentional ClassCastException. Note that this case should never happen.
          this.portletResponse = (PortletResponse) response;
        }
      }

      // Otherwise, the specified response is of type BridgeAfterViewContentResponse, then Mojarra's
      // JspViewHandlingStrategy#executePageToBuildView(FacesContext, UIViewRoot) method is trying
      // to restore the
      // bridge's response object that it originally got from calling the
      // ExternalContext#getResponse() method
      // prior to wrapping with it's ViewHandlerResponseWrapper.
      else if (response instanceof BridgeAfterViewContentResponse) {
        BridgeAfterViewContentResponse bridgeAfterViewContentResponse =
            (BridgeAfterViewContentResponse) response;
        this.portletResponse = bridgeAfterViewContentResponse.getWrapped();
      }

      // Otherwise, assume that the specified response is a PortletResponse.
      else {
        this.portletResponse = (PortletResponse) response;
      }

    }

    // Otherwise, since the JSF AFTER_VIEW_CONTENT feature is not activated, assume that the
    // specified response is
    // a PortletResponse.
    else {
      this.portletResponse = (PortletResponse) response;
    }

    try {
      boolean requestChanged = false;
      boolean responseChanged = true;
      preInitializeObjects(requestChanged, responseChanged);
    } catch (Exception e) {
      logger.error(e);
    }
  }

  @Override
  public String getResponseCharacterEncoding() {

    if (portletResponse instanceof MimeResponse) {
      MimeResponse mimeResponse = (MimeResponse) portletResponse;
      String characterEncoding = mimeResponse.getCharacterEncoding();

      if (manageIncongruities) {
        incongruityContext.setResponseCharacterEncoding(characterEncoding);
      }

      return characterEncoding;
    } else {

      if (manageIncongruities) {
        return incongruityContext.getResponseCharacterEncoding();
      } else {

        if (portletResponse instanceof StateAwareResponse) {

          String characterEncoding =
              (String)
                  bridgeContext.getAttributes().get(ViewHandlerImpl.RESPONSE_CHARACTER_ENCODING);

          if (characterEncoding != null) {

            // Workaround for patch applied to Mojarra in JAVASERVERFACES-3023
            return characterEncoding;
          } else {

            // TCK TestPage169: getResponseCharacterEncodingActionTest
            // TCK TestPage180: getResponseCharacterEncodingEventTest
            throw new IllegalStateException();
          }
        } else {
          return null;
        }
      }
    }
  }

  /** @see ExternalContext#setResponseCharacterEncoding(String) */
  @Override
  public void setResponseCharacterEncoding(String encoding) {

    if (encoding != null) {

      if (portletResponse instanceof ResourceResponse) {
        ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
        resourceResponse.setCharacterEncoding(encoding);
      } else {

        if (manageIncongruities) {
          incongruityContext.setResponseCharacterEncoding(encoding);
        } else {
          // TestPage196: setResponseCharacterEncodingTest expects this to be a no-op so throwing
          // IllegalStateException is not an option.
        }
      }
    }
  }

  /** @see {@link ExternalContext#getResponseContentType()} */
  @Override
  public String getResponseContentType() {

    if (portletResponse instanceof MimeResponse) {

      MimeResponse mimeResponse = (MimeResponse) portletResponse;

      String responseContentType = mimeResponse.getContentType();

      if (responseContentType == null) {
        responseContentType = portletRequest.getResponseContentType();
      }

      return responseContentType;
    } else {

      // TCK TestPage173: getResponseContentTypeActionTest
      // TCK TestPage174: getResponseContentTypeEventTest
      throw new IllegalStateException();
    }
  }

  /** @see {@link ExternalContext#getSession(boolean)} */
  @Override
  public Object getSession(boolean create) {
    return portletRequest.getPortletSession(create);
  }

  @Override
  public Map<String, Object> getSessionMap() {
    return sessionMap;
  }

  @Override
  public Principal getUserPrincipal() {

    if (userPrincipal == null) {
      userPrincipal = portletRequest.getUserPrincipal();
    }

    return userPrincipal;
  }
}
Example #5
0
/** @author Neil Griffin */
public class RendererUtil {

  // Public Constants
  public static final String ALLOY_END_SCRIPT = "});";
  public static final String BACKSLASH_COLON = "\\\\:";
  public static final String REGEX_COLON = "[:]";

  // Private Constants
  private static final String FUNCTION_A = "function(A)";
  private static final String JAVA_SCRIPT_HEX_PREFIX = "\\x";
  private static final boolean LIFERAY_FACES_BRIDGE_DETECTED =
      ProductMap.getInstance().get(ProductConstants.LIFERAY_FACES_BRIDGE).isDetected();
  private static final boolean LIFERAY_PORTAL_DETECTED =
      ProductMap.getInstance().get(ProductConstants.LIFERAY_PORTAL).isDetected();
  private static final String READY = "ready";
  private static final String USE = "use";
  private static final String AUI = "AUI";

  private static final char[] _HEX_DIGITS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  };

  public static void decodeClientBehaviors(FacesContext facesContext, UIComponent uiComponent) {

    if (uiComponent instanceof ClientBehaviorHolder) {

      ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) uiComponent;
      Map<String, List<ClientBehavior>> clientBehaviorMap =
          clientBehaviorHolder.getClientBehaviors();

      Map<String, String> requestParameterMap =
          facesContext.getExternalContext().getRequestParameterMap();
      String behaviorEvent = requestParameterMap.get(FacesConstants.JAVAX_FACES_BEHAVIOR_EVENT);

      if (behaviorEvent != null) {

        List<ClientBehavior> clientBehaviors = clientBehaviorMap.get(behaviorEvent);

        if (clientBehaviors != null) {
          String source = requestParameterMap.get(FacesConstants.JAVAX_FACES_SOURCE);

          if (source != null) {
            String clientId = uiComponent.getClientId(facesContext);

            if (clientId.startsWith(source)) {

              for (ClientBehavior behavior : clientBehaviors) {
                behavior.decode(facesContext, uiComponent);
              }
            }
          }
        }
      }
    }
  }

  public static void encodeFunctionCall(
      ResponseWriter responseWriter, String functionName, Object... parameters) throws IOException {

    responseWriter.write(functionName);
    responseWriter.write("(");

    boolean first = true;

    for (Object parameter : parameters) {

      if (first) {
        first = false;
      } else {
        responseWriter.write(",");
      }

      encodeFunctionParameter(responseWriter, parameter);
    }

    responseWriter.write(");");
  }

  public static void encodeFunctionParameter(ResponseWriter responseWriter, Object parameter)
      throws IOException {

    if (parameter == null) {
      responseWriter.write("null");
    } else {

      if (parameter instanceof Object[]) {
        Object[] parameterItems = (Object[]) parameter;

        if (parameterItems.length == 0) {
          responseWriter.write("[]");
        } else {
          responseWriter.write("[");

          boolean firstIndex = true;

          for (Object parameterItem : parameterItems) {

            if (firstIndex) {
              firstIndex = false;
            } else {
              responseWriter.write(",");
            }

            encodeFunctionParameter(responseWriter, parameterItem);
          }

          responseWriter.write("]");
        }
      } else if (parameter instanceof String) {
        responseWriter.write("'" + parameter.toString() + "'");
      } else {
        responseWriter.write(parameter.toString());
      }
    }
  }

  public static void encodeStyleable(
      ResponseWriter responseWriter, Styleable styleable, String... classNames) throws IOException {

    StringBuilder allCssClasses = new StringBuilder();
    String cssClasses = ComponentUtil.concatCssClasses(classNames);

    if (cssClasses != null) {
      allCssClasses.append(cssClasses);
      allCssClasses.append(StringPool.SPACE);
    }

    String styleClass = styleable.getStyleClass();

    if (styleClass != null) {
      allCssClasses.append(styleClass);
    }

    if (allCssClasses.length() > 0) {
      responseWriter.writeAttribute(
          StringPool.CLASS, allCssClasses.toString(), Styleable.STYLE_CLASS);
    }

    String style = styleable.getStyle();

    if (style != null) {
      responseWriter.writeAttribute(Styleable.STYLE, style, Styleable.STYLE);
    }
  }

  public static String escapeClientId(String clientId) {

    String escapedClientId = clientId;

    if (escapedClientId != null) {

      escapedClientId = escapedClientId.replaceAll(REGEX_COLON, BACKSLASH_COLON);
      escapedClientId = escapeJavaScript(escapedClientId);
    }

    return escapedClientId;
  }

  public static String escapeJavaScript(String javaScript) {

    StringBuilder stringBuilder = new StringBuilder();
    char[] javaScriptCharArray = javaScript.toCharArray();

    for (char character : javaScriptCharArray) {

      if ((character > 255) || Character.isLetterOrDigit(character)) {

        stringBuilder.append(character);
      } else {
        stringBuilder.append(JAVA_SCRIPT_HEX_PREFIX);

        String hexString = toHexString(character);

        if (hexString.length() == 1) {
          stringBuilder.append(StringPool.ASCII_TABLE[48]);
        }

        stringBuilder.append(hexString);
      }
    }

    if (stringBuilder.length() != javaScript.length()) {
      javaScript = stringBuilder.toString();
    }

    return javaScript;
  }

  public static void renderScript(
      FacesContext facesContext, UIComponent uiComponent, String script, String use) {

    // Render the script at the bottom of the page by setting the WebKeys.AUI_SCRIPT_DATA request
    // attribute.
    ExternalContext externalContext = facesContext.getExternalContext();
    ClientScriptFactory clientScriptFactory =
        (ClientScriptFactory) FactoryExtensionFinder.getFactory(ClientScriptFactory.class);
    ClientScript clientScript = clientScriptFactory.getClientScript(externalContext);

    String portletId = StringPool.BLANK;
    Object portlet = externalContext.getRequestMap().get(WebKeys.RENDER_PORTLET);

    if (portlet != null) {
      portletId = LiferayPortletUtil.getPortletId(portlet);
    }

    clientScript.append(portletId, script, use);
  }

  private static String toHexString(int i) {
    char[] buffer = new char[8];

    int index = 8;

    do {
      buffer[--index] = _HEX_DIGITS[i & 15];

      i >>>= 4;
    } while (i != 0);

    return new String(buffer, index, 8 - index);
  }

  public static String getAlloyBeginScript(FacesContext facesContext, String[] modules) {
    return getAlloyBeginScript(facesContext, modules, null);
  }

  public static String getAlloyBeginScript(
      String[] modules, float browserMajorVersion, boolean browserIE) {
    return getAlloyBeginScript(modules, null, browserMajorVersion, browserIE);
  }

  public static String getAlloyBeginScript(
      FacesContext facesContext, String[] modules, String config) {

    boolean browserIE = false;
    float browserMajorVersion = 1;

    BrowserSnifferFactory browserSnifferFactory =
        (BrowserSnifferFactory) FactoryExtensionFinder.getFactory(BrowserSnifferFactory.class);
    BrowserSniffer browserSniffer =
        browserSnifferFactory.getBrowserSniffer(facesContext.getExternalContext());

    if (LIFERAY_PORTAL_DETECTED) {
      browserIE = browserSniffer.isIe();
      browserMajorVersion = browserSniffer.getMajorVersion();
    } else if (LIFERAY_FACES_BRIDGE_DETECTED) {
      // no-op because there is no way to obtain the underlying HttpServletRequest.
    } else {
      browserIE = browserSniffer.isIe();
      browserMajorVersion = browserSniffer.getMajorVersion();
    }

    return getAlloyBeginScript(modules, config, browserMajorVersion, browserIE);
  }

  public static String getAlloyBeginScript(
      String[] modules, String config, float browserMajorVersion, boolean browserIE) {

    StringBuilder stringBuilder = new StringBuilder();
    String loadMethod = USE;

    if (browserIE && (browserMajorVersion < 8)) {
      loadMethod = READY;
    }

    stringBuilder.append(AUI);
    stringBuilder.append(StringPool.OPEN_PARENTHESIS);

    if ((config != null) && (config.length() > 0)) {
      stringBuilder.append(config);
    }

    stringBuilder.append(StringPool.CLOSE_PARENTHESIS);
    stringBuilder.append(StringPool.PERIOD);
    stringBuilder.append(loadMethod);
    stringBuilder.append(StringPool.OPEN_PARENTHESIS);

    if (modules != null) {

      for (String module : modules) {
        stringBuilder.append(StringPool.APOSTROPHE);
        stringBuilder.append(module.trim());
        stringBuilder.append(StringPool.APOSTROPHE);
        stringBuilder.append(StringPool.COMMA_AND_SPACE);
      }
    }

    stringBuilder.append(FUNCTION_A);
    stringBuilder.append(StringPool.OPEN_CURLY_BRACE);

    return stringBuilder.toString();
  }
}
// J-
@FacesRenderer(componentFamily = InputFile.COMPONENT_FAMILY, rendererType = InputFile.RENDERER_TYPE)
@ResourceDependencies({
  @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.css"),
  @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.js"),
  @ResourceDependency(
      library = "liferay-faces-reslib",
      name = "build/aui-css/css/bootstrap.min.css"),
  @ResourceDependency(library = "liferay-faces-reslib", name = "build/aui/aui-min.js"),
  @ResourceDependency(library = "liferay-faces-reslib", name = "liferay.js")
})
// J+
public class InputFileRenderer extends InputFileRendererBase {

  // Private Constants
  private static final boolean LIFERAY_FACES_BRIDGE_DETECTED =
      ProductMap.getInstance().get(ProductConstants.LIFERAY_FACES_BRIDGE).isDetected();

  // Protected Constants
  protected static final String[] MODULES = {"uploader", "aui-datatable", "datatype-xml"};

  @Override
  public void decode(FacesContext facesContext, UIComponent uiComponent) {

    InputFile inputFile = (InputFile) uiComponent;

    Map<String, List<UploadedFile>> uploadedFileMap =
        getUploadedFileMap(facesContext, inputFile.getLocation());

    if (uploadedFileMap != null) {

      String clientId = uiComponent.getClientId(facesContext);
      List<UploadedFile> uploadedFiles = uploadedFileMap.get(clientId);

      if ((uploadedFiles != null) && (uploadedFiles.size() > 0)) {

        inputFile.setSubmittedValue(uploadedFiles);

        // Queue the FileUploadEvent so that each uploaded file can be handled individually with an
        // ActionListener.
        for (UploadedFile uploadedFile : uploadedFiles) {

          FileUploadEvent fileUploadEvent = new FileUploadEvent(uiComponent, uploadedFile);
          uiComponent.queueEvent(fileUploadEvent);
        }
      }
    }
  }

  @Override
  public void encodeJavaScriptCustom(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();
    InputFile inputFile = (InputFile) uiComponent;
    JavaScriptFragment alloyNamespace = new JavaScriptFragment("A");

    // Determine the valid content-types and maximum file size from the validator (if specified).
    JavaScriptFragment contentTypes = new JavaScriptFragment("[]");
    String validContentTypes = inputFile.getContentTypes();

    if (validContentTypes != null) {
      contentTypes = toJavaScriptArray(validContentTypes.split(","));
    }

    String clientId = inputFile.getClientId(facesContext);
    Long maxFileSize = inputFile.getMaxFileSize();

    if (maxFileSize == null) {
      maxFileSize = Long.MAX_VALUE;
    }

    // If the component should render the upload progress table, then initialize the YUI progress
    // uploader widget.
    if (inputFile.isShowProgress()) {

      String clientVarName = getClientVarName(facesContext, inputFile);
      String clientKey = inputFile.getClientKey();

      if (clientKey == null) {
        clientKey = clientVarName;
      }

      UIViewRoot viewRoot = facesContext.getViewRoot();
      Locale locale = viewRoot.getLocale();
      String formClientId = getParentFormClientId(inputFile);
      Application application = facesContext.getApplication();
      ViewHandler viewHandler = application.getViewHandler();
      String actionURL = viewHandler.getActionURL(facesContext, viewRoot.getViewId());
      String partialActionURL = facesContext.getExternalContext().encodePartialActionURL(actionURL);
      String namingContainerId = "";

      if (viewRoot instanceof NamingContainer) {
        namingContainerId = viewRoot.getContainerClientId(facesContext);
      }

      AjaxParameters ajaxParameters = new AjaxParameters(inputFile, clientId, formClientId);
      String execute = ajaxParameters.getExecute();
      String render = ajaxParameters.getRender();

      String notStartedMessage = getMessageContext().getMessage(locale, "not-started");
      JavaScriptFragment clientComponent =
          new JavaScriptFragment("Liferay.component('" + clientKey + "')");
      encodeFunctionCall(
          responseWriter,
          "LFAI.initProgressUploader",
          alloyNamespace,
          clientComponent,
          contentTypes,
          clientId,
          formClientId,
          namingContainerId,
          inputFile.isAuto(),
          execute,
          render,
          partialActionURL,
          maxFileSize,
          notStartedMessage);
    }

    // Otherwise, if the component should render the upload preview table, then format the
    // preview-uploader.js
    // template and write it to the response.
    else if (inputFile.isShowPreview()) {

      encodeFunctionCall(
          responseWriter,
          "LFAI.initPreviewUploader",
          alloyNamespace,
          contentTypes,
          clientId,
          maxFileSize);
    }
  }

  @Override
  public void encodeMarkupBegin(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {
    ResponseWriter responseWriter = facesContext.getResponseWriter();

    InputFile inputFile = (InputFile) uiComponent;

    // If the component should render the preview table or the upload progress table, then
    if (inputFile.isShowPreview() || inputFile.isShowProgress()) {

      // Start encoding the outermost <div> element.
      responseWriter.startElement("div", uiComponent);

      String clientId = uiComponent.getClientId(facesContext);
      responseWriter.writeAttribute("id", clientId, "id");
      RendererUtil.encodeStyleable(responseWriter, (Styleable) uiComponent);

      // If the component should render the upload progress table, then format the
      // progress-table.html template
      // and write it to the response.
      if (inputFile.isShowProgress()) {
        encodeProgress(facesContext, responseWriter, uiComponent, clientId);
      }

      // Otherwise, delegate writing to the delegate renderer. Note that this effectively a no-op
      // with Mojarra and
      // MyFaces, since they both delay writing of the entire <input type="file"...> ... </input>
      // element until
      // encodeEnd.
      else {
        super.encodeMarkupBegin(facesContext, uiComponent);
      }
    }

    // Otherwise, delegate writing to the delegate renderer. Note that this effectively a no-op with
    // Mojarra and
    // MyFaces, since they both delay writing of the entire <input type="file"...> ... </input>
    // element until
    // encodeEnd.
    else {
      super.encodeMarkupBegin(facesContext, uiComponent);
    }
  }

  @Override
  public void encodeMarkupEnd(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    // If the component should show the progress table, then
    InputFile inputFile = (InputFile) uiComponent;
    ResponseWriter responseWriter = facesContext.getResponseWriter();

    if (inputFile.isShowProgress()) {

      // Finish encoding of the outermost <div> element. Since the template contains its own "Select
      // Files"
      // button, delegation must not occur.
      responseWriter.endElement("div");
    }

    // Otherwise, if the component should show the preview table, then
    else if (inputFile.isShowPreview()) {

      encodePreview(facesContext, responseWriter, inputFile);

      // Finish encoding of the outermost <div> element.
      responseWriter.endElement("div");
    }

    // Otherwise, delegate writing of the entire <input type="file"...> ... </input> element to the
    // delegate
    // renderer.
    else {
      DelegationResponseWriter delegationResponseWriter =
          new InputFileDelegationResponseWriter(responseWriter, inputFile.isAuto());
      super.encodeMarkupEnd(facesContext, uiComponent, delegationResponseWriter);
    }
  }

  @Override
  protected void encodeHiddenAttributes(
      FacesContext facesContext, ResponseWriter responseWriter, InputFile inputFile, boolean first)
      throws IOException {

    // fileFieldName
    encodeString(responseWriter, "fileFieldName", inputFile.getClientId(), first);
    first = false;

    // multipleFiles
    String multiple = inputFile.getMultiple();
    boolean multipleFiles = "multiple".equalsIgnoreCase(multiple);
    encodeBoolean(responseWriter, "multipleFiles", multipleFiles, first);

    // selectFilesButton
    Locale locale = facesContext.getViewRoot().getLocale();
    String chooseFiles = getMessageContext().getMessage(locale, "choose-files");
    StringBuilder selectFilesButtonScript = new StringBuilder();
    selectFilesButtonScript.append(
        "A.Node.create(\"<button type='button' class='alloy-button' role='button' aria-label='");
    selectFilesButtonScript.append(chooseFiles);
    selectFilesButtonScript.append("' tabindex='{tabIndex}'>");
    selectFilesButtonScript.append(chooseFiles);
    selectFilesButtonScript.append("</button>\")");
    encodeNonEscapedObject(responseWriter, "selectFilesButton", selectFilesButtonScript, first);
  }

  protected void encodePreview(
      FacesContext facesContext, ResponseWriter responseWriter, InputFile inputFile)
      throws IOException {

    // Delegate writing of the entire <input type="file"...> ... </input> element to the delegate
    // renderer.
    DelegationResponseWriter delegationResponseWriter =
        new InputFileDelegationResponseWriter(responseWriter, inputFile.isAuto());
    super.encodeMarkupEnd(facesContext, inputFile, delegationResponseWriter);

    // Format the preview-table.html template and write it to the response.
    Locale locale = facesContext.getViewRoot().getLocale();
    String clientId = inputFile.getClientId(facesContext);
    responseWriter.startElement("div", inputFile);
    responseWriter.startElement("table", inputFile);
    responseWriter.writeAttribute("id", clientId + "_table", null);
    responseWriter.writeAttribute("class", "table table-bordered", null);
    responseWriter.startElement("thead", inputFile);
    responseWriter.writeAttribute("class", "table-columns", null);
    responseWriter.startElement("tr", inputFile);
    responseWriter.startElement("th", inputFile);

    MessageContextFactory messageContextFactory =
        (MessageContextFactory) FactoryExtensionFinder.getFactory(MessageContextFactory.class);
    MessageContext messageContext = messageContextFactory.getMessageContext();
    String i18nFileName = messageContext.getMessage(locale, "file-name");
    responseWriter.writeText(i18nFileName, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", inputFile);

    String i18nFileType = messageContext.getMessage(locale, "file-type");
    responseWriter.writeText(i18nFileType, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", inputFile);

    String i18nFileSize = messageContext.getMessage(locale, "file-size");
    responseWriter.writeText(i18nFileSize, null);
    responseWriter.endElement("th");
    responseWriter.endElement("tr");
    responseWriter.endElement("thead");
    responseWriter.startElement("tfoot", inputFile);
    responseWriter.startElement("tr", inputFile);
    responseWriter.startElement("td", inputFile);
    responseWriter.writeAttribute("colspan", "3", null);

    String i18nNoFilesSelected = messageContext.getMessage(locale, "no-files-selected");
    responseWriter.writeText(i18nNoFilesSelected, null);
    responseWriter.endElement("td");
    responseWriter.endElement("tr");
    responseWriter.endElement("tfoot");
    responseWriter.startElement("tbody", inputFile);
    responseWriter.startElement("tr", inputFile);
    responseWriter.endElement("tr");
    responseWriter.endElement("tbody");
    responseWriter.endElement("table");
    responseWriter.endElement("div");
  }

  protected void encodeProgress(
      FacesContext facesContext,
      ResponseWriter responseWriter,
      UIComponent uiComponent,
      String clientId)
      throws IOException {

    Locale locale = facesContext.getViewRoot().getLocale();
    responseWriter.startElement("div", uiComponent);
    responseWriter.writeAttribute("id", clientId + "_selectFilesBox", null);
    responseWriter.writeAttribute("class", "select-files-box", null);
    responseWriter.endElement("div");
    responseWriter.startElement("div", uiComponent);
    responseWriter.writeAttribute("id", clientId + "_uploadFilesBox", null);
    responseWriter.writeAttribute("class", "upload-files-box", null);
    responseWriter.startElement("button", uiComponent);
    responseWriter.writeAttribute("id", clientId + "_uploadFilesButton", null);
    responseWriter.writeAttribute("class", "alloy-button", null);

    MessageContextFactory messageContextFactory =
        (MessageContextFactory) FactoryExtensionFinder.getFactory(MessageContextFactory.class);
    MessageContext messageContext = messageContextFactory.getMessageContext();
    String i18nUploadFiles = messageContext.getMessage(locale, "upload-files");
    responseWriter.writeText(i18nUploadFiles, null);
    responseWriter.endElement("button");
    responseWriter.endElement("div");
    responseWriter.startElement("div", uiComponent);
    responseWriter.startElement("table", uiComponent);
    responseWriter.writeAttribute("id", clientId + "_table", null);
    responseWriter.writeAttribute("class", "table table-bordered", null);
    responseWriter.startElement("thead", uiComponent);
    responseWriter.writeAttribute("class", "table-columns", null);
    responseWriter.startElement("tr", uiComponent);
    responseWriter.startElement("th", uiComponent);

    String i18nFileName = messageContext.getMessage(locale, "file-name");
    responseWriter.writeText(i18nFileName, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", uiComponent);

    String i18nFileType = messageContext.getMessage(locale, "file-type");
    responseWriter.writeText(i18nFileType, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", uiComponent);

    String i18nFileSize = messageContext.getMessage(locale, "file-size");
    responseWriter.writeText(i18nFileSize, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", uiComponent);

    String i18nProgress = messageContext.getMessage(locale, "progress");
    responseWriter.writeText(i18nProgress, null);
    responseWriter.endElement("th");
    responseWriter.endElement("tr");
    responseWriter.endElement("thead");
    responseWriter.startElement("tfoot", uiComponent);
    responseWriter.startElement("tr", uiComponent);
    responseWriter.startElement("td", uiComponent);
    responseWriter.writeAttribute("colspan", "4", null);

    String i18nNoFilesSelected = messageContext.getMessage(locale, "no-files-selected");
    responseWriter.writeText(i18nNoFilesSelected, null);
    responseWriter.endElement("td");
    responseWriter.endElement("tr");
    responseWriter.endElement("tfoot");
    responseWriter.startElement("tbody", uiComponent);
    responseWriter.startElement("tr", uiComponent);
    responseWriter.endElement("tr");
    responseWriter.endElement("tbody");
    responseWriter.endElement("table");
    responseWriter.endElement("div");
  }

  protected JavaScriptFragment toJavaScriptArray(String[] items) {

    StringBuilder buf = new StringBuilder("[");

    if (items != null) {

      for (int i = 0; i < items.length; i++) {

        if (i > 0) {
          buf.append(",");
        }

        buf.append("'");
        buf.append(items[i].trim());
        buf.append("'");
      }
    }

    buf.append("]");

    return new JavaScriptFragment(buf.toString());
  }

  @Override
  public Object getConvertedValue(
      FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
      throws ConverterException {
    return submittedValue;
  }

  protected MessageContext getMessageContext() {

    MessageContextFactory messageContextFactory =
        (MessageContextFactory) FactoryExtensionFinder.getFactory(MessageContextFactory.class);

    return messageContextFactory.getMessageContext();
  }

  @Override
  protected String[] getModules(FacesContext facesContext, UIComponent uiComponent) {
    return MODULES;
  }

  protected String getParentFormClientId(UIComponent uiComponent) {

    String parentFormClientId = null;

    if (uiComponent != null) {

      if (uiComponent instanceof UIForm) {
        parentFormClientId = uiComponent.getClientId();
      } else {
        parentFormClientId = getParentFormClientId(uiComponent.getParent());
      }
    }

    return parentFormClientId;
  }

  protected Map<String, List<UploadedFile>> getUploadedFileMap(
      FacesContext facesContext, String location) {

    Map<String, List<UploadedFile>> uploadedFileMap = null;

    if (LIFERAY_FACES_BRIDGE_DETECTED) {
      Map<String, Object> requestAttributeMap = facesContext.getExternalContext().getRequestMap();
      MultiPartFormData multiPartFormData =
          (MultiPartFormData) requestAttributeMap.get(MultiPartFormData.class.getName());

      if (multiPartFormData != null) {
        uploadedFileMap = multiPartFormData.getUploadedFileMap();
      }
    } else {
      InputFileDecoder inputFileDecoder = getInputFileDecoder();
      uploadedFileMap = inputFileDecoder.decode(facesContext, location);
    }

    return uploadedFileMap;
  }
}
/** @author Neil Griffin */
public class ContextMapFactoryImpl extends ContextMapFactory {

  // Private Constants
  private static final boolean ICEFACES_DETECTED =
      ProductMap.getInstance().get(ProductConstants.ICEFACES).isDetected();
  private static final String MULTIPART_FORM_DATA_FQCN = MultiPartFormData.class.getName();

  @Override
  public Map<String, Object> getApplicationScopeMap(BridgeContext bridgeContext) {
    return new ApplicationScopeMap(bridgeContext);
  }

  protected FacesRequestParameterMap getFacesRequestParameterMap(BridgeContext bridgeContext) {

    FacesRequestParameterMap facesRequestParameterMap = null;
    PortletRequest portletRequest = bridgeContext.getPortletRequest();
    PortletResponse portletResponse = bridgeContext.getPortletResponse();
    String namespace = portletResponse.getNamespace();
    BridgeRequestScope bridgeRequestScope = bridgeContext.getBridgeRequestScope();
    String defaultRenderKitId = bridgeContext.getDefaultRenderKitId();
    Map<String, String> facesViewParameterMap = getFacesViewParameterMap(bridgeContext);

    if (portletRequest instanceof ClientDataRequest) {

      ClientDataRequest clientDataRequest = (ClientDataRequest) portletRequest;
      String contentType = clientDataRequest.getContentType();

      // Note: ICEfaces ace:fileEntry relies on its own mechanism for handling file upload.
      if (!ICEFACES_DETECTED
          && (contentType != null)
          && contentType.toLowerCase().startsWith(BridgeConstants.MULTIPART_CONTENT_TYPE_PREFIX)) {

        MultiPartFormData multiPartFormData =
            (MultiPartFormData) portletRequest.getAttribute(MULTIPART_FORM_DATA_FQCN);

        if (multiPartFormData == null) {
          facesRequestParameterMap =
              new FacesRequestParameterMapImpl(
                  namespace, bridgeRequestScope, facesViewParameterMap, defaultRenderKitId);

          MultiPartFormDataProcessor multiPartFormDataProcessor =
              new MultiPartFormDataProcessorImpl();
          Map<String, List<UploadedFile>> uploadedFileMap =
              multiPartFormDataProcessor.process(
                  clientDataRequest, bridgeContext.getPortletConfig(), facesRequestParameterMap);

          multiPartFormData = new MultiPartFormDataImpl(facesRequestParameterMap, uploadedFileMap);

          // Save the multipart/form-data in a request attribute so that it can be referenced
          // later-on in the
          // JSF lifecycle by file upload component renderers.
          portletRequest.setAttribute(MULTIPART_FORM_DATA_FQCN, multiPartFormData);
        } else {
          facesRequestParameterMap = multiPartFormData.getFacesRequestParameterMap();
        }
      }
    }

    if (facesRequestParameterMap == null) {
      Map<String, String[]> parameterMap = portletRequest.getParameterMap();
      facesRequestParameterMap =
          new FacesRequestParameterMapImpl(
              parameterMap,
              namespace,
              bridgeRequestScope,
              facesViewParameterMap,
              defaultRenderKitId);
    }

    return facesRequestParameterMap;
  }

  @Override
  public Map<String, String> getFacesViewParameterMap(BridgeContext bridgeContext) {

    String facesViewQueryString = bridgeContext.getFacesViewQueryString();

    return new FacesViewParameterMap(facesViewQueryString);
  }

  @Override
  public Map<String, String> getInitParameterMap(PortletContext portletContext) {
    return Collections.unmodifiableMap(new InitParameterMap(portletContext));
  }

  @Override
  public Map<String, Object> getRequestCookieMap(BridgeContext bridgeContext) {
    PortletRequest portletRequest = bridgeContext.getPortletRequest();
    Cookie[] cookies = portletRequest.getCookies();

    return new RequestCookieMap(cookies);
  }

  @Override
  public Map<String, String> getRequestHeaderMap(BridgeContext bridgeContext) {
    return new RequestHeaderMap(getRequestHeaderValuesMap(bridgeContext));
  }

  @Override
  public Map<String, String[]> getRequestHeaderValuesMap(BridgeContext bridgeContext) {
    return new RequestHeaderValuesMap(bridgeContext);
  }

  @Override
  public Map<String, String> getRequestParameterMap(BridgeContext bridgeContext) {

    FacesRequestParameterMap facesRequestParameterMap = getFacesRequestParameterMap(bridgeContext);

    return new RequestParameterMap(facesRequestParameterMap);
  }

  @Override
  public Map<String, String[]> getRequestParameterValuesMap(BridgeContext bridgeContext) {

    FacesRequestParameterMap facesRequestParameterMap = getFacesRequestParameterMap(bridgeContext);

    return new RequestParameterValuesMap(facesRequestParameterMap);
  }

  @Override
  public Map<String, Object> getRequestScopeMap(BridgeContext bridgeContext) {
    return new RequestScopeMap(bridgeContext);
  }

  @Override
  public Map<String, Object> getServletContextAttributeMap(ServletContext servletContext) {
    return new ServletContextAttributeMap(servletContext);
  }

  @Override
  public Map<String, Object> getSessionScopeMap(BridgeContext bridgeContext, int scope) {
    return new SessionScopeMap(bridgeContext, scope);
  }

  @Override
  public Map<String, List<UploadedFile>> getUploadedFileMap(BridgeContext bridgeContext) {

    PortletRequest portletRequest = bridgeContext.getPortletRequest();
    MultiPartFormData multiPartFormData =
        (MultiPartFormData) portletRequest.getAttribute(MULTIPART_FORM_DATA_FQCN);
    Map<String, List<UploadedFile>> uploadedFileMap = null;

    if (multiPartFormData != null) {
      uploadedFileMap = multiPartFormData.getUploadedFileMap();
    }

    return uploadedFileMap;
  }

  @Override
  public ContextMapFactoryImpl getWrapped() {

    // Since this is the factory instance provided by the bridge, it will never wrap another
    // factory.
    return null;
  }
}