All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hisp.dhis.rules.RuleEngine Maven / Gradle / Ivy
package org.hisp.dhis.rules;
import org.hisp.dhis.antlr.Parser;
import org.hisp.dhis.rules.models.*;
import org.hisp.dhis.rules.parser.expression.CommonExpressionVisitor;
import org.hisp.dhis.rules.utils.RuleEngineUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.Callable;
import static org.hisp.dhis.antlr.AntlrParserUtils.castClass;
import static org.hisp.dhis.rules.parser.expression.ParserUtils.FUNCTION_FOR_DESCRIPTION;
// ToDo: logging
public final class RuleEngine
{
private static final Logger log = LoggerFactory.getLogger( RuleEngine.class.getName() );
@Nonnull
private final RuleEngineContext ruleEngineContext;
@Nonnull
private final List ruleEvents;
@Nullable
private final RuleEnrollment ruleEnrollment;
@Nullable
private TriggerEnvironment triggerEnvironment;
RuleEngine( @Nonnull RuleEngineContext ruleEngineContext,
@Nonnull List ruleEvents,
@Nullable RuleEnrollment ruleEnrollment, @Nullable TriggerEnvironment triggerEnvironment )
{
this.ruleEngineContext = ruleEngineContext;
this.ruleEvents = ruleEvents;
this.ruleEnrollment = ruleEnrollment;
this.triggerEnvironment = triggerEnvironment;
}
@Nonnull
public List events()
{
return ruleEvents;
}
@Nullable
public RuleEnrollment enrollment()
{
return ruleEnrollment;
}
@Nullable
public TriggerEnvironment triggerEnvironment()
{
return triggerEnvironment;
}
@Nonnull
public RuleEngineContext executionContext()
{
return ruleEngineContext;
}
@Nonnull
public Callable> evaluate( @Nonnull RuleEvent ruleEvent )
{
return evaluate( ruleEvent, ruleEngineContext.rules() );
}
@Nonnull
public Callable> evaluate( @Nonnull RuleEvent ruleEvent, @Nonnull List rulesToEvaluate )
{
if ( ruleEvent == null )
{
throw new IllegalArgumentException( "ruleEvent == null" );
}
Map valueMap = RuleVariableValueMapBuilder.target( ruleEvent )
.ruleVariables( ruleEngineContext.ruleVariables() )
.ruleEnrollment( ruleEnrollment )
.triggerEnvironment( triggerEnvironment )
.ruleEvents( ruleEvents )
.constantValueMap( ruleEngineContext.constantsValues() )
.build();
return new RuleEngineExecution( ruleEvent, rulesToEvaluate, valueMap, ruleEngineContext.supplementaryData() );
}
@Nonnull
public Callable> evaluate( @Nonnull RuleEnrollment ruleEnrollment,
@Nonnull List rulesToEvaluate )
{
if ( ruleEnrollment == null )
{
throw new IllegalArgumentException( "ruleEnrollment == null" );
}
Map valueMap = RuleVariableValueMapBuilder.target( ruleEnrollment )
.ruleVariables( ruleEngineContext.ruleVariables() )
.triggerEnvironment( triggerEnvironment )
.ruleEvents( ruleEvents )
.constantValueMap( ruleEngineContext.constantsValues() )
.build();
return new RuleEngineExecution( ruleEnrollment, rulesToEvaluate, valueMap, ruleEngineContext.supplementaryData() );
}
@Nonnull
public Callable> evaluate()
{
RuleVariableValueMap valueMap = RuleVariableValueMapBuilder.target()
.ruleVariables( ruleEngineContext.ruleVariables() )
.ruleEnrollment( ruleEnrollment )
.triggerEnvironment( triggerEnvironment )
.ruleEvents( ruleEvents )
.constantValueMap( ruleEngineContext.constantsValues() )
.multipleBuild();
return new RuleEngineMultipleExecution( ruleEngineContext.rules(), valueMap,
ruleEngineContext.supplementaryData() );
}
@Nonnull
public Callable> evaluate( @Nonnull RuleEnrollment ruleEnrollment )
{
return evaluate( ruleEnrollment, ruleEngineContext.rules() );
}
@Nonnull
public RuleValidationResult evaluate( String expression )
{
// Rule condition expression should be evaluated against Boolean
return getExpressionDescription( expression, Boolean.class );
}
@Nonnull
public RuleValidationResult evaluateDataFieldExpression( String expression )
{
// Rule action data field field should be evaluated against all i.e Boolean, String, Date and Numerical value
return getExpressionDescription( expression, null );
}
private RuleValidationResult getExpressionDescription( String expression, Class> klass )
{
Map itemDescriptions = new HashMap<>();
CommonExpressionVisitor visitor = CommonExpressionVisitor.newBuilder()
.withIteamStore( ruleEngineContext.getDataItemStore() )
.withFunctionMethod( FUNCTION_FOR_DESCRIPTION )
.withFunctionMap( RuleEngineUtils.FUNCTIONS )
.withItemDescriptions( itemDescriptions )
.validateAndBuildForDescription();
RuleValidationResult result;
try
{
if ( klass == null )
{
Parser.visit( expression, visitor );
}
else
{
castClass( klass, Parser.visit( expression, visitor ) );
}
String description = expression;
for ( Map.Entry entry : itemDescriptions.entrySet() )
{
description = description.replace( entry.getKey(), entry.getValue() );
}
result = RuleValidationResult.builder().isValid( true ).description( description ).build();
}
catch ( IllegalStateException e )
{
result = RuleValidationResult.builder().isValid( false )
.errorMessage( e.getMessage() )
.exception( e )
.build();
log.debug( e.getMessage(), e );
}
return result;
}
public static class Builder
{
@Nonnull
private final RuleEngineContext ruleEngineContext;
@Nullable
private List ruleEvents;
@Nullable
private RuleEnrollment ruleEnrollment;
@Nullable
private TriggerEnvironment triggerEnvironment;
Builder( @Nonnull RuleEngineContext ruleEngineContext )
{
this.ruleEngineContext = ruleEngineContext;
}
@Nonnull
public Builder events( @Nonnull List ruleEvents )
{
if ( ruleEvents == null )
{
throw new IllegalArgumentException( "ruleEvents == null" );
}
this.ruleEvents = Collections.unmodifiableList( new ArrayList<>( ruleEvents ) );
return this;
}
@Nonnull
public Builder enrollment( @Nonnull RuleEnrollment ruleEnrollment )
{
if ( ruleEnrollment == null )
{
throw new IllegalArgumentException( "ruleEnrollment == null" );
}
this.ruleEnrollment = ruleEnrollment;
return this;
}
@Nonnull
public Builder triggerEnvironment( @Nonnull TriggerEnvironment triggerEnvironment )
{
if ( triggerEnvironment == null )
{
throw new IllegalArgumentException( "triggerEnvironment == null" );
}
this.triggerEnvironment = triggerEnvironment;
return this;
}
@Nonnull
public RuleEngine build()
{
if ( ruleEvents == null )
{
ruleEvents = Collections.unmodifiableList( new ArrayList() );
}
return new RuleEngine( ruleEngineContext, ruleEvents, ruleEnrollment, triggerEnvironment );
}
}
}