Skip to main content

Operation Events Resolver

In applications that use SOKit, an Operation Events Resolver is used to configure which events should be executed for a specific operation before or after it runs.

While the actual execution of events is handled by the framework, this resolver is responsible for declaring what events should run for each operation.

Below is a basic implementation of a resolver for the CompanyDocument. It defines which pre-events should run depending on the current operation. This resolver implements a generated interface CompanyOperationEventsResolver.

EventsResolver.java
package com.dev.registration.company.flow;

import com.dev.registration.company.data.CompanyEntity;
import com.dev.registration.company.document.CompanyDocument;
import com.dev.registration.company.document.Operations;
import com.dev.registration.company.document.StartOperations;
import com.dev.registration.company.document.States;
import com.dev.registration.company.document.document.events.CompanyOperationEventsResolver;
import com.dev.registration.company.flow.events.ValidateRemark;
import com.dev.registration.company.flow.events.ValidateShare;
import com.dev.registration.company.flow.events.ValidateVatNumber;

import com.strategyobject.sokit.extensions.document.DocumentResolverTransaction;
import com.strategyobject.sokit.extensions.document.DocumentTransaction;
import com.strategyobject.sokit.extensions.document.api.annotations.DocumentAware;

@DocumentAware(CompanyDocument.class)
public class EventsResolver implements CompanyOperationEventsResolver {

@Override
public void resolve(
DocumentResolverTransaction<States, StartOperations, Operations, String, CompanyEntity>
transaction) {
final var op = transaction.operation();
if (op == Operations.SUBMIT) {
transaction.addPreEvent(ValidateShare.class);
}
if (op == Operations.REJECT) {
transaction.addPreEvent(ValidateRemark.class);
}

if (op == Operations.APPROVE) {
transaction.addPreEvent(ValidateVatNumber.class);
}
}

// Called only if there are more than one state
@Override
public States resolveEndState(
DocumentTransaction<States, StartOperations, Operations, String, CompanyEntity> transaction) {
return null;
}
}

The key concepts of the code snipped above are:

  • @DocumentAware(CompanyDocument.class): binds this resolver to a specific document.
  • resolve(...): used to register pre-events (in this case), for specific operations.
  • resolveEndState(...): only used when an operation can lead to multiple end states. In this example, it's not needed and returns null.

Inside the resolve method, we inspect the current operation using transaction.operation() and dynamically register pre-events based on the context. In particular, this class serves as the wiring layer that connects operations like APPROVE or REJECT to validation events such as ValidateVatNumber, ValidateShare or ValidateRemark that we will show in the next sections. This strategy will ensure that operations are connected to the right validation and execution flow.