
org.openremote.manager.rules.RulesBuilder Maven / Gradle / Ivy
/*
* Copyright 2018, OpenRemote Inc.
*
* See the CONTRIBUTORS.txt file in the distribution for a
* full listing of individual contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.openremote.manager.rules;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.core.RuleBuilder;
import java.util.ArrayList;
import java.util.List;
/**
* Call {@link #add()} to add rules.
*/
public class RulesBuilder {
@FunctionalInterface
public interface Condition {
Object evaluate(RulesFacts facts);
}
public interface Action {
void execute(RulesFacts facts);
}
public static class Builder {
protected String name = org.jeasy.rules.api.Rule.DEFAULT_NAME;
protected String description = org.jeasy.rules.api.Rule.DEFAULT_DESCRIPTION;
protected int priority = org.jeasy.rules.api.Rule.DEFAULT_PRIORITY;
protected Condition condition = facts -> false;
protected Action action = facts -> {
};
/**
* Required (short) rule name.
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* Optional longer description.
*/
public Builder description(String description) {
this.description = description;
return this;
}
/**
* Lower priority rules execute before higher priority rules.
* Default priority is Integer.MAX_VALUE - 1
.
*/
public Builder priority(int priority) {
this.priority = priority;
return this;
}
public Builder when(Condition condition) {
this.condition = condition;
return this;
}
public Builder then(Action action) {
this.action = action;
return this;
}
}
final protected List builders = new ArrayList<>();
public Builder add() {
Builder builder = new Builder();
builders.add(builder);
return builder;
}
public Rule[] build() {
List rules = new ArrayList<>();
// Maintain rule order by adjusting priority for each rule within the ruleset
int i = 1;
for (Builder builder : builders) {
int priority = (builder.priority < Integer.MAX_VALUE - 1) ? builder.priority : Integer.MAX_VALUE - 10000 + i;
i++;
Rule rule = new RuleBuilder()
.name(builder.name)
.description(builder.description)
.priority(priority)
.when(facts -> {
Object result;
try {
result = builder.condition.evaluate((RulesFacts) facts);
} catch (Exception ex) {
throw new RuntimeException("Error evaluating condition of rule '" + builder.name + "': " + ex.getMessage());
}
if (result instanceof Boolean) {
return (boolean)result;
} else {
throw new IllegalArgumentException("Error evaluating condition of rule '" + builder.name + "': result is not boolean but " + result);
}
})
.then(facts -> builder.action.execute((RulesFacts) facts))
.build();
rules.add(rule);
}
return rules.toArray(new Rule[rules.size()]);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy