/// <summary> /// Validates data for a given table with a data validator. /// </summary> /// <param name="dataValidator">Data validator which should validate the data.</param> /// <param name="table">Table on which to validate data.</param> /// <param name="tableData">Data to be validated.</param> /// <param name="endOfData">Indicates whether this is the last data for the table.</param> /// <param name="command">Execute command for the delivery engine.</param> private void Validate(IDataValidator dataValidator, ITable table, IDictionary <ITable, IEnumerable <IEnumerable <IDataObjectBase> > > tableData, bool endOfData, IDeliveryEngineExecuteCommand command) { if (dataValidator == null) { throw new ArgumentNullException("dataValidator"); } if (table == null) { throw new ArgumentNullException("table"); } if (tableData == null) { throw new ArgumentNullException("tableData"); } if (command == null) { throw new ArgumentNullException("command"); } try { dataValidator.Validate(table, tableData, endOfData, command); } catch (ThreadInterruptedException) { throw; } catch (DeliveryEngineConvertException ex) { lock (_syncRoot) { bool continueValidation; ExceptionHandler.HandleException(ex, out continueValidation); if (continueValidation == false) { throw new DeliveryEngineAlreadyHandledException(ex.Message, ex); } } if (command.ValidationOnly) { RemoveInvalidData(tableData, ex.Information.ConvertObjectData); } Validate(dataValidator, table, tableData, endOfData, command); } catch (DeliveryEngineMappingException ex) { lock (_syncRoot) { bool continueValidation; ExceptionHandler.HandleException(ex, out continueValidation); if (continueValidation == false) { throw new DeliveryEngineAlreadyHandledException(ex.Message, ex); } } if (command.ValidationOnly) { RemoveInvalidData(tableData, ex.Information.MappingObjectData); } Validate(dataValidator, table, tableData, endOfData, command); } catch (DeliveryEngineValidateException ex) { lock (_syncRoot) { bool continueValidation; ExceptionHandler.HandleException(ex, out continueValidation); if (continueValidation == false) { throw new DeliveryEngineAlreadyHandledException(ex.Message, ex); } } if (command.ValidationOnly) { RemoveInvalidData(tableData, ex.Information.ValidateObjectData); } Validate(dataValidator, table, tableData, endOfData, command); } catch (Exception ex) { var threadInterruptedException = ex.InnerException as ThreadInterruptedException; if (threadInterruptedException != null) { throw threadInterruptedException; } lock (_syncRoot) { bool continueValidation; ExceptionHandler.HandleException(ex, out continueValidation); if (continueValidation == false) { throw new DeliveryEngineAlreadyHandledException(ex.Message, ex); } } Validate(dataValidator, table, tableData, endOfData, command); } }
/// <summary> /// Execute the delivery engine to create and write the delivery format. /// </summary> /// <param name="command">Command for executing the delivery engine.</param> public virtual void Execute(IDeliveryEngineExecuteCommand command) { if (command == null) { throw new ArgumentNullException("command"); } try { // Get the data source. RaiseEvent(BeforeGetDataSource, new GetDataSourceEventArgs()); var dataSource = MetadataRepository.DataSourceGet(); if (!string.IsNullOrEmpty(command.OverrideArchiveInformationPackageId)) { dataSource.ArchiveInformationPackageId = command.OverrideArchiveInformationPackageId; } ArchiveVersionRepository.DataSource = dataSource; // Archive the metadata for the data source. if (command.ValidationOnly == false) { RaiseEvent(BeforeArchiveMetadata, new ArchiveMetadataEventArgs(dataSource)); ArchiveVersionRepository.ArchiveMetaData(); } // Handle and archive any target tables included in the data source. DataRepository.OnHandleData += HandleDataForTargetTable; DataRepository.OnClone += DataRepositoryCloned; var tableWorkers = new Collection <BackgroundWorker>(); try { var namedObjectComparer = new NameTargetComparer(); var targetTables = dataSource.Tables .Where(m => string.IsNullOrEmpty(m.NameTarget) == false && (string.IsNullOrEmpty(command.Table) || Regex.IsMatch(m.NameTarget, command.Table, RegexOptions.Compiled))) .Distinct(namedObjectComparer) .OfType <ITable>() .ToList(); foreach (var targetTable in targetTables) { while (tableWorkers.Count(m => m.IsBusy) >= (command.TablesHandledSimultaneity <= 0 ? 1 : command.TablesHandledSimultaneity) && _errors.Any() == false) { Thread.Sleep(250); } if (_errors.Any()) { throw _errors.ElementAt(0); } var tableWorker = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; tableWorker.DoWork += HandleTargetTableDoWork; tableWorker.RunWorkerCompleted += WorkerCompleted; tableWorker.Disposed += (sender, eventArgs) => tableWorkers.Remove((BackgroundWorker)sender); tableWorkers.Add(tableWorker); tableWorker.RunWorkerAsync(new Tuple <ITable, IDataSource, IDeliveryEngineExecuteCommand>(targetTable, dataSource, command)); } while (tableWorkers.Any(m => m.IsBusy)) { if (_errors.Any()) { throw _errors.ElementAt(0); } Thread.Sleep(250); } } finally { foreach (var tableWorker in tableWorkers.Where(m => m.IsBusy)) { tableWorker.CancelAsync(); } while (tableWorkers.Any(m => m.IsBusy)) { Thread.Sleep(250); } while (tableWorkers.Count > 0) { var tableWorker = tableWorkers.ElementAt(0); tableWorker.Dispose(); tableWorkers.Remove(tableWorker); } } } catch (DeliveryEngineAlreadyHandledException) { } catch (Exception ex) { lock (_syncRoot) { ExceptionHandler.HandleException(ex); } } finally { lock (_syncRoot) { while (_tableInformations.Count > 0) { _tableInformations.Clear(); } } while (_errors.Count > 0) { _errors.Clear(); } } }