You are here:
Custom Input and Output for Omnistudio Data Mappers in Omnistudio
By default, Data Mappers handle JSON and XML data. To handle other data formats, you can configure a Data Mapper to use a custom input or output that you implement is a custom class. For example, you can define a Data Mapper Transform that accepts CSV-formatted data and outputs it as JSON.
Options are as follows:
-
Data Mapper Load: Custom input (output is always a Salesforce object)
-
Data Mapper Transform: Custom input and output
-
Data Mapper Extract: Custom input and output
To configure a Data Mapper to use a custom input or output, set its type to Custom. Then specify the class that contains the serialize and deserialize methods that perform the operation. The following table shows properties for a Data Mapper Transform configured with a custom input and output.
| Property | Value |
|---|---|
| Data Mapper Interface Name | Custom Serialization Transform |
| Interface Type | Transform |
| Input Type | Custom |
| Custom Input Class | CSVProcessor |
| Output Type | Custom |
| Custom Output Class | CSVProcessor |
For ease of mapping, you can paste sample input into the Expected Input and Expected Output panes.
To create the logic required to custom input and output, you must define a custom class that implements Callable. For custom output, implement the serialize method. For custom input, implement the deserialize method. You can’t rename the input and output parameters.
The following example shows the basic structure of a customer serialization and deserialization class.
global with sharing class PreprocessorClassExample implements Callable {
public Object call(String action, Map<String, Object> args) {
Map<String, Object> input = (Map<String, Object>)args.get('input');
Map<String, Object> output = (Map<String, Object>)args.get('output');
Map<String, Object> options = (Map<String, Object>)args.get('options');
return invokeMethod(action, input, output, options);
}
private Object invokeMethod(String methodName, Map<String,Object> input, Map<String,Object> output, Map<String,Object> options) {
if (methodName == 'serialize') {
return serialize(input, output);
}
else if (methodName == 'deserialize') {
return deserialize(input, output);
}
return false;
}
/*
Serializes Apex objects into JSON content. Return String json
*/
global Boolean serialize(Map<String, Object> input, Map<String, Object> output) {
String jsonString = '';
// code
output.put('output', jsonString); // JSON String
return true;
}
/*
Deserializes the specified JSON string into collections of primitive data types. Return Object ((Map<String, Object>))
*/
global Boolean deserialize(Map<String, Object> input, Map<String, Object> output) {
Map<String, Object> returnMap = new Map<String, Object>();
// code
output.put('output', returnMap); // ---> collections of primitive data types Map<String, Object>, List<Map<String, Object>>()
return true;
}
}
The following example serializes and deserializes CSV data.
global with sharing class CSVProcessor implements Callable {
public Object call(String action, Map<String, Object> args) {
Map<String, Object> input = (Map<String, Object>)args.get('input');
Map<String, Object> output = (Map<String, Object>)args.get('output');
Map<String, Object> options = (Map<String, Object>)args.get('options');
return invokeMethod(action, input, output, options);
}
private Object invokeMethod(String methodName, Map<String,Object> input, Map<String,Object> output, Map<String,Object> options)
{
System.debug('METHOD NAME >>> ' + methodName);
if (methodName == 'deserialize')
{
return deserialize(input, output);
}
return false;
}
/*
Example Output: 'Column2,Column1\nvalue0,value1.0\nvalue0.1,value1.1';
*/
/*
Deserializes the specified JSON string into collections of primitive data types. Return Object ((Map<String, Object>))
Input: 'Column2,Column1\nvalue0,value1.0\nvalue0.1,value1.1';
Output:
[
{
"Column1Test": "value1.0",
"Column2Test": "value0"
},
{
"Column1Test": "value1.1sl",
"Column2Test": "value0.1"
}
]
*/
public class csvInput {
@AuraEnabled
public string VersionData;
}
global Boolean deserialize(Map<String, Object> input, Map<String, Object> output)
{
System.debug(input);
System.debug(input.get('input'));
System.debug(input.toString());
//csvInput s = (csvInput)JSON.deserialize((string)input.get('input'), csvInput.class);
Object data = input.get('input');
csvInput s;
if(data instanceof String) {
s = (csvInput)JSON.deserialize(String.valueOf(data), csvInput.class);
} else { // try to preserve the source formatting
s = (csvInput)JSON.deserialize(JSON.serialize(data), csvInput.class);
}
Blob decodedInputBlob = System.EncodingUtil.base64Decode(s.VersionData);
String decodedCsvString = decodedInputBlob.toString();
Object inputValue = decodedCsvString;
System.debug(inputValue);
if (inputValue != null && inputValue InstanceOf String)
{
List<String> valueSet = ((String)inputValue).split('\n');
List<Map<String, String>> csvList = new List<Map<String, String>>();
List<String> columns = new List<String>();
for (Integer i = 0; i < valueSet.size(); i++)
{
String value = valueSet[i];
if (String.isBlank(value))
{
continue;
}
if (i == 0)
{
List<String> valSet = value.split(',');
for (Integer y = 0; y < valSet.size(); y++)
{
columns.add(valSet[y]);
}
}
else
{
List<String> valSet = value.split(',');
if (columns.size() >= valSet.size())
{
Map<String, String> rows = new Map<String, String>();
for (Integer z = 0; z < valSet.size(); z++)
{
rows.put(columns[z], valSet[z]);
}
csvList.add(rows);
}
}
}
output.put('output', csvList);
//Map<String, Object> returnMap = new Map<String, Object>();
//output.put('output', returnMap);
System.debug(output);
return True;
}
return False;
}
}
For example, suppose your CSV file has this content:
Name |
Phone |
|
|---|---|---|
Mary Baker |
mbaker@example.com |
415-555-3331 |
Joe Baker |
jbaker@example.com |
415-555-3332 |
Russell Baker |
rbaker@example.com |
415-555-3333 |
The example CSVProcessor class converts it to this JSON input:
[
{
"Name": "Mary Baker",
"Email": "mbaker@example.com",
"Phone": "415-555-3331"
},
{
"Name": "Joe Baker",
"Email": "jbaker@example.com",
"Phone": "415-555-3332"
},
{
"Name": "Russell Baker",
"Email": "rbaker@example.com",
"Phone": "415-555-3333"
}
]

