public override async Task <IEnumerable <IMetadataTreeNode> > LoadNodesAsync(IMetadataLoadContext loadCtx) { loadCtx.EnsureNotNull(nameof(loadCtx)); // loadCtx.ThrowIfCancellationRequested(); return(await LoadNodesAsync(loadCtx : loadCtx, directory : GetLocationDirectory(loadCtx)).ConfigureAwait(false)); }
// TODO: Put strings into the resources. // TODO_HIGH: Реализовать поддержку переменных среды (%var%). // protected virtual DirectoryInfo GetLocationDirectory(IMetadataLoadContext loadCtx) { loadCtx.EnsureNotNull(nameof(loadCtx)); // var locationUri = LocationUri; if (locationUri.IsAbsoluteUri) { return(new DirectoryInfo(locationUri.LocalPath)); } else { var path = locationUri.ExpandEnvironmentVariables(); if (Path.IsPathRooted(path)) { return(new DirectoryInfo(path)); } else { Uri baseUri; try { baseUri = loadCtx.BaseUri; baseUri.Arg($"{nameof(loadCtx)}.{nameof(loadCtx.BaseUri)}").EnsureFileScheme().EnsureLoopbackOrUnc(); } catch (Exception exception) { throw new EonException( message: $"Базовый URI контекста загрузки метаданных не может быть использован для разрешения полного пути к требуемой директории расположения метаданных.{Environment.NewLine}\tКонтекст загрузки:{loadCtx.FmtStr().GNLI2()}{Environment.NewLine}\tТребуемая директория: '{locationUri.FmtStr().G()}'.", innerException: exception); } return(new DirectoryInfo(Path.Combine(path1: Path.GetDirectoryName(baseUri.LocalPath), path2: path))); } } }
protected sealed override async Task <IVh <IMetadata> > DoLoadMetadataAsync(IMetadataLoadContext loadCtx) { loadCtx.EnsureNotNull(nameof(loadCtx)); // await Task.CompletedTask; return(EmbeddedMetadata.ToValueHolder(ownsValue: false)); }
// TODO: Put strings into the resources. // IEnumerable <IMetadataTreeNode> P_LoadNodes(IMetadataLoadContext loadCtx, DirectoryInfo directory, IMetadataTreeNode parentNode = default, bool continuation = default) { loadCtx.EnsureNotNull(nameof(loadCtx)); directory.EnsureNotNull(nameof(directory)); // loadCtx.ThrowIfCancellationRequested(); var buffer = continuation ? null : new List <IMetadataTreeNode>(); var fileNameAndNodeMap = new Dictionary <string, IMetadataTreeNode>(FileSystemAccessUtilities.DefaultPathComparer); // var files = directory.GetFiles(searchPattern: "*", searchOption: SearchOption.TopDirectoryOnly); for (var i = 0; i < files.Length; i++) { loadCtx.ThrowIfCancellationRequested(); var file = files[i]; if (ShouldIncludeFile(context: loadCtx, file: file, mediaType: out var fileFormatMediaType)) { var metadataElement = new MetadataFileInclusionTreeElement() { LocationUri = new Uri(uriString: $"{UriUtilities.UriSchemeFile}://{file.FullName}", uriKind: UriKind.Absolute), FormatMediaTypeName = fileFormatMediaType }; var node = new MetadataTreeNode(parent: parentNode, caption: file.Name, metadataElement: metadataElement); buffer?.Add(node); fileNameAndNodeMap.Add(Path.GetFileNameWithoutExtension(file.Name), node); } } // var subdirectories = directory.GetDirectories(searchPattern: "*", searchOption: SearchOption.TopDirectoryOnly); for (var i = 0; i < subdirectories.Length; i++) { loadCtx.ThrowIfCancellationRequested(); var subdirectory = subdirectories[i]; if (!fileNameAndNodeMap.TryGetValue(subdirectory.Name, out var subdirectoryParentNode)) { MetadataName name; try { name = (MetadataName)subdirectory.Name; } catch (Exception exception) { throw new EonException(message: $"Directory name can't be converted to metadata name (type '{typeof(MetadataName)}').{Environment.NewLine}\tDirectory:{subdirectory.FmtStr().GNLI2()}", innerException: exception); } var metadataElement = new EmbeddedMetadataTreeElement(embeddedMetadata: new Namespace(name: name), ownsEmbeddedMetadata: true); var node = new MetadataTreeNode(parent: parentNode, caption: metadataElement.EmbeddedMetadata.Name, metadataElement: metadataElement); buffer?.Add(node); subdirectoryParentNode = node; } // P_LoadNodes(loadCtx: loadCtx, directory: subdirectory, parentNode: subdirectoryParentNode, continuation: true); } // return(buffer ?? Enumerable.Empty <IMetadataTreeNode>()); }
// TODO: Put strings into the resources. // TODO_HIGH: Use SubjectMaterializer component to load metadata. // protected override async Task <IVh <IMetadata> > DoLoadMetadataAsync(IMetadataLoadContext loadCtx) { loadCtx.EnsureNotNull(nameof(loadCtx)); // loadCtx.ThrowIfCancellationRequested(); await Task.CompletedTask; return(doLoad()); // IVh <IMetadata> doLoad() { var locDeserializedObjectAsIDisposable = default(IDisposable); try { var locFormatMediaTypeName = FormatMediaTypeName; var locLocationUri = LocationUri; // string locLoadFilePath; if (locLocationUri.IsAbsoluteUri) { locLoadFilePath = locLocationUri.LocalPath; } else { var locBaseUri = loadCtx.BaseUri; string locBaseUriValidationErrorMessage; if (!locBaseUri.IsAbsoluteUri) { throw new EonException( message: $"Базовый URI контекста загрузки метаданных не может быть использован для разрешения полного пути к файлу загрузки метаданных '{locLocationUri}'.{Environment.NewLine}{FormatXResource(typeof(Uri), "NotAbsoluteUri", locBaseUri.FmtStr().G())}{Environment.NewLine}\tКонтекст загрузки:{loadCtx.FmtStr().GNLI()}"); } else if (!P_IsLocationUriValid(locBaseUri, out locBaseUriValidationErrorMessage)) { throw new EonException( message: $"Базовый URI контекста загрузки метаданных не может быть использован для разрешения полного пути к файлу загрузки метаданных '{locLocationUri}'.{Environment.NewLine}{locBaseUriValidationErrorMessage}{Environment.NewLine}\tКонтекст загрузки:{loadCtx.FmtStr().GNLI2()}"); } locLoadFilePath = Path.Combine(Path.GetDirectoryName(locBaseUri.LocalPath), locLocationUri.ToString()); } var locLoadFile = new FileInfo(locLoadFilePath); if (!locLoadFile.Exists) { throw new FileNotFoundException(FormatXResource(locator: typeof(FileNotFoundException), subpath: null, args: new[] { locLoadFile.FullName }), locLoadFile.FullName); } // IMetadata locLoadedMetadata; object locDeserializedObject; if (IsXmlMediaType(locFormatMediaTypeName)) { try { using (var locFileStream = locLoadFile.OpenRead()) using (var locXmlReader = XmlReader.Create(locFileStream, loadCtx.CreateXmlReaderSettings())) { var locSerializer = loadCtx.CreateXmlObjectSerializer(typeof(object)); locDeserializedObjectAsIDisposable = (locDeserializedObject = locSerializer.ReadObject(reader: locXmlReader, verifyObjectName: false)) as IDisposable; } if (locDeserializedObject is IMetadata locMetadata) { if (locMetadata.IsAutoName && MetadataName.TryParse(value: Path.GetFileNameWithoutExtension(path: locLoadFile.Name), result: out var metadataName)) { locMetadata.Name = metadataName; } locLoadedMetadata = locMetadata; } else if (!(locDeserializedObject is null)) { throw new EonException(message: $"Десериализованный объект имеет тип '{locDeserializedObject.GetType()}', который не совместим с типом '{typeof(IMetadata)}'."); } else { locLoadedMetadata = null; } } catch (Exception exception) { throw new EonException(message: $"Ошибка загрузки объекта из файла.{Environment.NewLine}\tФайл:{locLoadFile.FullName.FmtStr().GNLI2()}.", innerException: exception); } }