Package com.liferay.faces.bridge.context.url

Source Code of com.liferay.faces.bridge.context.url.BridgeResourceURLImpl

/**
* Copyright (c) 2000-2014 Liferay, Inc. All rights reserved.
*
* This library 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 library 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.
*/
package com.liferay.faces.bridge.context.url;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Set;

import javax.faces.context.FacesContext;
import javax.portlet.BaseURL;
import javax.portlet.PortletURL;
import javax.portlet.ResourceURL;
import javax.portlet.faces.Bridge;

import com.liferay.faces.bridge.container.PortletContainer;
import com.liferay.faces.bridge.context.BridgeContext;
import com.liferay.faces.util.application.ResourceConstants;
import com.liferay.faces.util.helper.BooleanHelper;
import com.liferay.faces.util.lang.StringPool;
import com.liferay.faces.util.logging.Logger;
import com.liferay.faces.util.logging.LoggerFactory;


/**
* @author  Neil Griffin
*/
public class BridgeResourceURLImpl extends BridgeURLBaseImpl implements BridgeResourceURL {

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

  // Private Constants
  private static final String ENCODED_RESOURCE_TOKEN = "javax.faces.resource=";

  // Private Pseudo-Constants
  private static Set<String> EXCLUDED_PARAMETER_NAMES = new HashSet<String>();

  static {
    EXCLUDED_PARAMETER_NAMES.add(Bridge.PORTLET_MODE_PARAMETER);
    EXCLUDED_PARAMETER_NAMES.add(Bridge.PORTLET_SECURE_PARAMETER);
    EXCLUDED_PARAMETER_NAMES.add(Bridge.PORTLET_WINDOWSTATE_PARAMETER);
  }

  // Private Data Members
  private boolean inProtocol;
  private PortletContainer portletContainer;
  private boolean viewLink;

  public BridgeResourceURLImpl(String url, String currentFacesViewId, BridgeContext bridgeContext) {
    super(url, currentFacesViewId, bridgeContext);
    this.portletContainer = bridgeContext.getPortletContainer();
  }

  public void replaceBackLinkParameter(FacesContext facesContext) {
    String backLinkViewId = facesContext.getViewRoot().getViewId();
    String backLinkURL = facesContext.getApplication().getViewHandler().getActionURL(facesContext, backLinkViewId);
    String backLinkEncodedActionURL = StringPool.BLANK;

    try {
      backLinkEncodedActionURL = URLEncoder.encode(facesContext.getExternalContext().encodeActionURL(backLinkURL),
          StringPool.UTF8);
    }
    catch (UnsupportedEncodingException e) {
      logger.error(e.getMessage());
    }

    String newParamName = removeParameter(Bridge.BACK_LINK);
    setParameter(newParamName, backLinkEncodedActionURL);
  }

