RemoteContentProvider get items WIP

This commit is contained in:
2023-08-28 09:29:52 +02:00
parent 79971fe0f4
commit bb44ca0308
49 changed files with 765 additions and 118 deletions

View File

@@ -25,4 +25,5 @@
<ProjectReference Include="..\..\Library\InitableService\InitableService.csproj" />
</ItemGroup>
</Project>

View File

@@ -2,8 +2,8 @@ namespace FileTime.Core.Timeline;
public class PointInTime
{
public static readonly PointInTime Eternal = new PointInTime();
public static readonly PointInTime Present = new PointInTime();
public static readonly PointInTime Eternal = new();
public static readonly PointInTime Present = new();
private readonly List<Difference> _differences;
@@ -46,5 +46,5 @@ public class PointInTime
return merged;
}
public static PointInTime CreateEmpty() => new PointInTime();
public static PointInTime CreateEmpty() => new();
}

View File

@@ -1,13 +0,0 @@
using FileTime.Core.Command.Copy;
using FileTime.Core.Command.Move;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.Core.Command;
public static class Startup
{
public static IServiceCollection AddCommands(this IServiceCollection serviceCollection) =>
serviceCollection
.AddSingleton<CopyCommandFactory>()
.AddSingleton<MoveCommandFactory>();
}

View File

@@ -1,13 +0,0 @@
using FileTime.Core.Command;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.Core.CommandHandlers;
public static class Startup
{
public static IServiceCollection AddDefaultCommandHandlers(this IServiceCollection serviceCollection)
{
return serviceCollection
.AddSingleton<ICommandHandler, StreamCopyCommandHandler>();
}
}

View File

