
org.swblocks.decisiontree.DecisionTree Maven / Gradle / Ivy
/*
* This file is part of the swblocks-decisiontree library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.swblocks.decisiontree;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import org.swblocks.decisiontree.domain.DecisionTreeRuleSet;
import org.swblocks.decisiontree.tree.DecisionTreeFactory;
import org.swblocks.decisiontree.tree.DecisionTreeType;
import org.swblocks.decisiontree.tree.TimeSlicedRootNode;
import org.swblocks.decisiontree.tree.TreeNode;
import org.swblocks.jbl.eh.EhSupport;
import org.swblocks.jbl.eh.Result;
import org.swblocks.jbl.util.retry.ActionRetrier;
import org.swblocks.jbl.util.retry.Retrier;
/**
* Main accessor class for operating on a decision tree.
*/
public class DecisionTree {
protected final DecisionTreeRuleSet ruleSet;
private final Loader loader;
private final DecisionTreeType type;
private TreeNode node;
protected DecisionTree(final Loader loader,
final DecisionTreeType type,
final DecisionTreeRuleSet decisionTreeRuleSet) {
this.loader = loader;
this.type = type;
this.ruleSet = decisionTreeRuleSet;
initialiseRootNode();
}
/**
* Creates an instance of the {@link DecisionTree} with the specified {@link Loader}
*
* @param loader {@link Loader} to use to instantiate the underlying {@link DecisionTreeRuleSet}
* @param type {@link DecisionTreeType} Type of evaluation tree to create.
* @return instance of {@link DecisionTree}
*/
public static DecisionTree instanceOf(final Loader loader,
final DecisionTreeType type) {
final ActionRetrier retrier = Retrier.createNonRetrier();
final Result result = retrier.run(loader, booleanResult -> false);
EhSupport.checkResult(result);
return new DecisionTree(loader, type, result.getData());
}
/**
* Creates the holder to populate the search values for the Decision Tree evaluation.
*
* @return {@link Input}
*/
public Input createInputs() {
return Input.create(this.ruleSet.getName(), this.ruleSet.getWeightedDrivers());
}
/**
* Creates the holder and populates the search values for the Decision Tree evaluation.
*
* @param searchValues vararg search values in weighted order.
* @return {@link Input}
*/
public Input createInputs(final String... searchValues) {
return Input.create(this.ruleSet.getName(), this.ruleSet.getWeightedDrivers(), searchValues);
}
/**
* Creates the holder and populates the search values for the Decision Tree evaluation.
*
* @param evaluationDate date of evaluation for rules.
* @param searchValues vararg search values in weighted order.
* @return {@link Input}
*/
public Input createInputs(final Instant evaluationDate, final String... searchValues) {
if (evaluationDate == null) {
return createInputs(searchValues);
}
return Input.create(this.ruleSet.getName(), this.ruleSet.getWeightedDrivers(), evaluationDate, searchValues);
}
/**
* Evaluates the {@link Input} data against the Decision Tree.
*
* Decision tree root nodes are cached in this class when evaluating single node trees or dated time trees. The
* time sliced root node caches the individual time sliced trees separately and so the caching is delegated to the
* {@link TimeSlicedRootNode} class.
*
* @param input Search values to be used.
* @return {@link Optional} Output holder for the results.
*/
public Optional getEvaluationFor(final Input input) {
final TreeNode rootNodeToTree = this.node;
final Optional result = Evaluator.evaluate(input.getEvaluationInputs(), input.getEvaluationDate(),
rootNodeToTree);
if (result.isPresent()) {
return Optional.of(new OutputResults(this.ruleSet.getRules().get(result.get())));
}
return Optional.empty();
}
protected void initialiseRootNode() {
this.node = DecisionTreeFactory.constructDecisionTree(this.ruleSet, this.type);
}
}