Files
xStringService/Providers/Dtos/XStringServiceProvider.cs
T

1150 lines
34 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using xCommons.Configurations;
using xCommons.Extensions;
using xDataService.Configuration;
using xExceptions.Constants;
using xIdentityService.Interfaces;
using xModels.Dtos;
using xPushService.Base;
using xPushService.Constants;
using xStringService.Extensions;
using xStringService.Interfaces.Dtos;
using xStringService.Models.Dtos;
using xStringService.Models.Entities;
namespace xStringService.Providers.Dtos
{
public class XStringServiceProvider : XBaseDtoProvider<XString, XStringDto, int, XStringDtoHub>, IXStringServiceProvider
{
public XAppConfiguration AppConfiguration { get; }
public XStringServiceProvider(
IHubContext<XStringDtoHub> hub,
XDataServiceConfiguration dataConfiguration,
IXStringRepositoryService service,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider = null
) : base(
hub,
dataConfiguration,
service,
identityProvider
)
{
AppConfiguration = appConfiguration;
}
//
#region Retrievers ...
/// <summary>
/// Retrieve all Exists Languages ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> GetLanguages(
CancellationToken cancellationToken = default
)
{
//
var result = (await Service.GetAllAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
orderBuilder: x => x.OrderBy(y => y.Language)
))
.AsQueryable()
.Select(e => e.Language)
.Distinct()
.ToList();
//
// Check Configuration Default Language Exists ...
var hasDefaultLanguage = !AppConfiguration.DefaultLanguage.IsNullOrEmpty();
if (hasDefaultLanguage)
{
//
// Find Default Language on Result ...
hasDefaultLanguage = result.Any(e => e.ToNormalString() == AppConfiguration.DefaultLanguage.ToNormalString());
if (!hasDefaultLanguage)
{
result.Add(AppConfiguration.DefaultLanguage);
}
}
//
result = result
.Distinct()
.ToList();
//
return result;
}
/// <summary>
/// Check Specified Resource Exists or not ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> IsResourceExists(
string resource,
string language = null,
CancellationToken cancellationToken = default
)
{
//
var result = false;
//
// Validate ...
result = !resource.IsNullOrEmpty();
if (!result)
{
return result;
}
//
XStringDto dto = null;
if (language.IsNullOrEmpty())
{
//
dto = await Service
.FindOneAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate: e => e.ResourceTitle == resource
);
}
else
{
//
dto = await Service
.FindOneAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate:
e => e.ResourceTitle == resource &&
e.Language.ToNormalString() == language.ToNormalString()
);
}
//
result = !dto.IsNullOrDefault();
//
return result;
}
/// <summary>
/// Retrieve Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XStringDto> Get(
string resource,
string language = null,
CancellationToken cancellationToken = default
)
{
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
if (resource.IsNullOrEmpty() || language.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
//
// Check Resource Exists ...
var isExists = await IsResourceExists(
resource: resource,
language: language
);
if (!isExists)
{
XException.NotFound.Throw();
}
//
var result = await Service
.FindOneAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate: e =>
e.ResourceTitle == resource &&
e.Language.ToNormalString() == language.ToNormalString()
);
if (result.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Retrieve Specified Translation of Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<string> GetResourceValue(
string resource,
string language = null,
CancellationToken cancellationToken = default
)
{
//
var result = "";
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
var isValid =
!resource.IsNullOrEmpty() &&
!language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Langauage Exists ...
var languages = await GetLanguages(cancellationToken);
isValid = languages.Any(l => l.ToNormalString() == language.ToNormalString());
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Check Resource Exists ...
isValid = await IsResourceExists(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var dto = await Service.FindOneAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate: e =>
e.ResourceTitle == resource &&
e.Language.ToNormalString() == language.ToNormalString()
);
isValid = !dto.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
result = dto.TranslatedValue;
//
return result;
}
/// <summary>
/// Retrieve an Specified Resource Items ...
/// </summary>
/// <param name="resource"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XStringDto>> GetResources(
string resource,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid = await IsResourceExists(resource);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var result = await Service
.FindManyAsync(
includeBuilder: null,
ignoreSoftDeleteds: true,
predicate: e =>
e.ResourceTitle == resource,
orderBuilder: x =>
x.OrderBy(y => y.ResourceTitle),
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Retrieve Specified Resource Items as XResourceDto Presentation ...
/// </summary>
/// <param name="resource"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XResourceDto> GetResource(
string resource,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isExists = await IsResourceExists(
language: null,
resource: resource,
cancellationToken: cancellationToken
);
if (!isExists)
{
XException.NotFound.Throw();
}
//
// Retrieve String Dto (s) ...
var resources = await GetResources(
resource: resource,
cancellationToken: cancellationToken
);
if (!resource.HasChild())
{
XException.NotFound.Throw();
}
//
var result = new XResourceDto
{
Resource = resource,
Locales = resources.ToXLocaleResourceDtos()
};
//
return result;
}
#endregion
//
#region Query ...
/// <summary>
/// Query Resource IDs ...
/// </summary>
/// <param name="query"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<string>> QueryResourceIds(
XQuery query,
CancellationToken cancellationToken = default
)
{
//
var dtoResult = await Service.QueryAsync(
query: query,
predicate: null,
includeBuilder: null,
ignoreSoftDeleteds: true,
orderBuilder: x =>
x.OrderBy(y => y.ResourceTitle),
cancellationToken: cancellationToken
);
//
var result = new XQueryResult<string>()
.UpdateData(
updateWith: dtoResult,
propertyBlackList: new List<string>
{
nameof(XQueryResult<string>.Items)
});
//
result.Items = dtoResult.Items.ToList().Select(dto => dto.ResourceTitle);
//
return result;
}
/// <summary>
/// Query Specified Language Resources ...
/// </summary>
/// <param name="query"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XStringDto>> QueryLanguageResources(
XQuery query,
string language = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.QueryAsync(
query: query,
includeBuilder: null,
ignoreSoftDeleteds: true,
orderBuilder: x => x
.OrderBy(y => y.Language)
.ThenBy(y => y.ResourceTitle),
cancellationToken: cancellationToken,
predicate: x =>
x.Language.ToNormalString() == language.ToNormalString()
);
//
return result;
}
/// <summary>
/// Query Locale Resources ...
/// </summary>
/// <param name="query"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<XLocaleResourceDto>> QueryLocaleResources(
XQuery query,
string language = null,
CancellationToken cancellationToken = default
)
{
//
Expression<Func<XString, bool>> predicate = null;
if (!language.IsNullOrEmpty())
{
//
predicate = x =>
x.Language.ToNormalString() == language.ToNormalString();
}
//
var dtoResult = await Service.QueryAsync(
query: query,
includeBuilder: null,
predicate: predicate,
ignoreSoftDeleteds: true,
orderBuilder: x => x
.OrderBy(y => y.Language)
.ThenBy(y => y.ResourceTitle),
cancellationToken: cancellationToken
);
//
var result = new XQueryResult<XLocaleResourceDto>()
.UpdateData(
updateWith: dtoResult,
propertyBlackList: new List<string>
{
nameof(XQueryResult<XLocaleResourceDto>.Items)
});
//
result.Items = dtoResult.Items.ToList().ToXLocaleResourceDtos();
//
return result;
}
#endregion
//
#region Add/Update Actions ...
/// <summary>
/// Add Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="value"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> Add(
string resource,
string value,
string language = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
bool result = false;
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
result =
!value.IsNullOrEmpty() &&
!resource.IsNullOrEmpty() &&
!language.IsNullOrEmpty();
if (!result)
{
return result;
}
//
// Check Exists ...
bool isExists = await IsResourceExists(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
result = !isExists;
if (!result)
{
XException.Duplicate.Throw();
}
//
// Prepare Entity to Add ...
XStringDto item = new XStringDto
{
Language = language,
TranslatedValue = value,
ResourceTitle = resource,
};
item = await AddAsync(
item: item,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
result = !item.IsNullOrDefault();
//
return result;
}
/// <summary>
/// Update Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="value"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> Update(
string resource,
string value,
string language = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
bool result = false;
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
result =
!value.IsNullOrEmpty() &&
!language.IsNullOrEmpty() &&
!resource.IsNullOrEmpty();
if (!result)
{
return result;
}
//
// Check Value Must Exists ...
result = await IsResourceExists(
resource: resource,
language: language,
cancellationToken: cancellationToken
);
if (!result)
{
XException.NotFound.Throw();
}
//
var item = await Get(
language: language,
resource: resource,
cancellationToken: cancellationToken
);
item.TranslatedValue = value;
item = await UpdateAsync(
item: item,
id: item.Id,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
result = !item.IsNullOrDefault();
//
return result;
}
/// <summary>
/// Add Or Update Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="value"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> AddOrUpdate(
string resource,
string value,
string language = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = false;
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Check Existsance ...
bool isExists = await IsResourceExists(
resource: resource,
language: language
);
//
// Act Based on Existance ...
if (isExists)
{
//
result = await Update(
value: value,
resource: resource,
language: language,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
else
{
//
result = await Add(
value: value,
resource: resource,
language: language,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// Add Specified Locale Resource ...
/// </summary>
/// <param name="item"></param>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XStringDto> AddByLocaleResource(
XLocaleResourceDto item,
string resource,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
!item.IsNull() &&
!resource.IsNullOrEmpty() &&
!item.Value.IsNullOrEmpty() &&
!item.Language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Specified Resource / Language Exists ...
isValid = await IsResourceExists(
resource: resource,
language: item.Language,
cancellationToken: cancellationToken
);
if (isValid)
{
XException.Duplicate.Throw();
}
//
// Prepare Item to Add ...
var result = new XStringDto
{
Language = item.Language,
ResourceTitle = resource,
TranslatedValue = item.Value
};
result = await AddAsync(
item: result,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Update Specified Locale Resource ...
/// </summary>
/// <param name="item"></param>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XStringDto> UpdateByLocaleResource(
XLocaleResourceDto item,
string resource,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
!item.IsNull() &&
!resource.IsNullOrEmpty() &&
!item.Value.IsNullOrEmpty() &&
!item.Language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Specified Resource / Language Exists ...
isValid = await IsResourceExists(
resource: resource,
language: item.Language,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
var result = await Get(
resource: resource,
language: item.Language,
cancellationToken: cancellationToken
);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Update ...
result.TranslatedValue = item.Value;
result = await UpdateAsync(
item: result,
id: result.Id,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Add Or Update Resource By Locale ...
/// </summary>
/// <param name="item"></param>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XStringDto> AddOrUpdateByLocaleResource(
XLocaleResourceDto item,
string resource,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
!item.IsNull() &&
!resource.IsNullOrEmpty() &&
!item.Value.IsNullOrEmpty() &&
!item.Language.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Specified Resource / Language Exists ...
isValid = await IsResourceExists(
resource: resource,
language: item.Language,
cancellationToken: cancellationToken
);
//
XStringDto result = null;
if (!isValid)
{
//
result = await AddByLocaleResource(
item: item,
resource: resource,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
else
{
//
result = await UpdateByLocaleResource(
item: item,
resource: resource,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
if (result.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
return result;
}
/// <summary>
/// Add Or Update all XResourceDto(s) Locales ...
/// </summary>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XStringDto>> AddByResource(
XResourceDto item,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid =
!item.IsNull() &&
item.Locales.HasChild() &&
!item.Resource.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var result = await Task
.WhenAll(item.Locales
.Select(async e => await AddOrUpdateByLocaleResource(
item: e,
resource: item.Resource,
connectionId: connectionId,
cancellationToken: cancellationToken)));
//
return result;
}
#endregion
//
#region Remove Actions ...
/// <summary>
/// Remove all Specified Language's Resources ...
/// </summary>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task RemoveLanguageResources(
string language,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid = !language.IsNullOrEmpty();
if (!isValid)
{
return;
}
//
var dtos = await Service
.FindManyAsync(
orderBuilder: null,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate: e =>
e.Language.ToNormalString() == language.ToNormalString());
//
try
{
//
await Service.RemoveRangeAsync(
items: dtos,
softDelete: false,
saveChanges: true,
cancellationToken: cancellationToken
);
//
var ids = dtos.Select(e => e.Id);
await SendPush(
connectionId: connectionId,
payLoad: ids.ToJSON(camelCase: true),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.DeleteMany.GetStringValue()
);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// Remove all Specified Resource Ids instances ...
/// </summary>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<XStringDto>> RemoveResource(
string resource,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
bool isValid = !resource.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var result = await Service
.FindManyAsync(
orderBuilder: null,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken,
predicate: e =>
e.ResourceTitle.ToNormalString() == resource.ToNormalString());
//
try
{
//
await Service.RemoveRangeAsync(
items: result,
softDelete: false,
saveChanges: true,
cancellationToken: cancellationToken
);
//
var ids = result.Select(e => e.Id);
await SendPush(
connectionId: connectionId,
payLoad: ids.ToJSON(camelCase: true),
cancellationToken: cancellationToken,
action: XBaseEntityHubAction.DeleteMany.GetStringValue()
);
}
catch (Exception ex)
{
throw ex;
}
//
return result;
}
/// <summary>
/// Remove Specified Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> Remove(
string resource,
string language = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
bool result = false;
//
// Normalize ...
if (language.IsNullOrEmpty())
{
language = AppConfiguration.DefaultLanguage;
}
//
// Validate ...
result =
!language.IsNullOrEmpty() &&
!resource.IsNullOrEmpty();
if (!result)
{
return result;
}
//
// Check Resource Exists ...
result = await IsResourceExists(
language: language,
resource: resource,
cancellationToken: cancellationToken
);
if (!result)
{
return result;
}
//
var dto = await Get(
language: language,
resource: resource,
cancellationToken: cancellationToken
);
result = !dto.IsNullOrDefault();
if (!result)
{
return result;
}
//
dto = await RemoveAsync(
id: dto.Id,
softDelete: false,
saveChanges: true,
connectionId: connectionId,
cancellationToken: cancellationToken
);
result = !dto.IsNullOrDefault();
//
return result;
}
/// <summary>
/// Remove all Resource of Specified XResourceDto ...
/// </summary>
/// <param name="item"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task RemoveByResource(
XResourceDto item,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
bool isValid =
!item.IsNullOrDefault() &&
item.Locales.HasChild() &&
!item.Resource.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
foreach (var locale in item.Locales)
{
//
await Remove(
resource: item.Resource,
language: locale.Language,
connectionId: connectionId,
cancellationToken: cancellationToken
);
}
}
#endregion
}
}