Files
xContentService/Providers/XContentProvider.cs
T

692 lines
22 KiB
C#

using System;
using System.Linq;
using xModels.Dtos;
using System.Threading;
using xCommons.Extensions;
using xTagService.Providers;
using xExceptions.Constants;
using xIdentityModels.Models;
using System.Threading.Tasks;
using xPushService.Constants;
using System.Linq.Expressions;
using xCommons.Configurations;
using xContentService.Constants;
using xContentService.Interfaces;
using System.Collections.Generic;
using xContentService.Extensions;
using xContentService.Models.Dtos;
using xContentService.Providers.Dtos;
using xContentService.Models.Entities;
using xContentService.Interfaces.Dtos;
using Microsoft.EntityFrameworkCore.Query;
using xContentService.Interfaces.Enrichers;
namespace xContentService.Providers
{
public class XContentProvider : XBaseProvidedHasTag<XContent, XContentDto, Guid, XContentDtoHub>, IXContentProvider
{
private readonly IXContentEnricher enricher;
private readonly XAppConfiguration configuration;
private readonly IXContentTagProvider tagProvider;
private readonly IXContentServiceProvider provider;
private readonly IXContentTitleResourceProvider titleResourceProvider;
private readonly IXContentDescriptionResourceProvider descriptionResourceProvider;
public XContentProvider(
IXContentEnricher enricher,
XAppConfiguration configuration,
IXContentTagProvider tagProvider,
IXContentServiceProvider provider,
IXContentTitleResourceProvider titleResourceProvider,
IXContentDescriptionResourceProvider descriptionResourceProvider
) : base(
provider: provider,
tagProvider: tagProvider,
permittedRoles: [XContentServiceConstants.XAdminRole]
)
{
this.provider = provider;
this.enricher = enricher;
this.tagProvider = tagProvider;
this.configuration = configuration;
this.titleResourceProvider = titleResourceProvider;
this.descriptionResourceProvider = descriptionResourceProvider;
}
public override bool IsOwned(
XContent item,
XUserClaimsInfoDto userInfo
)
{
//
var result =
!item.IsNullOrDefault() &&
!userInfo.IsNullOrDefault() &&
!item.OwnerId.IsNullOrEmpty() &&
userInfo.UserId == item.OwnerId;
//
return result;
}
public override bool IsOwned(
XContentDto item,
XUserClaimsInfoDto userInfo
)
{
//
var result =
!item.IsNullOrDefault() &&
!userInfo.IsNullOrDefault() &&
!item.OwnerId.IsNullOrEmpty() &&
userInfo.UserId == item.OwnerId;
//
return result;
}
//
#region Overrides ...
/// <summary>
/// Get Specified Item by ID ...
/// </summary>
/// <param name="id"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XContentDto> Get(
Guid id,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Retrieve Item ...
var result = await provider.GetAsync(
id: id,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (!result.IsNullOrDefault())
{
//
result = await enricher.Enrich(
source: result,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// Get All Exists Items ...
/// </summary>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<IEnumerable<XContentDto>> GetAll(
Func<IQueryable<XContent>, IOrderedQueryable<XContent>> orderBuilder = null,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Retrieve Items ...
var result = await provider.GetAllAsync(
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (result.HasChild())
{
//
result = await enricher.EnrichRange(
sources: result,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// find an item by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XContentDto> FindOne(
Expression<Func<XContent, bool>> predicate,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Detect Item ...
var result = await provider.FindOneAsync(
predicate: predicate,
ignoreSoftDeleteds: true,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (!result.IsNullOrDefault())
{
//
result = await enricher.Enrich(
source: result,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// find a collection of Items by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<IEnumerable<XContentDto>> FindMany(
Expression<Func<XContent, bool>> predicate,
Func<IQueryable<XContent>, IOrderedQueryable<XContent>> orderBuilder = null,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Detect Items ...
var result = await provider.FindManyAsync(
predicate: predicate,
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (result.HasChild())
{
//
result = await enricher.EnrichRange(
sources: result,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XQueryResult<XContentDto>> Query(
XQuery query,
Expression<Func<XContent, bool>> predicate = null,
Func<IQueryable<XContent>, IOrderedQueryable<XContent>> orderBuilder = null,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Query Items ...
var result = await provider.QueryAsync(
query: query,
predicate: predicate,
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (!result.IsNullOrDefault() && result.Items.HasChild())
{
//
result.Items = await enricher.EnrichRange(
sources: result.Items,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// retrieve Owned Items based on XQuery Pagination structure ...
/// if supported ...
/// </summary>
/// <param name="query"></param>
/// <param name="userInfo"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XQueryResult<XContentDto>> QueryOwned(
XQuery query,
XUserClaimsInfoDto userInfo = null,
Expression<Func<XContent, bool>> predicate = null,
Func<IQueryable<XContent>, IOrderedQueryable<XContent>> orderBuilder = null,
Func<IQueryable<XContent>, IIncludableQueryable<XContent, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
// Prepare Predicator ...
Expression<Func<XContent, bool>> predicateor = null;
if (!predicate.IsNull())
{
//
var predicateFnc = predicate.Compile();
predicateor = x =>
predicateFnc(x) &&
IsOwned(x, userInfo);
}
else
{
predicateor = x => IsOwned(x, userInfo);
}
//
// Query Items ...
var result = await provider.QueryAsync(
query: query,
predicate: predicateor,
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
// Handle Enrichment ...
if (!result.IsNullOrDefault() && result.Items.HasChild())
{
//
result.Items = await enricher.EnrichRange(
sources: result.Items,
cancellationToken: cancellationToken
);
}
//
return result;
}
/// <summary>
/// Add an item values ...
/// </summary>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XContentDto> Add(
XContentDto item,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Add(
item: item,
language: null,
userInfo: userInfo,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Add an item values ...
/// </summary>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XContentDto> Add(
XContentDto item,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
string language = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid = !item.IsNullOrDefault();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Normalize ...
//
// Language ...
if (language.IsNullOrEmpty())
{
language = configuration.DefaultLanguage;
}
//
// Owner Id ...
if (item.OwnerId.IsNullOrEmpty())
{
//
if (!userInfo.IsNullOrDefault())
{
item.OwnerId = userInfo.UserId;
}
}
//
// Created On ...
if (item.CreatedOn.IsNull())
{
item.CreatedOn = DateTime.UtcNow;
}
//
// Validate Normalized Items ...
isValid = item.IsValid();
if (!isValid)
{
XException.InvalidData.Throw();
}
//
// Handle Insert Temp ...
var result = await provider.AddAsync(
item: item,
saveChanges: true,
connectionId: null, // Ignor Push Notifications ...,
cancellationToken: cancellationToken
);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Handle Insert Title/Description ...
//
var titleResource = await titleResourceProvider.AddOrUpdateLocale(
connectionId: null,
identifier: result.Id,
locale: new XLocaleResourceDto
{
Language = language,
Value = result.Title,
},
cancellationToken: cancellationToken
);
//
XResourceDto descriptionResource = null;
if (!result.Description.IsNullOrEmpty())
{
//
descriptionResource = await descriptionResourceProvider.AddOrUpdateLocale(
connectionId: null,
identifier: result.Id,
locale: new XLocaleResourceDto
{
Language = language,
Value = result.Description,
},
cancellationToken: cancellationToken
);
}
//
// Fill Item Title and Description ...
if (titleResource.IsNullOrDefault())
{
result.Title = titleResource.Resource;
}
if (descriptionResource.IsNullOrDefault())
{
result.Description = descriptionResource.Resource;
}
//
// Update Item ...
result = await Update(
item: result,
id: result.Id,
userInfo: userInfo,
connectionId: null,
cancellationToken: cancellationToken
);
isValid = !result.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Handle Enrichment ...
if (isValid)
{
//
result = await enricher.Enrich(
source: result,
cancellationToken: cancellationToken
);
}
//
// Handle Push Notifications ...
if (isValid && !connectionId.IsNullOrEmpty())
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Update an item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XContentDto> Update(
Guid id,
XContentDto item,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Check Permission ...
var hasPermission =
IsOwned(item, userInfo) ||
HasPermision(userInfo);
if (!hasPermission)
{
XException.NotAllowed.Throw();
}
//
// Handle Resources ...
if (!item.TitleResource.IsNullOrDefault())
{
item.TitleResource = await titleResourceProvider.AddOrUpdateResource(
identifier: item.Id,
connectionId: connectionId,
resource: item.TitleResource,
cancellationToken: cancellationToken
);
}
//
var result = await provider.UpdateAsync(
id: id,
item: item,
saveChanges: true,
connectionId: null,
cancellationToken: cancellationToken
);
var isValid = !result.IsNullOrDefault();
//
// Handle Enrichment ...
if (isValid)
{
//
result = await enricher.Enrich(
source: result,
cancellationToken: cancellationToken
);
}
//
// Handle Notification ...
if (isValid && !connectionId.IsNullOrEmpty())
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Update.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<XContentDto> Remove(
Guid id,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
// Check Permission ...
var item = await Get(
id: id,
cancellationToken: cancellationToken
);
var hasPermission =
IsOwned(item, userInfo) ||
HasPermision(userInfo);
if (!hasPermission)
{
XException.NotAllowed.Throw();
}
//
// Handle Item Remove ...
var result = await provider.RemoveAsync(
id: id,
saveChanges: true,
softDelete: false,
connectionId: null,
cancellationToken: cancellationToken
);
if (result.IsNullOrDefault())
{
XException.ActionFailed.Throw();
}
//
// Remove Titles/Descriptions ...
//
// Titles ...
await titleResourceProvider.RemoveLocales(
connectionId: null,
identifier: result.Id,
cancellationToken: cancellationToken
);
//
// Descriptions ...
await descriptionResourceProvider.RemoveLocales(
connectionId: null,
identifier: result.Id,
cancellationToken: cancellationToken
);
//
// Handle Notifications ...
if (!connectionId.IsNullOrEmpty())
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Delete.GetStringValue()
);
}
//
return result;
}
#endregion
}
}