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

Add BridgeEventHandlerFactory and BridgePublicRenderParameterHandlerFactory to the bridge API

    Details

      Description

      Section 4.2.12 of the JSR 329 Spec titled "getBridgeEventHandler()" states:

      Because portlet events contain arbitrary (typed) payloads, event processing is delegated by the bridge back to the portlet application. The configured BridgeEventHandler is called by the bridge at the appropriate point in the lifecycle to allow the application to update the model state from information in the event.

      The specific BridgeEventHandler is conveyed to the bridge via a PortletContext attribute. The GenericFacesPortlet gets the instance it sets for this attribute by calling getBridgeEventHandler. If not overridden, the GenericFacesPortlet's default behavior is to read the portlet initialization parameter javax.portlet.faces.bridgeEventHandler and return an instance of the class that corresponds to its value. If this initialization parameter doesn't exist, null is returned.

      Similarly, section 4.2.13 of the JSR 329 Spec titled "getBridgePublicRenderParameterHandler()" states:


      The bridge gives the portlet an opportunity to recompute and resynchronize its models after it has pushed new public render parameter values into any corresponding mapped managed beans by calling the BridgePublicRenderParameterHandler conveyed to it by the portlet via a PortletContext attribute. The GenericFacesPortlet gets the instance it sets for this attribute by calling getBridgePublicRenderParameterHandler. If not overridden, the GenericFacesPortlet's default behavior is to read the portlet initialization parameter javax.portlet.faces.bridgePublicRenderParameterHandler and return an instance of the class that corresponds to its value. If this initialization parameter doesn't exist, null is returned.

      The problem is that the javax.portlet.faces.GenericFacesPortlet class uses a Thread Context Class Loader (TCCL) in order to load classes and then instantiates them. This is incompatible with OSGi environments (such as GlassFish and WebSphere application servers).

      In order to move the responsibility class loading and object instantiation into the bridge implementation, this issue serves as a proposal for adding the following to the Bridge API:

      javax.portlet.faces.BridgeEventHandlerFactory.java
      public abstract class BridgeEventHandlerFactory implements FacesWrapper<BridgeEventHandlerFactory> {
      
      	public static BridgeEventHandler getBridgeEventHandlerInstance(PortletConfig portletConfig) {
      		...
      	}
      
      	public abstract BridgeEventHandler getBridgeEventHandler(PortletConfig portletConfig);
      }
      
      javax.portlet.faces.BridgeEventHandlerWrapper.java
      public abstract class BridgeEventHandlerWrapper implements BridgeEventHandler, FacesWrapper<BridgeEventHandler> {
      
      	@Override
      	public abstract BridgeEventHandler getWrapped();
      
      	@Override
      	public EventNavigationResult handleEvent(FacesContext facesContext, Event event) {
      		return getWrapped().handleEvent(facesContext, event);
      	}
      }
      javax.portlet.faces.BridgePublicRenderParameterHandlerFactory.java
      public abstract class BridgePublicRenderParameterHandlerFactory
      	implements FacesWrapper<BridgePublicRenderParameterHandlerFactory> {
      
      	public static BridgePublicRenderParameterHandler getBridgePublicRenderParameterHandlerInstance(
      		PortletConfig portletConfig) {
      		...
      	}
      
      	public abstract BridgePublicRenderParameterHandler getBridgePublicRenderParameterHandler(
      		PortletConfig portletConfig);
      
      	@Override
      	public abstract BridgePublicRenderParameterHandlerFactory getWrapped();
      }
      javax.portlet.faces.BridgePublicRenderParameterHandlerWrapper.java
      public abstract class BridgePublicRenderParameterHandlerWrapper implements BridgePublicRenderParameterHandler,
      	FacesWrapper<BridgePublicRenderParameterHandler> {
      
      	@Override
      	public abstract BridgePublicRenderParameterHandler getWrapped();
      
      	@Override
      	public void processUpdates(FacesContext facesContext) {
      		getWrapped().processUpdates(facesContext);
      	}
      }

      In order to provide backward compatibility with the requirement to have the PortletContext attributes set, it will be necessary to introduce Spec language in Chapter 4 titled "GenericFacesPortlet" that requires the attribute values to be instances of the aforementioned wrapper classes in order to defer lookup (in a thread-safe manner) of the factories via BridgeFactoryFinder until the first request. In addition, the TCK TestPage030 "getBridgeEventHandlerMethodSetTest" and TCK TestPage032 "getBridgePublicRenderParameterHandlerMethodSetTest" will need to unwrap the delegation chain of the wrappers in order to find the test instances.

        Attachments

          Activity

            People

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

              Dates

              • Created:
                Updated: