示例#1
0
        /// <summary>
        /// Try to deserialize the full resource represented by the specified <see cref="ArtifactSummary"/>.
        /// </summary>
        /// <param name="info">An <see cref="ArtifactSummary"/> instance.</param>
        /// <typeparam name="T">The expected resource type.</typeparam>
        /// <returns>A new instance of type <typeparamref name="T"/>, or <c>null</c>.</returns>
        private static T getResourceFromScannedSource <T>(ArtifactSummary info)
            where T : Resource
        {
            // File path of the containing resource file (could be a Bundle)
            var path = info.Origin;

            using (var navStream = DefaultNavigatorStreamFactory.Create(path))
            {
                // TODO: Handle exceptions & null return values
                // e.g. file may have been deleted/renamed since last scan

                // Advance stream to the target resource (e.g. specific Bundle entry)
                if (navStream != null && navStream.Seek(info.Position))
                {
                    // Create navigator for the target resource
                    var nav = navStream.Current;
                    if (nav != null)
                    {
                        // Parse target resource from navigator
                        var parser = new BaseFhirParser();
                        var result = parser.Parse <T>(nav);
                        if (result != null)
                        {
                            // Add origin annotation
                            result.SetOrigin(info.Origin);
                            return(result);
                        }
                    }
                }

                return(null);
            }
        }
        /// <summary>
        /// Generate a list of artifact summary information for a resource file on disk,
        /// using the specified list of <see cref="ArtifactSummaryHarvester"/> instances.
        /// <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="filePath">The file path of the target artifact (or the containing Bundle).</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 List <ArtifactSummary> Generate(
            string filePath,
            params ArtifactSummaryHarvester[] harvesters)
        {
            List <ArtifactSummary> result = null;

            // Try to create navigator stream factory
            // May fail if the specified input is invalid => return error summary
            INavigatorStream navStream = null;

            try
            {
                // Get some source file properties
                var fi = new FileInfo(filePath);

                // Local helper method to initialize origin-specific summary properties
                // All resources from common origin share common property values
                void InitializeSummaryFromOrigin(ArtifactSummaryPropertyBag properties)
                {
                    properties.SetOrigin(filePath);
                    properties.SetFileSize(fi.Length);
                    // implicit conversion to DateTimeOffet. This is allowed, because LastWriteTimeUtc is of DateTimeKind.Utc
                    properties.SetLastModified(fi.LastWriteTimeUtc);
                    switch (fi.Extension)
                    {
                    case FhirFileFormats.XmlFileExtension:
                        properties.SetSerializationFormat(FhirSerializationFormats.Xml);
                        break;

                    case FhirFileFormats.JsonFileExtension:
                        properties.SetSerializationFormat(FhirSerializationFormats.Json);
                        break;
                    }
                }

                // Factory returns null for unknown file formats
                navStream = DefaultNavigatorStreamFactory.Create(filePath);
                result    = Generate(navStream, InitializeSummaryFromOrigin, harvesters);
            }
            catch (Exception ex)
            {
                result = new List <ArtifactSummary>
                {
                    ArtifactSummary.FromException(ex, filePath)
                };
            }

            return(result);
        }
示例#3
0
        /// <summary>
        /// Generate a list of artifact summary information for a resource file on disk,
        /// using the specified list of <see cref="ArtifactSummaryHarvester"/> instances.
        /// <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="origin">The file path of the target artifact (or the containing Bundle).</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(
            string origin,
            params ArtifactSummaryHarvester[] harvesters)
        {
            List <ArtifactSummary> result = null;

            // Try to create navigator stream factory
            // May fail if the specified input is invalid => return error summary
            INavigatorStream navStream = null;

            try
            {
                navStream = DefaultNavigatorStreamFactory.Create(origin);

                // Factory returns null for unknown file formats
                if (navStream != null)
                {
                    // Get some source file properties
                    var fi = new FileInfo(origin);

                    // Resources from same origin share a common serialization format
                    string format =
                        fi.Extension == FhirFileFormats.XmlFileExtension ? FhirSerializationFormats.Xml
                        : fi.Extension == FhirFileFormats.JsonFileExtension ? FhirSerializationFormats.Json
                        : null;

                    // Local helper method to initialize specific summary properties
                    void InitializeSummaryFromOrigin(ArtifactSummaryPropertyBag properties)
                    {
                        properties.SetOrigin(origin);
                        properties.SetFileSize(fi.Length);
                        properties.SetLastModified(fi.LastWriteTimeUtc);
                        properties.SetSerializationFormat(format);
                    }

                    result = Generate(navStream, InitializeSummaryFromOrigin, harvesters);
                }
            }
            catch (Exception ex)
            {
                result = new List <ArtifactSummary>
                {
                    ArtifactSummary.FromException(ex, origin)
                };
            }

            return(result);
        }
