package gw.exportimport uses gw.api.locale.DisplayKey uses gw.exportimport.validation.ImportValidationResult uses gw.exportimport.validation.BeanAction uses java.lang.IllegalArgumentException uses java.lang.UnsupportedOperationException uses java.util.Map uses gw.api.extension.ExtensionInterfaces class CellDataRow { var _data : CellData[] as readonly Data var _rowIndex : int as readonly UIRowIndex var _metaData : ImportMetaData var _cellDataByColumnInfo : Map = {} var _createdNewParent : boolean = false construct(theData : CellData[], theRow : int, metaData : ImportMetaData) { _data = theData _rowIndex = theRow _metaData = metaData if (theData != null) { _cellDataByColumnInfo = theData.partitionUniquely(\ c -> c.ColumnInfo) } } function processAllData(period : PolicyPeriod, isTest : boolean) : String { if ( isTest ) { _metaData.setTest() } else { _metaData.setImport() } // for every row try to find or create a {@link KeyableBean} _metaData.ValidationResult.CurrentRow = _rowIndex var deleteThisBean = isDeleted(getActionCell()) var publicId = getCreateCell().Data try { var bean = getOrCreateBean(period, publicId, deleteThisBean) if ( bean == null ) { return null } if (deleteThisBean) { deleteBean(bean) return publicId } updateBean(bean) } finally { if ( isTest ) { _metaData.ValidationResult.markCurrentRowAsUnEdited() _metaData.setImport() } } return publicId } /** * Register all bean events that happened. This includes Add, Edit, Removed, Read */ function registerBeanEvents() { var publicId = getCreateCell().Data var beanChanged = _metaData.ValidationResult.IsCurrentRowEdited if (not publicId.NotBlank) { _metaData.ValidationResult.SummaryLog.registerBeanAction(BeanAction.Added) } else if (beanChanged) { _metaData.ValidationResult.SummaryLog.registerBeanAction(BeanAction.Edited) } if (isDeleted(getActionCell())) { _metaData.ValidationResult.SummaryLog.registerBeanAction(BeanAction.Removed) } } private function isDeleted(actionCell : CellData) : boolean { return (actionCell != null and DisplayKey.get("Export.Action.Delete").equalsIgnoreCase(actionCell.Data)) } private function isAdd(actionCell : CellData) : boolean { return (actionCell != null and DisplayKey.get("Export.Action.Add").equalsIgnoreCase(actionCell.Data)) } private function getOrCreateBean(period : PolicyPeriod, publicId : String, deleteBean : boolean) : KeyableBean { try { return (deleteBean or publicId.NotBlank) ? getBean(period, publicId) : createBean(period) } catch (ex : IllegalArgumentException) { _metaData.ValidationResult.flag(_rowIndex, ex.Message, /*warningMessage=*/null) } catch (ex : UnsupportedOperationException) { _metaData.ValidationResult.flag(_rowIndex, ex.Message, /*warningMessage=*/null) } return null } private function getOrCreateParentEntity(period : PolicyPeriod) : KeyableBean { var actionCell = getActionCell() var parentEntity : KeyableBean = null if (isAdd(actionCell)) { return getParent(period) } if (actionCell != null) { var displayName = gw.api.locale.DisplayKey.get(actionCell.ColumnInfo.Header) throw new IllegalArgumentException(DisplayKey.get("Import.Validation.Errors.RequiredField", displayName)) } return parentEntity } private function getParent(period : PolicyPeriod) : KeyableBean { if (_metaData.EntityInfo.ParentEntityType == null) { return null } var parent = getExistingParent(period) if (parent == null) { parent = getNewParent(period) } return parent } private function getExistingParent(period : PolicyPeriod) : KeyableBean { var parentEntityColumn = findCellDataWith(\ c -> c.FlagsParentEntityId) if (parentEntityColumn == null) { throw new IllegalArgumentException(DisplayKey.get("Import.Configuration.Errors.RequiresParentEntityIdColumn", _metaData.EntityInfo.EntityType, _metaData.EntityInfo.ParentEntityType)) } if (not parentEntityColumn.Data.NotBlank) { return null } if (_metaData.EntityInfo.ParentEntityType == null) { throw new IllegalArgumentException(DisplayKey.get("Import.Configuration.Errors.MissingParentEntityType", _metaData.EntityInfo.EntityType)) } return PublicIdEntityFinder.findBean(period, parentEntityColumn.Data, _metaData.EntityInfo.ParentEntityType) } private function getNewParent(period : PolicyPeriod) : KeyableBean { var entityIdColumn = findCellDataWith(\ c -> c.FlagsEntityId) if (entityIdColumn.Data.NotBlank) { throw new IllegalArgumentException(DisplayKey.get("Import.Validation.Errors.FieldMustBeBlankForAction", entityIdColumn.ColumnInfo.Header, DisplayKey.get("Export.Action.Add"))) } var parentEntityIDCellValue = findCellDataWith(\ c -> c.FlagsParentEntityId).Data // Already created ? if (_metaData.hasNewParentEntityWithPublicID(parentEntityIDCellValue)) { var parentEntity = _metaData.getNewParentEntityByPublicID(parentEntityIDCellValue) /* bundle will be null if parent was rolled back so ignore it and * recreate it (which will register it instead of the old one) */ if ( parentEntity.Bundle != null ) { return parentEntity } } // Create new entity var parentEntity = ExtensionInterfaces.IImportStrategyRegistryExtensions.getStrategy(_metaData.EntityInfo.ParentEntityType).createEntity(period, null) if (parentEntityIDCellValue.NotBlank) { _metaData.setNewParentEntityByPublicID(parentEntityIDCellValue, parentEntity) } _createdNewParent = true return parentEntity } private function createBean(period : PolicyPeriod) : KeyableBean { return ExtensionInterfaces.IImportStrategyRegistryExtensions.getStrategy(EntityType).createEntity(period, getOrCreateParentEntity(period)) } private function getBean(period : PolicyPeriod, id : String) : KeyableBean { var actionCell = getActionCell() if (isAdd(actionCell)) { var displayName = gw.api.locale.DisplayKey.get(actionCell.ColumnInfo.Header) throw new IllegalArgumentException(DisplayKey.get("Import.Validation.Errors.InvalidAction", displayName, actionCell.Data)) } var bean = PublicIdEntityFinder.findBean(period, id, _metaData.EntityInfo.EntityType) if (bean == null) { throw new IllegalArgumentException(DisplayKey.get("Import.Validation.Errors.InvalidPublicID", id, _metaData.EntityInfo.EntityType)) } return bean } private function updateBean(bean : KeyableBean) { var parentCells = findCellDatasWith(\ c -> c.ParentColumn) parentCells.each(\ c -> c.importBeanValue(bean, _metaData, findDependentCells(c))) if (not _createdNewParent and _metaData.ValidationResult.IsCurrentRowEdited) { //list of changed columns var editedColumns = _metaData.ValidationResult.EditedColumnsInCurrentRow var columnList = editedColumns*.ColumnInfo*.ColumnIdentifier.join(", ") _metaData.ValidationResult.flag(_rowIndex, DisplayKey.get("Import.Validation.Errors.CannotModifyParentEntityField", typeof bean, columnList), /*warningMessage=*/null) } var restOfCells = _data.subtract(parentCells) restOfCells.each(\ c -> c.importBeanValue(bean, _metaData, findDependentCells(c))) } private function findDependentCells(cellData : CellData) : Map { var dependentColumnInfos = cellData.ColumnInfo.DependentOn return ( dependentColumnInfos == null ) ? {} : dependentColumnInfos.mapValues(\ c -> _cellDataByColumnInfo[c]) } private function deleteBean(bean : KeyableBean) { try { deleteRow(bean) } catch (ex : UnsupportedOperationException) { _metaData.ValidationResult.flag(_rowIndex, ex.Message, /*warningMessage=*/null) } } private function deleteRow(bean : KeyableBean) { // delete ... ExtensionInterfaces.IImportStrategyRegistryExtensions.getStrategy(EntityType).deleteEntity(bean) } private function getActionCell() : CellData { return findCellDataWith(\ c -> c.FlagsAction) } private function getCreateCell() : CellData { return findCellDataWith(\ c -> c.FlagsEntityId) } private function findCellDataWith(match(columnInfo : ColumnInfo) : boolean ) : CellData { return _data.firstWhere(\ c -> match(c.ColumnInfo)) } private function findCellDatasWith(match(columnInfo : ColumnInfo) : boolean ) : CellData[] { return _data.where(\ c -> match(c.ColumnInfo)) } private property get EntityType() : Type { return _metaData.EntityInfo.EntityType } override function equals(o : Object) : boolean { if (this === o) { return true } if (not (o typeis CellDataRow)) { return false } var cellDataRow = o as CellDataRow for (cellData in cellDataRow._data index cellDataIndex) { if (not (this._data[cellDataIndex] == null ? cellData == null : this._data[cellDataIndex] == cellData)) { return false } } if (not (this._rowIndex == cellDataRow._rowIndex)) { return false } return true } override function hashCode() : int { var result = 17 _data.each(\ cellData -> { result = 31 * result + (_data == null ? 0 : cellData.hashCode()) }) result = 31 * result + _rowIndex return result } }