All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gs.dmn.validation.SweepMissingIntervalValidator Maven / Gradle / Ivy

There is a newer version: 8.7.3
Show newest version
/*
 * Copyright 2016 Goldman Sachs.
 *
 * 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 com.gs.dmn.validation;

import com.gs.dmn.DMNModelRepository;
import com.gs.dmn.ast.TDRGElement;
import com.gs.dmn.ast.TDecisionTable;
import com.gs.dmn.ast.TDefinitions;
import com.gs.dmn.context.DMNContext;
import com.gs.dmn.dialect.DMNDialectDefinition;
import com.gs.dmn.el.analysis.semantics.type.Type;
import com.gs.dmn.el.synthesis.ELTranslator;
import com.gs.dmn.log.BuildLogger;
import com.gs.dmn.log.Slf4jBuildLogger;
import com.gs.dmn.validation.table.Bound;
import com.gs.dmn.validation.table.Interval;
import com.gs.dmn.validation.table.MissingIntervals;
import com.gs.dmn.validation.table.Table;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class SweepMissingIntervalValidator extends SweepValidator {
    public SweepMissingIntervalValidator() {
        this(new Slf4jBuildLogger(LOGGER));
    }

    public SweepMissingIntervalValidator(BuildLogger logger) {
        super(logger);
    }

    public SweepMissingIntervalValidator(DMNDialectDefinition dmnDialectDefinition) {
        super(dmnDialectDefinition);
    }

    @Override
    protected void validate(TDRGElement element, TDecisionTable decisionTable, SweepValidationContext context) {
        if (element != null) {
            DMNModelRepository repository = context.getRepository();
            ELTranslator elTranslator = context.getElTranslator();
            logger.debug(String.format("Validating element '%s'", element.getName()));

            List ruleIndex = new ArrayList<>();
            int totalNumberOfRules = decisionTable.getRule().size();
            for (int i = 0; i< totalNumberOfRules; i++) {
                ruleIndex.add(i);
            }
            MissingIntervals missingIntervals = new MissingIntervals();
            int totalNumberOfColumns = decisionTable.getInput().size();
            Table table = this.factory.makeTable(totalNumberOfRules, totalNumberOfColumns, repository, element, decisionTable, elTranslator);
            if (!table.isEmpty()) {
                findMissingIntervals(ruleIndex, totalNumberOfColumns, missingIntervals, table);

                logger.debug(String.format("Found missing intervals '%s'", missingIntervals));

                for (int i=0; i intervals = missingIntervals.getIntervals(i);
                    if (intervals != null && !intervals.isEmpty()) {
                        context.addError(makeError(element, i, intervals, repository));
                    }
                }
            }
        }
    }

    private String makeError(TDRGElement element, int columnIndex, List intervals, DMNModelRepository repository) {
        TDefinitions model = repository.getModel(element);
        String intervalsString = intervals.stream().map(Interval::serialize).collect(Collectors.joining(", "));
        String message;
        if (intervals.size() == 1) {
            message = String.format("Interval '%s' is not covered for column %d in '%s' table", intervalsString, columnIndex + 1, repository.displayName(element));
        } else {
            message = String.format("Intervals '%s' are not covered for column %d in '%s' table", intervalsString, columnIndex + 1, repository.displayName(element));
        }
        return makeError(repository, model, element, message);
    }

    //  Algorithm: findMissingRules.
    //  Input: ruleList; missingIntervals; i; N; missingRuleList.
    //      - ruleList, containing all rules of the input DMN table;
    //      - missingIntervals, storing the current missing intervals;
    //      - i, containing the index of the column under scrutiny;
    //      - N, representing the total number of columns;
    //      - missingRuleList, storing the missing rules.

    //  if i < N then
    //      Lxi = [] // initializes the current list of bounds
    //      sortedListAllBounds = ruleList.sort(i)
    //      lastBound = 0
    //      foreach currentBound ∈ sortedListAllBounds do
    //          if !areAdjacent( lastBound, currentBound) then
    //              missingIntervals[i] = constructInterval(lastBound, currentBound)
    //              if missingRuleList.canBeMerged(missingIntervals) then
    //                  missingRuleList.merge(missingIntervals)
    //              else
    //                  missingRuleList.add(missingIntervals)
    //          if !Lxi.isEmpty() then
    //              missingIntervals[i] = constructInterval(lastBound, currentBound)
    //              findMissingRules(Lxi, missingIntervals, i+1, N, missingRuleList) /* recursive invocation */
    //          if currentBound.isLower() then
    //              Lxi.put(currentBound)
    //          else
    //              Lxi.delete( currentBound);
    //          lastBound = currentBound
    //  return missingRuleList;
    private void findMissingIntervals(List ruleList, int totalNumberOfColumns, MissingIntervals missingIntervals, Table table) {
        for (int columnIndex=0; columnIndex sortedListAllBounds = makeBoundList(ruleList, columnIndex, table);
            Bound lowerBound = table.getLowerBoundForColumn(columnIndex);
            Bound upperBound = table.getUpperBoundForColumn(columnIndex);
            Bound lastBound = lowerBound;
            int boundCount = sortedListAllBounds.size();
            List lxi = new ArrayList<>();

            logger.debug(String.format("%sColumn = %s Sorted bounds = '%s'", indent, columnIndex, sortedListAllBounds));

            for (int i = 0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy