src/typesystem/CompositeTypeProvider.ps1
# Copyright 2020, Adam Edwards # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. . (import-script TypeSchema) . (import-script TypeDefinition) ScriptClass CompositeTypeProvider { $base = $null $namespace = $null $entityTypeTable = $null $complexTypeTable = $null $namespaceAlias = $null function __initialize($graph) { $this.base = new-so TypeProvider $this $graph $this.namespace = $this.base.scriptclass |=> GetGraphNamespace $this.base.graph $this.namespaceAlias = (($::.GraphManager |=> GetGraph (gg -current).details).builder.dataModel).namespaceAlias } function GetTypeDefinition($typeClass, $typeId) { if ( $typeClass -ne 'Entity' -and $typeClass -ne 'Complex' -and $typeClass -ne 'Unknown' ) { throw "The '$($this.scriptclass.classname)' type provider does not support type class '$typeClass'" } $nameInfo = $::.TypeSchema |=> GetTypeNameInfo $this.namespace $typeId $nativeSchema = GetNativeSchemaFromGraph $nameInfo.Name $typeClass $properties = if ( $nativeSchema | gm property -erroraction ignore ) { foreach ( $property in $nativeSchema.property ) { $typeInfo = $::.TypeSchema |=> GetNormalizedPropertyTypeInfo $this.namespace $this.namespaceAlias $property.Type new-so TypeProperty $property.Name $typeInfo.TypeFullName $typeInfo.IsCollection } } $baseType = if ( $nativeSchema | gm BaseType -erroraction ignore) { $::.Entity |=> UnAliasQualifiedName $this.namespace $this.namespaceAlias $nativeSchema.baseType } new-so TypeDefinition $typeId $typeClass $nativeSchema.name $this.namespace $baseType $properties $null $null $true $nativeSchema } function GetSortedTypeNames($typeClass) { $this.scriptclass |=> ValidateTypeClass $typeClass switch ( $typeClass ) { 'Entity' { (GetEntityTypeSchemas).Keys break } 'Complex' { (GetComplexTypeSchemas).Keys break } } } function GetComplexTypeSchemas { if ( ! $this.complexTypeTable ) { $graphDataModel = ($::.GraphManager |=> GetGraph $this.base.graph).builder.dataModel $complexTypeTable = [System.Collections.Generic.SortedList[String, Object]]::new() $complexTypeSchemas = $graphDataModel |=> GetComplexTypes UpdateTypeTable $complexTypeTable $complexTypeSchemas $this.complexTypeTable = $complexTypeTable } $this.complexTypeTable } function GetEntityTypeSchemas { if ( ! $this.entityTypeTable ) { $graphDataModel = ($::.GraphManager |=> GetGraph $this.base.graph).builder.dataModel $entityTypeTable = [System.Collections.Generic.SortedList[String, Object]]::new() $entityTypeSchemas = $graphDataModel |=> GetEntityTypes UpdateTypeTable $entityTypeTable $entityTypeSchemas $this.entityTypeTable = $entityTypeTable } $this.entityTypeTable } function UpdateTypeTable($typeTable, $typeSchemas) { foreach ( $schema in $typeSchemas ) { $qualifiedTypeName = $::.TypeSchema |=> GetQualifiedTypeName $this.namespace $schema.name $typeTable.Add($qualifiedTypeName.tolower(), $schema) } } function GetTypeByName($typeClass, $typeName) { $typeTable = if ( $typeClass -eq 'Entity' ) { GetEntityTypeSchemas } else { GetComplexTypeSchemas } $typeTable[$typeName.tolower()] } function GetNativeSchemaFromGraph($unqualifiedTypeName, $typeClass) { $qualifiedTypeName = $::.TypeSchema |=> GetQualifiedTypeName $this.namespace $unqualifiedTypeName $nativeSchema = if ( $typeClass -eq 'Entity' -or $typeClass -eq 'Unknown' ) { # Using try / catch here and below because erroractionpreference ignore / silentlyconitnue # are known not to work due to a defect fixed in PowerShell 7.0 try { GetTypeByName Entity $qualifiedTypeName } catch { } } if ( ! $nativeSchema -and ( $typeClass -eq 'Complex' -or $typeClass -eq 'Unknown' ) ) { $nativeSchema = try { GetTypeByName Complex $qualifiedTypeName } catch { } } if ( ! $nativeSchema ) { throw "Schema for type '$unqualifiedTypeName' of type class '$typeClass' was not found in Graph '$($this.base.graph.name)'" } $nativeSchema } static { function GetTypeProvider($graph) { $::.TypeProvider |=> GetTypeProvider $this $graph } function GetSupportedTypeClasses { @('Entity', 'Complex') } function GetDefaultNamespace($typeClass, $graph) { $::.TypeProvider |=> GetGraphNamespace $graph } function ValidateTypeClass($typeClass) { $::.TypeProvider |=> ValidateTypeClass $this $typeClass } } } |