コード例 #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="readerToEntityAdapter">Adapter for reading content and storing in entities.</param>
        /// <param name="entitySaver">Service for saving entities in bulk.</param>
        /// <param name="importReporter">Service for receiving import progress.</param>
        /// <param name="resourceMapping">The resource mapping, to provde settings such as merging and workflow suppression.</param>
        /// <param name="testRun">Indicates that the importer is performing test runs.</param>
        public RecordImporter(IReaderToEntityAdapter readerToEntityAdapter, IEntitySaver entitySaver, IImportReporter importReporter, ApiResourceMapping resourceMapping, bool testRun)
        {
            if (readerToEntityAdapter == null)
            {
                throw new ArgumentNullException(nameof(readerToEntityAdapter));
            }
            if (entitySaver == null)
            {
                throw new ArgumentNullException(nameof(entitySaver));
            }
            if (importReporter == null)
            {
                throw new ArgumentNullException(nameof(importReporter));
            }
            if (resourceMapping == null)
            {
                throw new ArgumentNullException(nameof(resourceMapping));
            }

            _entitySaver          = entitySaver;
            ReaderToEntityAdapter = readerToEntityAdapter;
            Reporter           = importReporter;
            _resourceMapping   = resourceMapping;
            _mergeRecords      = resourceMapping.ImportMergeExisting == true;
            _suppressWorkflows = resourceMapping.MappingSuppressWorkflows == true;
            _testRun           = testRun;
        }
コード例 #2
0
        /// <summary>
        /// Creates a new instance and fills the fields. Does not call save.
        /// </summary>
        /// <param name="reader">The source of data for this entity.</param>
        /// <param name="reporter">Repoter for errors.</param>
        public IEntity CreateEntity(IObjectReader reader, IImportReporter reporter)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            IReadOnlyCollection <ReaderEntityPair> result = CreateEntities(reader.ToEnumerable(), reporter);

            return(result.First().Entity);
        }
コード例 #3
0
        /// <summary>
        /// Sets fields on multiple entities. Does not call save.
        /// </summary>
        /// <param name="readerEntityPairs">The source of the object readers and the corresponding entities to write them in to.</param>
        /// <param name="reporter">Repoter for errors.</param>
        /// <exception cref="FormatException">Thrown if the object reader value was unacceptably formatted for the target field.</exception>
        public void FillEntities(IEnumerable <ReaderEntityPair> readerEntityPairs, IImportReporter reporter)
        {
            if (readerEntityPairs == null)
            {
                throw new ArgumentNullException("readerEntityPairs");
            }

            foreach (var memberProcessor in _memberProcessors)
            {
                memberProcessor.Action(readerEntityPairs, reporter);
            }
        }
コード例 #4
0
        /// <summary>
        /// Sets fields. Does not call save.
        /// </summary>
        /// <param name="reader">The source of data for this entity.</param>
        /// <param name="entity">The entity to be filled.</param>
        /// <param name="reporter">Repoter for errors.</param>
        /// <exception cref="System.ArgumentNullException">
        /// reader
        /// or
        /// entity
        /// </exception>
        public void FillEntity(IObjectReader reader, IEntity entity, IImportReporter reporter)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            var pair = new ReaderEntityPair(reader, entity);

            FillEntities(pair.ToEnumerable(), reporter);
        }
