diff --git a/KVA/Migration.Toolkit.Source/Handlers/MigratePageTypesCommandHandler.cs b/KVA/Migration.Toolkit.Source/Handlers/MigratePageTypesCommandHandler.cs index 39dd8215..089c4d08 100644 --- a/KVA/Migration.Toolkit.Source/Handlers/MigratePageTypesCommandHandler.cs +++ b/KVA/Migration.Toolkit.Source/Handlers/MigratePageTypesCommandHandler.cs @@ -48,18 +48,18 @@ public async Task Handle(MigratePageTypesCommand request, Cancell modelFacade.Select("ClassIsDocumentType=1", "ClassID") .OrderBy(x => x.ClassID) ); - + ExecReusableSchemaBuilders(); - + var manualMappings = new Dictionary(); foreach (var classMapping in classMappings) { var newDt = DataClassInfoProvider.GetDataClassInfo(classMapping.TargetClassName) ?? DataClassInfo.New(); classMapping.PatchTargetDataClass(newDt); - + // might not need ClassGUID // newDt.ClassGUID = GuidHelper.CreateDataClassGuid($"{newDt.ClassName}|{newDt.ClassTableName}"); - + var cmsClasses = new List(); foreach (string sourceClassName in classMapping.SourceClassNames) { @@ -68,7 +68,7 @@ public async Task Handle(MigratePageTypesCommand request, Cancell var nfi = string.IsNullOrWhiteSpace(newDt.ClassFormDefinition) ? new FormInfo() : new FormInfo(newDt.ClassFormDefinition); bool hasPrimaryKey = false; - foreach (var formFieldInfo in nfi.GetFields(true, true, true, true, false)) + foreach (var formFieldInfo in nfi.GetFields(true, true, true, true, false)) { if (formFieldInfo.PrimaryKey) { @@ -86,7 +86,7 @@ public async Task Handle(MigratePageTypesCommand request, Cancell { var prototype = FormHelper.GetBasicFormDefinition(classMapping.PrimaryKey); nfi.AddFormItem(prototype.GetFormField(classMapping.PrimaryKey)); - } + } } newDt.ClassFormDefinition = nfi.GetXmlDefinition(); @@ -109,12 +109,12 @@ public async Task Handle(MigratePageTypesCommand request, Cancell // part of reusable schema continue; } - + var sc = cmsClasses.FirstOrDefault(sc => sc.ClassName.Equals(cmm.SourceClassName, StringComparison.InvariantCultureIgnoreCase)) ?? throw new NullReferenceException($"The source class '{cmm.SourceClassName}' does not exist - wrong mapping {classMapping}"); var fi = new FormInfo(sc.ClassFormDefinition); - if(nfi.GetFormField(cmm.TargetFieldName) is {}) + if (nfi.GetFormField(cmm.TargetFieldName) is { }) { } else @@ -137,18 +137,18 @@ public async Task Handle(MigratePageTypesCommand request, Cancell nfi = new FormInfo(newDt.ClassFormDefinition); foreach (string fieldName in classMapping.TargetFieldPatchers.Keys) { - classMapping.TargetFieldPatchers[fieldName].Invoke(nfi.GetFormField(fieldName)); + classMapping.TargetFieldPatchers[fieldName].Invoke(nfi.GetFormField(fieldName)); } newDt.ClassFormDefinition = nfi.GetXmlDefinition(); } - + DataClassInfoProvider.SetDataClassInfo(newDt); foreach (var gByClass in classMapping.Mappings.GroupBy(x => x.SourceClassName)) { manualMappings.TryAdd(gByClass.Key, newDt); } - + foreach (string sourceClassName in classMapping.SourceClassNames) { var sourceClass = cmsClasses.First(c => c.ClassName.Equals(sourceClassName, StringComparison.InvariantCultureIgnoreCase)); @@ -182,7 +182,7 @@ public async Task Handle(MigratePageTypesCommand request, Cancell { continue; } - + if (ksClass.ClassInheritsFromClassID is { } classInheritsFromClassId && !primaryKeyMappingContext.HasMapping(c => c.ClassID, classInheritsFromClassId)) { // defer migration to later stage @@ -299,10 +299,10 @@ private void ExecReusableSchemaBuilders() true, false ); - + patcher.PatchFields(); patcher.RemoveCategories(); - + var fi = new FormInfo(patcher.GetPatched()); return fi.GetFormField(fieldIdentifier.FieldName) switch { @@ -316,7 +316,7 @@ private void ExecReusableSchemaBuilders() } } }); - + reusableSchemaService.EnsureReusableFieldSchema(reusableSchemaBuilder.SchemaName, reusableSchemaBuilder.SchemaDisplayName, reusableSchemaBuilder.SchemaDescription, fieldInfos.ToArray()); } } diff --git a/KVA/Migration.Toolkit.Source/Helpers/FormDefinitionHelper.cs b/KVA/Migration.Toolkit.Source/Helpers/FormDefinitionHelper.cs index d02a9bfe..7e6f09ad 100644 --- a/KVA/Migration.Toolkit.Source/Helpers/FormDefinitionHelper.cs +++ b/KVA/Migration.Toolkit.Source/Helpers/FormDefinitionHelper.cs @@ -39,8 +39,8 @@ public static void MapFormDefinitionFields(ILogger logger, IFieldMigrationServic target.ClassFormDefinition = new FormInfo().GetXmlDefinition(); } } - - public static void MapFormDefinitionFields(ILogger logger, IFieldMigrationService fieldMigrationService, + + public static void MapFormDefinitionFields(ILogger logger, IFieldMigrationService fieldMigrationService, string sourceClassDefinition, bool? classIsForm, bool classIsDocumentType, DataClassInfo target, bool isCustomizableSystemClass, bool classIsCustom) { diff --git a/KVA/Migration.Toolkit.Source/Mappers/ContentItemMapper.cs b/KVA/Migration.Toolkit.Source/Mappers/ContentItemMapper.cs index 26caf96d..a9b68b2c 100644 --- a/KVA/Migration.Toolkit.Source/Mappers/ContentItemMapper.cs +++ b/KVA/Migration.Toolkit.Source/Mappers/ContentItemMapper.cs @@ -10,7 +10,6 @@ using CMS.Websites.Internal; using Kentico.Xperience.UMT.Model; using Microsoft.Data.SqlClient; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Migration.Toolkit.Common; using Migration.Toolkit.Common.Abstractions; @@ -63,7 +62,7 @@ public class ContentItemMapper( IAssetFacade assetFacade, MediaLinkServiceFactory mediaLinkServiceFactory, ToolkitConfiguration configuration, - ClassMappingProvider classMappingProvider + ClassMappingProvider classMappingProvider ) : UmtMapperBase { private const string CLASS_FIELD_CONTROL_NAME = "controlname"; @@ -81,7 +80,7 @@ protected override IEnumerable MapInternal(CmsTreeMapperSource source { targetClassGuid = DataClassInfoProvider.ProviderObject.Get(mapping.TargetClassName)?.ClassGUID ?? throw new InvalidOperationException($"Unable to find target class '{mapping.TargetClassName}'"); } - + bool migratedAsContentFolder = sourceNodeClass.ClassName.Equals("cms.folder", StringComparison.InvariantCultureIgnoreCase) && !configuration.UseDeprecatedFolderPageType.GetValueOrDefault(false); var contentItemGuid = spoiledGuidContext.EnsureNodeGuid(cmsTree.NodeGUID, cmsTree.NodeSiteID, cmsTree.NodeID); @@ -272,7 +271,7 @@ protected override IEnumerable MapInternal(CmsTreeMapperSource source { throw new Exception("Error, unable to find coupled data primary key"); } - + var commonFields = UnpackReusableFieldSchemas(fi.GetFields()).ToArray(); var targetColumns = commonFields .Select(cf => ReusableSchemaService.RemoveClassPrefix(sourceNodeClass.ClassName, cf.Name)) @@ -285,8 +284,8 @@ protected override IEnumerable MapInternal(CmsTreeMapperSource source MapCoupledDataFieldValues(dataModel.CustomProperties, columnName => coupledDataRow?[columnName], columnName => coupledDataRow?.ContainsKey(columnName) ?? false, - cmsTree, cmsDocument.DocumentID, - targetColumns, sfi, fi, + cmsTree, cmsDocument.DocumentID, + targetColumns, sfi, fi, false, sourceNodeClass, sourceSite, mapping ).GetAwaiter().GetResult(); @@ -466,10 +465,11 @@ private IEnumerable MigrateDraft(ICmsVersionHistory checkoutVersion, ); } - dataModel = new ContentItemDataModel { - ContentItemDataGUID = commonDataModel.ContentItemCommonDataGUID, - ContentItemDataCommonDataGuid = commonDataModel.ContentItemCommonDataGUID, - ContentItemContentTypeName = mapping?.TargetClassName ?? sourceNodeClass.ClassName + dataModel = new ContentItemDataModel + { + ContentItemDataGUID = commonDataModel.ContentItemCommonDataGUID, + ContentItemDataCommonDataGuid = commonDataModel.ContentItemCommonDataGUID, + ContentItemContentTypeName = mapping?.TargetClassName ?? sourceNodeClass.ClassName }; if (sourceNodeClass.ClassIsCoupledClass) @@ -560,7 +560,7 @@ IClassMapping mapping ) { Debug.Assert(sourceNodeClass.ClassTableName != null, "sourceNodeClass.ClassTableName != null"); - + foreach (string targetColumnName in newColumnNames) { string targetFieldName = null!; @@ -585,8 +585,11 @@ IClassMapping mapping valueConvertor = sourceValue => sourceValue; break; } + + default: + break; } - + if ( targetFieldName.Equals("ContentItemDataID", StringComparison.InvariantCultureIgnoreCase) || targetFieldName.Equals("ContentItemDataCommonDataID", StringComparison.InvariantCultureIgnoreCase) || @@ -605,7 +608,7 @@ IClassMapping mapping logger.LogTrace("Skipping '{FieldName}' - is external", targetFieldName); continue; } - + string sourceFieldName = mapping?.GetSourceFieldName(targetColumnName, sourceNodeClass.ClassName) ?? targetColumnName; if (!containsSourceValue(sourceFieldName)) { @@ -624,7 +627,7 @@ IClassMapping mapping var field = oldFormInfo.GetFormField(sourceFieldName); string? controlName = field.Settings[CLASS_FIELD_CONTROL_NAME]?.ToString()?.ToLowerInvariant(); - + object? sourceValue = getSourceValue(sourceFieldName); target[targetFieldName] = valueConvertor.Invoke(sourceValue); var fvmc = new FieldMigrationContext(field.DataType, controlName, targetColumnName, new DocumentSourceObjectContext(cmsTree, sourceNodeClass, site, oldFormInfo, newFormInfo, documentId)); @@ -670,7 +673,7 @@ IClassMapping mapping target[targetFieldName] = valueConvertor.Invoke(sourceValue); } } - else if(fmb != null) + else if (fmb != null) { switch (await fmb.MigrateValue(sourceValue, fvmc)) { @@ -684,6 +687,9 @@ IClassMapping mapping logger.LogError("Error while migrating field '{Field}' value {Value}", targetFieldName, sourceValue); break; } + + default: + break; } } else @@ -695,7 +701,7 @@ IClassMapping mapping var newField = newFormInfo.GetFormField(targetColumnName); if (newField == null) { - + var commonFields = UnpackReusableFieldSchemas(newFormInfo.GetFields()).ToArray(); newField = commonFields .FirstOrDefault(cf => ReusableSchemaService.RemoveClassPrefix(mapping?.TargetClassName ?? sourceNodeClass.ClassName, cf.Name).Equals(targetColumnName, StringComparison.InvariantCultureIgnoreCase)); diff --git a/KVA/Migration.Toolkit.Source/Providers/ClassMappingProvider.cs b/KVA/Migration.Toolkit.Source/Providers/ClassMappingProvider.cs index 36f737cd..758e770b 100644 --- a/KVA/Migration.Toolkit.Source/Providers/ClassMappingProvider.cs +++ b/KVA/Migration.Toolkit.Source/Providers/ClassMappingProvider.cs @@ -1,4 +1,3 @@ -using Migration.Toolkit.Common; using Migration.Toolkit.Common.Builders; namespace Migration.Toolkit.Source.Providers; @@ -18,6 +17,6 @@ public class ClassMappingProvider(IEnumerable classMappings) return current; }); - + public IClassMapping? GetMapping(string className) => mappingsByClassName.GetValueOrDefault(className); } diff --git a/KVA/Migration.Toolkit.Source/Services/ReusableSchemaService.cs b/KVA/Migration.Toolkit.Source/Services/ReusableSchemaService.cs index 815a2d9f..e6c3d527 100644 --- a/KVA/Migration.Toolkit.Source/Services/ReusableSchemaService.cs +++ b/KVA/Migration.Toolkit.Source/Services/ReusableSchemaService.cs @@ -6,7 +6,6 @@ using Microsoft.Extensions.Logging; using Migration.Toolkit.Common; -using Migration.Toolkit.Common.Builders; using Migration.Toolkit.Common.Helpers; namespace Migration.Toolkit.Source.Services; @@ -84,7 +83,7 @@ public void AddReusableSchemaToDataClass(DataClassInfo dataClassInfo, Guid reusa formInfo.AddFormItem(new FormSchemaInfo { Name = dataClassInfo.ClassName, Guid = reusableFieldSchemaGuid }); dataClassInfo.ClassFormDefinition = formInfo.GetXmlDefinition(); } - + public void AddReusableSchemaToDataClass(DataClassInfo dataClassInfo, string reusableFieldSchemaName) { var formInfo = new FormInfo(dataClassInfo.ClassFormDefinition); diff --git a/Migration.Tool.Extensions/ClassMappings/ClassMapping.cs b/Migration.Tool.Extensions/ClassMappings/ClassMapping.cs index 5c131678..5c564efc 100644 --- a/Migration.Tool.Extensions/ClassMappings/ClassMapping.cs +++ b/Migration.Tool.Extensions/ClassMappings/ClassMapping.cs @@ -22,18 +22,18 @@ public static IServiceCollection AddClassMergeExample(this IServiceCollection se }); m.BuildField("EventID").AsPrimaryKey(); - + var title = m .BuildField("Title") .WithFieldPatch(f => f.Caption = "Event title"); - + title.SetFrom("_ET.Event1", "EventTitle", true); title.SetFrom("_ET.Event2", "EventTitle"); - + var description = m .BuildField("Description") .WithFieldPatch(f => f.Caption = "Event description"); - + description.SetFrom("_ET.Event2", "EventSmallDesc", true); var teaser = m @@ -46,18 +46,18 @@ public static IServiceCollection AddClassMergeExample(this IServiceCollection se .WithFieldPatch(f => f.Caption = "Event text"); text.SetFrom("_ET.Event1", "EventText", true); text.SetFrom("_ET.Event2", "EventHtml"); - + var startDate = m .BuildField("StartDate") .WithFieldPatch(f => f.Caption = "Event start date"); - + startDate.SetFrom("_ET.Event1", "EventDateStart", true); startDate.ConvertFrom("_ET.Event2", "EventStartDateAsText", false, v => v?.ToString() is { } av && !string.IsNullOrWhiteSpace(av) ? DateTime.Parse(av) : null ); serviceCollection.AddSingleton(m); - + return serviceCollection; } @@ -73,7 +73,7 @@ public static IServiceCollection AddSimpleRemodelingSample(this IServiceCollecti }); m.BuildField("CoffeeRemodeledID").AsPrimaryKey(); - + m .BuildField("FarmRM") .SetFrom("DancingGoatCore.Coffee", "CoffeeFarm", true) @@ -88,17 +88,17 @@ public static IServiceCollection AddSimpleRemodelingSample(this IServiceCollecti .BuildField("CoffeeVarietyRM") .SetFrom("DancingGoatCore.Coffee", "CoffeeVariety", true) .WithFieldPatch(f => f.SetPropertyValue(FormFieldPropertyEnum.FieldCaption, "Variety RM")); - + m .BuildField("CoffeeProcessingRM") .SetFrom("DancingGoatCore.Coffee", "CoffeeProcessing", true) .WithFieldPatch(f => f.SetPropertyValue(FormFieldPropertyEnum.FieldCaption, "Processing RM")); - + m .BuildField("CoffeeAltitudeRM") .SetFrom("DancingGoatCore.Coffee", "CoffeeAltitude", true) .WithFieldPatch(f => f.SetPropertyValue(FormFieldPropertyEnum.FieldCaption, "Altitude RM")); - + m .BuildField("CoffeeIsDecafRM") .SetFrom("DancingGoatCore.Coffee", "CoffeeIsDecaf", true) @@ -106,7 +106,7 @@ public static IServiceCollection AddSimpleRemodelingSample(this IServiceCollecti // register class mapping serviceCollection.AddSingleton(m); - + return serviceCollection; } @@ -114,40 +114,48 @@ public static IServiceCollection AddReusableSchemaIntegrationSample(this IServic { const string schemaNameDgcCommon = "DGC.Address"; const string sourceClassName = "DancingGoatCore.Cafe"; - + var sb = new ReusableSchemaBuilder(schemaNameDgcCommon, "Common address", "Reusable schema that defines common address"); sb .BuildField("City") .WithFactory(() => new FormFieldInfo { - Name = "City", Caption = "City", Guid = new Guid("F9DC7EBE-29CA-4591-BF43-E782D50624AF"), DataType = FieldDataType.Text, Size = 400, + Name = "City", + Caption = "City", + Guid = new Guid("F9DC7EBE-29CA-4591-BF43-E782D50624AF"), + DataType = FieldDataType.Text, + Size = 400, Settings = { ["controlname"] = FormComponents.AdminTextInputComponent } }); - + sb .BuildField("Street") .WithFactory(() => new FormFieldInfo { - Name = "Street", Caption = "Street", Guid = new Guid("712C0B07-45AC-4CD0-A355-2BA4C46941B6"), DataType = FieldDataType.Text, Size = 400, + Name = "Street", + Caption = "Street", + Guid = new Guid("712C0B07-45AC-4CD0-A355-2BA4C46941B6"), + DataType = FieldDataType.Text, + Size = 400, Settings = { ["controlname"] = FormComponents.AdminTextInputComponent } }); - + sb .BuildField("ZipCode") .CreateFrom(sourceClassName, "CafeZipCode"); - + sb .BuildField("Phone") .CreateFrom(sourceClassName, "CafePhone"); - - + + var m = new MultiClassMapping("DancingGoatCore.CafeRS", target => { target.ClassName = "DancingGoatCore.CafeRS"; @@ -165,12 +173,12 @@ public static IServiceCollection AddReusableSchemaIntegrationSample(this IServic m.BuildField("CafeName").SetFrom(sourceClassName, "CafeName", isTemplate: true); m.BuildField("CafePhoto").SetFrom(sourceClassName, "CafePhoto", isTemplate: true); m.BuildField("CafeAdditionalNotes").SetFrom(sourceClassName, "CafeAdditionalNotes", isTemplate: true); - + // register mapping serviceCollection.AddSingleton(m); // register reusable schema builder serviceCollection.AddSingleton(sb); - + return serviceCollection; } } diff --git a/Migration.Tool.Extensions/CommunityMigrations/SampleTextMigration.cs b/Migration.Tool.Extensions/CommunityMigrations/SampleTextMigration.cs index 33ee528e..4160a21c 100644 --- a/Migration.Tool.Extensions/CommunityMigrations/SampleTextMigration.cs +++ b/Migration.Tool.Extensions/CommunityMigrations/SampleTextMigration.cs @@ -9,18 +9,18 @@ namespace Migration.Tool.Extensions.CommunityMigrations; -public class SampleTextMigration(ILogger logger, SpoiledGuidContext spoiledGuidContext): IFieldMigration +public class SampleTextMigration(ILogger logger, SpoiledGuidContext spoiledGuidContext) : IFieldMigration { // Migrations will be sorted by this number before checking with "ShallMigrate" method. Set rank to number bellow 100 000 (default migration will have 100 000 or higher) public int Rank => 5000; - + // this method will check, if this implementation handles migration (for both, definition and value) public bool ShallMigrate(FieldMigrationContext context) => context.SourceDataType is "text" or "longtext" && context.SourceFormControl is "MY_COMMUNITY_TEXT_EDITOR"; public void MigrateFieldDefinition(FormDefinitionPatcher formDefinitionPatcher, XElement field, XAttribute? columnTypeAttr, string fieldDescriptor) { // now we migrate field definition - + // field is element from class form definition, for example /* */ - + // we usually want to change field type and column type, lets assume our custom control content is HTML, then target type would be: columnTypeAttr?.SetValue(FieldDataType.RichTextHTML); @@ -48,14 +48,14 @@ public void MigrateFieldDefinition(FormDefinitionPatcher formDefinitionPatcher, public async Task MigrateValue(object? sourceValue, FieldMigrationContext context) { // if required, migrate value (for example cut out any unsupported features or migrated them to kentico supported variants if available) - + // check context - if (context.SourceObjectContext is DocumentSourceObjectContext(var cmsTree, var nodeClass, var cmsSite, var oldFormInfo, var newFormInfo, var documentId)) + if (context.SourceObjectContext is DocumentSourceObjectContext(_, _, _, _, _, _)) { // do migration logic - + // return result - return new FieldMigrationResult(true, sourceValue); + return new FieldMigrationResult(true, sourceValue); } else { diff --git a/Migration.Tool.Extensions/DefaultMigrations/AssetMigration.cs b/Migration.Tool.Extensions/DefaultMigrations/AssetMigration.cs index 8a038ef9..4bad3e49 100644 --- a/Migration.Tool.Extensions/DefaultMigrations/AssetMigration.cs +++ b/Migration.Tool.Extensions/DefaultMigrations/AssetMigration.cs @@ -20,9 +20,9 @@ namespace Migration.Tool.Extensions.DefaultMigrations; public class AssetMigration( - ILogger logger, - ClassService classService, - IAttachmentMigrator attachmentMigrator, + ILogger logger, + ClassService classService, + IAttachmentMigrator attachmentMigrator, ModelFacade modelFacade, KxpMediaFileFacade mediaFileFacade, ToolkitConfiguration configuration, @@ -51,9 +51,9 @@ public async Task MigrateValue(object? sourceValue, FieldM { throw new ArgumentNullException(nameof(sourceObjectContext)); } - + var field = oldFormInfo.GetFormField(fieldName); - + List mfis = []; bool hasMigratedAsset = false; if (sourceValue is string link && @@ -121,7 +121,7 @@ public async Task MigrateValue(object? sourceValue, FieldM ]; hasMigratedAsset = true; logger.LogTrace("MediaFile migrated from media file '{Field}': '{Value}'", fieldName, result); - } + } } } } @@ -327,13 +327,10 @@ public void MigrateFieldDefinition(FormDefinitionPatcher formDefinitionPatcher, columnTypeAttr?.SetValue(configuration.MigrateMediaToMediaLibrary ? FieldDataType.Assets : FieldDataType.ContentItemReference); var settings = field.EnsureElement(FormDefinitionPatcher.FieldElemSettings); - settings.EnsureElement(FormDefinitionPatcher.SettingsElemControlname, e => - { - e.Value = configuration.MigrateMediaToMediaLibrary ? FormComponents.AdminAssetSelectorComponent : FormComponents.AdminContentItemSelectorComponent; - }); + settings.EnsureElement(FormDefinitionPatcher.SettingsElemControlname, e => e.Value = configuration.MigrateMediaToMediaLibrary ? FormComponents.AdminAssetSelectorComponent : FormComponents.AdminContentItemSelectorComponent); if (configuration.MigrateMediaToMediaLibrary) { - settings.EnsureElement(FormDefinitionPatcher.SettingsMaximumassets, maxAssets => maxAssets.Value = FormDefinitionPatcher.SettingsMaximumassetsFallback); + settings.EnsureElement(FormDefinitionPatcher.SettingsMaximumassets, maxAssets => maxAssets.Value = FormDefinitionPatcher.SettingsMaximumassetsFallback); } } } diff --git a/Migration.Tool.Extensions/ServiceCollectionExtensions.cs b/Migration.Tool.Extensions/ServiceCollectionExtensions.cs index 8e93ddc6..cfaa49ba 100644 --- a/Migration.Tool.Extensions/ServiceCollectionExtensions.cs +++ b/Migration.Tool.Extensions/ServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.DependencyInjection; -using Migration.Tool.Extensions.ClassMappings; using Migration.Tool.Extensions.CommunityMigrations; using Migration.Tool.Extensions.DefaultMigrations; using Migration.Toolkit.KXP.Api.Services.CmsClass; @@ -13,9 +12,9 @@ public static IServiceCollection UseCustomizations(this IServiceCollection servi services.AddTransient(); services.AddTransient(); - services.AddClassMergeExample(); - services.AddSimpleRemodelingSample(); - services.AddReusableSchemaIntegrationSample(); + // services.AddClassMergeExample(); + // services.AddSimpleRemodelingSample(); + // services.AddReusableSchemaIntegrationSample(); return services; } } diff --git a/Migration.Toolkit.Common/Builders/ClassMapper.cs b/Migration.Toolkit.Common/Builders/ClassMapper.cs index 12386373..4735f489 100644 --- a/Migration.Toolkit.Common/Builders/ClassMapper.cs +++ b/Migration.Toolkit.Common/Builders/ClassMapper.cs @@ -1,13 +1,12 @@ using CMS.DataEngine; using CMS.FormEngine; -using MimeKit.Encodings; namespace Migration.Toolkit.Common.Builders; public interface IClassMapping { string TargetClassName { get; } - + bool IsMatch(string sourceClassName); void PatchTargetDataClass(DataClassInfo target); ICollection SourceClassNames { get; } @@ -35,10 +34,10 @@ public record FieldMapping(string TargetFieldName, string SourceClassName, strin public record FieldMappingWithConversion(string TargetFieldName, string SourceClassName, string SourceFieldName, bool IsTemplate, Func Converter) : IFieldMapping; -public class MultiClassMapping(string targetClassName, Action classPatcher): IClassMapping +public class MultiClassMapping(string targetClassName, Action classPatcher) : IClassMapping { public void PatchTargetDataClass(DataClassInfo target) => classPatcher(target); - + ICollection IClassMapping.SourceClassNames => SourceClassNames; IList IClassMapping.Mappings => Mappings; IDictionary> IClassMapping.TargetFieldPatchers => TargetFieldPatchers; @@ -62,8 +61,8 @@ public class MultiClassMapping(string targetClassName, Action cla }; string IClassMapping.TargetClassName => targetClassName; - - public List Mappings { get; } = new(); + + public List Mappings { get; } = []; public string PrimaryKey { get; set; } public HashSet SourceClassNames = new(StringComparer.InvariantCultureIgnoreCase); @@ -82,7 +81,7 @@ public FieldBuilder BuildField(string targetFieldName) public void UseResusableSchema(string reusableSchemaName) { ArgumentException.ThrowIfNullOrWhiteSpace(reusableSchemaName); - + if (reusableSchemaNames.Contains(reusableSchemaName)) { throw new Exception($"The reusable Schema {reusableSchemaName} is already assigned"); diff --git a/Migration.Toolkit.Common/Builders/ReusableSchemaBuilder.cs b/Migration.Toolkit.Common/Builders/ReusableSchemaBuilder.cs index dcd7594d..4db61bf1 100644 --- a/Migration.Toolkit.Common/Builders/ReusableSchemaBuilder.cs +++ b/Migration.Toolkit.Common/Builders/ReusableSchemaBuilder.cs @@ -20,14 +20,14 @@ public class ReusableSchemaBuilder(string schemaName, string displayName, string public string SchemaDisplayName { get; } = displayName; public string? SchemaDescription { get; } = schemaDescription; public IList FieldBuilders { get; set; } = []; - + public IReusableFieldBuilder BuildField(string targetFieldName) { if (FieldBuilders.Any(fb => fb.TargetFieldName.Equals(targetFieldName, StringComparison.InvariantCultureIgnoreCase))) { throw new InvalidOperationException($"Target field '{targetFieldName}' already exists"); } - + var newFieldBuilder = new ReusableFieldBuilder(targetFieldName); FieldBuilders.Add(newFieldBuilder); return newFieldBuilder; @@ -37,7 +37,7 @@ public void AssertIsValid() { ArgumentException.ThrowIfNullOrWhiteSpace(SchemaName, nameof(SchemaName)); ArgumentException.ThrowIfNullOrWhiteSpace(SchemaDisplayName, nameof(SchemaDisplayName)); - + foreach (var reusableFieldBuilder in FieldBuilders) { reusableFieldBuilder.AssertIsValid(); @@ -86,7 +86,7 @@ public IReusableFieldBuilder CreateFrom(string sourceClassName, string sourceFie { ArgumentException.ThrowIfNullOrWhiteSpace(sourceClassName, nameof(sourceClassName)); ArgumentException.ThrowIfNullOrWhiteSpace(sourceFieldName, nameof(sourceFieldName)); - + SourceFieldIdentifier = new SourceFieldIdentifier(sourceClassName, sourceFieldName); return this; } diff --git a/Migration.Toolkit.Common/Helpers/SerializationHelper.cs b/Migration.Toolkit.Common/Helpers/SerializationHelper.cs index 5c724173..154966be 100644 --- a/Migration.Toolkit.Common/Helpers/SerializationHelper.cs +++ b/Migration.Toolkit.Common/Helpers/SerializationHelper.cs @@ -12,7 +12,7 @@ public static string SerializeOnlyNonComplexProperties(T obj) => JsonConvert. new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore, MaxDepth = 1 }); public static string Serialize(T obj) => JsonConvert.SerializeObject(obj); - + public class ShouldSerializeContractResolver : DefaultContractResolver { public static readonly ShouldSerializeContractResolver Instance = new(); diff --git a/Migration.Toolkit.KXP.Api/DependencyInjectionExtensions.cs b/Migration.Toolkit.KXP.Api/DependencyInjectionExtensions.cs index 47ef5290..23292b11 100644 --- a/Migration.Toolkit.KXP.Api/DependencyInjectionExtensions.cs +++ b/Migration.Toolkit.KXP.Api/DependencyInjectionExtensions.cs @@ -18,10 +18,10 @@ public static IServiceCollection UseKxpApi(this IServiceCollection services, ICo SystemContext.WebApplicationPhysicalPath = applicationPhysicalPath; } - + services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(s => (s.GetService() as FieldMigrationService)!); + services.AddSingleton(s => (s.GetService() as FieldMigrationService)!); services.AddSingleton(); services.AddSingleton(); diff --git a/Migration.Toolkit.KXP.Api/Services/CmsClass/FieldMigrationService.cs b/Migration.Toolkit.KXP.Api/Services/CmsClass/FieldMigrationService.cs index c1d45dd3..2720dac8 100644 --- a/Migration.Toolkit.KXP.Api/Services/CmsClass/FieldMigrationService.cs +++ b/Migration.Toolkit.KXP.Api/Services/CmsClass/FieldMigrationService.cs @@ -41,7 +41,7 @@ public FieldMigrationService(ToolkitConfiguration configuration, ILogger {TargetDataType}", fieldDescriptor, columnType, targetDataType); columnTypeAttr?.SetValue(targetDataType); @@ -249,6 +249,9 @@ public void PatchField(XElement field) fieldMigration.MigrateFieldDefinition(this, field, columnTypeAttr, fieldDescriptor); break; } + + default: + break; } if (!classIsForm && !classIsDocumentType) diff --git a/Migration.Toolkit.KXP.Api/Services/CmsClass/FormFieldMappingModel.cs b/Migration.Toolkit.KXP.Api/Services/CmsClass/FormFieldMappingModel.cs index c1a1abee..81c71164 100644 --- a/Migration.Toolkit.KXP.Api/Services/CmsClass/FormFieldMappingModel.cs +++ b/Migration.Toolkit.KXP.Api/Services/CmsClass/FormFieldMappingModel.cs @@ -20,19 +20,19 @@ public record DataTypeMigrationModel( public interface ISourceObjectContext; -public record EmptySourceObjectContext: ISourceObjectContext; +public record EmptySourceObjectContext : ISourceObjectContext; public record FieldMigrationContext(string SourceDataType, string? SourceFormControl, string? FieldName, ISourceObjectContext SourceObjectContext); public record FieldMigrationResult(bool Success, object? MigratedValue); public interface IFieldMigration { int Rank { get; } bool ShallMigrate(FieldMigrationContext context); - + void MigrateFieldDefinition(FormDefinitionPatcher formDefinitionPatcher, XElement field, XAttribute? columnTypeAttr, string fieldDescriptor); Task MigrateValue(object? sourceValue, FieldMigrationContext context); } -public record FieldMigration(string SourceDataType, string TargetDataType, string SourceFormControl, string? TargetFormComponent, string[]? Actions = null, Regex? FieldNameRegex = null): IFieldMigration +public record FieldMigration(string SourceDataType, string TargetDataType, string SourceFormControl, string? TargetFormComponent, string[]? Actions = null, Regex? FieldNameRegex = null) : IFieldMigration { public int Rank => 100_000; public bool ShallMigrate(FieldMigrationContext context) => throw new NotImplementedException();