ESM Listener Overview
Data Card Listeners in Matrix42 Professional
Data card listeners are a mechanism for implementing business logic within Matrix42 Professional (ESM). They are designed to respond to specific events within M42 Pro templates, allowing for automated actions based on defined conditions. When a template has a listener, all data cards which are created can trigger the listener when they are saved:

Execution order: see the article “Save Process in M42 Pro”.
Configuring Data Card Listeners
Data card listeners are configured using XML files that define the listener's properties and behaviors. The configuration process involves:
- Creating XML Configuration: The listener’s behavior and conditions are defined within an XML file. This file specifies how the listener will interact with the data card events.
- Importing to M42 Pro Template: Once the XML configuration is created, it must be imported into the relevant M42 Pro template. This step activates the listener within the template.
- Adjust the Order of Listeners: Pre saves run first in their sequential order, post saves then in the same way. There is relevance on which gets run first. For example, put validator listeners first on pre save. Move the listeners to reflect the correct running order.
Listeners can also be exported as part of the overall M42 Pro configuration XML, allowing for easy replication and deployment across different environments.
Listener Functionality and Trigger Settings
Each M42 Pro template can contain one or more listeners. When the data card associated with a template is saved, any listener registered to that template is notified of the event.
Listeners are configured to respond to specific events based on their Trigger Settings, which can be either:
- Pre-Save Trigger: The listener activates before the data card is saved. It only modifies the source data card.
-
Post-Save Trigger: The listener activates after the data card is saved. It only modifies other data cards.
- Unless there is a specific need to modify a source datacard and intentionally trigger a second save cycle on that. Example situation is to switch a status value on ticket with a listener, but wanting to trigger DataCardHiddenState and ValueChange handlers to reflect the change when doing it.

