/// <summary> /// Executed when entering the page for selecting schema types. /// It fires PageEntering event which ensures all types are loaded on the UI. /// It also ensures all related entities are computed and cached. /// </summary> /// <param name="args">Event arguments being passed to the method.</param> public override async Task OnPageEnteringAsync(WizardEnteringArgs args) { this.IsEntered = true; await base.OnPageEnteringAsync(args).ConfigureAwait(false); View = new SchemaTypes() { DataContext = this }; PageEntering?.Invoke(this, EventArgs.Empty); if (this.View is SchemaTypes view) { view.SelectedSchemaTypesCount.Text = SchemaTypes.Count(x => x.IsSelected).ToString(CultureInfo.InvariantCulture); view.SelectedBoundOperationsCount.Text = SchemaTypes .Where(x => x.IsSelected && x.BoundOperations?.Any() == true).SelectMany(x => x.BoundOperations) .Count(x => x.IsSelected).ToString(CultureInfo.InvariantCulture); } }
/// <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(); }