/// <summary> /// Executed when leaving the page for selecting schema types. /// It checks if there is a type that is required but has not been selected. /// If found, these types are automatically selected and the user notified. /// </summary> /// <param name="args">Event arguments being passed to the method.</param> public override async Task <PageNavigationResult> OnPageLeavingAsync(WizardLeavingArgs args) { SaveToUserSettings(); var numberOfTypesToBeIncluded = 0; var correctTypeSelection = true; PageLeaving?.Invoke(this, EventArgs.Empty); //check each excluded schema type and check if they are required. If so, then automatically select them. foreach (var schemaType in ExcludedSchemaTypeNames) { if (RelatedTypes.TryGetValue(schemaType, out ICollection <string> relatedTypes)) { //Check if any of the related types has been selected if (relatedTypes.Any(o => { if (SchemaTypeModelMap.TryGetValue(o, out SchemaTypeModel schemaTypeModel)) { return(schemaTypeModel.IsSelected); } return(false); })) { if (SchemaTypeModelMap.TryGetValue(schemaType, out SchemaTypeModel schemaTypeModel)) { schemaTypeModel.IsSelected = true; correctTypeSelection = false; numberOfTypesToBeIncluded++; } } } } if (!correctTypeSelection) { return(await Task.FromResult(new PageNavigationResult { ErrorMessage = $"{numberOfTypesToBeIncluded} {Constants.SchemaTypesWillAutomaticallyBeIncluded}", IsSuccess = correctTypeSelection, ShowMessageBoxOnFailure = true }).ConfigureAwait(false)); } else { return(await base.OnPageLeavingAsync(args).ConfigureAwait(false)); } }
/// <summary> /// Add related type and its relation to the RelatedTypes dictionary /// </summary> /// <param name="type">the schema type fullname.</param> /// <param name="relatedType">Related schema type fullname.</param> public void AddRelatedType(string type, string relatedType) { if (RelatedTypes.TryGetValue(type, out ICollection <string> relatedTypes)) { relatedTypes.Add(relatedType); } else { relatedTypes = new HashSet <string>() { relatedType }; RelatedTypes.Add(type, relatedTypes); } }
/// <summary> /// Creates a list of types that needs to be loaded on the UI. /// Initially all the types are loaded /// </summary> /// <param name="schemaTypes">A list of schema types that need to be laoded.</param> /// <param name="boundOperations">The associated bound operations.</param> public void LoadSchemaTypes( IEnumerable <IEdmSchemaType> schemaTypes, IDictionary <IEdmStructuredType, List <IEdmOperation> > boundOperations) { var toLoad = new List <SchemaTypeModel>(); foreach (var type in schemaTypes) { if (!SchemaTypeModelMap.ContainsKey(type.FullName()) || SchemaTypeModelMap.Count() != schemaTypes.Count()) { SchemaTypes = toLoad; SchemaTypeModelMap.Clear(); break; } } if (SchemaTypes.Any()) { return; } foreach (var schemaType in schemaTypes) { var schemaTypeModel = new SchemaTypeModel() { Name = schemaType.FullTypeName(), ShortName = EdmHelper.GetTypeNameFromFullName(schemaType.FullTypeName()) }; // Create propertyChange handler. // Anytime a property is selected/unslected, the handler ensures // all the related types and operations are selected/unselected schemaTypeModel.PropertyChanged += (s, args) => { if (schemaTypeModel.IsSelected && schemaType is IEdmStructuredType structuredType) { //Check for the base type and automatically select it if not selected already. string baseTypeFullName = structuredType.BaseType?.FullTypeName(); if (baseTypeFullName != null) { AddRelatedType(baseTypeFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(baseTypeFullName, out SchemaTypeModel baseTypeSchemaTypeModel) && !baseTypeSchemaTypeModel.IsSelected) { baseTypeSchemaTypeModel.IsSelected = true; } } // Check the required navigational property types and ensure they are selected as well foreach (var property in structuredType.DeclaredProperties) { string propertyName = property is IEdmNavigationProperty?property.Type.ToStructuredType().FullTypeName() : property.Type.FullName(); if (property.Type.ToStructuredType() != null || property.Type.IsEnum()) { propertyName = property.Type.ToStructuredType()?.FullTypeName() ?? property.Type.FullName(); AddRelatedType(propertyName, structuredType.FullTypeName()); bool hasProperty = SchemaTypeModelMap.TryGetValue(propertyName, out SchemaTypeModel navigationPropertyModel); if (hasProperty && !navigationPropertyModel.IsSelected) { navigationPropertyModel.IsSelected = true; } } } // Check for bound operations and ensure related types are also selected. // In this case related types means return types and parameter types. if (boundOperations.TryGetValue(structuredType, out List <IEdmOperation> operations)) { foreach (var operation in operations) { // Check if return type of associated bound operation has been selected. if (operation.ReturnType != null && (operation.ReturnType.ToStructuredType() != null || operation.ReturnType.IsEnum())) { string returnTypeFullName = operation.ReturnType.ToStructuredType()?.FullTypeName() ?? operation.ReturnType.FullName(); AddRelatedType(returnTypeFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(returnTypeFullName, out SchemaTypeModel referencedSchemaTypeModel) && !referencedSchemaTypeModel.IsSelected) { referencedSchemaTypeModel.IsSelected = true; } } // Check if parameter types of associated bound operations has been selected. IEnumerable <IEdmOperationParameter> parameters = operation.Parameters; foreach (var parameter in parameters) { if (parameter.Type.ToStructuredType() != null || parameter.Type.IsEnum()) { string parameterFullName = parameter.Type.ToStructuredType()?.FullTypeName() ?? parameter.Type.FullName(); AddRelatedType(parameterFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(parameterFullName, out SchemaTypeModel model) && !model.IsSelected) { model.IsSelected = true; } } } } } } else if (!schemaTypeModel.IsSelected) { // automatically deselect related types for deselected type if (RelatedTypes.TryGetValue(schemaTypeModel.Name, out ICollection <string> relatedTypes)) { foreach (var relatedType in relatedTypes) { if (SchemaTypeModelMap.TryGetValue(relatedType, out SchemaTypeModel relatedSchemaTypeModel) && relatedSchemaTypeModel.IsSelected) { relatedSchemaTypeModel.IsSelected = false; } } } } }; toLoad.Add(schemaTypeModel); schemaTypeModel.IsSelected = true; SchemaTypeModelMap.Add(schemaType.FullTypeName(), schemaTypeModel); } SchemaTypes = toLoad.OrderBy(o => o.Name).ToList(); }
/// <summary> /// Creates a list of types that needs to be loaded on the UI. /// Initially all the types are loaded /// </summary> /// <param name="schemaTypes">A list of schema types that need to be laoded.</param> /// <param name="boundOperations">The associated bound operations.</param> public void LoadSchemaTypes( IEnumerable <IEdmSchemaType> schemaTypes, IDictionary <IEdmType, List <IEdmOperation> > boundOperations) { var toLoad = new List <SchemaTypeModel>(); foreach (var type in schemaTypes) { if (!SchemaTypeModelMap.ContainsKey(type.FullName()) || SchemaTypeModelMap.Count != schemaTypes.Count()) { SchemaTypes = toLoad; SchemaTypeModelMap.Clear(); break; } } if (SchemaTypes.Any()) { return; } foreach (var schemaType in schemaTypes) { var schemaTypeModel = new SchemaTypeModel { Name = schemaType.FullTypeName(), ShortName = EdmHelper.GetTypeNameFromFullName(schemaType.FullTypeName()) }; // Create propertyChange handler. // Anytime a property is selected/unslected, the handler ensures // all the related types and operations are selected/unselected schemaTypeModel.PropertyChanged += (s, args) => { if (schemaTypeModel.IsSelected && schemaType is IEdmStructuredType structuredType) { //Check for the base type and automatically select it if not selected already. string baseTypeFullName = structuredType.BaseType?.FullTypeName(); if (baseTypeFullName != null) { AddRelatedType(baseTypeFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(baseTypeFullName, out SchemaTypeModel baseTypeSchemaTypeModel) && !baseTypeSchemaTypeModel.IsSelected) { baseTypeSchemaTypeModel.IsSelected = true; } } // Check the required property types and ensure they are selected as well foreach (var property in structuredType.DeclaredProperties) { IEdmTypeReference propertyType = property.Type.IsCollection() ? property.Type.AsCollection().ElementType() : property.Type; if (propertyType.ToStructuredType() != null || propertyType.IsEnum()) { string propertyTypeName = propertyType.ToStructuredType()?.FullTypeName() ?? propertyType.FullName(); AddRelatedType(propertyTypeName, structuredType.FullTypeName()); bool hasProperty = SchemaTypeModelMap.TryGetValue(propertyTypeName, out SchemaTypeModel propertySchemaTypeModel); if (hasProperty && !propertySchemaTypeModel.IsSelected) { propertySchemaTypeModel.IsSelected = true; } } } // Check for bound operations and ensure related types are also selected. // In this case related types means return types and parameter types. if (boundOperations.TryGetValue(structuredType, out List <IEdmOperation> operations)) { foreach (var operation in operations) { // Check if return type of associated bound operation has been selected. if (operation.ReturnType != null && (operation.ReturnType.ToStructuredType() != null || operation.ReturnType.IsEnum())) { string returnTypeFullName = operation.ReturnType.ToStructuredType()?.FullTypeName() ?? operation.ReturnType.FullName(); AddRelatedType(returnTypeFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(returnTypeFullName, out SchemaTypeModel referencedSchemaTypeModel) && !referencedSchemaTypeModel.IsSelected) { referencedSchemaTypeModel.IsSelected = true; } } // Check if parameter types of associated bound operations has been selected. IEnumerable <IEdmOperationParameter> parameters = operation.Parameters; foreach (var parameter in parameters) { if (parameter.Type.ToStructuredType() != null || parameter.Type.IsEnum()) { string parameterFullName = parameter.Type.ToStructuredType()?.FullTypeName() ?? parameter.Type.FullName(); AddRelatedType(parameterFullName, structuredType.FullTypeName()); if (SchemaTypeModelMap.TryGetValue(parameterFullName, out SchemaTypeModel model) && !model.IsSelected) { model.IsSelected = true; } } } } } } else if (!schemaTypeModel.IsSelected) { // automatically deselect related types for deselected type if (RelatedTypes.TryGetValue(schemaTypeModel.Name, out ICollection <string> relatedTypes)) { foreach (var relatedType in relatedTypes) { if (SchemaTypeModelMap.TryGetValue(relatedType, out SchemaTypeModel relatedSchemaTypeModel) && relatedSchemaTypeModel.IsSelected) { relatedSchemaTypeModel.IsSelected = false; } } } // deselect all related bound operations foreach (var boundOperation in schemaTypeModel.BoundOperations) { boundOperation.IsSelected = false; } } if (this.View is SchemaTypes view) { view.SelectedSchemaTypesCount.Text = SchemaTypes.Count(x => x.IsSelected).ToString(CultureInfo.InvariantCulture); } }; // load bound operations that require the schema type var boundOperationsToLoad = boundOperations .Where(x => x.Key == schemaType || x.Key.AsElementType() == schemaType) .ToDictionary(x => x.Key, x => x.Value); LoadBoundOperations(schemaTypeModel, boundOperationsToLoad, ExcludedSchemaTypeNames.ToList(), SchemaTypeModelMap); toLoad.Add(schemaTypeModel); schemaTypeModel.IsSelected = true; SchemaTypeModelMap.Add(schemaType.FullTypeName(), schemaTypeModel); } SchemaTypes = toLoad.OrderBy(o => o.Name).ToList(); _schemaTypesCount = SchemaTypes.Count(); _boundOperationsCount = SchemaTypes.Where(x => x?.BoundOperations?.Any() == true) .SelectMany(x => x.BoundOperations).Count(); }