TDIing out loud, ok SDIing as well

Ramblings on the paradigm-shift that is TDI.

Wednesday, October 9, 2013

Dynamically changing Attribute Maps

One way to handle multiple Attribute Maps (either Input or Output) for a Connector during AL cycling is to do the mapping yourself via script. However, there are alternatives.

The easiest way to dynamically change a map is by defining multiple Attribute Maps under Resources in your Project and then swapping between these, for example in the Before Execute Hook of the Connector.

// first decide which map to use
// for example, "AttributeMaps/ComputerSystemMap"
// or just "ComputerSystemMap"
mapToUse = computeMapName(work)

if (mapToUse != null) {
   try {
      // true for Input Map, or false for Output
      thisConnector.useAttributeMap(mapToUse,true)
      return
   } catch (exc) {
      // report that the map is missing or invalid
   }
}


Another way is to use an externalized map file, which is a text file containing any number of lines. Each line represents a single mapping rule.


Mapping

Description

sn=
When the assignment is empty then simple mapping is used.
In the example rule shown in the left column, the attribute named 'sn' gets its value(s) from a similarly named attribute in the source Entry. For an Input Map this would be the 'sn' attribute of the conn Entry. For all other map types (Output Maps or Attribute Map components) the source will be the work Entry.
status='Updated'
Anything entered after the equal sign is considered the assignment of the mapping rule. It must be a snippet of Javascript, unless the Text with Substitution flag is used: {S}, described later in this post.

You can also reference variables or call scripted functions that are defined by the time the map rule is invoked.
In the example rule shown in the left column, the 'status' attribute will get the value specified by the Javascript snippet, resulting in the literal string value Updated


giveName=[
first = work.FirstName 

last = work.LastName 
return first + " " + last 
]
Using square brackets as shown allows the Javascript assignment to stretch over multiple lines.
You can also reference variables or call scripted functions that you have defined.
In the example mapping rule, a full name value is returned by concatenating the FirstName and LastName attributes in the Work Entry.

In addition, flags can be specified to control the behavior of a mapping rule. These flags must appear in curly braces immediately after the name of the attribute being mapped. Valid flags are: A, M and S.

The A and M flags correspond to the Add and Mod columns in the Output map of a Connector in Update mode, and control whether this attribute is mapped during Add and Modify operations. The S flag denotes that the assignment uses the TDI Text with Substitution feature, which allows for literal text values that can include one or more substitution tokens.


Mapping


Description

objectClass{A}=
The 'A' and 'M' flags are used to control when this attribute is enabled with regards to the Add and Modify operations of a Connector in Update mode. By default, attributes will be included for both Add and Modify operations unless only one is specified: A or M.
im The A flag shown in this example specifies that the 'objectClass' attribute should only be mapped for Add operations.


mail{S}={work.uid}@acme.com

The 'S' flag indicates that the following mapping rule uses Text with Substitution. As a result, any curly braces found will be replaced with the value of the substitution token specified in the braces.
For this example, the value of the uid attribute in the Work Entry is substituted for the token {work.uid} and then the literal string '@acme.com ' is appended to it. The resulting string is returned as the value for 'mail'.

Note that multiple mapping flags can combined by separating them with commas. For example: {M,S}.

Note also that in order for externalized map files to work correctly, you must apply Fixpack 3 to your TDI 7.1.1 installation.

By externalizing your map to a file, you can easily change the format of the file, or allow users of your solution to do so without having to fire up the CE. You can also swap which map file to use with the same code snippet show above - just make sure that the mapToUse variable contains the path to a valid file on disk.