+

Search Tips   |   Advanced Search

Event Mappers

In more complex scenarios, it might not suffice to adapt only the event names or QNames. Sometimes the payload itself needs to be transformed.

To explain event mappers and their influence, here is an example: As in the previous example, a portlet1 emits an employee ID under the key employeeID. The payload is of type Integer. A portlet2 expects an employee ID under the key userID, and sent as payload of type String.

As with DCX keys to enable portlet1 to communicate with portlet2, we have the following two options:

  • We can make portlet1 store its payload under the key userID and as of type String, even though it emits an event with the QName employeeID and as of type Integer.

  • We can make portlet2 read the key employeeID and as of type Integer, even though it expects an event with the QName userID and as of type String.

Mappers have full access to the DCX segment of the currently processed dialog instance and also to the payload being processed. Therefore, mappers are powerful tools, as they can run various transformations.
UX Screen Flow Manager supports the following two types of event mappers: PayloadToContextMappers and ContextToPayloadMappers.

PayloadToContextMappers mappers can transform an event that was emitted by a transition source and influence the way that it is stored in the DCX segment. These mappers are started before data is stored in the DCX. This action means these mappers can control the key under which data is stored and the data type itself. Code sample 37 shows how use a PayloadToContextMapper mapper to enable the portlets portlet1 and portlet2 mentioned earlier to communicate with each other.

Code sample 37:

01 public void payloadToContext(final QName dcxKey, final Object payload, final DCXData dcxData) {
 02   // ...
 03   04   QName mappedDcxKey = new QName("userID");
 05   String transformedPayload = ((Integer)payload).toString();
 06   07   dcxData.put(mappedDcxKey, transformedPayload);
 08 }  

To use this mapper, we need to implement the interface PayloadToContextMapper. The input parameters carry information about the following two items:

  • The DCX key used to store the event as defined in association with the source, if it is not changed by the mapper

  • The payload stored under this key, if it is not changed by the mapper.

The input parameters also provide a reference to the DCX segment that belongs to a specific dialog instance. In this example, the mapper changes the DCX key where the payload is to be stored and the payload itself by transforming it from type Integer to type String. Code sample 38 shows how you register PayloadToContextMappers.

Code sample 38:

01  <transition>
 02      <source>
 03          <transition-endpoint nameref="portlet1">
 04              <event qname="employeeID" mapper-class="myPackage.myMapper"/>
 05          </transition-endpoint>
 06      </source>
 07      <target>
 08          <transition-endpoint nameref="portlet2">
 09              <event qname="userID"/>
 10          </transition-endpoint>
 11      </target>
 12  </transition>

ContextToPayloadMappers can transform an event before it is transmitted to a transition target. These mappers are started after data is read from the DCX and before it is transmitted to the target. This action means these mappers can influence the payload before it is sent. Code sample 39 shows how use a ContextToPayloadMapper to enable the portlets portlet1 and portlet2 mentioned earlier to communicate with each other.

Code sample 39:

01 public Serializable contextToPayload(final DCXData dcxData, final QName dcxKey, final Class<?> targetClass) {
 02    // ...      03    Object payload = dcxData.get(dcxKey, targetClass);
 04    String transformedPayload = ((Integer)payload).toString();
 05
 06    return (Serializable) transformedPayload;
 07 }

To use this mapper, we need to implement the interface ContextToPayloadMapper. The input parameters carry information about the following two items:

  • The DCX key or QName used to send the event as defined in association with the source

  • The payload is sent under this key - if it is not changed by the mapper.

The input parameters also provide a reference to the DCX segment that belongs to a specific dialog instance. In this example, the mapper changes the type of the payload to be sent by transforming it from type Integer to type String.

Code sample 40 shows how you register ContextToPayloadMappers.

Code sample 40:

01  <transition>
 02      <source>
 03          <transition-endpoint nameref="portlet1">
 04              <event qname="employeeID"/>
 05          </transition-endpoint>
 06      </source>
 07      <target>
 08          <transition-endpoint nameref="portlet2">
 09              <event qname="userID" dcx-key="employeeID" mapper-class="myPackage.myMapper"/>
 10          </transition-endpoint>
 11      </target>
 12  </transition>

Before use mappers, we need to make them available. We can make the mappers available by implementing a so called MapperFactory. You register the MapperFactory using an Eclipse Extension Point. For more information, read Application Eclipse Extension Registry. The advantage of this approach is we can register new mappers without having to restart the server. This action is also called hot deployment. To use a MapperFactory, we need to implement the interface MapperFactory and return an object instance of type ContextToPayloadMapper or PayloadToContextMapper. This implementation depends on the concrete event mapper that is requested. Code sample 41 shows an example of how a MapperFactory can look.

Code sample 41:

01 public class MapperFactory implements com.ibm.portal.pcm.events.MapperFactory {
 02   03  public ContextToPayloadMapper getContextToPayloadMapper(String name) {        04      ContextToPayloadMapper result = null;         05      if (name.equals("myPackage.myMapper")) {
 06          result = new MyMapper();
 07      }
 08   09      return result;
 10  }
 11   12  public PayloadToContextMapper getPayloadToContextMapper(String name) {
 13      // ...
 14  }
 15 }

Code sample 42 shows how we can register a MapperFactory using a plugin.xml file.

Code sample 42:

01 <plugin
 02     id="com.ibm.wps.portlet.pcm.demo"
 03     name="Portlet Control Manager Demo"
 04     version="1.0.0"
 05     provider-name="IBM">
 06
 07     <!-- Mapper Factory -->
 08     <extension point="com.ibm.portal.pcm.MapperFactory" id="PcmMapperFactory">
 09         <factory class="com.ibm.wps.pcm.demo.mapper.MapperFactory"/>
 10     </extension>
 11 </plugin>
 


Parent Retrieve and store event payload