Exemplo n.º 1
0
        /// <summary>Export the passed FHIR version into the specified directory.</summary>
        /// <param name="info">           The information.</param>
        /// <param name="serverInfo">     Information describing the server.</param>
        /// <param name="options">        Options for controlling the operation.</param>
        /// <param name="exportDirectory">Directory to write files.</param>
        void ILanguage.Export(
            FhirVersionInfo info,
            FhirServerInfo serverInfo,
            ExporterOptions options,
            string exportDirectory)
        {
            // set internal vars so we don't pass them to every function
            // this is ugly, but the interface patterns get bad quickly because we need the type map to copy the FHIR info
            _info    = info;
            _options = options;

            // create a filename for writing (single file for now)
            string filename = Path.Combine(exportDirectory, $"R{info.MajorVersion}.txt");

            using (FileStream stream = new FileStream(filename, FileMode.Create))
                using (ExportStreamWriter writer = new ExportStreamWriter(stream))
                {
                    _writer = writer;

                    WriteHeader();

                    WritePrimitiveTypes(_info.PrimitiveTypes.Values);
                    WriteComplexes(_info.ComplexTypes.Values, "Complex Types");
                    WriteComplexes(_info.Resources.Values, "Resources");

                    WriteOperations(_info.SystemOperations.Values, true, "System Operations");
                    WriteSearchParameters(_info.AllResourceParameters.Values, "All Resource Parameters");
                    WriteSearchParameters(_info.SearchResultParameters.Values, "Search Result Parameters");
                    WriteSearchParameters(_info.AllInteractionParameters.Values, "All Interaction Parameters");

                    WriteValueSets(_info.ValueSetsByUrl.Values, "Value Sets");

                    WriteFooter();
                }
        }
Exemplo n.º 2
0
        /// <summary>Export the passed FHIR version into the specified directory.</summary>
        /// <param name="info">           The information.</param>
        /// <param name="serverInfo">     Information describing the server.</param>
        /// <param name="options">        Options for controlling the operation.</param>
        /// <param name="exportDirectory">Directory to write files.</param>
        void ILanguage.Export(
            FhirVersionInfo info,
            FhirServerInfo serverInfo,
            ExporterOptions options,
            string exportDirectory)
        {
            // set internal vars so we don't pass them to every function
            // this is ugly, but the interface patterns get bad quickly because we need the type map to copy the FHIR info
            _info    = info;
            _options = options;

            _exportedCodes = new HashSet <string>();

            if (options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.Enum))
            {
                _exportEnums = true;
            }
            else
            {
                _exportEnums = false;
            }

            // create a filename for writing (single file for now)
            string filename = Path.Combine(exportDirectory, $"R{info.MajorVersion}.ts");

            using (FileStream stream = new FileStream(filename, FileMode.Create))
                using (ExportStreamWriter writer = new ExportStreamWriter(stream))
                {
                    _writer = writer;

                    WriteHeader();

                    WriteComplexes(_info.ComplexTypes.Values, false);
                    WriteComplexes(_info.Resources.Values, true);

                    if (_exportEnums)
                    {
                        WriteValueSets(_info.ValueSetsByUrl.Values);
                    }

                    WriteFooter();
                }
        }
Exemplo n.º 3
0
        /// <summary>Export the passed FHIR version into the specified directory.</summary>
        /// <param name="info">           The information.</param>
        /// <param name="serverInfo">     Information describing the server.</param>
        /// <param name="options">        Options for controlling the operation.</param>
        /// <param name="exportDirectory">Directory to write files.</param>
        void ILanguage.Export(
            FhirVersionInfo info,
            FhirServerInfo serverInfo,
            ExporterOptions options,
            string exportDirectory)
        {
            // set internal vars so we don't pass them to every function
            // this is ugly, but the interface patterns get bad quickly because we need the type map to copy the FHIR info
            _info    = info;
            _options = options;

            Dictionary <string, CytoElement> elementDict = BuildNodes();

            // create a filename for writing
            string filename = Path.Combine(exportDirectory, $"{_languageName}_R{info.MajorVersion}.json");

            using (FileStream stream = new FileStream(filename, FileMode.Create))
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(writer, elementDict.Values);
                }
        }
