< Summary

Information
Class: ValidateLib.Metadata.MetdataLocation.MetadataLocator
Assembly: validatelib.dll
File(s): C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\Metadata\MetadataLocation\MetadataLocator.cs
Line coverage
87%
Covered lines: 88
Uncovered lines: 13
Coverable lines: 101
Total lines: 245
Line coverage: 87.1%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

C:\skola_karlovka\RP\code\csv-validator\CSV_Validator\ValidateLib\Metadata\MetadataLocation\MetadataLocator.cs

#LineLine coverage
 1using Newtonsoft.Json.Linq;
 2using ValidateLib.ErrorsAndWarnings.Warnings;
 3using ValidateLib.IRINormalization;
 4using ValidateLib.Metadata.Descriptors;
 5using ValidateLib.UtilityClasses;
 6
 7namespace ValidateLib.Metadata.MetdataLocation
 8{
 9    /// <summary>
 10    /// Locates metadata according to the algorithm specified at:
 11    /// https://www.w3.org/TR/2015/REC-tabular-data-model-20151217/#locating-metadata
 12    /// </summary>
 13    public class MetadataLocator : ILinkLocationTest
 14    {
 115        static string DEFAULT_NAME = "csv-metadata.json";
 116        static string DEFAULT_SUFFIX = "-metadata.json";
 117        public List<Warning> warnings = new List<Warning>();
 18
 19        /// <summary>
 20        /// Locates metadata for remote file.
 21        /// </summary>
 22        /// <param name="fileURL"> Url of remote file we want to located metadata for. </param>
 23        /// <returns> List of possible metadata files. </returns>
 24        public async Task<string?> LocateMetadataForRemoteFileAsync(string fileURL)
 25        {
 26            try
 27            {
 128                return await LocateMetadataForRemoteFileUnsafeAsync(fileURL);
 29            }
 030            catch (Exception)
 31            {
 032                return null;
 33            }
 34
 135        }
 36
 37        async Task<string?> LocateMetadataForRemoteFileUnsafeAsync(string fileURL)
 38        {
 39
 140            string normalizedFileURL = IRINormalizator.NormalizeIri(fileURL);
 141            string baseURL = IRINormalizator.GetBaseUrl(normalizedFileURL);
 42
 143            string? metadataUrl = await GetMetadataLocationFromLinkHeaderAsync(normalizedFileURL, baseURL);
 144            if (metadataUrl is not null)
 045                return metadataUrl;
 46
 147            metadataUrl = GetMetadataLocationFromSiteWideConfig(normalizedFileURL, baseURL);
 148            return metadataUrl;
 149        }
 50
 51        string? GetMetadataLocationFromSiteWideConfig(string normalizedFileURL, string baseURL)
 52        {
 153            List<string> possibleLocations = SiteWideLocator.GetMetadataLocationFromSiteWideConfigAsync(normalizedFileUR
 54
 155            foreach (var possibleLocation in possibleLocations)
 56            {
 157                if (DoesMetadataFileReferenceTheTabularDataFile(normalizedFileURL, possibleLocation, warnings))
 158                    return possibleLocation;
 59
 60            }
 161            return null;
 162        }
 63
 64        async Task<string?> GetMetadataLocationFromLinkHeaderAsync(string normalizedFileURL, string baseURL)
 65        {
 166            string? metadataURL = null;
 167            using (HttpClient httpClient = new HttpClient())
 68            {
 69                // Create a HttpRequestMessage with HttpMethod.Head to not fully download the file just get the link hea
 170                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, normalizedFileURL);
 71
 72                // Send the request
 173                HttpResponseMessage response = await httpClient.SendAsync(request);
 174                var possibleLocations = LinkHeaderProcessor.GetMetadataLocationsFromLinkHeader(response);
 175                foreach (var possibleLocation in possibleLocations)
 76                {
 077                    string absoluteNormalizedMetadataUrl = IRINormalizator.TurnUrlIntoAbsoluteWithBase(baseURL, possible
 078                    if (DoesMetadataFileReferenceTheTabularDataFile(normalizedFileURL, absoluteNormalizedMetadataUrl, wa
 079                        metadataURL = absoluteNormalizedMetadataUrl;
 80                }
 181                return metadataURL;
 82
 83            }
 84
 185        }
 86        /// <summary>
 87        /// Tries the locate the metadata file for local tabular data file.
 88        /// </summary>
 89        /// <param name="filePath">Path to local tabular data file</param>
 90        /// <returns> File of the metadata file or null if the metadata file could not be found </returns>
 91        public string? LocateMetadataForLocalFile(string filePath)
 92        {
 193            string? pathWithDefaulSuffix = filePath + DEFAULT_SUFFIX;
 194            pathWithDefaulSuffix = IriUtilityClass.GetMetadataLocation(pathWithDefaulSuffix);
 195            var defaultSuffixUri = new Uri(pathWithDefaulSuffix!);
 196            pathWithDefaulSuffix = defaultSuffixUri.LocalPath;
 197            if (pathWithDefaulSuffix is not null && File.Exists(pathWithDefaulSuffix))
 98            {
 199                if (DoesMetadataFileReferenceTheTabularDataFile(filePath, pathWithDefaulSuffix, warnings))
 1100                    return pathWithDefaulSuffix;
 101            }
 102
 103
 1104            string? pathWithDefaultName = ReplaceFileName(filePath, DEFAULT_NAME);
 1105            pathWithDefaultName = IriUtilityClass.GetMetadataLocation(pathWithDefaultName);
 1106            if (pathWithDefaultName is not null)
 107            {
 1108                var defaultNameUri = new Uri(pathWithDefaultName);
 1109                pathWithDefaultName = defaultNameUri.LocalPath;
 110            }
 1111            if (pathWithDefaultName is not null && File.Exists(pathWithDefaultName))
 112            {
 1113                if (DoesMetadataFileReferenceTheTabularDataFile(filePath, pathWithDefaultName, warnings))
 1114                    return pathWithDefaultName;
 115            }
 1116            return null;
 117        }
 118
 119        static bool DoesMetadataFileReferenceTheTabularDataFile(string tabularDataIRI, string metadataIRI, List<Warning>
 120        {
 1121            var metadataLocation = IriUtilityClass.GetMetadataLocation(metadataIRI);
 1122            if (metadataLocation is null) return false;
 1123            JObject? jObject = ObjectPropertyUtilityClass.GetDescriptor(metadataIRI);
 1124            if (jObject is null) return false;
 1125            var context = Context.GetContextFromJToken(jObject, new List<Warning>(), metadataLocation);
 126
 1127            if (JsonUtilityClass.IsObjectTableGroupDescriptor(jObject))
 128            {
 1129                if (DoesTheTableGroupReferenceTabularFile(tabularDataIRI, jObject, context))
 130                {
 1131                    return true;
 132                }
 133                else
 134                {
 1135                    if (warnings is not null)
 136                    {
 1137                        warnings.Add(WarningFactory.GetFoundMetadataFileNotDescribingTabularFileWarning(metadataIRI));
 138                    }
 1139                    return false;
 140                }
 141
 142            }
 1143            else if (JsonUtilityClass.IsObjectTableDescriptor(jObject))
 144            {
 1145                TableDescriptor.Normalize(jObject, context);
 1146                if (DoesTableReferenceTheTabularDataFIle(tabularDataIRI, jObject))
 147                {
 1148                    return true;
 149                }
 150                else
 151                {
 0152                    if (warnings is not null)
 153                    {
 0154                        warnings.Add(WarningFactory.GetFoundMetadataFileNotDescribingTabularFileWarning(metadataIRI));
 155                    }
 0156                    return false;
 157                }
 158            }
 159
 0160            return false;
 161        }
 162
 163        static bool DoesTheTableGroupReferenceTabularFile(string tabularDataIRI, JObject tableGroupObject, Context conte
 164        {
 1165            TableGroupDescriptor.Normalize(tableGroupObject, context);
 1166            JArray tablesArray = (JArray)tableGroupObject["tables"]!;
 1167            foreach (var table in tablesArray)
 168            {
 1169                JObject tableObj = (JObject)table;
 1170                if (table.Type == JTokenType.Object && tableObj.ContainsKey("url"))
 171                {
 1172                    if (DoesTableReferenceTheTabularDataFIle(tabularDataIRI, tableObj))
 1173                        return true;
 174                }
 175            }
 1176            return false;
 1177        }
 178        static bool DoesTableReferenceTheTabularDataFIle(string tabularDataIRI, JObject tableObject)
 179        {
 1180            if (tableObject["url"]?.Type == JTokenType.String)
 181            {
 1182                return tableObject["url"]!.ToString() == tabularDataIRI;
 183            }
 0184            return false;
 185        }
 186        static string ReplaceFileName(string originalPath, string newFileName)
 187        {
 188            // Get the directory of the original path
 1189            string? directory = Path.GetDirectoryName(originalPath);
 190
 1191            if (directory is null) return newFileName;
 192
 193            // Combine the directory and the new file name to get the new path
 1194            string newPath = Path.Combine(directory, newFileName);
 1195            return newPath;
 196        }
 197
 198        /// <summary>
 199        /// This is only used for integration tests. Should never be used otherwise. Following methods also.
 200        /// </summary>
 201        /// <param name="fileURL"></param>
 202        /// <param name="mockupMessage"></param>
 203        /// <returns></returns>
 204        /// <exception cref="NotImplementedException"></exception>
 205        string? ILinkLocationTest.LocateMetadataForRemoteFile(string fileURL, HttpResponseMessage mockupMessage)
 206        {
 207            try
 208            {
 1209                return ((ILinkLocationTest)this).LocateMetadataForRemoteFileUnsafe(fileURL, mockupMessage);
 210            }
 0211            catch (Exception)
 212            {
 0213                return null;
 214            }
 1215        }
 216
 217        string? ILinkLocationTest.LocateMetadataForRemoteFileUnsafe(string fileURL, HttpResponseMessage mockupMessage)
 218        {
 1219            string normalizedFileURL = IRINormalizator.NormalizeIri(fileURL);
 1220            string baseURL = IRINormalizator.GetBaseUrl(normalizedFileURL);
 221
 1222            string? metadataUrl = ((ILinkLocationTest)this).GetMetadataLocationFromLinkHeader(normalizedFileURL, baseURL
 1223            if (metadataUrl is not null)
 1224                return metadataUrl;
 225
 1226            metadataUrl = GetMetadataLocationFromSiteWideConfig(normalizedFileURL, baseURL);
 1227            return metadataUrl;
 228        }
 229
 230        string? ILinkLocationTest.GetMetadataLocationFromLinkHeader(string normalizedFileURL, string baseURL, HttpRespon
 231        {
 1232            string? metadataURL = null;
 1233            var possibleLocations = LinkHeaderProcessor.GetMetadataLocationsFromLinkHeader(mockupMessage);
 1234            foreach (var possibleLocation in possibleLocations)
 235            {
 1236                string absoluteNormalizedMetadataUrl = IRINormalizator.TurnUrlIntoAbsoluteWithBase(baseURL, possibleLoca
 1237                if (DoesMetadataFileReferenceTheTabularDataFile(normalizedFileURL, absoluteNormalizedMetadataUrl, warnin
 1238                    metadataURL = absoluteNormalizedMetadataUrl;
 239            }
 1240            return metadataURL;
 241
 242
 243        }
 244    }
 245}