コード例 #5
0
        /// <summary>
        /// Run-time implementation for copying the relationship data from object readers to corresponding entities.
        /// </summary>
        /// <param name="readerEntityPairs">The readers and their corresponding entities.</param>
        /// <param name="identityReader">Callback for reading the identities from the readers.</param>
        /// <param name="resourceResolver">Service for resolving identity values.</param>
        /// <param name="memberName">Name of the member.</param>
        /// <param name="relationshipId">ID of relationship being updated.</param>
        /// <param name="direction">Direction that the relationship is being updated.</param>
        /// <param name="mandatory">Indicates that the member is mandatory.</param>
        /// <param name="reporter">Target for any errors.</param>
        /// <param name="reportingName">Member name used for reporting.</param>
        /// <exception cref="ConnectorRequestException">
        /// </exception>
        private void RelationshipProcessorImpl(IEnumerable <ReaderEntityPair> readerEntityPairs, Func <IObjectReader, string, IReadOnlyCollection <object> > identityReader, IResourceResolver resourceResolver, string memberName, long relationshipId, Direction direction, bool mandatory, IImportReporter reporter, string reportingName)
        {
            if (reporter == null)
            {
                throw new ArgumentNullException(nameof(reporter));
            }

            // Get identifiers
            var identities           = new HashSet <object>( );
            var entitiesToIdentities = new Dictionary <IEntity, IReadOnlyCollection <object> >( );

            foreach (ReaderEntityPair pair in readerEntityPairs)
            {
                // Resolve targeted entity
                IReadOnlyCollection <object> targetResourceIdentities;
                IObjectReader reader = pair.ObjectReader;
                try
                {
                    targetResourceIdentities = identityReader(reader, memberName);

                    // Handle missing fields
                    if (mandatory && (!reader.HasKey(memberName) || targetResourceIdentities.Count == 0))
                    {
                        string message = string.Format(Messages.MandatoryPropertyMissing, reportingName);
                        reporter.ReportError(reader, message);
                        continue;
                    }
                }
                catch (FormatException)   // hmm .. this is a bit specific to the JSON reader
                {
                    reporter.ReportError(reader, Messages.IdentifierListContainedNulls);
                    continue;
                }

                if (targetResourceIdentities == null)
                {
                    continue;
                }

                foreach (object identity in targetResourceIdentities)
                {
                    if (identity == null || identity as string == string.Empty)
                    {
                        continue;
                    }
                    identities.Add(identity);
                }
                entitiesToIdentities.Add(pair.Entity, targetResourceIdentities);
            }

            // Resolve resources
            IDictionary <object, ResourceResolverEntry> resourceLookup = null;

            if (identities.Count > 0)
            {
                resourceLookup = resourceResolver.ResolveResources(identities.ToList());
            }

            // Update relationships
            foreach (ReaderEntityPair pair in readerEntityPairs)
            {
                IObjectReader reader       = pair.ObjectReader;
                IEntity       updateEntity = pair.Entity;
                IReadOnlyCollection <object> targetIdentities;
                if (!entitiesToIdentities.TryGetValue(updateEntity, out targetIdentities))
                {
                    continue;
                }

                // Update relationship
                var col = updateEntity.GetRelationships(relationshipId, direction);

                // Clearing is mandatory for lookups;
                // mandatory for relationships on new instances with default values;
                // and a good idea for other relationships.
                // Clearing will reset any default instances, but we've decided this is sensible, otherwise a subsequent update using the
                // same data would just clear them anyway. Default values do not get applied for mapped columns.
                col.Clear( );

                // Find each target identity in the lookup
                foreach (object targetIdentity in targetIdentities)
                {
                    if (targetIdentity == null)
                    {
                        continue;
                    }

                    ResourceResolverEntry entry;
                    if (resourceLookup == null || !resourceLookup.TryGetValue(targetIdentity, out entry))
                    {
                        reporter.ReportError(reader, Messages.ResourceNotFoundByField);
                        continue;
                    }
                    if (entry.Error != ResourceResolverError.None)
                    {
                        string message = ResourceResolver.FormatResolverError(entry.Error, targetIdentity.ToString( ));
                        reporter.ReportError(reader, message);
                        continue;
                    }

                    IEntity targetEntity = entry.Entity;

                    // And set into the relationship
                    if (targetEntity != null)
                    {
                        col.Add(targetEntity);
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Creates new instance and fills the fields. Does not call save.
        /// </summary>
        /// <param name="readers">The list of readers for these entities.</param>
        /// <param name="reporter">Repoter for errors.</param>
        /// <exception cref="FormatException">Thrown if the object reader value was unacceptably formatted for the target field.</exception>
        public IReadOnlyCollection <ReaderEntityPair> CreateEntities(IEnumerable <IObjectReader> readers, IImportReporter reporter)
        {
            if (readers == null)
            {
                throw new ArgumentNullException("readers");
            }

            // Create instances
            List <ReaderEntityPair> pairs;

            pairs = readers.Select(reader => new ReaderEntityPair(reader, _instanceFactory( ))).ToList( );

            // Set default values
            _defaultsProcessor?.Action(pairs, reporter);

            // Fill
            FillEntities(pairs, reporter);

            return(pairs);
        }