1033 lines
30 KiB
C#
1033 lines
30 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using xCommons.Extensions;
|
|
using xDataService.Extensions;
|
|
using xDataService.Models;
|
|
using xExceptions.Constants;
|
|
using xFileService.Interfaces;
|
|
using xFileService.Models.Dtos;
|
|
using xFileService.Models.Entities;
|
|
using xIdentityModels.Models;
|
|
using xModels.Dtos;
|
|
using XFileDto = xFileService.Models.Dtos.XFileDto;
|
|
|
|
namespace xFileService.Providers
|
|
{
|
|
public abstract class XBaseFileProvider<TKey> : IXBaseFileProvider<TKey>
|
|
{
|
|
//
|
|
#region Props ...
|
|
/// <summary>
|
|
/// Provider Identifier ...
|
|
/// </summary>
|
|
public string Provider { get; }
|
|
|
|
/// <summary>
|
|
/// Tag Provider for Maipulating Tags ...
|
|
/// </summary>
|
|
public IXFileProvider FileProvider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XBaseFileProvider(
|
|
string providedFor,
|
|
IXFileProvider fileProvider
|
|
)
|
|
{
|
|
//
|
|
Provider = providedFor;
|
|
FileProvider = fileProvider;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Identifier ...
|
|
public async Task<int> LastIndex(TKey providedForId)
|
|
{
|
|
return await Task.FromResult(GetLastIndex(providedForId));
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<FileStreamResult> Stream(Guid id)
|
|
{
|
|
//
|
|
// Check Validation and Owning ...
|
|
var isValid = await IsOwned(id);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.Stream(id);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stream Specified File ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public async Task<FileStreamResult> Stream(string fileName)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !fileName.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Dto and also Checking Owned ...
|
|
var dto = await GetDto(fileName);
|
|
isValid = !dto.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.Stream(fileName);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<PhysicalFileResult> Download(Guid id)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = await IsOwned(id);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.Download(id);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download Specified File ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public async Task<PhysicalFileResult> Download(string fileName)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !fileName.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Dto and also Checking Owned ...
|
|
var dto = await GetDto(fileName);
|
|
isValid = !dto.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.Download(fileName);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Upload Files ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="files"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XFileDto>> Upload(
|
|
TKey providedForId,
|
|
IFormFileCollection files,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Here we are Following Custom Senario ...
|
|
var dtos = await FileProvider.Upload(
|
|
files: files,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId
|
|
);
|
|
|
|
//
|
|
// Validate Dtos ...
|
|
isValid = !dtos.IsNull() && dtos.HasChild();
|
|
if (isValid)
|
|
{
|
|
//
|
|
// Preparing Index ...
|
|
int index = GetLastIndex(providedForId);
|
|
if (index > 0)
|
|
{
|
|
index++;
|
|
}
|
|
|
|
//
|
|
var isReferenced = false;
|
|
foreach (var dto in dtos)
|
|
{
|
|
//
|
|
// Try to Add Reference to Specified DTO ...
|
|
isReferenced = await AddReference(
|
|
model: dto,
|
|
forIndex: index,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
providedForId: providedForId
|
|
);
|
|
if (isReferenced)
|
|
{
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var result = new List<XFileDto>();
|
|
|
|
//
|
|
isValid = !dtos.IsNull() && dtos.HasChild();
|
|
if (isValid)
|
|
{
|
|
//
|
|
foreach (var dto in dtos)
|
|
{
|
|
//
|
|
var idto = await FileProvider.Get(dto.Id);
|
|
isValid = !idto.IsNullOrDefault() &&
|
|
await IsOwned(idto.Id);
|
|
if (isValid)
|
|
{
|
|
result.Add(idto);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Files ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="ids"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<Guid>> RemoveFile(
|
|
TKey providedForId,
|
|
string ids = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Parse Provided IDS ...
|
|
var idsList = new List<Guid>();
|
|
IEnumerable<XFile> entities = null;
|
|
if (!ids.IsNullOrEmpty())
|
|
{
|
|
//
|
|
idsList = ids
|
|
.ParseListGuid()
|
|
.ToList();
|
|
|
|
}
|
|
|
|
//
|
|
// Retrieve Entities ...
|
|
entities = FileProvider.FileRepository
|
|
.AsQueryable()
|
|
.Where(d => !idsList.Contains(d.Id) &&
|
|
d.References.Contains(Provider));
|
|
|
|
//
|
|
var result = new List<Guid>();
|
|
var isValid = !entities.IsNull() && entities.HasChild();
|
|
if (isValid)
|
|
{
|
|
//
|
|
foreach (var entity in entities)
|
|
{
|
|
//
|
|
// Remove File ...
|
|
var idsToRemove = new List<string> { entity.Id.ToString() }.ToListString();
|
|
var removeIds = await FileProvider.Remove(
|
|
ids: idsToRemove,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId
|
|
);
|
|
isValid = !removeIds.IsNull() &&
|
|
removeIds.HasChild() &&
|
|
removeIds.Contains(entity.Id);
|
|
if (isValid)
|
|
{
|
|
result.Add(entity.Id);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileStreamDescriptorDto> GetFileDescriptor(Guid id)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !id.IsNull() && !id.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Owned ...
|
|
isValid = await IsOwned(id);
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.GetFileDescriptor(id);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified File Streaming Info ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileStreamDescriptorDto> GetFileDescriptor(string fileName)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var isValid = !fileName.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Owned ...
|
|
var dto = GetDto(fileName);
|
|
isValid = !dto.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotAllowed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.GetFileDescriptor(fileName);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Referenced Actions ...
|
|
/// <summary>
|
|
/// Get Specified Indexed Reference for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileDto> GetReference(
|
|
TKey providedForId,
|
|
int forIndex = 0
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
if (forIndex < 0)
|
|
{
|
|
forIndex = 0;
|
|
}
|
|
|
|
//
|
|
// Retrieve Last Index ...
|
|
var lastIndex = GetLastIndex(providedForId);
|
|
if (forIndex > lastIndex)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var indexedIdentifier = GetIndexedProvidedID(
|
|
forIndex: forIndex,
|
|
providedForId: providedForId
|
|
);
|
|
var entity = FileProvider.FileRepository
|
|
.AsQueryable()
|
|
.Where(t => t.References.Contains(indexedIdentifier))
|
|
.FirstOrDefault();
|
|
if (entity.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await FileProvider.ToDto(entity);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists References of Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XFileDto>> GetAllReferences(TKey providedForId)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
var entities = FileProvider.FileRepository
|
|
.AsQueryable()
|
|
.Where(t => t.References.Contains(identifier))
|
|
.AsEnumerable();
|
|
|
|
//
|
|
var dtos = new List<XFileDto>();
|
|
foreach (var entity in entities)
|
|
{
|
|
//
|
|
var dto = await FileProvider.ToDto(entity);
|
|
if (!dto.IsNullOrDefault())
|
|
{
|
|
dtos.Add(dto);
|
|
}
|
|
}
|
|
|
|
//
|
|
List<XFileDto> result = dtos;
|
|
if (dtos.HasChild())
|
|
{
|
|
//
|
|
// Sorting Result Based on Indexes ...
|
|
var lastIndex = GetLastIndex(providedForId);
|
|
if (lastIndex > 0)
|
|
{
|
|
//
|
|
result.Clear();
|
|
for (int i = 0; i <= lastIndex; i++)
|
|
{
|
|
//
|
|
var dto = dtos
|
|
.FirstOrDefault(d => d.References
|
|
.Any(dr => dr.Index == i && dr.ReferencedTo == $"{providedForId}"));
|
|
if (!dto.IsNullOrDefault())
|
|
{
|
|
result.Add(dto);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return await Task.FromResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve References of Specific Provided ID as Query ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XFileDto>> QueryReferences(
|
|
XQuery query,
|
|
TKey providedForId
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (query.IsNull() || providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(FileProvider.DataSercviceConfiguration);
|
|
|
|
//
|
|
var items = await GetAllReferences(providedForId);
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<XFileDto>
|
|
{
|
|
Page = query.Page,
|
|
Items = items.ToList(),
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XFileDto model,
|
|
TKey providedForId,
|
|
int forIndex = 0,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid = !model.IsNullOrDefault() &&
|
|
!model.Name.IsNullOrEmpty() &&
|
|
!model.Id.IsNull() &&
|
|
!model.Id.IsDefaultGuid() &&
|
|
!providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Model Exists ...
|
|
isValid = await FileProvider.IsExists(model.Id);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Model by Retrieving ...
|
|
model = await FileProvider.Get(model.Id);
|
|
|
|
//
|
|
var lastIndex = GetLastIndex(providedForId);
|
|
if (lastIndex == 0)
|
|
{
|
|
//
|
|
// This Means there isnot any Reference ...
|
|
forIndex = 0;
|
|
model.References.Add(new XReference<string>
|
|
{
|
|
Index = forIndex,
|
|
ProvidedFor = Provider,
|
|
ReferencedTo = $"{providedForId}"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Check Provided Index Exists or not ...
|
|
var isExists = model.References.Any(r => r.Index == forIndex);
|
|
if (!isExists)
|
|
{
|
|
//
|
|
// Normalize For Index ...
|
|
if (forIndex > lastIndex + 1)
|
|
{
|
|
forIndex = lastIndex + 1;
|
|
}
|
|
|
|
//
|
|
// Add New Reference ...
|
|
model.References.Add(new XReference<string>
|
|
{
|
|
Index = forIndex,
|
|
ProvidedFor = Provider,
|
|
ReferencedTo = $"{providedForId}"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Data Base ...
|
|
model = await FileProvider
|
|
.Update(
|
|
item: model,
|
|
id: model.Id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add Reference a Model to Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="reference"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> AddReference(
|
|
XFileDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
// Since other Validations Handled in Calling, we Ignore them here ...
|
|
if (model.IsNull() ||
|
|
reference.IsNullOrDefault() ||
|
|
(!reference.ProvidedFor.IsNullOrEmpty() && reference.ProvidedFor != Provider))
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await AddReference(
|
|
model: model,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific Provided ID ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="forIndex">if null, removes all</param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XFileDto model,
|
|
TKey providedForId,
|
|
int? forIndex = null,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (model.IsNull() ||
|
|
providedForId.IsNull() ||
|
|
model.Id.IsNull() ||
|
|
model.Id.IsDefaultGuid())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Model ...
|
|
model = await FileProvider.Get(model.Id);
|
|
if (model.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Model Reference to ID ...
|
|
var isReferenced = model.References
|
|
.Any(r => r.ProvidedFor == Provider &&
|
|
r.ReferencedTo == $"{providedForId}" &&
|
|
(!forIndex.HasValue || r.Index == forIndex.Value));
|
|
|
|
//
|
|
var result = false;
|
|
if (isReferenced)
|
|
{
|
|
//
|
|
model.References = model.References
|
|
.Where(r => r.ProvidedFor != Provider ||
|
|
(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo != $"{providedForId}" &&
|
|
(!forIndex.HasValue || r.Index == forIndex.Value)))
|
|
.ToList();
|
|
|
|
//
|
|
model = await FileProvider.Update(
|
|
item: model,
|
|
id: model.Id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId
|
|
);
|
|
result = !model.IsNullOrDefault();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Reference a Model for Specific XRefence<TKey> ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReference(
|
|
XFileDto model,
|
|
XReference<TKey> reference,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
if (model.IsNullOrDefault() ||
|
|
reference.IsNullOrDefault() ||
|
|
reference.ReferencedTo.IsNull() ||
|
|
reference.ProvidedFor != Provider)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await RemoveReference(
|
|
model: model,
|
|
userInfo: userInfo,
|
|
forIndex: reference.Index,
|
|
connectionId: connectionId,
|
|
providedForId: reference.ReferencedTo
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove All References to Specified Key ...
|
|
/// </summary>
|
|
/// <param name="providedForId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <param name="userInfo"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveReferences(
|
|
TKey providedForId,
|
|
string connectionId = null,
|
|
XUserClaimsInfoDto userInfo = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = false;
|
|
var references = await GetAllReferences(providedForId);
|
|
if (!references.IsNull() && references.HasChild())
|
|
{
|
|
//
|
|
foreach (var reference in references)
|
|
{
|
|
//
|
|
// Remove Reference ...
|
|
reference.References = reference.References
|
|
.Where(r =>
|
|
r.ProvidedFor != Provider ||
|
|
(r.ProvidedFor == Provider &&
|
|
r.ReferencedTo != $"{providedForId}"))
|
|
.ToList();
|
|
var updatedModel = await FileProvider.Update(
|
|
item: reference,
|
|
id: reference.Id,
|
|
userInfo: userInfo,
|
|
connectionId: connectionId
|
|
);
|
|
if (!updatedModel.IsNullOrDefault())
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Private ...
|
|
private string GetProvidedID(
|
|
TKey providedForId,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (providedForId.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = $"{Provider}{splitter}{providedForId}";
|
|
return result;
|
|
}
|
|
|
|
private string GetIndexedProvidedID(
|
|
TKey providedForId,
|
|
int forIndex,
|
|
char splitter = '_'
|
|
)
|
|
{
|
|
//
|
|
var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{providedForId}";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
private int GetLastIndex(TKey providedForId)
|
|
{
|
|
//
|
|
var result = 0;
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid = !providedForId.IsNull();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var identifier = GetProvidedID(providedForId);
|
|
|
|
//
|
|
var all = FileProvider.FileRepository
|
|
.AsQueryable()
|
|
.Where(t => t.References
|
|
.Contains(identifier))
|
|
.Select(t => t.References)
|
|
.AsEnumerable();
|
|
if (all.IsNull() || !all.HasChild())
|
|
{
|
|
result = 0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
var references = all
|
|
.SelectMany(a => a.ParseXReferenceList<TKey>())
|
|
.OrderByDescending(r => r.Index)
|
|
.ToList();
|
|
if (!references.IsNull() && references.HasChild())
|
|
{
|
|
result = references[0].Index;
|
|
}
|
|
else
|
|
{
|
|
result = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified Dto is Has Reference to Provider ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
private async Task<bool> IsOwned(Guid id)
|
|
{
|
|
//
|
|
// Validate ...
|
|
var result = !id.IsNull() && !id.IsDefaultGuid();
|
|
if (!result)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Exists ...
|
|
result = await FileProvider.IsExists(id);
|
|
if (!result)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Dto ...
|
|
var dto = await FileProvider.Get(id);
|
|
result = !dto.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
result = !dto.References.IsNull() &&
|
|
dto.References.HasChild() &&
|
|
dto.References.Any(r => r.ProvidedFor == Provider);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Specified Owned Dto by File Name ...
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
private async Task<XFileDto> GetDto(string fileName)
|
|
{
|
|
//
|
|
XFileDto result = null;
|
|
|
|
//
|
|
if (!fileName.IsNullOrEmpty())
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
result = await FileProvider.FindOne(d =>
|
|
d.Name == fileName ||
|
|
d.Thumb == fileName ||
|
|
d.FileName == fileName ||
|
|
d.Path.Contains(fileName) ||
|
|
d.ThumbPath.Contains(fileName)
|
|
);
|
|
if (!result.IsNullOrDefault())
|
|
{
|
|
//
|
|
// Check Owning ...
|
|
var isOwned = await IsOwned(result.Id);
|
|
if (!isOwned)
|
|
{
|
|
result = null;
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
} |