Uploaded image for project: 'PUBLIC - Liferay Faces'
  1. PUBLIC - Liferay Faces
  2. FACES-2696

Utilize Portlet 3.0 dynamic resource dependency feature

    Details

      Description

      Portlet 3.0 added the HEADER_PHASE to the portlet lifecycle which blurs the distinction (in the eyes of the portlet developer) between streaming portals (like Pluto) and buffered portals (like Liferay Portal).

      This issue serves as a task for defining the requirements in the Bridge Spec and adding the following methods and a PortletPhase.HEADER_PHASE enum value to the Bridge API in order to utilize the HEADER_PHASE in order to dynamically add JS/CSS resources that are determined as a result of running the RENDER_RESPONSE phase of the JSF lifecycle:

      Bridge.java
      import javax.portlet.HeaderRequest;
      import javax.portlet.HeaderResponse;
      
      public static enum PortletPhase {
          ACTION_PHASE, EVENT_PHASE, RENDER_PHASE, RESOURCE_PHASE, HEADER_PHASE
      }
      public void doFacesRequest(HeaderRequest headerRequest, HeaderResponse headerResponse)
          throws BridgeDefaultViewNotSpecifiedException, BridgeUninitializedException, BridgeException;
      
      GenericFacesPortlet.java
      import javax.portlet.HeaderRequest;
      import javax.portlet.HeaderResponse;
      
      @Override
      public void renderHeaders(HeaderRequest headerRequest, HeaderResponse headerResponse) throws PortletException, IOException {
          // Call through to Bridge.doFacesRequest(headerRequest, headerResponse);
      }
      
      BridgePortletRequestFactory.java
      import javax.portlet.HeaderRequest;
      import javax.portlet.HeaderResponse;
      
      /**
       * Returns a new instance of {@link HeaderRequest} from the {@link BridgePortletRequestFactory} found by the
       * {@link BridgeFactoryFinder}. The returned instance is not guaranteed to be {@link java.io.Serializable}.
       */
      public static HeaderRequest getHeaderRequestInstance(HeaderRequest headerRequest,
          HeaderResponse headerResponse, PortletConfig portletConfig, BridgeConfig bridgeConfig) {
      
          BridgePortletRequestFactory bridgePortletRequestFactory = (BridgePortletRequestFactory) BridgeFactoryFinder
              .getFactory(BridgePortletRequestFactory.class);
      
          return bridgePortletRequestFactory.getHeaderRequest(headerRequest, headerResponse, portletConfig,
                  bridgeConfig);
      }
      
      /**
       * Returns a new instance of {@link HeaderRequest}. The returned instance is not guaranteed to be {@link
       * java.io.Serializable}.
       */
      public abstract HeaderRequest getHeaderRequest(HeaderRequest headerRequest,
          HeaderResponse headerResponse, PortletConfig portletConfig, BridgeConfig bridgeConfig);
      
      BridgePortletResponseFactory.java
      import javax.portlet.HeaderRequest;
      import javax.portlet.HeaderResponse;
      
      /**
       * Returns a new instance of {@link HeaderResponse} from the {@link BridgePortletResponseFactory} found by the
       * {@link BridgeFactoryFinder}. The returned instance is not guaranteed to be {@link java.io.Serializable}.
       */
      public static HeaderResponse getHeaderResponseInstance(HeaderRequest headerRequest,
          HeaderResponse headerResponse, PortletConfig portletConfig, BridgeConfig bridgeConfig) {
      
          BridgePortletResponseFactory bridgePortletResponseFactory = (BridgePortletResponseFactory) BridgeFactoryFinder
              .getFactory(BridgePortletResponseFactory.class);
      
          return bridgePortletResponseFactory.getHeaderResponse(headerRequest, headerResponse, portletConfig,
                  bridgeConfig);
      }
      
      /**
       * Returns a new instance of {@link HeaderResponse}. The returned instance is not guaranteed to be {@link
       * java.io.Serializable}.
       */
      public abstract HeaderResponse getHeaderResponse(HeaderRequest headerRequest,
          HeaderResponse headerResponse, PortletConfig portletConfig, BridgeConfig bridgeConfig);
      

      For example, given the following Facelet view:

      view.xhtml
      <f:view>
          <h:form>
              <alloy:inputDate />
          </h:form>
      </f:view>
      

      The alloy:inputDate renderer contains the following resource dependencies:

      InputDateRenderer.java
      @ResourceDependencies(
          {
              @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.css"),
              @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.js"),
              @ResourceDependency(library = "liferay-faces-alloy-reslib", name = "build/aui-css/css/bootstrap.min.css"),
              @ResourceDependency(library = "liferay-faces-alloy-reslib", name = "build/aui/aui-min.js"),
              @ResourceDependency(library = "liferay-faces-alloy-reslib", name = "liferay.js")
          }
      )
      

      It will be the responsibility of the bridge to ensure that these dependencies are added by calling HeaderResponse.addResourceDependency(String name, String scope, String version, String markup) for each resource.

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Packages

                  Version Package
                  facesbridge-api-5.0.0
                  facesbridge-spec-5.0.0
                  bridge-impl-5.0.0