  @Override
  protected BaseURL toBaseURL() throws MalformedURLException {

    BaseURL baseURL = null;

    // If the URL is opaque, meaning it starts with something like "portlet:" or "mailto:" and
    // doesn't have the double-forward-slash like "http://" does, then
    if (isOpaque()) {

      // If the specified URL starts with "portlet:", then return a BaseURL that contains the modified
      // parameters. This will be a URL that represents navigation to a different viewId.
      if (isPortletScheme()) {

        // TCK TestPage005: modeViewIDTest
        // TCK TestPage042: requestRenderIgnoresScopeViaCreateViewTest
        // TCK TestPage043: requestRenderRedisplayTest
        // TCK TestPage044: requestRedisplayOutOfScopeTest
        // TCK TestPage049: renderRedirectTest
        // TCK TestPage050: ignoreCurrentViewIdModeChangeTest
        // TCK TestPage051: exceptionThrownWhenNoDefaultViewIdTest
        String portletMode = getParameter(Bridge.PORTLET_MODE_PARAMETER);
        boolean modeChanged = ((portletMode != null) && (portletMode.length() > 0));
        String security = getParameter(Bridge.PORTLET_SECURE_PARAMETER);
        String windowState = getParameter(Bridge.PORTLET_WINDOWSTATE_PARAMETER);
        String urlWithModifiedParameters = _toString(modeChanged);
        Bridge.PortletPhase urlPortletPhase = getPortletPhase();

        if (urlPortletPhase == Bridge.PortletPhase.ACTION_PHASE) {
          baseURL = portletContainer.createActionURL(urlWithModifiedParameters);
        }
        else if (urlPortletPhase == Bridge.PortletPhase.RENDER_PHASE) {
          baseURL = portletContainer.createRenderURL(urlWithModifiedParameters);
        }
        else {
          baseURL = portletContainer.createResourceURL(urlWithModifiedParameters);
        }

        // If the URL string is self-referencing, meaning, it targets the current Faces view, then copy the
        // render parameters from the current PortletRequest to the BaseURL. NOTE: This has the added benefit of
        // copying the bridgeRequestScopeId render parameter, which will preserve the BridgeRequestScope if the
        // user clicks on the link (invokes the BaseURL).
        if (isSelfReferencing()) {
          setRenderParameters(baseURL);
        }

        // If the portlet container created a PortletURL, then apply the PortletMode and WindowState to the
        // PortletURL.
        if (baseURL instanceof PortletURL) {

          PortletURL portletURL = (PortletURL) baseURL;
          setPortletModeParameter(portletMode, portletURL);
          setWindowStateParameter(windowState, portletURL);
        }

        // Apply the security.
        setSecureParameter(security, baseURL);
      }

      // Otherwise, return the a BaseURL string representation (unmodified value) as required by the Bridge Spec.
      else {

        // TCK TestPage128: encodeResourceURLOpaqueTest
        baseURL = new BaseURLNonEncodedStringImpl(url, getParameterMap());
      }
    }

    // Otherwise, if the URL is identified by the ResourceHandler as a JSF2 resource URL, then
    else if ((url != null) && (url.indexOf(ResourceConstants.JAVAX_FACES_RESOURCE) >= 0)) {

      // If the URL has already been encoded, then return the URL string unmodified.
      if (url.indexOf(ENCODED_RESOURCE_TOKEN) > 0) {

        // FACES-63: Prevent double-encoding of resource URLs
        baseURL = new BaseURLNonEncodedStringImpl(url, getParameterMap());
      }

      // Otherwise, return a ResourceURL that can retrieve the JSF2 resource.
      else {
        baseURL = portletContainer.createResourceURL(url);
      }
    }

    // Otherwise, if the URL is external, then return an encoded BaseURL string representation of the URL.
    else if (isExternal()) {

      // TCK TestPage130: encodeResourceURLForeignExternalURLBackLinkTest
      baseURL = new BaseURLEncodedExternalStringImpl(url, getParameterMap(), bridgeContext);
    }

    // Otherwise, if the URL is relative, in that it starts with "../", then return a BaseURL string representation
    // of the URL that contains the context-path.
    else if (isPathRelative()) {

      // TCK TestPage131: encodeResourceURLRelativeURLTest
      // TCK TestPage132: encodeResourceURLRelativeURLBackLinkTest
      baseURL = new BaseURLRelativeStringImpl(url, getParameterMap(), bridgeContext);
    }

    // Otherwise, if the URL originally contained the "javax.portlet.faces.ViewLink" which represents navigation
    // to a different Faces view, then
    else if (viewLink) {

      String urlWithModifiedParameters = _toString(false, EXCLUDED_PARAMETER_NAMES);
      String portletMode = getParameter(Bridge.PORTLET_MODE_PARAMETER);
      String windowState = getParameter(Bridge.PORTLET_WINDOWSTATE_PARAMETER);
      boolean secure = BooleanHelper.toBoolean(getParameter(Bridge.PORTLET_SECURE_PARAMETER));

      // If the URL targets a Faces viewId, then return a PortletURL (Action URL) that targets the view with the
      // appropriate PortletMode, WindowState, and Security settings built into the URL. For more info, see
      // JavaDoc comments for {@link Bridge#VIEW_LINK}.
      if (isFacesViewTarget()) {

        // TCK TestPage135: encodeResourceURLViewLinkTest
        // TCK TestPage136: encodeResourceURLViewLinkWithBackLinkTest
        baseURL = new PortletURLFacesTargetActionImpl(bridgeContext, urlWithModifiedParameters, portletMode,
            windowState, secure);
      }

      // Otherwise, return a PortletURL (Render URL) that contains the "_jsfBridgeNonFacesView" render parameter,
      // which is a signal to the GenericFacesPortlet to dispatch to this non-Faces target when the URL is
      // requested. Note that this seems to be a use-case that is contradictory with the JavaDoc for
      // Brige#VIEW_LINK which claims navigation to a different view. But there are a number of tests in the TCK
      // that utilize this (see below).
      else {

        // TCK TestPage097: encodeActionURLNonJSFViewRenderTest
        // TCK TestPage098: encodeActionURLNonJSFViewWithParamRenderTest
        // TCK TestPage099: encodeActionURLNonJSFViewWithModeRenderTest
        // TCK TestPage100: encodeActionURLNonJSFViewWithInvalidModeRenderTest
        // TCK TestPage101: encodeActionURLNonJSFViewWithWindowStateRenderTest
        // TCK TestPage102: encodeActionURLNonJSFViewWithInvalidWindowStateRenderTest
        // TCK TestPage103: encodeActionURLNonJSFViewResourceTest
        // TCK TestPage104: encodeActionURLNonJSFViewWithParamResourceTest
        // TCK TestPage105: encodeActionURLNonJSFViewWithModeResourceTest
        // TCK TestPage106: encodeActionURLNonJSFViewWithInvalidModeResourceTest
        // TCK TestPage107: encodeActionURLNonJSFViewWithWindowStateResourceTest
        // TCK TestPage108: encodeActionURLNonJSFViewWithInvalidWindowStateResourceTest
        baseURL = new PortletURLNonFacesTargetRenderImpl(bridgeContext, urlWithModifiedParameters, portletMode,
            windowState, secure, getURI().getPath());
      }
    }

    // Otherwise, if the URL targets a Faces viewId, then return a ResourceURL that targets the view.
    else if (isFacesViewTarget()) {

      // TCK TestPage073: scopeAfterRedisplayResourcePPRTest
      // TCK TestPage121: encodeActionURLJSFViewResourceTest
      // TCK TestPage122: encodeActionURLWithParamResourceTest
      // TCK TestPage123: encodeActionURLWithModeResourceTest
      // TCK TestPage124: encodeActionURLWithInvalidModeResourceTest
      // TCK TestPage125: encodeActionURLWithWindowStateResourceTest
      // TCK TestPage126: encodeActionURLWithInvalidWindowStateResourceTest
      // TCK TestPage127: encodeURLEscapingTest
      // TCK TestPage137: encodeResourceURLWithModeTest
      String urlWithModifiedParameters = _toString(false, EXCLUDED_PARAMETER_NAMES);
      baseURL = portletContainer.createResourceURL(urlWithModifiedParameters);
    }

    // Otherwise, if the bridge must encode the URL to satisfy "in-protocol" resource serving, then return a
    // an appropriate ResourceURL.
    else if (inProtocol) {

      // TCK TestPage071: nonFacesResourceTest
      String urlWithModifiedParameters = _toString(false);
      ResourceURL resourceURL = portletContainer.createResourceURL(urlWithModifiedParameters);
      resourceURL.setResourceID(getContextRelativePath());
      baseURL = resourceURL;
    }

    // Otherwise, assume that the URL is for an resource external to the portlet context like
    // "/portalcontext/resources/foo.png" and return a BaseURL string representation of it.
    else {

      // TCK TestPage133: encodeResourceURLTest
      baseURL = new BaseURLEncodedExternalStringImpl(url, getParameterMap(), bridgeContext);
    }

    return baseURL;
  }

  public void setInProtocol(boolean inProtocol) {
    this.inProtocol = inProtocol;
  }

  public void setViewLink(boolean viewLink) {
    this.viewLink = viewLink;
  }
}
TOP

Related Classes of com.liferay.faces.bridge.context.url.BridgeResourceURLImpl

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.