Esempio n. 1
0
        /// <summary>
        /// Generate a list of artifact summary information from a resource input stream,
        /// using the default <see cref="ConformanceHarvesters"/>.
        /// <para>
        /// If the target resource represents a <see cref="Bundle"/> instance, then the generator
        /// returns a list of summaries for all resource entries contained in the bundle.
        /// </para>
        /// </summary>
        /// <param name="navStream">An <see cref="INavigatorStream"/> instance.</param>
        /// <param name="initProperties">
        /// An optional summary properties initialization method, or <c>null</c>.
        /// If specified, the generator will call this method for each generated summary,
        /// allowing the caller to modify or enrich the set of generated summary properties.
        /// </param>
        /// <param name="harvesters">
        /// A list of <see cref="ArtifactSummaryHarvester"/> delegates that the
        /// generator calls to harvest summary information from each artifact.
        /// If the harvester list equals <c>null</c> or empty, then the generator will
        /// harvest only the common default summary properties.
        /// </param>
        /// <returns>A list of new <see cref="ArtifactSummary"/> instances.</returns>
        /// <remarks>
        /// The generator catches all runtime exceptions that occur during harvesting and returns
        /// them as <see cref="ArtifactSummary"/> instances with <see cref="ArtifactSummary.IsFaulted"/>
        /// equal to <c>true</c> and <see cref="ArtifactSummary.Error"/> returning the exception.
        /// </remarks>

        public static List <ArtifactSummary> Generate(
            INavigatorStream navStream,
            Action <ArtifactSummaryPropertyBag> initProperties,
            params ArtifactSummaryHarvester[] harvesters)
        {
            var result = new List <ArtifactSummary>();

            // Factory returns null for unknown file formats
            if (navStream == null)
            {
                return(result);
            }

            try
            {
                // Run default or specified (custom) harvesters
                if (harvesters == null || harvesters.Length == 0)
                {
                    harvesters = ConformanceHarvesters;
                }

                while (navStream.MoveNext())
                {
                    var current = navStream.Current;
                    if (current != null)
                    {
                        var properties = new ArtifactSummaryPropertyBag();

                        // Initialize default summary information
                        // Note: not exposed by IElementNavigator, cannot use harvester
                        properties.SetPosition(navStream.Position);
                        properties.SetTypeName(current.Type);
                        properties.SetResourceUri(navStream.Position);

                        // Allow caller to modify/enrich harvested properties
                        initProperties?.Invoke(properties);

                        // Generate the final (immutable) ArtifactSummary instance
                        var summary = generate(properties, current, harvesters);

                        result.Add(summary);
                    }
                }
            }
            // TODO Catch specific exceptions
            // catch (System.IO.FileNotFoundException)
            // catch (UnauthorizedAccessException)
            // catch (System.Security.SecurityException)
            // catch (FormatException)
            catch (Exception ex)
            {
                result.Add(ArtifactSummary.FromException(ex));
            }
            finally
            {
                navStream?.Dispose();
            }
            return(result);
        }
        // Generate summary for a single artifact
        static ArtifactSummary generate(
            ArtifactSummaryPropertyBag props,
            ISourceNode nav,
            ArtifactSummaryHarvester[] harvesters)
        {
            Exception error = null;

            // [WMR 20180419] Support empty harvester list (harvest only default props, no custom props)
            if (harvesters != null && harvesters.Length > 0)
            {
                try
                {
                    // Harvest summary information via specified harvesters
                    // Top-level harvesters receive navigator positioned on the first child element level

                    // Catch individual exceptions inside loop, return as AggregateException
                    var errors = new List <Exception>();
                    if (nav.Children().Any())
                    {
                        foreach (var harvester in harvesters)
                        {
                            try
                            {
                                if (harvester != null && harvester.Invoke(nav, props))
                                {
                                    break;
                                }
                            }
                            // TODO Catch specific exceptions
                            // catch (FormatException)
                            catch (Exception ex)
                            {
                                errors.Add(ex);
                            }
                        }
                    }

                    // Combine all errors into single AggregateException
                    error = errors.Count > 0 ? new AggregateException(errors) : null;
                }
                // TODO Catch specific exceptions
                // catch (FormatException)
                // catch (NotSupportedException)
                catch (Exception ex)
                {
                    // Error in summary factory?
                    // Make sure we always return a valid summary
                    error = ex;
                }
            }

            // Create final summary from harvested properties and optional error
            return(new ArtifactSummary(props, error));
        }