示例#4
0
        /// <summary>Returns <c>null</c> if the specified <paramref name="summary"/> equals <c>null</c>.</summary>
        T loadResourceInternal <T>(ArtifactSummary summary) where T : Resource
        {
            if (summary == null)
            {
                return(null);
            }

            // File path of the containing resource file (could be a Bundle)
            var origin = summary.Origin;

            if (string.IsNullOrEmpty(origin))
            {
                throw Error.Argument($"Cannot load resource from summary. The {nameof(ArtifactSummary.Origin)} information is empty or missing.");
            }

            var pos = summary.Position;

            if (string.IsNullOrEmpty(pos))
            {
                throw Error.Argument($"Cannot load resource from summary. The {nameof(ArtifactSummary.Position)} information is empty or missing.");
            }

            T result = null;

            using (var navStream = DefaultNavigatorStreamFactory.Create(origin))
            {
                // Handle exceptions & null return values?
                // e.g. file may have been deleted/renamed since last scan

                // Advance stream to the target resource (e.g. specific Bundle entry)
                if (navStream != null && navStream.Seek(pos))
                {
                    // Create navigator for the target resource
                    var nav = navStream.Current;
                    if (nav != null)
                    {
                        // Parse target resource from navigator
                        var parser = new BaseFhirParser();
                        result = parser.Parse <T>(nav);
                        // Add origin annotation
                        result?.SetOrigin(origin);
                    }
                }
            }

            return(result);
        }
        /// <summary>Generate a list of artifact summary information from an <see cref="INavigatorStream"/> instance.</summary>
        /// <param name="origin">The original location of the target artifact (or the containing Bundle).</param>
        /// <param name="harvesters">
        /// An optional list of <see cref="ArtifactSummaryHarvester"/> delegates that the generator will call
        /// instead of the default harvesters to harvest summary information from an artifact.
        /// </param>
        /// <returns>A list of new <see cref="ArtifactSummary"/> instances.</returns>
        /// <remarks>
        /// For each artifact, the generator executes all (default or specified) harvester delegates
        /// in the specified order. When a delegate returns <c>true</c> to signal that harvesting has
        /// finished, the generator will not call any of the remaining delegates and immediately
        /// proceed to create the final <see cref="ArtifactSummary"/> return value.
        /// <para>
        /// By default, if the <paramref name="harvesters"/> parameter value is null or empty, the
        /// <see cref="ArtifactSummaryGenerator"/> calls the built-in default harvesters
        /// as specified by <see cref="ArtifactSummaryGenerator.DefaultHarvesters"/>.
        /// However if the caller specifies one or more harvester delegates, then the summary
        /// generator calls only the provided delegates, in the specified order.
        /// A custom delegate array may include one or more of the default harvesters.
        /// </para>
        /// <para>
        /// 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.
        /// </para>
        /// </remarks>
        public static List <ArtifactSummary> Generate(
            string origin,
            params ArtifactSummaryHarvester[] harvesters)
        {
            var result = new List <ArtifactSummary>();

            // In case of error, return completed summaries and error info
            INavigatorStream navStream = null;

            try
            {
                // Call default navigator factory
                navStream = DefaultNavigatorStreamFactory.Create(origin);

                // Get some source file properties
                var fi = new FileInfo(origin);

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

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

                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.SetOrigin(origin);
                        properties.SetFileSize(fi.Length);
                        properties.SetLastModified(fi.LastWriteTimeUtc);
                        properties.SetPosition(navStream.Position);
                        properties.SetTypeName(current.Type);
                        properties.SetResourceUri(navStream.Position);

                        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, origin));
            }
            finally
            {
                navStream?.Dispose();
            }
            return(result);
        }