Exemplo n.º 4
0
        /// <summary>Export the passed FHIR version into the specified directory.</summary>
        /// <param name="info">           The information.</param>
        /// <param name="serverInfo">     Information describing the server.</param>
        /// <param name="options">        Options for controlling the operation.</param>
        /// <param name="exportDirectory">Directory to write files.</param>
        void ILanguage.Export(
            FhirVersionInfo info,
            FhirServerInfo serverInfo,
            ExporterOptions options,
            string exportDirectory)
        {
            // set internal vars so we don't pass them to every function
            // this is ugly, but the interface patterns get bad quickly because we need the type map to copy the FHIR info
            _info    = info;
            _options = options;

            if (options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.Enum))
            {
                _exportEnums = true;
            }
            else
            {
                _exportEnums = false;
            }

            if ((options.LanguageOptions != null) && (options.LanguageOptions.Count > 0))
            {
                foreach (KeyValuePair <string, string> kvp in options.LanguageOptions)
                {
                    string key = kvp.Key.ToUpperInvariant();

                    switch (key)
                    {
                    case "NAMESPACE":
                        _namespace = kvp.Value;
                        break;
                    }
                }
            }

            _exportedResourceNamesAndTypes = new Dictionary <string, string>();
            _exportedCodes = new HashSet <string>();

            // create a filename for writing (single file for now)
            string filename = Path.Combine(exportDirectory, $"R{info.MajorVersion}.cs");

            using (FileStream stream = new FileStream(filename, FileMode.Create))
                using (ExportStreamWriter writer = new ExportStreamWriter(stream))
                {
                    _writer = writer;

                    WriteHeader();

                    // open namespace
                    _writer.WriteLineIndented($"namespace {_namespace}");
                    _writer.WriteLineIndented("{");
                    _writer.IncreaseIndent();

                    WriteComplexes(_info.ComplexTypes.Values, false);
                    WriteComplexes(_info.Resources.Values, true);

                    if (_exportEnums)
                    {
                        WriteValueSets(_info.ValueSetsByUrl.Values);
                    }

                    WritePolymorphicHelpers();

                    // close namespace
                    _writer.DecreaseIndent();
                    _writer.WriteLineIndented("}");

                    WriteFooter();
                }
        }
        /// <summary>
        /// Attempts to get server information a FhirServerInfo from the given string.
        /// </summary>
        /// <param name="serverUrl"> URL of the server.</param>
        /// <param name="serverInfo">[out] Information describing the server.</param>
        /// <returns>True if it succeeds, false if it fails.</returns>
        public static bool TryGetServerInfo(
            string serverUrl,
            out FhirServerInfo serverInfo)
        {
            if (string.IsNullOrEmpty(serverUrl))
            {
                serverInfo = null;
                return(false);
            }

            HttpClient         client  = null;
            HttpRequestMessage request = null;

            try
            {
                Uri serverUri = new Uri(serverUrl);

                client = new HttpClient();

                request = new HttpRequestMessage()
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(serverUri, "metadata"),
                    Headers    =
                    {
                        Accept =
                        {
                            new MediaTypeWithQualityHeaderValue("application/fhir+json"),
                        },
                    },
                };

                Console.WriteLine($"Requesting metadata from {request.RequestUri}...");

                HttpResponseMessage response = client.SendAsync(request).Result;

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    Console.WriteLine($"Request to {request.RequestUri} failed! {response.StatusCode}");
                    serverInfo = null;
                    return(false);
                }

                string content = response.Content.ReadAsStringAsync().Result;

                if (string.IsNullOrEmpty(content))
                {
                    Console.WriteLine($"Request to {request.RequestUri} returned empty body!");
                    serverInfo = null;
                    return(false);
                }

                ServerFhirVersionStruct version = JsonConvert.DeserializeObject <ServerFhirVersionStruct>(content);

                if (string.IsNullOrEmpty(version.FhirVersion))
                {
                    Console.WriteLine($"Could not determine the FHIR version for {serverUrl}!");
                    serverInfo = null;
                    return(false);
                }

                Console.WriteLine($"Connected to {serverUrl}, FHIR version: {version.FhirVersion}");

                IFhirConverter fhirConverter = ConverterHelper.ConverterForVersion(version.FhirVersion);

                object metadata = fhirConverter.ParseResource(content);

                fhirConverter.ProcessMetadata(metadata, serverUrl, out serverInfo);

                if (serverInfo != null)
                {
                    Console.WriteLine($"Server Information from {serverUrl}:");
                    Console.WriteLine($"\t    FHIR Version: {serverInfo.FhirVersion}");
                    Console.WriteLine($"\t   Software Name: {serverInfo.SoftwareName}");
                    Console.WriteLine($"\tSoftware Version: {serverInfo.SoftwareVersion}");
                    Console.WriteLine($"\t    Release Date: {serverInfo.SoftwareReleaseDate}");
                    Console.WriteLine($"\t     Description: {serverInfo.ImplementationDescription}");
                    Console.WriteLine($"\t       Resources: {serverInfo.ResourceInteractions.Count}");
                    return(true);
                }
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Console.WriteLine($"Failed to get server info from: {serverUrl}, {ex.Message}");
                serverInfo = null;
                return(false);
            }
            finally
            {
                if (request != null)
                {
                    request.Dispose();
                }

                if (client != null)
                {
                    client.Dispose();
                }
            }

            serverInfo = null;
            return(false);
        }
