in src/Readers/Vipr.Reader.OData.v4/OdcmReader.cs [253:400]
private void WriteNamespaceDeep(IEdmModel edmModel, string @namespace)
{
// Get all of the top-level elements defined in the metadata <Schema> element. This includes the EntityContainer.
var allElements = AllElementsByNamespace(edmModel.SchemaElements, @namespace).ToList();
// Get all of the types found in the metadata <Schema> element. No EntityContainer elements.
var types = AllTypes(allElements).ToList();
foreach (var enumType in AllEnumTypes(types))
{
var odcmEnum = TryResolveType<OdcmEnum>(enumType.Name, enumType.Namespace);
odcmEnum.UnderlyingType = (OdcmPrimitiveType)ResolveType(enumType.UnderlyingType.Name, enumType.UnderlyingType.Namespace);
odcmEnum.IsFlags = enumType.IsFlags;
AddVocabularyAnnotations(odcmEnum, enumType);
foreach (var enumMember in enumType.Members)
{
var odcmEnumMember = new OdcmEnumMember(enumMember.Name)
{
Value = (enumMember.Value).Value
};
AddVocabularyAnnotations(odcmEnumMember, enumMember);
odcmEnum.Members.Add(odcmEnumMember);
}
}
foreach (var typeDefinition in AllTypeDefinitions(types))
{
var odcmTypeDefinition = TryResolveType<OdcmTypeDefinition>(typeDefinition.Name, typeDefinition.Namespace);
// Type definitions should only support primitives as their base types [http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part3-csdl.html]
var baseType = ResolveType(typeDefinition.UnderlyingType.Name, typeDefinition.UnderlyingType.Namespace) as OdcmPrimitiveType;
if (baseType == null)
{
throw new InvalidOperationException("Type definitions should only accept primitive type as their base type.");
}
odcmTypeDefinition.BaseType = baseType;
AddVocabularyAnnotations(odcmTypeDefinition, typeDefinition);
}
foreach (var complexType in AllComplexTypes(types))
{
var odcmClass = TryResolveType<OdcmClass>(complexType.Name, complexType.Namespace);
odcmClass.IsAbstract = complexType.IsAbstract;
odcmClass.IsOpen = complexType.IsOpen;
AddVocabularyAnnotations(odcmClass, complexType);
ResolveBaseClass(odcmClass, complexType);
foreach (var property in complexType.DeclaredProperties)
{
WriteProperty(odcmClass, property);
}
}
var entityTypes = AllEntityTypes(types).ToList();
// First make a pass through entity types to establish their hierarchy;
// this is useful for cases when base entity type is defined after derived one
foreach (var entityType in entityTypes)
{
var odcmClass = TryResolveType<OdcmEntityClass>(entityType.Name, entityType.Namespace);
ResolveBaseClass(odcmClass, entityType);
}
foreach (var entityType in entityTypes)
{
var odcmClass = TryResolveType<OdcmEntityClass>(entityType.Name, entityType.Namespace);
odcmClass.IsAbstract = entityType.IsAbstract;
odcmClass.IsOpen = entityType.IsOpen;
// Add all of the structural and navigation properties to the EntityType, which is an OdcmClass.
// Capability annotations are not yet set on the OdcmClass.Properties[x].Projection.
foreach (var property in entityType.DeclaredProperties)
{
WriteProperty(odcmClass, property);
}
foreach (IEdmStructuralProperty keyProperty in entityType.Key())
{
OdcmProperty property;
if (!odcmClass.TryFindProperty(keyProperty.Name, out property))
{
throw new InvalidOperationException();
}
if (property.IsNullable)
{
//TODO: need to create a warning...
}
odcmClass.Key.Add(property);
}
// Add the capability annotations to OdcmClass.Properties[x].Projection
AddVocabularyAnnotations(odcmClass, entityType);
}
foreach (var entityContainer in AllEntityContainers(allElements))
{
var odcmClass = TryResolveType<OdcmClass>(entityContainer.Name, entityContainer.Namespace);
odcmClass.Projection = new OdcmProjection
{
Type = odcmClass
};
try
{
_propertyCapabilitiesCache.Add(odcmClass, new List<OdcmCapability>());
}
catch (InvalidOperationException e)
{
Logger.Warn("Failed to add property to cache", e);
}
AddVocabularyAnnotations(odcmClass, entityContainer);
var entitySets = ContainerElementsByKind<IEdmEntitySet>(entityContainer, EdmContainerElementKind.EntitySet);
foreach (var entitySet in entitySets)
{
WriteProperty(odcmClass, entitySet);
}
var singletons = ContainerElementsByKind<IEdmSingleton>(entityContainer, EdmContainerElementKind.Singleton);
foreach (var singleton in singletons)
{
WriteProperty(odcmClass, singleton);
}
var actionImports = ContainerElementsByKind<IEdmActionImport>(entityContainer, EdmContainerElementKind.ActionImport);
foreach (var actionImport in actionImports)
{
WriteMethodImport(odcmClass, actionImport.Action, actionImport);
}
var functionImports = ContainerElementsByKind<IEdmFunctionImport>(entityContainer, EdmContainerElementKind.FunctionImport);
foreach (var functionImport in functionImports)
{
WriteMethodImport(odcmClass, functionImport.Function, functionImport);
}
}
}