|
|
@@ -0,0 +1,239 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
+using System.Security.Principal;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using BO.AppServer.Business.Exceptions;
|
|
|
+using BO.AppServer.Business.Mapper;
|
|
|
+using BO.AppServer.Business.Services.Base;
|
|
|
+using BO.AppServer.Data.Entity;
|
|
|
+using BO.AppServer.Data.Repository;
|
|
|
+using BO.AppServer.Metadata.Dto;
|
|
|
+using BO.AppServer.Metadata.Enums;
|
|
|
+using Microsoft.AspNetCore.Identity;
|
|
|
+using Microsoft.Extensions.Logging;
|
|
|
+using Quadarax.Foundation.Core.Data;
|
|
|
+using Quadarax.Foundation.Core.Data.Interface;
|
|
|
+using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
|
|
|
+
|
|
|
+namespace BO.AppServer.Business.Services
|
|
|
+{
|
|
|
+ public class DocumentService : UserContextService
|
|
|
+ {
|
|
|
+ #region *** Private fields ***
|
|
|
+ private WorkspaceRepo _repoWorkspace;
|
|
|
+ private MetadocumentRepo _repoDocument;
|
|
|
+ private MimeTypeRepo _repoMType;
|
|
|
+ private ArtifactRepo _repoArtifact;
|
|
|
+
|
|
|
+ private StorageService _srvStorage;
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region *** Constructors ***
|
|
|
+ public DocumentService(
|
|
|
+ WorkspaceRepo repoWorkspace,
|
|
|
+ MetadocumentRepo repoDocument,
|
|
|
+ MimeTypeRepo repoMType,
|
|
|
+ ArtifactRepo repoArtifact,
|
|
|
+ UserRepo repoUser,
|
|
|
+ UserManager<IdentityUser> userManager,
|
|
|
+ IPrincipal currentPrincipal,
|
|
|
+ ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
|
|
|
+ {
|
|
|
+ _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
|
|
|
+ _repoDocument = repoDocument ?? throw new ArgumentNullException(nameof(repoDocument));
|
|
|
+ _repoMType = repoMType ?? throw new ArgumentNullException(nameof(repoMType));
|
|
|
+ _repoArtifact = repoArtifact ?? throw new ArgumentNullException(nameof(repoArtifact));
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region *** Public Operations ***
|
|
|
+
|
|
|
+ public async Task<ResultValueDto<DocumentRDto>> GetDocumentAsync(long workspaceId, long documentId)
|
|
|
+ {
|
|
|
+ var document = CheckAndGetDocument(workspaceId, documentId);
|
|
|
+ return new ResultValueDto<DocumentRDto>(document.Map<Metadocument, DocumentRDto>());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task<ResultsValueDto<DocumentRDto>> GetAllDocumentsAsync(long workspaceId, DocumentsScopeEnums scope, PagingDto paging)
|
|
|
+ {
|
|
|
+ CheckAndGetWorkspace(workspaceId);
|
|
|
+ IList<Metadocument> documents = new List<Metadocument>();
|
|
|
+ switch (scope)
|
|
|
+ {
|
|
|
+ case DocumentsScopeEnums.All:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Pending:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.Pending).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Done:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.DoneOk).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Working:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.Processing).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Failed:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Structure.WorkspaceId == workspaceId && x.Status == (int)DocumentStatusEnum.DoneFail).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return new ResultsValueDto<DocumentRDto>(documents.MapList<Metadocument, DocumentRDto>());
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task<ResultsValueDto<DocumentRDto>> GetAllDocumentsAsync(DocumentsScopeEnums scope, PagingDto paging)
|
|
|
+ {
|
|
|
+ IList<Metadocument> documents = new List<Metadocument>();
|
|
|
+ switch (scope)
|
|
|
+ {
|
|
|
+ case DocumentsScopeEnums.All:
|
|
|
+ documents = _repoDocument.Query(paging).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Pending:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.Pending).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Done:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.DoneOk).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Working:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.Processing).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ case DocumentsScopeEnums.Failed:
|
|
|
+ documents = _repoDocument.Query(paging).Where(x => x.Status == (int)DocumentStatusEnum.DoneFail).OrderBy(x => x.Name).ToList();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return new ResultsValueDto<DocumentRDto>(documents.MapList<Metadocument, DocumentRDto>());
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task<ResultValueDto<DocumentRDto>> CreateDocumentAsync(long workspaceId, DocumentCDto document)
|
|
|
+ {
|
|
|
+ var workspace = CheckAndGetWorkspace(workspaceId);
|
|
|
+ var exists = _repoDocument.Query(new Paging())
|
|
|
+ .Any(x => x.Structure.WorkspaceId == workspaceId && x.Name == document.Name);
|
|
|
+ if (exists)
|
|
|
+ {
|
|
|
+ var exc = new EntityAlreadyExistsException(typeof(Metadocument), document.Name);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+
|
|
|
+ var newDocument = _repoDocument.New();
|
|
|
+ document.CopyToDto(newDocument);
|
|
|
+ newDocument.Created = DateTime.Now;
|
|
|
+ newDocument.CreatedByUser = GetCurrentUser();
|
|
|
+ newDocument.Status = (int)DocumentStatusEnum.New;
|
|
|
+ newDocument.StructureId = workspace.Structures.First().Id;
|
|
|
+ _repoDocument.Set(newDocument);
|
|
|
+ _repoDocument.Commit();
|
|
|
+
|
|
|
+ return new ResultValueDto<DocumentRDto>(newDocument.Map<Metadocument, DocumentRDto>());
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task<ResultValueDto<ArtifactRDto>> AppendArtifactAsync(long workspaceId, long documentId,
|
|
|
+ ArtifactCDto artifact, ArtifactTypeEnum type, Stream content)
|
|
|
+ {
|
|
|
+ //TODO: Rewrite better way - mainly rollback scenario
|
|
|
+
|
|
|
+ var document = CheckAndGetDocument(workspaceId, documentId);
|
|
|
+ var exists = document.Artifacts.Any(x =>
|
|
|
+ x.Name.ToLower() == artifact.Name.ToLower() && x.Extension.ToLower() == artifact.Extension.ToLower());
|
|
|
+ if (exists)
|
|
|
+ {
|
|
|
+ var exc = new EntityAlreadyExistsException(typeof(Artifact), artifact.Name + "." + artifact.Extension);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+
|
|
|
+ var mtype = _repoMType.GetByMimeType(artifact.MimeType);
|
|
|
+ if (mtype == null)
|
|
|
+ {
|
|
|
+ var exc = new EntityNotExistsException(typeof(MimeType), artifact.MimeType, 0);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+
|
|
|
+ var newArtifact = _repoArtifact.New();
|
|
|
+
|
|
|
+ newArtifact.Name = artifact.Name;
|
|
|
+ newArtifact.Extension = artifact.Extension;
|
|
|
+ newArtifact.Length = content.Length;
|
|
|
+ newArtifact.Metadocument = document;
|
|
|
+ newArtifact.MimeType = mtype;
|
|
|
+ newArtifact.Created = DateTime.Now;
|
|
|
+ newArtifact.CreatedByUser = GetCurrentUser();
|
|
|
+ newArtifact.Type = (int)type;
|
|
|
+ _repoArtifact.Set(newArtifact);
|
|
|
+ document = _repoDocument.Get(documentId);
|
|
|
+ document.Modified = DateTime.Now;
|
|
|
+ document.ModifiedByUser = GetCurrentUser();
|
|
|
+ _repoDocument.Set(document);
|
|
|
+ _repoArtifact.Commit();
|
|
|
+ _repoDocument.Commit();
|
|
|
+
|
|
|
+ await _srvStorage.PushContentAsync(newArtifact.Id, content);
|
|
|
+
|
|
|
+ return new ResultValueDto<ArtifactRDto>(newArtifact.Map<Artifact, ArtifactRDto>());
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public async Task<Tuple<Stream, string>> GetArtifactAsync(long workspaceId, long documentId, long artifactId)
|
|
|
+ {
|
|
|
+ var artifact = CheckAndGetArtifact(workspaceId, documentId, artifactId);
|
|
|
+ var result = await _srvStorage.PopContentAsync(artifact.Id);
|
|
|
+
|
|
|
+ return new Tuple<Stream, string>(result.Item1, artifact.MimeType.Mimetype1);
|
|
|
+
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region *** Private Operations ***
|
|
|
+
|
|
|
+ private Workspace CheckAndGetWorkspace(long workspaceId)
|
|
|
+ {
|
|
|
+ var workspace = _repoWorkspace.Get(workspaceId);
|
|
|
+ if (workspace == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ var exc = new EntityNotExistsException(typeof(Workspace), nameof(Workspace.Id), workspaceId);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return workspace;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Metadocument CheckAndGetDocument(long workspaceId, long documentId)
|
|
|
+ {
|
|
|
+ CheckAndGetWorkspace(workspaceId);
|
|
|
+ var document = _repoDocument.Get(workspaceId ,documentId);
|
|
|
+ if (document == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ var exc = new EntityNotExistsException(typeof(Metadocument), nameof(Metadocument.Id), documentId);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return document;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Artifact CheckAndGetArtifact(long workspaceId, long documentId, long artifactId)
|
|
|
+ {
|
|
|
+ CheckAndGetWorkspace(workspaceId);
|
|
|
+ CheckAndGetDocument(workspaceId, documentId);
|
|
|
+ var artifact = _repoDocument.GetArtifact(documentId, artifactId);
|
|
|
+ if (artifact == null)
|
|
|
+ {
|
|
|
+ var exc = new EntityNotExistsException(typeof(Artifact), nameof(Artifact.Id), artifactId);
|
|
|
+ Log.LogWarning(exc.Message);
|
|
|
+ throw exc;
|
|
|
+ }
|
|
|
+ return artifact;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+}
|