Exemplo n.º 6
0
        /// <summary>Exports.</summary>
        /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
        /// <param name="sourceFhirInfo">  Information describing the source FHIR version information.</param>
        /// <param name="sourceServerInfo">Information describing the source server.</param>
        /// <param name="exportLanguage">  The export language.</param>
        /// <param name="options">         Options for controlling the operation.</param>
        /// <param name="outputPath">      The output filename.</param>
        /// <param name="isPartOfBatch">   True if is part of batch, false if not.</param>
        /// <returns>A List of files written by the export operation.</returns>
        public static List <string> Export(
            FhirVersionInfo sourceFhirInfo,
            FhirServerInfo sourceServerInfo,
            ILanguage exportLanguage,
            ExporterOptions options,
            string outputPath,
            bool isPartOfBatch)
        {
            List <string> filesWritten = new List <string>();

            if (sourceFhirInfo == null)
            {
                throw new ArgumentNullException(nameof(sourceFhirInfo));
            }

            if (exportLanguage == null)
            {
                throw new ArgumentNullException(nameof(exportLanguage));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }

            // check for rooted vs relative
            if (!Path.IsPathRooted(outputPath))
            {
                outputPath = Path.Combine(Directory.GetCurrentDirectory(), outputPath);
            }

            // resolve directory oddness (e.g., follow ..'s, etc.)
            outputPath = Path.GetFullPath(outputPath);

            string tempDir;

            if (Path.HasExtension(outputPath))
            {
                tempDir = Path.Combine(Path.GetDirectoryName(outputPath), $"{exportLanguage.LanguageName}-{DateTime.Now.Ticks}");
            }
            else
            {
                tempDir = Path.Combine(outputPath, $"{exportLanguage.LanguageName}-{DateTime.Now.Ticks}");
            }

            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }

            bool copyPrimitives = false;

            if (exportLanguage.RequiredExportClassTypes.Contains(ExporterOptions.FhirExportClassType.PrimitiveType) ||
                options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.PrimitiveType))
            {
                copyPrimitives = true;
            }

            bool copyComplexTypes = false;

            if (exportLanguage.RequiredExportClassTypes.Contains(ExporterOptions.FhirExportClassType.ComplexType) ||
                options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.ComplexType))
            {
                copyComplexTypes = true;
            }

            bool copyResources = false;

            if (exportLanguage.RequiredExportClassTypes.Contains(ExporterOptions.FhirExportClassType.Resource) ||
                options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.Resource))
            {
                copyResources = true;
            }

            bool copyProfiles = false;

            if (exportLanguage.RequiredExportClassTypes.Contains(ExporterOptions.FhirExportClassType.Profile) ||
                options.OptionalClassTypesToExport.Contains(ExporterOptions.FhirExportClassType.Profile))
            {
                copyProfiles = true;
            }

            // create a copy of the FHIR information for use in this export
            FhirVersionInfo info = sourceFhirInfo.CopyForExport(
                exportLanguage.FhirPrimitiveTypeMap,
                options.ExportList,
                copyPrimitives: copyPrimitives,
                copyComplexTypes: copyComplexTypes,
                copyResources: copyResources,
                copyExtensions: true,
                copyProfiles: copyProfiles,
                options.ExtensionUrls,
                options.ExtensionElementPaths,
                sourceServerInfo,
                options.IncludeExperimental);

            FhirServerInfo serverInfo = null;

            if (sourceServerInfo != null)
            {
                serverInfo = sourceServerInfo.CopyForExport(info);
            }

            // perform our export
            exportLanguage.Export(
                info,
                serverInfo,
                options,
                tempDir);

            string[] exportedFiles = Directory.GetFiles(tempDir, string.Empty, SearchOption.AllDirectories);

            string requestedExtension = string.Empty;

            if (Path.HasExtension(outputPath))
            {
                requestedExtension = Path.GetExtension(outputPath).ToUpperInvariant();
            }

            if (requestedExtension == ".ZIP")
            {
                if (File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }

                // zip the files in the directory for download/output
                CreateZip(outputPath, tempDir);

                // tell the caller the file we wrote
                filesWritten.Add(outputPath);

                // clean up
                DeleteDirectory(tempDir);

                return(filesWritten);
            }

            if ((exportedFiles.Length == 1) &&
                (!string.IsNullOrEmpty(requestedExtension)))
            {
                if (File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }

                File.Move(exportedFiles[0], outputPath);
                filesWritten.Add(outputPath);

                DeleteDirectory(tempDir);

                return(filesWritten);
            }

            if (exportedFiles.Length == 1)
            {
                string filename = Path.Combine(
                    outputPath,
                    $"{exportLanguage.LanguageName}_R{info.MajorVersion}");

                filename = Path.ChangeExtension(filename, exportLanguage.SingleFileExportExtension);

                if (File.Exists(filename))
                {
                    File.Delete(filename);
                }

                File.Move(exportedFiles[0], filename);
                filesWritten.Add(filename);

                DeleteDirectory(tempDir);

                return(filesWritten);
            }

            string path = outputPath;

            if (isPartOfBatch)
            {
                path = Path.Combine(outputPath, $"{exportLanguage.LanguageName}_R{info.MajorVersion}");
            }

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            int duplicateLen = tempDir.Length + 1;

            foreach (string file in exportedFiles)
            {
                string exportName = Path.Combine(path, file.Substring(duplicateLen));

                if (!TryMoveFile(file, exportName))
                {
                    throw new Exception($"Failed to move file {file} into the requested export location!");
                }

                filesWritten.Add(exportName);
            }

            DeleteDirectory(tempDir);

            return(filesWritten);
        }