diff --git a/Controllers/XBaseResourceProviderControllerBase.cs b/Controllers/XBaseResourceProviderControllerBase.cs new file mode 100644 index 0000000..5930f53 --- /dev/null +++ b/Controllers/XBaseResourceProviderControllerBase.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Extensions; +using xCommons.Providers; +using xIdentityService.Controllers; +using xIdentityService.Interfaces; +using xModels.Dtos; +using xStringService.Interfaces; +using xStringService.Models.Dtos; + +namespace xStringService.Controllers +{ + public abstract class XBaseResourceProviderControllerBase : XBaseIdentityApiV1Controller, IXBaseResourceProviderController + where TResourceProvider : IXResourceProvider + { + private readonly TResourceProvider provider; + + protected XBaseResourceProviderControllerBase( + ILogger> logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + TResourceProvider provider + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider + ) + { + this.provider = provider; + } + + #region Actions ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + [HttpGet("Languages")] + public virtual async Task>> GetLanguages( + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLanguages(cancellationToken); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve all Exists Items ... + /// + /// Specified Resource Title + /// + /// + [HttpGet("LocalesResource")] + public virtual async Task>> GetResourceLocales( + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResourceLocales(cancellationToken); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Extract Translation of in Specified Language ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Translation")] + public virtual async Task> GetResourceTranslation( + [FromRoute] string language, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResourceTranslation( + language: language, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Check Has Specified Translation or not ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Has")] + public virtual async Task> HasLocale( + [FromRoute] string language, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .HasLocale( + language: language, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve as Locale Model ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Locale")] + public virtual async Task> GetLocale( + [FromRoute] string language, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLocale( + language: language, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve all Exists Locale Models ... + /// + /// + /// + [HttpGet("Locales")] + public virtual async Task>> GetLocales( + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLocales(cancellationToken); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve as XResourceDto ... + /// + /// + /// + [HttpGet("Resource")] + public virtual async Task> GetResource( + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResource(cancellationToken); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("")] + public virtual async Task> AddOrUpdateResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .AddOrUpdateResource( + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Add Or Update Locale ... + /// + /// + /// + /// + [HttpPost("Locales")] + public virtual async Task> AddOrUpdateLocale( + [FromBody] XLocaleResourceDto locale, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .AddOrUpdateLocale( + locale: locale, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Remove Locale ... + /// + /// + /// + /// + [HttpPost("Locale/Remove")] + public virtual async Task> RemoveLocale( + [FromBody] XLocaleResourceDto locale, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .RemoveLocale( + locale: locale, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("Resource/Remove")] + public virtual async Task RemoveResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + await provider + .RemoveResource( + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Controllers/XStringProviderControllerBase.cs b/Controllers/XStringProviderControllerBase.cs new file mode 100644 index 0000000..d0ca3e4 --- /dev/null +++ b/Controllers/XStringProviderControllerBase.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Extensions; +using xCommons.Providers; +using xExceptions.Constants; +using xIdentityService.Interfaces; +using xModels.Dtos; +using xPushService.Controllers; +using xStringService.Interfaces; +using xStringService.Models.Dtos; +using xStringService.Models.Entities; +using xStringService.Providers.Dtos; + +namespace xStringService.Controllers +{ + public abstract class XStringProviderControllerBase : XBaseProvidedController, IXStringProviderController + { + private readonly IXStringProvider provider; + + protected XStringProviderControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXStringProvider provider, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider, + provider, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { + this.provider = provider; + } + + // + #region Tools ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + [HttpGet("Languages")] + public virtual async Task>> GetLanguages( + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLanguages(cancellationToken); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve a List of Resource Titles ... + /// + /// if provided, returns all language Specified resource titles, if not, all Resource Titles + /// + /// + [HttpGet("ResourceTitles")] + public virtual async Task>> GetResourceTitles( + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResourceTitles( + language: language, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve all Exists Items which belongs to Specified Resource Title ... + /// + /// Specified Resource Title + /// + /// + [HttpGet("ResourceLocales")] + public virtual async Task>> GetResourceLocales( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResourceLocales( + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Extract Translation of a Resource in Specified Language ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + [HttpGet("Translation")] + public virtual async Task> GetResourceTranslation( + [FromQuery] string language, + [FromQuery] string resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResourceTranslation( + language: language, + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve a Resource as Locale Model ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + [HttpGet("Locale")] + public virtual async Task> GetLocale( + [FromQuery] string language, + [FromQuery] string resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLocale( + language: language, + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve all Exists Resource Instances as Locale Models ... + /// + /// + /// + /// + [HttpGet("Locales")] + public virtual async Task>> GetLocales( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetLocales( + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve all Locales of Specified Resource and Represent as XResourceDto ... + /// + /// + /// + /// + [HttpGet("GetResource")] + public virtual async Task> GetResource( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + var result = await provider + .GetResource( + resource: resource, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("AddOrUpdateResource")] + public virtual async Task> AddOrUpdateResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(resource) + .AddNotEmpty(resource.Resource) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider + .AddOrUpdateResource( + resource: resource, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("RemoveResource")] + public virtual async Task RemoveResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(resource) + .AddNotEmpty(resource.Resource) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + await provider + .RemoveResource( + resource: resource, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + } +} \ No newline at end of file diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index ee2089f..589dd9c 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -15,6 +15,8 @@ using xStringService.Interfaces.Entities; using xStringService.Providers.Entities; using xPushService.Helpers; using xPushService.DI; +using xStringService.Interfaces; +using xStringService.Providers; namespace xStringService.DI { @@ -213,6 +215,12 @@ namespace xStringService.DI new ServiceDescriptor(typeof(IXStringRepositoryProvider), typeof(XStringRepositoryProvider), lifeTime) ); + // + // Register XString Provider ... + services.Add( + new ServiceDescriptor(typeof(IXStringProvider), typeof(XStringProvider), lifeTime) + ); + // Log("Service Regitration Succeed ..."); } diff --git a/Interfaces/IXBaseResourceProviderController.cs b/Interfaces/IXBaseResourceProviderController.cs new file mode 100644 index 0000000..25fe6ab --- /dev/null +++ b/Interfaces/IXBaseResourceProviderController.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using xModels.Dtos; +using xStringService.Models.Dtos; + +namespace xStringService.Interfaces +{ + public interface IXBaseResourceProviderController + { + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + [HttpGet("Languages")] + Task>> GetLanguages( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Items ... + /// + /// Specified Resource Title + /// + /// + [HttpGet("LocalesResource")] + Task>> GetResourceLocales( + CancellationToken cancellationToken = default + ); + + /// + /// Extract Translation of in Specified Language ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Translation")] + Task> GetResourceTranslation( + [FromRoute] string language, + CancellationToken cancellationToken = default + ); + + /// + /// Check Has Specified Translation or not ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Has")] + Task> HasLocale( + [FromRoute] string language, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve as Locale Model ... + /// + /// Specified Language ... + /// + /// + [HttpGet("{language}/Locale")] + Task> GetLocale( + [FromRoute] string language, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Locale Models ... + /// + /// + /// + [HttpGet("Locales")] + Task>> GetLocales( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve as XResourceDto ... + /// + /// + /// + [HttpGet("Resource")] + Task> GetResource( + CancellationToken cancellationToken = default + ); + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("")] + Task> AddOrUpdateResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ); + + /// + /// Add Or Update Locale ... + /// + /// + /// + /// + [HttpPost("Locales")] + Task> AddOrUpdateLocale( + [FromBody] XLocaleResourceDto locale, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Locale ... + /// + /// + /// + /// + [HttpPost("Locale/Remove")] + Task> RemoveLocale( + [FromBody] XLocaleResourceDto locale, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("Resource/Remove")] + Task RemoveResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ); + } +} \ No newline at end of file diff --git a/Interfaces/IXResourceProvider.cs b/Interfaces/IXResourceProvider.cs new file mode 100644 index 0000000..b0d8529 --- /dev/null +++ b/Interfaces/IXResourceProvider.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using xIdentityModels.Models; +using xModels.Dtos; +using xStringService.Models.Dtos; + +namespace xStringService.Interfaces +{ + public interface IXResourceProvider + { + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + Task> GetLanguages( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Items ... + /// + /// Specified Resource Title + /// + /// + Task> GetResourceLocales( + CancellationToken cancellationToken = default + ); + + /// + /// Extract Translation of in Specified Language ... + /// + /// Specified Language ... + /// + /// + Task GetResourceTranslation( + string language, + CancellationToken cancellationToken = default + ); + + /// + /// Check Has Specified Translation or not ... + /// + /// Specified Language ... + /// + /// + Task HasLocale( + string language, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve as Locale Model ... + /// + /// Specified Language ... + /// + /// + Task GetLocale( + string language, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Locale Models ... + /// + /// + /// + Task> GetLocales( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve as XResourceDto ... + /// + /// + /// + Task GetResource( + CancellationToken cancellationToken = default + ); + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + Task AddOrUpdateResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Add Or Update Locale ... + /// + /// + /// Actor User for Permissions ... + /// + /// + /// + Task AddOrUpdateLocale( + XLocaleResourceDto locale, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Locale ... + /// + /// + /// Actor User for Permissions ... + /// + /// + /// + Task RemoveLocale( + XLocaleResourceDto locale, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + Task RemoveResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + } +} \ No newline at end of file diff --git a/Interfaces/IXStringProvider.cs b/Interfaces/IXStringProvider.cs new file mode 100644 index 0000000..01670a3 --- /dev/null +++ b/Interfaces/IXStringProvider.cs @@ -0,0 +1,127 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using xIdentityModels.Models; +using xModels.Dtos; +using xPushService.Interfaces; +using xStringService.Models.Dtos; +using xStringService.Models.Entities; +using xStringService.Providers.Dtos; + +namespace xStringService.Interfaces +{ + public interface IXStringProvider : IXBaseProvided + { + // + #region Tools ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + Task> GetLanguages( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve a List of Resource Titles ... + /// + /// if provided, returns all language Specified resource titles, if not, all Resource Titles + /// + /// + Task> GetResourceTitles( + string language = null, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Items which belongs to Specified Resource Title ... + /// + /// Specified Resource Title + /// + /// + Task> GetResourceLocales( + string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Extract Translation of a Resource in Specified Language ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + Task GetResourceTranslation( + string language, + string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve a Resource as Locale Model ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + Task GetLocale( + string language, + string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Resource Instances as Locale Models ... + /// + /// + /// + /// + Task> GetLocales( + string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Locales of Specified Resource and Represent as XResourceDto ... + /// + /// + /// + /// + Task GetResource( + string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + Task AddOrUpdateResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + Task RemoveResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ); + #endregion + } +} \ No newline at end of file diff --git a/Interfaces/IXStringProviderController.cs b/Interfaces/IXStringProviderController.cs new file mode 100644 index 0000000..b13fae8 --- /dev/null +++ b/Interfaces/IXStringProviderController.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using xModels.Dtos; +using xPushService.Interfaces; +using xStringService.Models.Dtos; +using xStringService.Models.Entities; +using xStringService.Providers.Dtos; + +namespace xStringService.Interfaces +{ + public interface IXStringProviderController : IXBaseProvidedController + { + // + #region Tools ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + [HttpGet("Languages")] + Task>> GetLanguages( + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve a List of Resource Titles ... + /// + /// if provided, returns all language Specified resource titles, if not, all Resource Titles + /// + /// + [HttpGet("ResourceTitles")] + Task>> GetResourceTitles( + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Items which belongs to Specified Resource Title ... + /// + /// Specified Resource Title + /// + /// + [HttpGet("ResourceLocales")] + Task>> GetResourceLocales( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Extract Translation of a Resource in Specified Language ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + [HttpGet("Translation")] + Task> GetResourceTranslation( + [FromQuery] string language, + [FromQuery] string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve a Resource as Locale Model ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + [HttpGet("Locale")] + Task> GetLocale( + [FromQuery] string language, + [FromQuery] string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Exists Resource Instances as Locale Models ... + /// + /// + /// + /// + [HttpGet("Locales")] + Task>> GetLocales( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Retrieve all Locales of Specified Resource and Represent as XResourceDto ... + /// + /// + /// + /// + [HttpGet("GetResource")] + Task> GetResource( + [FromQuery] string resource, + CancellationToken cancellationToken = default + ); + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("AddOrUpdateResource")] + Task> AddOrUpdateResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// + /// + [HttpPost("RemoveResource")] + Task RemoveResource( + [FromBody] XResourceDto resource, + CancellationToken cancellationToken = default + ); + #endregion + } +} \ No newline at end of file diff --git a/Providers/XBaseResourceProvider.cs b/Providers/XBaseResourceProvider.cs new file mode 100644 index 0000000..3c5dbd5 --- /dev/null +++ b/Providers/XBaseResourceProvider.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using xCommons.Extensions; +using xExceptions.Constants; +using xIdentityModels.Models; +using xModels.Dtos; +using xStringService.Extensions; +using xStringService.Interfaces; +using xStringService.Interfaces.Dtos; +using xStringService.Models.Dtos; + +namespace xStringService.Providers +{ + public abstract class XBaseResourceProvider : IXResourceProvider + { + protected string resource; + private readonly IXStringServiceProvider provider; + + protected XBaseResourceProvider( + string resource, + IXStringServiceProvider provider + ) + { + this.resource = resource; + this.provider = provider; + } + + // + #region Actions ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + public virtual async Task> GetLanguages( + CancellationToken cancellationToken = default + ) + { + // + var result = (await ExtractItems(cancellationToken)) + .Select(x => x.Language) + .Distinct() + .ToList(); + + // + return result; + } + + /// + /// Retrieve all Exists Items ... + /// + /// Specified Resource Title + /// + /// + public virtual async Task> GetResourceLocales( + CancellationToken cancellationToken = default + ) + { + // + var result = await ExtractItems(cancellationToken); + + // + return result; + } + + /// + /// Extract Translation of in Specified Language ... + /// + /// Specified Language ... + /// + /// + public virtual async Task GetResourceTranslation( + string language, + CancellationToken cancellationToken = default + ) + { + // + var item = (await ExtractItems(cancellationToken)) + .FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase)); + + // + var result = item?.TranslatedValue ?? string.Empty; + + // + return result; + } + + /// + /// Check Has Specified Translation or not ... + /// + /// Specified Language ... + /// + /// + public virtual async Task HasLocale( + string language, + CancellationToken cancellationToken = default + ) + { + // + var item = (await ExtractItems(cancellationToken)) + .FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase)); + + // + var result = !item.IsNullOrDefault(); + + // + return result; + } + + /// + /// Retrieve as Locale Model ... + /// + /// Specified Language ... + /// + /// + public virtual async Task GetLocale( + string language, + CancellationToken cancellationToken = default + ) + { + // + var item = (await ExtractItems(cancellationToken)) + .FirstOrDefault(x => x.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase)); + + // + var result = + !item.IsNullOrDefault() + ? item.ToXLocaleResourceDto() + : null; + + // + return result; + } + + /// + /// Retrieve all Exists Locale Models ... + /// + /// + /// + public virtual async Task> GetLocales( + CancellationToken cancellationToken = default + ) + { + // + var result = (await ExtractItems(cancellationToken)) + .Select(x => x.ToXLocaleResourceDto()) + .ToList(); + + // + return result; + } + + /// + /// Retrieve as XResourceDto ... + /// + /// + /// + /// + public virtual async Task GetResource( + CancellationToken cancellationToken = default + ) + { + // + var locales = await GetLocales(); + + // + var result = new XResourceDto + { + Locales = locales, + Resource = resource, + }; + + // + return result; + } + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + public virtual async Task AddOrUpdateResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + var isValid = + !resource.IsNullOrDefault() && + resource.Resource == this.resource; + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Retrieve Exists Resource ... + var result = await GetResource(cancellationToken); + isValid = !result.IsNullOrDefault() && result.Locales.HasChild(); + if (isValid) + { + await RemoveResource( + resource: result, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + foreach (var locale in resource.Locales) + { + // + var item = new XStringDto + { + Language = locale.Language, + ResourceTitle = this.resource, + TranslatedValue = locale.Value, + }; + + // + await provider.AddAsync( + item: item, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + result = await GetResource(cancellationToken); + return result; + } + + /// + /// Add Or Update Locale ... + /// + /// + /// + /// + public virtual async Task AddOrUpdateLocale( + XLocaleResourceDto locale, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + var item = (await ExtractItems(cancellationToken)) + .FirstOrDefault(x => + x.ResourceTitle == resource && + x.Language == locale.Language); + var isExists = !item.IsNullOrDefault(); + if (isExists) + { + item.TranslatedValue = locale.Value; + item = await provider.UpdateAsync( + item: item, + id: item.Id, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + else + { + item = new XStringDto + { + ResourceTitle = resource, + Language = locale.Language, + TranslatedValue = locale.Value + }; + item = await provider.AddAsync( + item: item, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + var result = await GetResource(cancellationToken); + + // + return result; + } + + /// + /// Remove Locale ... + /// + /// + /// + /// + public virtual async Task RemoveLocale( + XLocaleResourceDto locale, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + var item = (await ExtractItems(cancellationToken)) + .FirstOrDefault(x => + x.ResourceTitle == resource && + x.Language == locale.Language); + var isExists = !item.IsNullOrDefault(); + if (isExists) + { + await provider.RemoveAsync( + id: item.Id, + softDelete: false, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + var result = await GetResource(cancellationToken); + + // + return result; + } + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + public virtual async Task RemoveResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + var items = await ExtractItems(cancellationToken); + + // + foreach (var item in items) + { + // + await provider.RemoveAsync( + id: item.Id, + softDelete: false, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + } + #endregion + + // + #region Provate ... + private async Task> ExtractItems( + CancellationToken cancellationToken = default + ) + { + // + var result = await provider.FindManyAsync( + includeBuilder: null, + ignoreSoftDeleteds: true, + orderBuilder: x => x + .OrderBy(y => y.Language) + .ThenBy(y => y.ResourceTitle), + cancellationToken: cancellationToken, + predicate: x => + x.ResourceTitle.Equals(resource, StringComparison.InvariantCultureIgnoreCase) + ); + + // + return result; + } + + // public void SetResourceTitle(string resource) + // { + // this.resource = resource; + // } + #endregion + } +} \ No newline at end of file diff --git a/Providers/XStringProvider.cs b/Providers/XStringProvider.cs new file mode 100644 index 0000000..d1ee88f --- /dev/null +++ b/Providers/XStringProvider.cs @@ -0,0 +1,392 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using xCommons.Extensions; +using xExceptions.Constants; +using xIdentityModels.Models; +using xModels.Dtos; +using xPushService.Providers; +using xStringService.Extensions; +using xStringService.Interfaces; +using xStringService.Interfaces.Dtos; +using xStringService.Models.Dtos; +using xStringService.Models.Entities; +using xStringService.Providers.Dtos; + +namespace xStringService.Providers +{ + public class XStringProvider : XBaseProvided, IXStringProvider + { + public XStringProvider( + IXStringServiceProvider provider + ) : base( + provider, + permittedRoles: new string[] { } + ) + { } + + public override bool IsOwned( + XStringDto item, + XUserClaimsInfoDto userInfo + ) + { + return !item.IsNullOrDefault(); + } + + public override bool IsOwned( + XString item, + XUserClaimsInfoDto userInfo + ) + { + return !item.IsNullOrDefault(); + } + + // + #region Tools ... + /// + /// Retrieve a List of Exists Languages ... + /// + /// + /// + public async Task> GetLanguages( + CancellationToken cancellationToken = default + ) + { + // + var result = (await GetAll( + includeBuilder: null, + cancellationToken: cancellationToken, + orderBuilder: x => x.OrderBy(y => y.Language) + )) + .Select(x => x.Language) + .Distinct() + .ToList(); + + // + return result; + } + + /// + /// Retrieve a List of Resource Titles ... + /// + /// if provided, returns all language Specified resource titles, if not, all Resource Titles + /// + /// + public async Task> GetResourceTitles( + string language = null, + CancellationToken cancellationToken = default + ) + { + // + var result = (await FindMany( + includeBuilder: null, + cancellationToken: cancellationToken, + orderBuilder: x => x.OrderBy(y => y.ResourceTitle), + predicate: x => + string.IsNullOrWhiteSpace(language) || + x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase) + )) + .Select(x => x.ResourceTitle) + .Distinct() + .ToList(); + + // + return result; + } + + /// + /// Retrieve all Exists Items which belongs to Specified Resource Title ... + /// + /// Specified Resource Title + /// + /// + public async Task> GetResourceLocales( + string resource, + CancellationToken cancellationToken = default + ) + { + // + var result = await FindMany( + includeBuilder: null, + cancellationToken: cancellationToken, + orderBuilder: x => x.OrderBy(y => y.Language), + predicate: x => + !string.IsNullOrWhiteSpace(resource) && + resource.Equals(x.ResourceTitle, System.StringComparison.InvariantCultureIgnoreCase) + ); + + // + return result; + } + + /// + /// Extract Translation of a Resource in Specified Language ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + public async Task GetResourceTranslation( + string language, + string resource, + CancellationToken cancellationToken = default + ) + { + // + var result = (await FindOne( + includeBuilder: null, + cancellationToken: cancellationToken, + predicate: x => + !string.IsNullOrWhiteSpace(language) && + !string.IsNullOrWhiteSpace(resource) && + x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase) && + x.ResourceTitle.Equals(resource, System.StringComparison.InvariantCultureIgnoreCase) + ))? + .TranslatedValue ?? ""; + + // + return result; + } + + /// + /// Retrieve a Resource as Locale Model ... + /// + /// Specified Language ... + /// Specified Resource Title ... + /// + /// + public async Task GetLocale( + string language, + string resource, + CancellationToken cancellationToken = default + ) + { + // + var result = (await FindOne( + includeBuilder: null, + cancellationToken: cancellationToken, + predicate: x => + !string.IsNullOrWhiteSpace(language) && + !string.IsNullOrWhiteSpace(resource) && + x.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase) && + x.ResourceTitle.Equals(resource, System.StringComparison.InvariantCultureIgnoreCase) + ))? + .ToXLocaleResourceDto() ?? null; + + // + return result; + } + + /// + /// Retrieve all Exists Resource Instances as Locale Models ... + /// + /// + /// + /// + public async Task> GetLocales( + string resource, + CancellationToken cancellationToken = default + ) + { + // + var result = (await GetResourceLocales( + resource: resource, + cancellationToken: cancellationToken + )) + .ToList() + .Select(x => x.ToXLocaleResourceDto()) + .ToList(); + + // + return result; + } + + /// + /// Retrieve all Locales of Specified Resource and Represent as XResourceDto ... + /// + /// + /// + /// + public async Task GetResource( + string resource, + CancellationToken cancellationToken = default + ) + { + // + XResourceDto result = null; + + // + // Validate Resource ... + if (resource.IsNullOrEmpty()) + { + return result; + } + + // + // Extract Locales of Resource ... + var locales = await GetLocales( + resource: resource, + cancellationToken: cancellationToken + ); + + // + // Prepare Result ... + result = new XResourceDto + { + Locales = locales, + Resource = resource, + }; + + // + return result; + } + + /// + /// Add or Update a Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + public async Task AddOrUpdateResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + XResourceDto result = null; + + // + // Validate Args ... + var isValid = + !resource.IsNullOrDefault() && + !resource.Resource.IsNullOrEmpty(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Permissions ... + isValid = + userInfo.IsNullOrDefault() || + HasPermision(userInfo); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + // Remove all Resources if Exists ... + result = await GetResource( + resource: resource.Resource, + cancellationToken: cancellationToken + ); + var isExists = !result.IsNullOrDefault(); + if (isExists) + { + // + await RemoveResource( + resource: result, + userInfo: userInfo, + cancellationToken: cancellationToken + ); + } + + // + // Loop through all Exists Locales and Add them ... + foreach (var locale in resource.Locales) + { + // + if (cancellationToken.IsCancellationRequested) + { + break; + } + + // + var item = new XStringDto + { + Language = locale.Language, + TranslatedValue = locale.Value, + ResourceTitle = resource.Resource, + }; + await Add( + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + // Reload Result after Updates ... + result = await GetResource( + resource: resource.Resource, + cancellationToken: cancellationToken + ); + + // + return result; + } + + /// + /// Remove Specified Resource Model ... + /// + /// a XResourceDto Model ... + /// Actor User for Permissions ... + /// + /// + /// + public async Task RemoveResource( + XResourceDto resource, + XUserClaimsInfoDto userInfo = null, + string connectionId = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + var isValid = !resource.IsNullOrDefault(); + if (!isValid) + { + return; + } + + // + var items = await GetResourceLocales( + resource: resource.Resource, + cancellationToken: cancellationToken + ); + isValid = + !items.IsNullOrDefault() && + items.HasChild(); + if (!isValid) + { + return; + } + + // + foreach (var item in items) + { + // + if (cancellationToken.IsCancellationRequested) + { + break; + } + + // + await Remove( + id: item.Id, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + } + #endregion + } +} \ No newline at end of file