package gw.rating.rtm.validation uses gw.api.extension.ExtensionInterfaces uses gw.api.locale.DisplayKey uses gw.api.validation.EntityValidationException uses gw.rating.rtm.domain.ErrorCollector uses gw.rating.rtm.domain.RateBookVisitor uses gw.rating.rtm.domain.OrderedPersistenceElement.OrderedPersistenceClass uses gw.rating.rtm.domain.table.RateBookModel uses gw.rating.rtm.domain.table.RateTableCell uses gw.rating.rtm.domain.table.RateTableModel uses gw.rating.rtm.domain.table.RateTableRow uses gw.rating.rtm.query.StatelessRowLoadUtil uses gw.rating.rtm.query.StatelessRowLoadUtil.PartitionAbortedException uses gw.validation.PCValidationResult uses java.lang.Comparable uses java.util.ArrayList uses gw.api.system.PCLoggerCategory uses java.util.List class RateTableValidator { public static final var INVALID_ROW_COUNT : int = -1 private var _result : PCValidationResult construct() { } function validate(model : RateTableModel, errorCollector: ErrorCollector) { var compositeVisitor = new CompositeVisitor() compositeVisitor.addVisitor(new NormalizingRowValidationVisitor (errorCollector)) // checks for duplicate rows and range overlaps compositeVisitor.addVisitor(new AtLeastOneFactor (errorCollector)) // checks that each row has a factor filled in compositeVisitor.addVisitor(new NullParamValidationVisitor(errorCollector)) // checks for actual values after nulls compositeVisitor.addVisitor(new RemovedParameterValidationVisitor(errorCollector)) // checks for parameters removed from the RTD if (model.RateTableDefinition.MatchOps.hasMatch( \ matchOp -> matchOp.IsRange)) { compositeVisitor.addVisitor(new RangeValidatorVisitor (errorCollector)) // checks for valid ranges (i.e. rangeMin <= rangeMax) } model.accept(compositeVisitor) var priorResult = _result _result = ExtensionInterfaces.IPCValidationResultFactory.createValidationResult() if (errorCollector.getErrorCount() == 0) { if (model.RateTableDefinition.MatchOps.hasMatch(\mo -> mo.MatchOpDefinition.OpCode.startsWith("RangeMatch"))) { checkNormalizedRowCount(model, _result) } } if (errorCollector.getErrorCount() > 0) { _result.addError(model.RateTable, ValidationLevel.TC_DEFAULT, errorCollector.getErrorSummary()) } if (_result.hasErrors() || _result.hasNewWarnings(priorResult)) { throw new EntityValidationException(_result, ValidationLevel.TC_DEFAULT) } } private function checkNormalizedRowCount(model : RateTableModel, result : PCValidationResult) { var rows = model.FactorRows.map(\factorRow -> new OrderedPersistenceClass(factorRow.Row, model.RateTableDefinition)) final var matchOps = model.RateTableDefinition.SortedMatchOps.map(\ o -> o.newStatelessInstance()) try { var normalizedRowCount = new StatelessRowLoadUtil().getPartitionedOrderedRowsMap(matchOps, rows, true) .Values.map(\v -> v.size()).sum() if (normalizedRowCount == rows.size()) { model.RateTable.RowUniformityStatus = RowUniformityStatus.TC_UNIFORM } else { model.RateTable.RowUniformityStatus = RowUniformityStatus.TC_NONUNIFORM } model.RateTable.NormalizedRowCount = normalizedRowCount } catch (pae : PartitionAbortedException) { model.RateTable.RowUniformityStatus = RowUniformityStatus.TC_INTRACTABLE model.RateTable.NormalizedRowCount = INVALID_ROW_COUNT result.addWarning(model.RateTable, ValidationLevel.TC_DEFAULT, DisplayKey.get("Web.Rating.Warnings.RateTable.FailedToNormalize", model.RateTable.DisplayName)) } } private static class CompositeVisitor implements RateBookVisitor { var _visitors : List construct() { _visitors = new ArrayList() } function addVisitor(visitor : RateBookVisitor) { _visitors.add(visitor) } override function visitBoolean(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitBoolean(ratingCell)) } override function visitDate(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitDate(ratingCell)) } override function visitDecimal(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitDecimal(ratingCell)) } override function visitInteger(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitInteger(ratingCell)) } override function visitString(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitString(ratingCell)) } override function visitEmpty(ratingCell : RateTableCell) { _visitors.each(\ v -> v.visitEmpty(ratingCell)) } override function visit(ratingRow : RateTableRow) { _visitors.each(\ v -> v.visit(ratingRow)) } override function visitingEmptyCells() : boolean { return true } override function visit(bookModel : RateBookModel) { _visitors.each(\ v -> v.visit(bookModel)) } override function visitAfter(tableModel: RateTableModel) { _visitors.each( \ v -> v.visitAfter(tableModel)) } override function visit(tableModel: RateTableModel) { for (var visitor in _visitors) { if (PCLoggerCategory.RTM.DebugEnabled) { PCLoggerCategory.RTM.debug("Calling validation on : " + visitor.IntrinsicType.DisplayName) } visitor.visit(tableModel) } } override function visit(routine: CalcRoutineDefinition) { _visitors.each(\ v -> v.visit(routine)) } } }