Upon being triggered, the listener evaluates whether it should respond to the event. This decision is based on defined Source Conditions, which are criteria set within the listener’s configuration. The source conditions determine whether the source data card (i.e., the saved data card) matches the parameters required for the listener to act. Similarly, to target changes to specific target data card(s) of another template, target conditions in the beginning of the action chain section determine the target(s).
- Multiple Listeners: A single template can support multiple listeners, each responding to different triggers or conditions.
- Conditional Logic: Listeners only react to events if the specified conditions are met, allowing for precise control over when and how business logic is applied.
Best Practices
Be careful of: Creating constructions where you update same data card several times with different post save listeners. Conflicts between listeners and other handler based functions.
General
Listener XML can be commented with a <!-- foobar --> section, but the comments are removed once listener is imported to M42 Pro (I.e., commenting listeners is useful only if listener "master data" is stored somewhere else).
- You can add more than one Action chain
- For example, if you would need to touch multiple different target templates datacards in a post save listener, based on the same source conditions
- Avoid using deep/multilevel combined AND-OR-AND.. conditions in order to keep the listener code more understandable and instead try to either simplify the conditions or do the more complex logic in expression code in a helper attribute
- Hint: the expression helper attribute can be set as a multivalue string to enable multiple values to be set in one helper attribute for the listeners to use as different triggers
XML
- Traditional method of creating business logic / running non-field based automatic functionalities on a certain template.
Configured by creating an appropriate XML configuration.- Listeners are taken into use by importing this XML to an M42 Pro template.
- Listeners can be exported as a part of M42 Pro configuration XML.
- Sequencing the order is a thing to consider.
- First pre-saves in order, then post-saves in order per template.
- Pre-save listeners:
- Run and checked on every datacard save, after all handlers except AutoMailSender and TargetDeleter.
- Used on datacards of “this” template.
- Post-save listeners:
- Usually used on datacards of other templates related to the data card of “this” template.
- Can include target conditions.
- Can re-trigger a sequence on another template.
- Handlers on the target template are run after these
Pushing string data to a reference field with change or copy action might not work.
- Traditionally you would need to push the entityid if you want to link to certain datacard.
- Copying reference to reference should work.
- Easier to link references with expressions in most cases, but when doing transformations for example you might need to use listeners to do some references afterwards.
Be careful of:
- Creating constructions where you update same datacard several times with different post save listeners.
- Conflicts between listeners and other handler based functions.
- Deciding the running order .
REMEMBER: You need to update statistical datetime tags with the listener if you are closing datacards with datechecker – listener automation. This method is a beginner way of doing it incompletely and in a hard coded way which is not flexible in the long run. Note that this is not possible in a situation where you would need to create ValueChanges. A more flexible, but complicated way, is to use post save and then trigger the appropriate handlers (which may then vary with their configuration after the listeners would have been created).
Importing a Listener
When importing a listener, M42 Pro validates the contents and structure of XML:
- Error message given is often uninterpretable, such as “XML cannot be empty”.
- Check that you have closed all XML tags </> and all attribute codes are correct etc.
- Review listener documentation, that you are not trying to do stuff that is not possible, such as comparing text fields or external reference fields.
- Try to remove or modify suspicious components and attempt without them.
Using Logging and DEBUG
- You could try to extract further information by opening some of these classes for runtime logging and set DEBUG level when trying to import the XML
- com.bitmount.equipment.action.TemplateListenerImport check this in most cases
- com.bitmount.equipment.importing.ValidatingEntityXMLImporter
- com.efecte.datamodel.entity.listener.importing.XMLActionChainImporter
- com.efecte.datamodel.entity.listener.importing.XMLDataCardListenerImporter
- com.efecte.datamodel.entity.listener.importing.XMLSourceConditionsImporter
- com.efecte.datamodel.entity.listener.importing.XMLTemplatesDataCardListenerImporter
- Remember to set logging back to INFO level after fixing the listeners or you will produce huge amounts of logfiles!!
- Listener imported successfully but is not working the way to would like
- Check runtime logs and set DEBUG level and you should see what triggers and what doesn’t
- Source conditions
- com.efecte.datamodel.entity.listener.condition.(?????)
- Target conditions
- com.efecte.datamodel.entity.action.chain.condition.(?????)
- Actions
- com.efecte.datamodel.entity.action.implementations.(?????)
- (?????) = each XML component
- Source conditions
- Remember to set logging back to INFO level after fixing the listeners or you will produce huge amounts of logfiles!!
- Platform settings for listeners
- datacard.listeners.run.as.root
Ticket Status Change
If you change a ticket status value with listener, you want to consider:
- Statistics timestamps gets updated accordingly
- ValueChange history of status gets updated accordingly
- Possibly hide / set visible of the datacard gets updated accordingly
- If you set a field with pre-save listener, don’t expect an expression to run based on it unless you do it inside listener!
- If you delete an attribute related to a listener, listener gets broken
- Listener must be deleted to get configuration exported
- In most cases can be fixed by re-creating the deleted attribute with the same attribute code
GuiEdit
GuiEdit –condition does not work in these scenarios:
- ValueButton handler clicked in view mode
- TicketReservation handler clicked in view mode
- EntityStateMail sent in view mode
- WorklogHandler comment added in view mode
Always add GuiEdit when doing AlwaysFailDataCardAction to make sure integration edits would not get blocked by it and have these always as the first listeners in the order.
- Via the admin UI you can only see the names and sequence of listeners and you will need to export the entire configuration in XML to investigate the actual functionalities of listeners
Listener Order
Keep listeners in running order: Pre saves are run first, then post saves.
Naming
Keep a consistent naming method!
- Consider naming them neatly and informatively, for example including most of these:
- Presave or postsave
- Order number
- Short description
- what it does
- what/why it triggers
- If multiple people administering or developing
- Date when modified
- Maybe even initials or abbreviation of who modified
Examples:
- presave.Copy development team if value empty and service selected-09.10.2019-AA
- presave.SET Resolved within SLA_04052021_MK
- postsave.4. Set references if incoming email generated-04.05.2017
Listeners – Current value true vs Current value false
current_value false = Old / Previous value
current_value true = New / Current value
<source_condition>
<value>
<attribute>
<code>status</code>
<current_value>false</current_value>
</attribute>
<operator>=</operator>
<compared_value>01 - New</compared_value>
</value>
</source_condition>
<source_condition>
<value>
<attribute>
<code>status</code>
<current_value>true</current_value>
</attribute>
<operator>=</operator>
<compared_value>02 - Solving</compared_value>
</value>
</source_condition>
Table of Contents