diff --git a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs
index 342811b..878a0e7 100644
--- a/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/Aonprd/Processors/AbstractEntityProcessor.cs
@@ -36,9 +36,16 @@ internal abstract class AbstractEntityProcessor(
AonprdBuilderGlobals globals
) : AbstractInputProcessor(input)
{
+ ///
public Pf2eDbContext Context { get; } = new();
+
+ ///
public StringHelper StringHelper { get; } = stringHelper;
+
+ ///
public DatabaseHelper Helper { get; } = helper;
+
+ ///
public AonprdBuilderGlobals Globals { get; } = globals;
///
@@ -86,7 +93,7 @@ internal abstract class AbstractEntityProcessor(
{
if (Globals.MergeSources.ContainsKey(Input.GetRequired("id")))
{
- throw new SkipItemException(Input.GetRequired("name"), "помечено на слияние.");
+ throw new SkipItemException(GetEntityName(), "помечено на слияние.");
}
}
@@ -145,6 +152,12 @@ internal abstract class AbstractEntityProcessor(
#region "Генерация сущности"
+ ///
+ /// Получает имя сущности из входных данных.
+ ///
+ /// Имя сущности.
+ protected virtual string GetEntityName() => Input.GetRequired("name");
+
///
/// Генерация основных полей корневой сущности.
///
@@ -156,7 +169,7 @@ internal abstract class AbstractEntityProcessor(
}
Entity.Type = Type;
- Entity.Name[LocaleType.English] = Input.GetRequired("name");
+ Entity.Name[LocaleType.English] = GetEntityName();
Entity.Img = "";
Entity.Description = GetDescription();
Entity.Rarity = Input.EnumOptional("rarity", EntityRarity.Common);
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
index 4aadb35..c1c31b5 100644
--- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/Entities/ActionProcessor.cs
@@ -1,9 +1,7 @@
-using Newtonsoft.Json.Linq;
-using Pf2eDataScrapper.Helpers;
+using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
-using Pf2eDataScrapper.Processors.Collection;
using Pf2eModel;
using Pf2eModel.Model.Enum;
@@ -17,7 +15,7 @@ namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors.Entiti
Group = ProcessorGroupEnum.FoundryEnEntities,
Active = false
)]
-[ProcessorDependencies(["foundry-en:compendium"])]
+[ProcessorDependencies(["foundry-en:compendium", "foundry-en:external"])]
internal class ActionProcessor(
DatabaseHelper databaseHelper,
Pf2eDbContext context,
diff --git a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
index c2e72f7..604f62f 100644
--- a/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
+++ b/Pf2eDataScrapper/Importers/Implementations/FoundryEn/Processors/FoundryEnAbstractProcessor.cs
@@ -1,105 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using System.Windows.Documents;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.FoundryEn.Helpers;
using Pf2eDataScrapper.Processors;
+using Pf2eDataScrapper.Processors.Attributes;
using Pf2eDataScrapper.Processors.Definitions;
using Pf2eModel;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
-using Pf2eModel.Model.Base.Source;
using Pf2eModel.Model.Base.Targets;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
-using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.FoundryEn.Processors;
+///
+/// Абстрактный класс-обработчик сущностей, полученных из молуля Foundry pf2e.
+/// Класс предназначен для обработки данных с помощью различных обработчиков,
+/// для которых указан атрибут .
+///
+///
+/// [DI]
+/// [DI]
+/// [DI]
+/// Объект обработки вводимого JSON.
internal abstract class FoundryEnAbstractProcessor(
DatabaseHelper databaseHelper,
Pf2eDbContext context,
FoundryEnGlobals enGlobals,
ProcessorInput input
) : AbstractInputProcessor(input)
- where TEntity : class, IEntity?
+ where TEntity : class, IEntity
{
+ ///
protected DatabaseHelper Helper { get; } = databaseHelper;
+ ///
public Pf2eDbContext Context { get; } = context;
+ ///
public FoundryEnGlobals EnGlobals { get; } = enGlobals;
+ ///
+ /// Тип сущности.
+ ///
public abstract EntityType Type { get; }
+ ///
+ /// Представление сущности, которое будет использоваться для обработки данных.
+ ///
public EntityView View { get; private set; } = null!;
+ ///
+ /// Основная сущность, которая будет использоваться для обработки данных.
+ ///
public Entity Entity => View.Entity;
+ ///
+ /// Подчинённая сущность, которая будет использоваться для обработки данных.
+ ///
public TEntity Object =>
View.SubEntity as TEntity
?? throw new InvalidOperationException(
$"Сущность {View.SubEntity} некорректного типа, ожидался тип {typeof(TEntity)}."
);
- public virtual void ResolveEntity()
+ ///
+ /// Разрешает сущность, основываясь на входных данных.
+ ///
+ /// Идентификатор сущности.
+ public virtual int ResolveEntity()
{
- string name = Input.GetRequired("name");
+ string name = GetEntityName();
try
{
- int id = Context
- .Entities.Include(e => e.Name)
+ List entities = Context
+ .Entities.AsNoTracking()
+ .Include(e => e.Traits)
+ .ThenInclude(t => t.Entity)
.Where(e => Pf2eDbContext.LocaleSearch(e.Name, name) && e.Type == Type)
- .Select(e => e.Id)
- .FirstOrDefault();
+ .ToList();
- View = new EntityView(Context, Type, id);
+ switch (entities.Count)
+ {
+ case 0:
+ throw new("сущность не найдена.");
+ case 1:
+ return entities[0].Id;
+ }
+
+ List inputTraits = Input
+ .GetRequired("system.traits.value")
+ .Select(token => token.ToString())
+ .Order()
+ .ToList();
+
+ foreach (Entity entity in entities)
+ {
+ List entityTraits = entity
+ .Traits.Select(t => t.Entity.Name[LocaleType.English])
+ .Order()
+ .ToList();
+
+ if (entityTraits.SequenceEqual(inputTraits))
+ {
+ return entity.Id;
+ }
+ }
}
catch (Exception ex)
{
throw new SkipItemException(name, ex.Message);
}
+
+ throw new SkipItemException(
+ name,
+ $"Несколько сущностей \"{name}\" найдено, но ни одна не совпадает с входными данными по признакам."
+ );
}
+ ///
public override void Process()
{
- ResolveEntity();
+ View = new(Context, Type, ResolveEntity());
+ AddExternal();
+ }
+
+ ///
+ public override void Save()
+ {
+ Context.SaveChanges();
+ }
+
+ ///
+ /// Получает имя сущности из входных данных.
+ ///
+ /// Имя сущности.
+ protected virtual string GetEntityName() => Input.GetRequired("name");
+
+ ///
+ /// Генерация внешних ссылок сущности.
+ ///
+ protected virtual void AddExternal()
+ {
// External
EntityExternal external = new()
{
- Entity = Entity,
- Target = EnGlobals.FoundryTarget,
+ EntityId = Entity.Id,
+ TargetId = EnGlobals.FoundryTarget.Id,
ExternalId = Input.GetOptional("_id"),
Suffix = Input.GetRequired("_id"),
Md5 = Input.Md5(),
};
Context.EntityExternals.Add(external);
}
-
- public override void Save()
- {
- Context.SaveChanges();
- }
-
- protected Source GetSource(string name)
- {
- Source? source = Context.Sources.FirstOrDefault(s => s.Name == name);
-
- if (source != null)
- {
- return source;
- }
-
- source = new() { Name = name };
-
- Context.Sources.Add(source);
- return source;
- }
}