package gw.exportimport.validation uses com.guidewire.pl.system.validation.ValidationIssueFilter uses typekey.ValidationLevel uses com.guidewire.pl.web.widget.WebMessage uses gw.api.validation.FieldValidation uses gw.api.validation.GeneralValidation uses gw.api.validation.ValidationIssue uses gw.api.validation.ValidationResult uses gw.exportimport.CellData uses gw.pl.persistence.core.Key uses java.lang.IllegalArgumentException uses java.lang.Integer uses java.util.ArrayList uses java.util.Arrays uses java.util.HashMap uses java.util.Map uses gw.web.productmodel.IProductModelSyncIssueWrapper uses java.util.List /** * Data Import Results. */ @ReadOnly class ImportValidationResult extends ValidationResult { /** * Cached row index while processing row. */ internal var _row : Integer as CurrentRow /** * Non-instance specific validation failures. These apply to the aggregate * import or to a specific row, but not to any specific entity instance. */ var _validationsByRow : Map = new HashMap() var _summaryLog : ImportValidationSummaryLog as readonly SummaryLog = new ImportValidationSummaryLog() var _editedRows : Map> = new HashMap>() var _syncIssueWrappers : List as SyncIssueWrappers = {} /** * Import Validation Level. This is the lowest possible level. */ public static final var IMPORT_VALIDATION_LEVEL : ValidationLevel = ValidationLevel.TC_LOADSAVE /** * All Errors ValidationIssueFilter. */ public static final var ALL_ERRORS : ValidationIssueFilter = ValidationIssueFilter.ALL_ERRORS /** * All Warnings ValidationIssueFilter. */ public static final var ALL_WARNINGS : ValidationIssueFilter = ValidationIssueFilter.ALL_WARNINGS construct() { } override property get Empty() : boolean { return _validationsByRow.isEmpty() } /* override to only look in validations... */ override function hasErrors(level : ValidationLevel) : boolean { return _validationsByRow.Values.hasMatch(\ v -> v.hasErrors(level) ) } /* override to only look in validations... */ override function hasWarnings(level : ValidationLevel) : boolean { return _validationsByRow.Values.hasMatch(\ v -> v.hasWarnings(level) ) } /** * An array of row or import validations * not associated with a specific entity. */ property get Validations() : RowValidation[] { var importValidations = _validationsByRow.Values return importValidations.toArray(new RowValidation[importValidations.Count]) } property get HasFatalErrors() : boolean { return getGeneralValidation()?.hasErrors() } property get HasNonFatalErrors() : boolean { return not _validationsByRow.Values.subtract({getGeneralValidation()}).where(\ r -> r.hasErrors()).Empty } /** * Return a RowValidation indexed by the specified row number. */ function getRowValidation(row : Integer) : RowValidation { return _validationsByRow[row] } /** * Return the general import validation. * * The general validation is not associated with a particular row. */ function getGeneralValidation() : RowValidation { return _validationsByRow[null as Integer] } /** * Flag a validation issue for a row. This is for rows * or the import not associated with a specific entity. */ function flag(row : Integer, errorMessage : String, warningMessage : String) { if (not (errorMessage.NotBlank or warningMessage.NotBlank)) { throw new IllegalArgumentException("Both errorMessage and warningMessage parameters are null or empty. At least one must be non-null.") } var rowValidation = getOrCreateRowValidation(row) /* ValidationIssue properties are supposed to be invisible in Gosu, but * for some reason, only SupersedingIssue gives an error. Use associative * access to work-around this limitation. */ var errorIssue : ValidationIssue = null if ( errorMessage.NotBlank ) { errorIssue = createIssue(rowValidation, null, null) errorIssue.Type = ValidationIssueType.TC_ERROR errorIssue.Reason = errorMessage } if ( warningMessage.NotBlank ) { var issue : ValidationIssue = createIssue(rowValidation, null, null) issue.Type = ValidationIssueType.TC_WARNING issue.Reason = warningMessage issue.SupersedingIssue = errorIssue // access workaround... } } protected function getOrCreateRowValidation(row : Integer) : RowValidation { var rowValidation = _validationsByRow[row] if ( rowValidation == null ) { rowValidation = ( row == null ) ? new RowValidation(this) : new RowValidation(this, row) addToValidations(rowValidation) } return rowValidation } /** * Add a general import error message. This is not associated with any * particular row or entity. */ function addError(msg : String) { flag(/*row=*/null, /*errorMsg=*/msg, /*warningMessage=*/null) } /** * Add a general import warning message. This is not associated with any * particular row or entity. */ function addWarning(msg : String) { flag(/*row=*/null, /*errorMsg=*/null, /*warningMessage=*/msg) } /** * Add an error issue for an entity. */ function addError(bean : KeyableBean, relatedBean : KeyableBean, path : String, errorMsg : String) { reject(bean.ID, relatedBean, path, IMPORT_VALIDATION_LEVEL, errorMsg, /*warningLevel=*/null, /*warningMessage=*/null, /*stepId=*/null) } /* override to ensure EntityRowValidation insertion... */ override function reject(id : Key, relatedBean : KeyableBean, strRelativeFieldPath : String, errorLevel : ValidationLevel, strErrorReason : String, warningLevel : ValidationLevel, strWarningReason : String, flowStepId : String) { if ( ( errorLevel != null ) or ( warningLevel != null ) ) { // valid arguments (see super); insert row-specific EntityValiation... if ( getEntityValidation(id) == null ) { var validation = new EntityRowValidation(id, _row) addToValidations(validation) addToEntityValidations(validation) } } super.reject(id, relatedBean, strRelativeFieldPath, errorLevel, strErrorReason, warningLevel, strWarningReason, flowStepId) } /** * Flag a field with a import validation issue. */ function flagField(id : Key, fieldValidation : FieldValidation) { getOrCreateEntityRowValidation(id).addValidationIssue(fieldValidation) } override function rejectField(id : Key, fieldValidation : FieldValidation) { flagField(id, fieldValidation) } protected function getOrCreateEntityRowValidation(id : Key) : EntityRowValidation { var ev = getEntityValidation(id) as EntityRowValidation if ( ev == null ) { ev = new EntityRowValidation(id, _row) addToEntityValidations(ev) addToValidations(ev) } return ev } override function getWebMessages(requiredValidationLevel : ValidationLevel) : WebMessage[] { var entityMessages = Arrays.asList(super.getWebMessages(requiredValidationLevel)) var result = new ArrayList(_validationsByRow.Count + entityMessages.Count) result.addAll(entityMessages) // Flatten each of the import validations... for ( importValidation in Validations ) { importValidation.addWebMessages(result, requiredValidationLevel) } return result.toArray(new WebMessage[result.size()]) } override function filterIssues(filter : ValidationIssueFilter) :List { var result = {} as List for ( validation in _validationsByRow.Values ) { result.addAll(validation.filterIssues(filter)) } return result } /** * Return an array of fatal error messages. * * Fatal error messages are associated with the general import validation. */ function getFatalErrorMessages() : String[] { var generalValidation = getGeneralValidation() if ( generalValidation == null ) { return {} } return generalValidation.ErrorMessages } private function createIssue(rowValidation : RowValidation, relatedBean : KeyableBean, strRelativeFieldPath : String) : ValidationIssue { var issue : ValidationIssue if ( ( strRelativeFieldPath == null ) or !strRelativeFieldPath.NotBlank ) { if ( relatedBean != null ) { throw new IllegalArgumentException("Cannot set a non-null relatedBean and an empty field path"); } issue = new GeneralValidation(); } else { var fv = new FieldValidation() fv.FieldName = strRelativeFieldPath if ( relatedBean != null ) { fv.RelatedBeanID = relatedBean.ID } issue = fv } issue.Level = IMPORT_VALIDATION_LEVEL rowValidation.addValidationIssue(issue) return issue } internal function addToValidations(element : RowValidation) { var row = element.Row if ( _validationsByRow.containsKey(row) ) { throw new IllegalArgumentException("A validation already exists for row " + row) } if ( element.ValidationResult != this ) { element.ValidationResult = this } _validationsByRow.put(row, element); } function markCurrentColumnAsEdited(cellData : CellData) { var editedFields = _editedRows.get(_row) if (editedFields == null) { editedFields = new ArrayList() } editedFields.add(cellData) _editedRows.put(_row, editedFields) } function markCurrentRowAsUnEdited() { _editedRows.remove(_row) } property get IsCurrentRowEdited() : boolean { return _editedRows.Keys.contains(_row) } property get EditedColumnsInCurrentRow() : List { return _editedRows.get(_row) } }