The WSRP specifications allows for implementations to extend the protocol using Extensions. GateIn Portal, as of its WSRP implementation version 2.2.0, provides a way for client code (e.g. portlets) to interact with such extensions in the form of several classes and interfaces gathered within the org.gatein.wsrp.api.extensions package, the most important ones being InvocationHandlerDelegate, ConsumerExtensionAccessor and ProducerExtensionAccessor.
To be able to use this API, you will need to include the wsrp-integration-api-$WSRP_VERSION.jar file to your project, where $WSRP_VERSION is the version of the GateIn Portal WSRP implementation you wish to use, 2.2.2.Final being the current one. This can be done by adding the following dependency to your maven project:
Using the InvocationHandlerDelegate infrastructure, custom behavior can now be inserted on either consumer or producer sides to enrich WSRP applications before and/or after portlet requests and/or responses. Please refer to the Javadoc for org.gatein.wsrp.api.extensions.InvocationHandlerDelegate for more details on this interface and how to implement it.
|Since InvocationHandlerDelegate is a very generic interface, it could potentially be used for more than simply working with WSRP extensions. Moreover, since it has access to internal GateIn Portal classes, it is important to be treat access to these internal classes as read-only to prevent any un-intentional side-effects.|
Implementations of InvocationHandlerDelegate must follow the same constraints as RegistrationPolicy implementations as detailed in Customization of Registration handling behavior section of the Configuring GateIn's WSRP Producer chapter, in essence, they must follow the Java ServiceLoader architectural pattern and be deployed in the appropriate $JBOSS_HOME/gatein/extensions directory.
You can specify only one InvocationHandlerDelegate implementation per side: one implementation for the consumer and another one for the producer. This is accomplished by passing the fully classified class name to the appropriate system property when the portal is started:
|WSRP side||System property|
will inject the com.example.FooInvocationHandlerDelegate class on the consumer side, assuming that class implements the org.gatein.wsrp.api.extensions.InvocationHandlerDelegate interface and is packaged and deployed appropriately as explained above.
You can access extensions from client code using ConsumerExtensionAccessor and ProducerExtensionAccessor on the consumer and producer, respectively. Each interface provides several methods but you should only have to ever call two of them on each, as shown in the following table:
Please refer to the Javadoc for these classes for more details.
|We currently only support adding and accessing extensions from a core subset of WSRP classes pertaining to markup, interaction, resource or event requests and responses, as follows:
|We strongly recommend that you use org.w3c.dom.Element values as extensions for interoperability purposes.|
We also provide a complete, end-to-end example to get you started, which you can find at https://github.com/gatein/gatein-wsrp/tree/master/examples/invocation-handler-delegate. This example shows how ExampleConsumerInvocationHandlerDelegate, a consumer-side InvocationHandlerDelegate implementation, can add information extracted from the consumer and pass it along to the producer, working in conjunction with ExampleProducerInvocationHandlerDelegate, the associated producer-side InvocationHandlerDelegate, to establish a round-trip communication channel outside of the standard WSRP protocol, implementing the following scenario:
- ExampleConsumerInvocationHandlerDelegate attaches to the consumer to add the current session id as an extension to render requests sent to the producer.
- ExampleProducerInvocationHandlerDelegate provides the counterpart of ExampleConsumerInvocationHandlerDelegate on the producer. It checks incoming render requests for potential extensions matching what ExampleConsumerInvocationHandlerDelegate sends and adds an extension of its own to the render response so that the consumer-side delegate can know that the information it passed was properly processed.