@@ -28,6 +28,7 @@ public class ContentProviderRegistry : IContentProviderRegistry
private void InitializeContentProviderListIfNeeded()
{
if (_initialized) return;
lock (_lock)
{
if (!_initialized)

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>FileTime.Core</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FileTime.Core.Abstraction\FileTime.Core.Abstraction.csproj" />
<ProjectReference Include="..\FileTime.Core.CommandHandlers\FileTime.Core.CommandHandlers.csproj" />
<ProjectReference Include="..\FileTime.Core.Command\FileTime.Core.Command.csproj" />
<ProjectReference Include="..\FileTime.Core.ContentAccess\FileTime.Core.ContentAccess.csproj" />
<ProjectReference Include="..\FileTime.Core.Serialization\FileTime.Core.Serialization.csproj" />
<ProjectReference Include="..\FileTime.Core.Services\FileTime.Core.Services.csproj" />
<ProjectReference Include="..\FileTime.Core.Timeline\FileTime.Core.Timeline.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,88 @@
using FileTime.Core.Command;
using FileTime.Core.Command.Copy;
using FileTime.Core.Command.CreateContainer;
using FileTime.Core.Command.CreateElement;
using FileTime.Core.Command.Delete;
using FileTime.Core.Command.Move;
using FileTime.Core.CommandHandlers;
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
using FileTime.Core.Serialization;
using FileTime.Core.Serialization.Container;
using FileTime.Core.Services;
using FileTime.Core.Timeline;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace FileTime.Core;
public static class Startup
{
public static IServiceCollection AddCoreDependencies(this IServiceCollection serviceCollection)
=> serviceCollection
.AddCoreServices()
.AddTimelineServices()
.AddDefaultCommandHandlers()
.AddCommands()
.AddCommandFactories()
.AddCommandServices()
.AddContentAccessServices()
.AddSerialization();
private static IServiceCollection AddContentAccessServices(this IServiceCollection serviceCollection)
{
serviceCollection.TryAddSingleton<IContentAccessorFactory, ContentAccessorFactory>();
serviceCollection.TryAddSingleton<IContentProviderRegistry, ContentProviderRegistry>();
serviceCollection.TryAddSingleton<IRootContentProvider, RootContentProvider>();
return serviceCollection;
}
private static IServiceCollection AddCommandServices(this IServiceCollection serviceCollection)
{
serviceCollection.TryAddSingleton<ICommandRunner, CommandRunner>();
return serviceCollection;
}
private static IServiceCollection AddCoreServices(this IServiceCollection serviceCollection)
{
serviceCollection.TryAddTransient<ITab, Tab>();
serviceCollection.TryAddSingleton<ITabEvents, TabEvents>();
return serviceCollection;
}
private static IServiceCollection AddTimelineServices(this IServiceCollection serviceCollection)
{
serviceCollection.TryAddSingleton<ICommandScheduler, CommandScheduler>();
serviceCollection.TryAddSingleton<ITimelessContentProvider, TimelessContentProvider>();
//TODO: check local/remote context
serviceCollection.TryAddSingleton<ILocalCommandExecutor, LocalCommandExecutor>();
serviceCollection.TryAddSingleton<ICommandSchedulerNotifier, LocalCommandSchedulerNotifier>();
return serviceCollection;
}
private static IServiceCollection AddCommands(this IServiceCollection serviceCollection)
=> serviceCollection
.AddTransient<CreateContainerCommand>()
.AddTransient<CreateElementCommand>()
.AddTransient<DeleteCommand>();
private static IServiceCollection AddCommandFactories(this IServiceCollection serviceCollection) =>
serviceCollection
.AddSingleton<CopyCommandFactory>()
.AddSingleton<MoveCommandFactory>();
private static IServiceCollection AddSerialization(this IServiceCollection serviceCollection)
{
serviceCollection.TryAddSingleton<ISerializer<IContainer>, ContainerSerializer>();
return serviceCollection;
}
private static IServiceCollection AddDefaultCommandHandlers(this IServiceCollection serviceCollection)
=> serviceCollection
.AddSingleton<ICommandHandler, StreamCopyCommandHandler>();
}

View File

@@ -0,0 +1,14 @@
using FileTime.Core.Models;
namespace FileTime.Core.Serialization;
public class AbsolutePathSerializer
{
public static SerializedAbsolutePath Serialize(AbsolutePath absolutePath)
=> new()
{
PointInTime = absolutePath.PointInTime,
Path = absolutePath.Path.Path,
Type = absolutePath.Type
};
}

View File

@@ -0,0 +1,5 @@
using FileTime.Core.ContentAccess;
namespace FileTime.Core.Serialization.Container;
public record ContainerDeserializationContext(IContentProvider ContentProvider);

View File

@@ -0,0 +1,10 @@
using System.Collections.ObjectModel;
using FileTime.Core.Models;
namespace FileTime.Core.Serialization.Container;
public record ContainerDeserializationResult(
Models.Container Container,
ObservableCollection<Exception> Exceptions,
ExtensionCollection Extensions,
ObservableCollection<AbsolutePath> Items);

View File

@@ -0,0 +1,67 @@
using System.Collections.ObjectModel;
using FileTime.Core.Enums;
using FileTime.Core.Models;
using FileTime.Core.Timeline;
namespace FileTime.Core.Serialization.Container;
public class ContainerDeserializer
{
private readonly ITimelessContentProvider _timelessContentProvider;
public ContainerDeserializer(ITimelessContentProvider timelessContentProvider)
{
_timelessContentProvider = timelessContentProvider;
}
public ContainerDeserializationResult Deserialize(
SerializedContainer source,
ContainerDeserializationContext context)
{
ObservableCollection<Exception> exceptions = new();
ExtensionCollection extensions = new();
ObservableCollection<AbsolutePath> items = new();
var mappedItems = source.Items
.Select(x => new AbsolutePath(
_timelessContentProvider,
x.PointInTime,
new FullName(x.Path),
x.Type
)
);
foreach (var item in
mappedItems)
{
items.Add(item);
}
var container = new Models.Container(
source.Name,
source.DisplayName,
new FullName(source.FullName),
new NativePath(source.NativePath),
new AbsolutePath(_timelessContentProvider, PointInTime.Present, new FullName(source.Parent), AbsolutePathType.Container),
source.IsHidden,
source.IsExists,
source.CreatedAt,
source.ModifiedAt,
source.CanDelete,
source.CanRename,
source.Attributes,
context.ContentProvider,
source.AllowRecursiveDeletion,
PointInTime.Present,
exceptions,
new ReadOnlyExtensionCollection(extensions),
items
);
return new ContainerDeserializationResult(
container,
exceptions,
extensions,
items);
}
}

View File

@@ -0,0 +1,32 @@
using FileTime.Core.Models;
namespace FileTime.Core.Serialization.Container;
public class ContainerSerializer : ISerializer<IContainer>
{
Task<ISerialized> ISerializer<IContainer>.SerializeAsync(int id, IContainer item) => Task.FromResult(Serialize(id, item));
private ISerialized Serialize(int id, IContainer container)
{
var items = container.Items.Select(AbsolutePathSerializer.Serialize).ToArray();
var serialized = new SerializedContainer
{
Id = id,
Name = container.Name,
DisplayName = container.DisplayName,
FullName = container.FullName!.Path,
NativePath = container.NativePath!.Path,
Parent = container.Parent!.Path.Path,
IsHidden = container.IsHidden,
IsExists = container.IsExists,
CreatedAt = container.CreatedAt,
ModifiedAt = container.ModifiedAt,
CanDelete = container.CanDelete,
CanRename = container.CanRename,
Attributes = container.Attributes,
AllowRecursiveDeletion = container.AllowRecursiveDeletion,
Items = items
};
return serialized;
}
}

View File

@@ -0,0 +1,29 @@
using System.Runtime.Serialization;
using FileTime.Core.Enums;
using MessagePack;
namespace FileTime.Core.Serialization.Container;
[DataContract]
[MessagePackObject]
public class SerializedContainer : ISerialized
{
[Key(0)] [DataMember(Order = 0)] public required int Id { get; set; }
[Key(1)] [DataMember(Order = 1)] public required string Name { get; set; }
[Key(2)] [DataMember(Order = 2)] public required string DisplayName { get; set; }
[Key(3)] [DataMember(Order = 3)] public required string FullName { get; set; }
[Key(4)] [DataMember(Order = 4)] public required string NativePath { get; set; }
[Key(5)] [DataMember(Order = 5)] public required string Parent { get; set; }
[Key(6)] [DataMember(Order = 6)] public required bool IsHidden { get; set; }
[Key(7)] [DataMember(Order = 7)] public required bool IsExists { get; set; }
[Key(8)] [DataMember(Order = 8)] public required DateTime? CreatedAt { get; set; }
[Key(9)] [DataMember(Order = 9)] public required DateTime? ModifiedAt { get; set; }
[Key(10)] [DataMember(Order = 10)] public required SupportsDelete CanDelete { get; set; }
[Key(11)] [DataMember(Order = 11)] public required bool CanRename { get; set; }
[Key(12)] [DataMember(Order = 12)] public required string? Attributes { get; set; }
[Key(13)] [DataMember(Order = 13)] public required bool AllowRecursiveDeletion { get; set; }
[Key(14)] [DataMember(Order = 14)] public required SerializedAbsolutePath[] Items { get; set; }
}

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FileTime.Core.Abstraction\FileTime.Core.Abstraction.csproj" />
<ProjectReference Include="..\FileTime.Core.Models\FileTime.Core.Models.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="2.5.124" />
<PackageReference Include="MessagePackAnalyzer" Version="2.5.124">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,9 @@
using FileTime.Core.Serialization.Container;
namespace FileTime.Core.Serialization;
[MessagePack.Union(0, typeof(SerializedContainer))]
public interface ISerialized
{
int Id { get; }
}

View File

@@ -0,0 +1,14 @@
using FileTime.Core.Models;
namespace FileTime.Core.Serialization;
public interface ISerializer
{
Task<ISerialized> SerializeAsync(int id, object item);
}
public interface ISerializer<T> where T : IItem
{
async Task<ISerialized> SerializeAsync(int id, object item) => await SerializeAsync(id, (T) item);
Task<ISerialized> SerializeAsync(int id, T item);
}

View File

@@ -0,0 +1,15 @@
using System.Runtime.Serialization;
using FileTime.Core.Enums;
using FileTime.Core.Timeline;
using MessagePack;
namespace FileTime.Core.Serialization;
[MessagePackObject]
[DataContract]
public class SerializedAbsolutePath
{
[Key(0)] [DataMember(Order = 0)] public required PointInTime PointInTime { get; set; }
[Key(1)] [DataMember(Order = 1)] public required string Path { get; set; }
[Key(2)] [DataMember(Order = 2)] public required AbsolutePathType Type { get; set; }
}

View File

@@ -0,0 +1,11 @@
using FileTime.Core.Timeline;
namespace FileTime.Core.Serialization.Timeline;
public class PointInTimeSerializer
{
public static SerializedPointInTime Serialize(PointInTime pointInTime)
{
return new();
}
}

View File

@@ -0,0 +1,9 @@
using FileTime.Core.Timeline;
namespace FileTime.Core.Serialization.Timeline;
public class SerializedDifference
{
public required SerializedAbsolutePath AbsolutePath { get; set; }
public required DifferenceActionType Action { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace FileTime.Core.Serialization.Timeline;
public class SerializedPointInTime
{
}

View File

@@ -188,7 +188,17 @@ public class Tab : ITab
private static IItem MapItem(AbsolutePath item)
{
var t = Task.Run(async () => await item.ResolveAsync(true));
var t = Task.Run(async () =>
{
try
{
return await item.ResolveAsync(true);
}
catch
{
return null;
}
});
t.Wait();
return t.Result;
}