fferpcore.SubscriptionDescriptionglobal inherited sharing class SubscriptionDescription implements LinkingMessageToObjectMarshaller, LinkingMessageToObjectMarshaller2 Contains the information and methods necessary to enable a subscription to handle an incoming message and update records accordingly. The data is transformed (Marshalled) into a format suitable for the subscribing product using Mappings. You can extend mappings to carry out complex operations on records before the final version of the records are produced. This class implements the following interfaces: Methods
SubscriptionDescriptionglobal SubscriptionDescription(SObjectType context) Constructor that specifies the object to be updated by the messages. Input Parameters
SubscriptionDescriptionglobal SubscriptionDescription(SObjectType context, List<fferpcore.SubscriptionDescription.Mapping> mappings) Constructor that specifies the object to be updated by the messages and mappings to be applied to the message fields. Input Parameters
addMappingsglobal void addMappings(List<fferpcore.SubscriptionDescription.Mapping> mappings) Add mappings to the description. Mappings are executed in order, allowing later mappings to override work done by earlier mappings. Input Parameters
Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class ConcreteDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = ExampleSObject__c.SObjectType; public override fferpcore.SubscriptionDescription describe() { fferpcore.SubscriptionDescription description = new fferpcore.SubscriptionDescription(SOBJECT_TYPE); description.addMappings(getStaticMappings()); return description; } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { new fferpcore.SubscriptionDescription.FieldMapping(ExampleSObject__c.Name, 'Name'), new fferpcore.SubscriptionDescription.FieldMapping(ExampleSObject__c.Address1__c, new List<String>{'Address', 'Line 1'}), new fferpcore.SubscriptionDescription.FieldMapping(ExampleSObject__c.Address2__c, new List<String>{'Address', 'Line 2'}), new fferpcore.SubscriptionDescription.LinkingFieldMapping(SOBJECT_TYPE, 'Link Control Field') }; } } createStaticRecordTypeMappingglobal static fferpcore.SubscriptionDescription.Mapping createStaticRecordTypeMapping(String recordTypeName, SObjectType objectType) Creates a StaticRecordTypeMapping that applies the record type with the given name and SObjectType. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createStaticMappingglobal static fferpcore.SubscriptionDescription.Mapping createStaticMapping(Object data, SObjectField targetField) Creates a StaticMapping that applies the given data to the specified field. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createLookupRecordTypeMappingglobal static fferpcore.SubscriptionDescription.Mapping createLookupRecordTypeMapping(List<String> messageKey, SObjectType lookupObjectType, SObjectField lookupField, SObjectField resultField, SObjectType recordTypeObjectType) Creates a LookupRecordTypeMapping that locates a record belonging to the given SObjectType where the value on the given lookup field matches the value at the given message key. The value on the result field of the record is in turn used to locate a matching record type for the given record type SObjectType, which is subsequently applied to the record. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createDataTransformationRecordTypeMappingglobal static fferpcore.SubscriptionDescription.Mapping createDataTransformationRecordTypeMapping(List<List<String>> messageKeys, Id transformTableId, SObjectType objectType) Creates a DataTransformationRecordTypeMapping that extracts the data at the specified keys within the message, transforms it using the specified transformation table, and finally applies the record type with the matching name for the given SObjectType. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createRecordTypeMappingglobal static fferpcore.SubscriptionDescription.Mapping createRecordTypeMapping(List<String> messageKey, SObjectType objectType) Creates a RecordTypeMapping that applies a record type for the given SObjectType with the name matching the data at the specified key within the message. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createDataTransformationLookupMappingglobal static fferpcore.SubscriptionDescription.Mapping createDataTransformationLookupMapping(SObjectField targetField, List<List<String>> messageKeys, Id transformTableId, SObjectType relatedObjectType) Create a DataTransformationLookupMapping that can take 1 or 2 message keys to transform using the DataTransformationTable designated by the transformTableId. The result from the transformation is then used to lookup a record using the designated name field on a related object. The Id is then applied to the targetField. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String JOB_TITLE_KEY = 'JobTitle'; public static final String[] JOB_TITLE_PATH = new String[]{JOB_TITLE_KEY}; public static final Id JOB_TITLE_TRANSFORMATION_TABLE_ID = getJobTitleTransformationTableId(); public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), //Take the JobTitle from the message, do a transformation to convert it to a role, the look up the role and put the role ID on the resource. fferpcore.SubscriptionDescription.createDataTransformationLookupMapping( PSAFakeResource__c.Role__c, new List<List<String>>{JOB_TITLE_PATH}, JOB_TITLE_TRANSFORMATION_TABLE_ID, PSAFakeRole__c), }; } } createDataTransformationLookupMappingglobal static fferpcore.SubscriptionDescription.Mapping createDataTransformationLookupMapping(SObjectField targetField, List<List<String>> messageKeys, Id transformTableId, SObjectType relatedObjectType, SObjectField relatedLookupField, SObjectField relatedResultField) Create a DataTransformationLookupMapping that can take 1 or 2 message keys to transform using the DataTransformationTable designated by the transformTableId. The result from the transformation is then used to lookup a record using the designated relatedLookupField field on a related object. The contents of relatedResultField is then applied to the targetField. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String JOB_TITLE_KEY = 'JobTitle'; public static final String[] JOB_TITLE_PATH = new String[]{JOB_TITLE_KEY}; public static final Id JOB_TITLE_TRANSFORMATION_TABLE_ID = getJobTitleTransformationTableId(); public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), //Take the JobTitle from the message, do a transformation to convert it to a role, then look up the role using the role name, and put the primary area on the resource fferpcore.SubscriptionDescription.createDataTransformationLookupMapping( PSAFakeResource__c.Role__c, new List<List<String>>{JOB_TITLE_PATH}, JOB_TITLE_TRANSFORMATION_TABLE_ID, PSAFakeRole__c, PSAFakeRole__c.Name, PSAFakeRole__c.PrimaryArea__c) }; } } createDataTransformationMappingglobal static fferpcore.SubscriptionDescription.Mapping createDataTransformationMapping(SObjectField targetField, List<List<String>> messageKeys, Id transformTableId) Create a TransformationMapping that can take 1 or 2 message keys to transform using the DataTransformationTable designated by the transformTableId. The result from the transformation is then applied to the target field on the target object. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String JOB_TITLE_KEY = 'JobTitle'; public static final String[] JOB_TITLE_PATH = new String[]{JOB_TITLE_KEY}; public static final Id JOB_TITLE_TRANSFORMATION_TABLE_ID = getJobTitleTransformationTableId(); public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), //Take the JobTitle from the message and apply a mapping to a role. fferpcore.SubscriptionDescription.createDataTransformationMapping( PSAFakeResource__c.RoleName__c, new List<List<String>>{JOB_TITLE_PATH}, JOB_TITLE_TRANSFORMATION_TABLE_ID ) }; } } createLookupMappingglobal static fferpcore.SubscriptionDescription.Mapping createLookupMapping(SObjectField targetField, List<String> messageKey, SObjectType relatedObjectType) Create a LookupMapping that takes a message key which is used to lookup a record using the designated name field on a related object. The id of the related record is then applied to the targetField. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String DEPARTMENT_KEY = 'Department'; public static final String DEPARTMENT_NAME_KEY = 'Name'; public static final String[] DEPARTMENT_NAME_PATH = new String[]{DEPARTMENT_KEY, DEPARTMENT_NAME_KEY}; public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), //Put the department ID in the Department field fferpcore.SubscriptionDescription.createLookupMapping(PSAFakeResource__c.Department__c, DEPARTMENT_NAME_PATH, PSAFakeDepartment__c.SObjectType) }; } } createLookupMappingglobal static fferpcore.SubscriptionDescription.Mapping createLookupMapping(SObjectField targetField, List<String> messageKey, SObjectType relatedObjectType, SObjectField relatedLookupField, SObjectField relatedResultField) Create a LookupMapping that takes a message key which is used to lookup a record using the designated relatedLookupField field on a related object. The contents of relatedResultField is then applied to the targetField. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String DEPARTMENT_KEY = 'Department'; public static final String DEPARTMENT_NAME_KEY = 'Name'; public static final String[] DEPARTMENT_NAME_PATH = new String[]{DEPARTMENT_KEY, DEPARTMENT_NAME_KEY}; public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), //Look up the department name, and set the department building on our resource. fferpcore.SubscriptionDescription.createLookupMapping( PSAFakeResource__c.DepartmentBuilding__c, DEPARTMENT_NAME_PATH, PSAFakeDepartment__c.SObjectType, PSAFakeDepartment__c.Name, PSAFakeDepartment__c.Building), }; } } createLookupMappingglobal static fferpcore.SubscriptionDescription.Mapping createLookupMapping(SObjectField targetField, List<List<String>> messageKeys, SObjectType relatedObjectType, List<SObjectField> relatedLookupFields, SObjectField relatedResultField) Create a lookup mapping that uses multiple message keys to locate a record on a related object using the specified lookup fields. The contents of the specified result field is applied to the target field. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. createFieldMappingglobal static fferpcore.SubscriptionDescription.Mapping createFieldMapping(SObjectField targetField, List<String> messageKey) Create a FieldMapping that takes one message key to populate the target field with. Input Parameters
Return ValueA mapping that can be used in a SubscriptionDescriber. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PSAResourceUpdateSubscriptionDescriber extends fferpcore.SubscriptionDescriber { private static final SObjectType SOBJECT_TYPE = PSAFakeResource__c.SObjectType; public static final String NAME_KEY = 'Name'; public static final String ADDRESS_KEY = 'Address'; public static final String ADDRESS_LINE_1_KEY = 'Line 1'; public static final String ADDRESS_LINE_2_KEY = 'Line 2'; public static final String ADDRESS_LINE_3_KEY = 'Line 3'; public static final String ADDRESS_LINE_4_KEY = 'Line 4'; public static final String TELEPHONE_KEY = 'Telephone'; public static final String[] ADDRESS_LINE_1_PATH = new String[]{ADDRESS_KEY, ADDRESS_LINE_1_KEY}; public static final String[] ADDRESS_LINE_2_PATH = new String[]{ADDRESS_KEY, ADDRESS_LINE_2_KEY}; public static final String[] ADDRESS_LINE_3_PATH = new String[]{ADDRESS_KEY, ADDRESS_LINE_3_KEY}; public static final String[] ADDRESS_LINE_4_PATH = new String[]{ADDRESS_KEY, ADDRESS_LINE_4_KEY}; public override fferpcore.SubscriptionDescription describe() { return new fferpcore.SubscriptionDescription(SOBJECT_TYPE, getStaticMappings()); } private List<fferpcore.SubscriptionDescription.Mapping> getStaticMappings() { return new List<fferpcore.SubscriptionDescription.Mapping> { fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Name, NAME_KEY), fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Phone__c, TELEPHONE_KEY), fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Address1__c, ADDRESS_LINE_1_PATH), fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Address2__c, ADDRESS_LINE_2_PATH), fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Address3__c, ADDRESS_LINE_3_PATH), fferpcore.SubscriptionDescription.createFieldMapping(PSAFakeResource__c.Address4__c, ADDRESS_LINE_4_PATH), }; } } fferpcore.SubscriptionDescription.ApplyMappingRequestglobal inherited sharing abstract class ApplyMappingRequest A request to apply a mapping to a record. A fferpcore.SubscriptionDescription.Mapping object accepts an ApplyMappingRequest in the performImmediateActions method. The request contains the record to be updated as well as the message. Methods
getRecordglobal abstract SObject getRecord() Returns the record being worked on. Return ValueThe record being worked on. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. /** * Simple class that only ever updates one field on ExampleObject */ public abstract class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { public static List<String> COST_KEY = new List<String>{"Cost"}; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { fferpcore.SubscriptionDescriptionValue value = request.getValue(COST_KEY); // If value is null then the path is not present in the message. If the message explicitly states a null value // then value.getValue() will be null. if(value != null) { //get the object to update ExampleObject record = request.getRecord(); //Update the record with the value from the message record.Cost__c = value.getValue()); } } } isFirstRequestForRecordglobal abstract Boolean isFirstRequestForRecord() When messages are sent in bulk, ApplyMappingRequests are grouped by record before being provided to the mapping. For example, a mapping might handle two messages for record A, then one message for record B, then five messages for record C. This method can be used to find if we have moved on to a different record. When messages are sent synchronously they are handled one at a time and this method will always return true. Return ValueTrue if this is the first request for the given record. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { ... public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { if (request.isFirstRequestForRecord()) { //Can execute code you only want to run once per record, or when you change from one record to the next. ExampleObject recordBeingUpdated = request.getRecord(); ... } //Code that you want to run for every message ... } } isLastRequestForRecordglobal virtual Boolean isLastRequestForRecord() Return ValueTrue if this is the last request for the given record. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { ... public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { //Code that you want to run for every message ... if (request.isLastRequestForRecord()) { //Can modify the final record in someway which we only want to do on the final request ExampleObject recordBeingUpdated = request.getRecord(); ... } } } getMessageglobal abstract Map<String, Object> getMessage() Returns the deserialized messageBody. The getValue method has been provided for easy access to a specific part of the message. Return ValueThe deserialized message being worked on. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. fferpcore.SubscriptionDescription.ApplyMappingRequest request = getRequest(); //The request we are handling. Map<String, Object> body = request.getMessage(); //Can now access all the data in the message. //Note that request.getMessage() is equivalent to (Map<String, Object>) request.getValue(new List<String>{}).getValue(); //I.e. getting the value of the root node. getValueglobal abstract fferpcore.SubscriptionDescription.Value getValue(List<String> jsonPath) Return a fferpcore.SubscriptionDescription.Value containing the value for the given path in the messages, or null if the path is not present in the message. If the path is present with an explicit null value then a fferpcore.SubscriptionDescription.Value containing null is returned. Input Parameters
Return ValueThe value if found, or null if missing. Sample DataList<String> jsonPath: ["Department", "AddressLine1"] Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. String serializedMessageBody = '{"Size": "Large", "Vehicles": {"Car": "Honda", "Bike": "BMX"}, "Flowers": null }'; fferpcore.SubscriptionDescription.ApplyMappingRequestImpl request = ...; //a request for a message with 'messageBody' System.assertEquals('Large', request.getValue(new List<String>{'Size'}).getValue()); System.assertEquals('Honda', request.getValue(new List<String>{'Vehicles', 'Car'}).getValue()); System.assertEquals('BMX', request.getValue(new List<String>{'Vehicles', 'Bike'}).getValue()); System.assertEquals(null, request.getValue(new List<String>{'Vehicles', 'Tractor'}); System.assertEquals(null, request.getValue(new List<String>{'Smells'}); System.assertEquals(null, request.getValue(new List<String>{'Flowers'}).getValue()); respondErrorglobal abstract void respondError(fferpcore.ErpErrorBody error) Marks the message with an error. If the error logging is set to MessagingSettingsService.LOGGING_LEVEL_ERROR or MessagingSettingsService.LOGGING_LEVEL_ALL, the message is marked with an error that you can investigate. After this method is called, processing on the record will be stopped and changes will not be saved. All other messages for that record will be marked in error. Input Parameters
Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { public static List<String> COST_KEY = new List<String>{'Cost'}; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { try { request.getRecord().put('TargetField__c', request.getValue('MessageKey').getValue()); } catch (Exception e) { request.respondError(new fferpcore.ErpErrorBody(e.getMessage())); } } } fferpcore.SubscriptionDescription.Valueglobal inherited sharing class Value A holder for a value, so we can tell the difference between null and missing. MethodsValueglobal Value(Object value) Constructs a Value object wrapping the provided parameter. Input Parameters
getValueglobal Object getValue() Return ValueReturns the value wrapped by this object, or null to indicate the key was not present in the message. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. /** * Simple class that only ever updates one field on ExampleObject */ public class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { public static List<String> COST_KEY = new List<String>{'Cost'}; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { fferpcore.SubscriptionDescriptionValue value = request.getValue(COST_KEY); if(value != null) { //get the object to update ExampleObject record = request.getRecord(); //Update the record with the value from the message record.Cost__c = value.getValue()); } } } fferpcore.SubscriptionDescription.Mappingglobal inherited sharing abstract class Mapping A strategy to marshal data from the fferpcore.Message to the target record. Any concrete Mapping implementation must extend this class. Methods
getAdditionalSelectionsglobal virtual Set<String> getAdditionalSelections() These selections are passed to the fferpcore.LinkingCorrelationStrategy to be used when querying the SObject Records. Names must be fully qualified. The selections can include relationship selections and subselects, but beware of LIMITs when doing this. The default implementation returns null. Return ValueSet of any additional selections required by the mapping. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PersonNameMapping extends fferpcore.SubscriptionDescription.Mapping { //Message contains keys FirstName, MiddleNames, LastName public static List<String> firstNameKey = new List<String>{'FirstName'}; public static List<String> middleNameKey = new List<String>{'MiddleNames'}; public static List<String> lastNameKey = new List<String>{'LastName'}; //Target object has two name fields private static String forenamesTargetField = 'Forenames__c'; private static String surnameTargetField = 'Surname__c'; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { //Use string manipulation to populate two name fields from three. ... } public override Set<String> getAdditionalSelections() { //If our calculation requires data from other tables or other fields on this table that aren't updated, //we need to identify them here. return new Set<String>{'Forenames__c', 'Surname__c', 'DateOfBirth__c'}; } public override Set<String> getTargetFields() { return new Set<String>{'Forenames__c', 'Surname__c'}; } public override List<List<String>> getMessageKeys() { return new List<List<String>>{firstNameKey, middleNameKey, lastNameKey}; } } performImmediateActionsglobal abstract void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) Applies information from the fferpcore.Message to the Record. This is called before performBulkActions. This method must be overridden by any class that extends SubscriptionDescription.Mapping. Input Parameters
Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. /** * Simple class that only ever updates one field on ExampleObject */ public class ExampleMapping extends fferpcore.SubscriptionDescription.Mapping { public static List<String> COST_KEY = new List<String>{'Cost'}; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { fferpcore.SubscriptionDescription.Value value = request.getValue(COST_KEY); if(value != null) { //get the object to update ExampleObject record = request.getRecord(); //Update the record with the value from the message record.Cost__c = value.getValue(); } } } performBulkActionsglobal virtual void performBulkActions() Called after all messages have been processed, to allow the Mapping to perform any bulk actions. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class FatalisticMapping extends fferpcore.SubscriptionDescription.Mapping { private boolean fatalErroroccurred = false; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { //Handle requests, and potentially set fatalErroroccurred if something goes wrong. If something has gone wrong we can //still fail messages that we have already successfully processed. ... } public override void performBulkActions() { if (fatalErroroccurred) { throw new Exception('A fatal error occurred. Failing all messages.'); } } } getTargetFieldsglobal abstract Set<String> getTargetFields() Mappings must override this method to indicate which fields they can affect. Return ValueThe set of field names on the target record populated by this Mapping. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PersonNameMapping extends fferpcore.SubscriptionDescription.Mapping { //Message contains keys FirstName, MiddleNames, LastName public static List<String> firstNameKey = new List<String>{'FirstName'}; public static List<String> middleNameKey = new List<String>{'MiddleNames'}; public static List<String> lastNameKey = new List<String>{'LastName'}; //Target object has two name fields private static String forenamesTargetField = 'Forenames__c'; private static String surnameTargetField = 'Surname__c'; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { //Use string manipulation to populate two name fields from three. ... } public override Set<String> getAdditionalSelections() { //If our calculation requires data from other tables or other fields on this table that aren't updated, //we need to identify them here. return new Set<String>{'Forenames__c', 'Surname__c', 'DateOfBirth__c'}; } public override Set<String> getTargetFields() { return new Set<String>{'Forenames__c', 'Surname__c'}; } public override List<List<String>> getMessageKeys() { return new List<List<String>>{firstNameKey, middleNameKey, lastNameKey}; } } getMessageKeysglobal abstract List<List<String>> getMessageKeys() Mappings must override this method to indicate which fields they use from the message. Return ValueThe message keys read by this Mapping. Sample Code//Note: This sample code is for demonstration purposes only. It is not intended for //use in a production environment, is not guaranteed against defects or errors, and //is in no way optimized or streamlined. public class PersonNameMapping extends fferpcore.SubscriptionDescription.Mapping { //Message contains keys FirstName, MiddleNames, LastName public static List<String> firstNameKey = new List<String>{'FirstName'}; public static List<String> middleNameKey = new List<String>{'MiddleNames'}; public static List<String> lastNameKey = new List<String>{'LastName'}; //Target object has two name fields private static String forenamesTargetField = 'Forenames__c'; private static String surnameTargetField = 'Surname__c'; public override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) { //Use string manipulation to populate two name fields from three. ... } public override Set<String> getAdditionalSelections() { //If our calculation requires data from other tables or other fields on this table that aren't updated, //we need to identify them here. return new Set<String>{'Forenames__c', 'Surname__c', 'DateOfBirth__c'}; } public override Set<String> getTargetFields() { return new Set<String>{'Forenames__c', 'Surname__c'}; } public override List<List<String>> getMessageKeys() { return new List<List<String>>{firstNameKey, middleNameKey, lastNameKey}; } } disableFieldsglobal virtual void disableFields(Set<String> fieldNames) Allows mappings to be superseded by providing the set of fields that later mappings write to. A Mapping must not write to a field if it was provided in this set. Input Parameters
isDisabledglobal virtual Boolean isDisabled() Return ValueTrue if the result of disableFields() is that this mapping is completely disabled. fferpcore.SubscriptionDescription.FieldMappingglobal inherited sharing class FieldMapping extends Mapping If the value is present but null, then null is applied. If the value is absent then no action is taken. This class extends fferpcore.SubscriptionDescription.Mapping Methods
FieldMappingglobal FieldMapping(SObjectField targetField, List<String> messageKey) Constructs a FieldMapping that populates targetField with data from the part of the message accessed by messageKey. Input Parameters
FieldMappingglobal FieldMapping(SObjectField targetField, String messageKey) Constructs a FieldMapping that populates targetField with data from the part of the message accessed by messageKey. This method is a convenience for calling: new SubscriptionDescription.FieldMapping(targetField, new List<String>{messageKey}). Input Parameters
getAdditionalSelectionsglobal override Set<String> getAdditionalSelections() Implementation of SubscriptionDescription.Mapping.getAdditionalSelections(). This method is invoked by the fferpcore.SubscriptionDescription and should not be called directly. Return ValueAny fields that will be updated and therefore need to be queried. performImmediateActionsglobal override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) Implementation of SubscriptionDescription.Mapping.performImmediateActions(SubscriptionDescription.ApplyMappingRequest request). This method is invoked by the fferpcore.SubscriptionDescription and should not be called directly. Perform any mapping functionality on the given request only. Input Parameters
getTargetFieldsglobal override Set<String> getTargetFields() Implementation of SubscriptionDescription.Mapping.getTargetFields(). This method is invoked by the SubscriptionDescriptionController and should not be called directly. Return ValueAny fields that will be updated. getMessageKeysglobal override List<List<String>> getMessageKeys() Implementation of SubscriptionDescription.Mapping.getMessageKeys(). This method is invoked by the SubscriptionDescriptionController and should not be called directly. Return ValueAny message keys that will be used. fferpcore.SubscriptionDescription.LinkingFieldMappingglobal inherited sharing class LinkingFieldMapping extends Mapping Mapping that maintains Linking Fields based on information in the Message. See fferpcore.LinkingFieldManager for details on the fields maintained. Often these LinkControl Messages are received in response to an outgoing message and are used to indicate whether or not the message was successfully handled in the other product. This class extends fferpcore.SubscriptionDescription.Mapping Methods
LinkingFieldMappingglobal LinkingFieldMapping(SObjectType recordType, List<String> linkControlPath) Constructs a LinkingFieldMapping to update the specified record type. Input Parameters
LinkingFieldMappingglobal LinkingFieldMapping(SObjectType recordType, String linkControlKey) This method is provided as a shorthand for calling: new SubscriptionDescription.LinkingFieldMapping(recordType, new List<String>{linkControlKey}) Input Parameters
getAdditionalSelectionsglobal override Set<String> getAdditionalSelections() Implementation of SubscriptionDescription.Mapping.getAdditionalSelections(). This method is invoked by the fferpcore.SubscriptionDescription and should not be called directly. Return ValueAny fields that will be updated and therefore need to be queried. performImmediateActionsglobal override void performImmediateActions(fferpcore.SubscriptionDescription.ApplyMappingRequest request) Implementation of SubscriptionDescription.Mapping.performImmediateActions(SubscriptionDescription.ApplyMappingRequest request). This method is invoked by the fferpcore.SubscriptionDescription and should not be called directly. Perform any mapping functionality on the given request only. Input Parameters
getTargetFieldsglobal override Set<String> getTargetFields() Implementation of SubscriptionDescription.Mapping.getTargetFields(). This method is invoked by the SubscriptionDescriptionController and should not be called directly. Return ValueAny fields that will be updated. getMessageKeysglobal override List<List<String>> getMessageKeys() Implementation of SubscriptionDescription.Mapping.getMessageKeys(). This method is invoked by the SubscriptionDescriptionController and should not be called directly. Return ValueAny message keys that will be used. |