Ejemplo n.º 1
0
        private string GetIdentifierPrefix(IEdmEntityType entityType)
        {
            if (entityType.BaseEntityType() != null)
            {
                return(GetIdentifierPrefix(entityType.BaseEntityType()));
            }
            TypeMapping existingMapping;

            if (_typeUriMap.TryGetValue(entityType.FullName(), out existingMapping))
            {
                return(existingMapping.IdentifierPrefix);
            }
            var keyList = entityType.DeclaredKey.ToList();

            if (keyList.Count != 1)
            {
                // Ignore this entity
                // TODO: Log an error
                return(null);
            }
            var identifierPrefix = GetStringAnnotationValue(keyList.First(), AnnotationsNamespace, "IdentifierPrefix");

            if (identifierPrefix == null)
            {
                // TODO: Log an error
            }
            return(identifierPrefix);
        }
Ejemplo n.º 2
0
 private string GetIdentifierPrefix(IEdmEntityType entityType)
 {
     if (entityType.BaseEntityType() != null)
     {
         return GetIdentifierPrefix(entityType.BaseEntityType());
     }
     TypeMapping existingMapping;
     if (_typeUriMap.TryGetValue(entityType.FullName(), out existingMapping))
     {
         return existingMapping.IdentifierPrefix;
     }
     var keyList = entityType.DeclaredKey.ToList();
     if (keyList.Count != 1)
     {
         // Ignore this entity
         // TODO: Log an error
         return null;
     }
     var identifierPrefix = GetStringAnnotationValue(keyList.First(), AnnotationsNamespace, "IdentifierPrefix");
     if (identifierPrefix == null)
     {
         // TODO: Log an error
     }
     return identifierPrefix;
 }
		protected override void ProcessEntityType(IEdmEntityType element)
		{
			base.ProcessEntityType(element);
			if (element.BaseEntityType() != null)
			{
				this.CheckSchemaElementReference(element.BaseEntityType());
			}
		}
 protected override void ProcessEntityType(IEdmEntityType element)
 {
     base.ProcessEntityType(element);
     if (element.BaseEntityType() != null)
     {
         this.CheckSchemaElementReference(element.BaseEntityType());
     }
 }
Ejemplo n.º 5
0
        internal void WriteEntityTypeElementHeader(IEdmEntityType entityType)
        {
            this.xmlWriter.WriteStartElement(CsdlConstants.Element_EntityType);
            this.WriteRequiredAttribute(CsdlConstants.Attribute_Name, entityType.Name, EdmValueWriter.StringAsXml);
            this.WriteOptionalAttribute(CsdlConstants.Attribute_BaseType, entityType.BaseEntityType(), this.TypeDefinitionAsXml);
            this.WriteOptionalAttribute(CsdlConstants.Attribute_Abstract, entityType.IsAbstract, CsdlConstants.Default_Abstract, EdmValueWriter.BooleanAsXml);
            this.WriteOptionalAttribute(CsdlConstants.Attribute_OpenType, entityType.IsOpen, CsdlConstants.Default_OpenType, EdmValueWriter.BooleanAsXml);

            // HasStream value should be inherited.  Only have it on base type is sufficient.
            bool writeHasStream = entityType.HasStream && (entityType.BaseEntityType() == null || (entityType.BaseEntityType() != null && !entityType.BaseEntityType().HasStream));

            this.WriteOptionalAttribute(CsdlConstants.Attribute_HasStream, writeHasStream, CsdlConstants.Default_HasStream, EdmValueWriter.BooleanAsXml);
        }
        /// <summary>
        /// Initializes the EPM annotation with EPM information from the specified type.
        /// </summary>
        /// <param name="definingEntityType">Entity type to use the EPM infromation from.</param>
        /// <param name="affectedEntityType">Entity type for this the EPM information is being built.</param>
        internal void BuildEpmForType(IEdmEntityType definingEntityType, IEdmEntityType affectedEntityType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(definingEntityType != null, "definingEntityType != null");
            Debug.Assert(affectedEntityType != null, "affectedEntityType != null");

            if (definingEntityType.BaseType != null)
            {
                this.BuildEpmForType(definingEntityType.BaseEntityType(), affectedEntityType);
            }

            ODataEntityPropertyMappingCollection mappingsForType = this.model.GetEntityPropertyMappings(definingEntityType);

            if (mappingsForType == null)
            {
                return;
            }

            foreach (EntityPropertyMappingAttribute mapping in mappingsForType)
            {
                this.epmSourceTree.Add(new EntityPropertyMappingInfo(mapping, definingEntityType, affectedEntityType));

                if (definingEntityType == affectedEntityType)
                {
                    if (!PropertyExistsOnType(affectedEntityType, mapping))
                    {
                        this.MappingsForInheritedProperties.Add(mapping);
                        this.MappingsForDeclaredProperties.Remove(mapping);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public void EntityType_reference_extensions()
        {
            IEdmModel      edmModel          = this.GetEdmModel();
            IEdmEntityType derivedEntityType = edmModel.SchemaElements.OfType <IEdmEntityType>().First(c => c.BaseType != null);
            IEdmEntityType baseEntityType    = derivedEntityType.BaseEntityType();

            Assert.IsNotNull(baseEntityType, "Base entity type should not be null!");

            IEdmEntityTypeReference derivedEntityTypeRef = (IEdmEntityTypeReference)derivedEntityType.ToTypeReference();

            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseEntityType(), "EntityTypeReference.BaseEntityType()");
            Assert.AreEqual(baseEntityType, derivedEntityTypeRef.BaseType(), "EntityTypeReference.BaseType()");

            Assert.AreEqual(derivedEntityType.IsAbstract, derivedEntityTypeRef.IsAbstract(), "StructuralTypeReference.IsAbstract()");
            Assert.AreEqual(derivedEntityType.IsOpen, derivedEntityTypeRef.IsOpen(), "StructuralTypeReference.IsOpen()");

            Assert.AreEqual(derivedEntityType.DeclaredStructuralProperties().Count(), derivedEntityTypeRef.DeclaredStructuralProperties().Count(), "StructuralTypeReference.DeclaredStructuralProperties()");
            Assert.AreEqual(derivedEntityType.StructuralProperties().Count(), derivedEntityTypeRef.StructuralProperties().Count(), "StructuralTypeReference.StructuralProperties()");

            Assert.AreEqual(derivedEntityType.DeclaredNavigationProperties().Count(), derivedEntityTypeRef.DeclaredNavigationProperties().Count(), "EntityTypeReference.DeclaredNavigationProperties()");
            Assert.AreEqual(derivedEntityType.NavigationProperties().Count(), derivedEntityTypeRef.NavigationProperties().Count(), "EntityTypeReference.NavigationProperties()");

            IEdmNavigationProperty result = derivedEntityTypeRef.FindNavigationProperty("_Not_Exist_");

            Assert.IsNull(result, "Should not find Navigation Property {0}", "_Not_Exist_");

            var navigation = derivedEntityType.NavigationProperties().First();

            result = derivedEntityTypeRef.FindNavigationProperty(navigation.Name);
            Assert.AreEqual(navigation, result, "FindNavigationProperty({0})", navigation.Name);
        }
Ejemplo n.º 8
0
 internal void WriteEntityTypeElementHeader(IEdmEntityType entityType)
 {
     this.xmlWriter.WriteStartElement("EntityType");
     this.WriteRequiredAttribute <string>("Name", entityType.Name, new Func <string, string>(EdmValueWriter.StringAsXml));
     this.WriteOptionalAttribute <IEdmEntityType>("BaseType", entityType.BaseEntityType(), new Func <IEdmEntityType, string>(this.TypeDefinitionAsXml));
     this.WriteOptionalAttribute <bool>("Abstract", entityType.IsAbstract, false, new Func <bool, string>(EdmValueWriter.BooleanAsXml));
     this.WriteOptionalAttribute <bool>("OpenType", entityType.IsOpen, false, new Func <bool, string>(EdmValueWriter.BooleanAsXml));
 }
Ejemplo n.º 9
0
 internal void WriteEntityTypeElementHeader(IEdmEntityType entityType)
 {
     this.xmlWriter.WriteStartElement(CsdlConstants.Element_EntityType);
     this.WriteRequiredAttribute(CsdlConstants.Attribute_Name, entityType.Name, EdmValueWriter.StringAsXml);
     this.WriteOptionalAttribute(CsdlConstants.Attribute_BaseType, entityType.BaseEntityType(), this.TypeDefinitionAsXml);
     this.WriteOptionalAttribute(CsdlConstants.Attribute_Abstract, entityType.IsAbstract, CsdlConstants.Default_Abstract, EdmValueWriter.BooleanAsXml);
     this.WriteOptionalAttribute(CsdlConstants.Attribute_OpenType, entityType.IsOpen, CsdlConstants.Default_OpenType, EdmValueWriter.BooleanAsXml);
 }
Ejemplo n.º 10
0
        public static IEdmEntityType AssertHasEntityType(this IEdmModel model, Type mappedEntityClrType, Type mappedEntityBaseType)
        {
            IEdmEntityType entity     = AssertHasEntityType(model, mappedEntityClrType);
            IEdmEntityType baseEntity = AssertHasEntityType(model, mappedEntityBaseType);

            Assert.Equal(baseEntity, entity.BaseEntityType());
            return(entity);
        }
Ejemplo n.º 11
0
        private static void PropertiesThreadFunction(object o)
        {
            IEdmModel model = (IEdmModel)o;

            int index = 0;

            foreach (IEdmSchemaElement element in model.SchemaElements)
            {
                IEdmEntityType entityType = element as IEdmEntityType;
                if (entityType != null)
                {
                    IEdmEntityType baseType = entityType.BaseEntityType();

                    if (BaseTypes[index] == null)
                    {
                        BaseTypes[index] = baseType;
                    }

                    if (BaseTypes[index] != baseType)
                    {
                        BaseTypes[index] = BadBaseType;
                    }

                    IEnumerable <IEdmProperty> declaredProperties = entityType.DeclaredProperties;

                    if (Properties[index] == null)
                    {
                        Properties[index] = declaredProperties;
                    }

                    if (Properties[index] != declaredProperties)
                    {
                        Properties[index] = BadProperties;
                    }

                    int innerIndex = 0;
                    foreach (IEdmProperty property in declaredProperties)
                    {
                        IEdmTypeReference propertyType = property.Type;

                        int effectiveIndex = (index * 10) + innerIndex;
                        if (PropertyTypes[effectiveIndex] == null)
                        {
                            PropertyTypes[effectiveIndex] = propertyType;
                        }

                        if (PropertyTypes[effectiveIndex] != propertyType)
                        {
                            PropertyTypes[effectiveIndex] = BadTypeReference;
                        }

                        innerIndex++;
                    }

                    index++;
                }
            }
        }
Ejemplo n.º 12
0
        private static IEnumerable <IEdmEntityType> GetTypeHierarchy(IEdmEntityType entityType)
        {
            IEdmEntityType current = entityType;

            while (current != null)
            {
                yield return(current);

                current = current.BaseEntityType();
            }
        }
Ejemplo n.º 13
0
 internal static bool HasEntityPropertyMappings(this IEdmModel model, IEdmEntityType entityType)
 {
     for (IEdmEntityType type = entityType; type != null; type = type.BaseEntityType())
     {
         if (model.GetEntityPropertyMappings(type) != null)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Find all base types for a given <see cref="IEdmEntityType"/>
        /// </summary>
        /// <param name="entityType">The given entity type.</param>
        /// <returns>All base types or null.</returns>
        public static IEnumerable <IEdmEntityType> FindAllBaseTypes(this IEdmEntityType entityType)
        {
            if (entityType == null)
            {
                yield return(null);
            }

            IEdmEntityType current = entityType.BaseEntityType();

            while (current != null)
            {
                yield return(current);

                current = current.BaseEntityType();
            }
        }
Ejemplo n.º 15
0
        private static ODataEntityPropertyMappingCache EnsureEpmCacheInternal(IEdmModel model, IEdmEntityType entityType, int maxMappingCount, out bool cacheModified)
        {
            cacheModified = false;
            if (entityType == null)
            {
                return(null);
            }
            IEdmEntityType type = entityType.BaseEntityType();
            ODataEntityPropertyMappingCache baseCache = null;

            if (type != null)
            {
                baseCache = EnsureEpmCacheInternal(model, type, maxMappingCount, out cacheModified);
            }
            ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);

            if (model.HasOwnOrInheritedEpm(entityType))
            {
                ODataEntityPropertyMappingCollection entityPropertyMappings = model.GetEntityPropertyMappings(entityType);
                if (!(((epmCache == null) || cacheModified) || epmCache.IsDirty(entityPropertyMappings)))
                {
                    return(epmCache);
                }
                cacheModified = true;
                int totalMappingCount = ValidationUtils.ValidateTotalEntityPropertyMappingCount(baseCache, entityPropertyMappings, maxMappingCount);
                epmCache = new ODataEntityPropertyMappingCache(entityPropertyMappings, model, totalMappingCount);
                try
                {
                    epmCache.BuildEpmForType(entityType, entityType);
                    epmCache.EpmSourceTree.Validate(entityType);
                    model.SetAnnotationValue <ODataEntityPropertyMappingCache>(entityType, epmCache);
                    return(epmCache);
                }
                catch
                {
                    model.RemoveEpmCache(entityType);
                    throw;
                }
            }
            if (epmCache != null)
            {
                cacheModified = true;
                model.RemoveEpmCache(entityType);
            }
            return(epmCache);
        }
Ejemplo n.º 16
0
        // returns -1 if type does not derive from baseType and a positive number representing the distance
        // between them if it does.
        private static int IsDerivedTypeOf(IEdmEntityType type, IEdmEntityType baseType)
        {
            int distance = 0;

            while (type != null)
            {
                if (baseType == type)
                {
                    return(distance);
                }

                type = type.BaseEntityType();
                distance++;
            }

            return(-1);
        }
Ejemplo n.º 17
0
 private static ODataEntityPropertyMappingCache EnsureEpmCacheInternal(IEdmModel model, IEdmEntityType entityType, int maxMappingCount, out bool cacheModified)
 {
     cacheModified = false;
     if (entityType == null)
     {
         return null;
     }
     IEdmEntityType type = entityType.BaseEntityType();
     ODataEntityPropertyMappingCache baseCache = null;
     if (type != null)
     {
         baseCache = EnsureEpmCacheInternal(model, type, maxMappingCount, out cacheModified);
     }
     ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);
     if (model.HasOwnOrInheritedEpm(entityType))
     {
         ODataEntityPropertyMappingCollection entityPropertyMappings = model.GetEntityPropertyMappings(entityType);
         if (!(((epmCache == null) || cacheModified) || epmCache.IsDirty(entityPropertyMappings)))
         {
             return epmCache;
         }
         cacheModified = true;
         int totalMappingCount = ValidationUtils.ValidateTotalEntityPropertyMappingCount(baseCache, entityPropertyMappings, maxMappingCount);
         epmCache = new ODataEntityPropertyMappingCache(entityPropertyMappings, model, totalMappingCount);
         try
         {
             epmCache.BuildEpmForType(entityType, entityType);
             epmCache.EpmSourceTree.Validate(entityType);
             model.SetAnnotationValue<ODataEntityPropertyMappingCache>(entityType, epmCache);
             return epmCache;
         }
         catch
         {
             model.RemoveEpmCache(entityType);
             throw;
         }
     }
     if (epmCache != null)
     {
         cacheModified = true;
         model.RemoveEpmCache(entityType);
     }
     return epmCache;
 }
Ejemplo n.º 18
0
        private static bool TryGetAlternateKeys(this IEdmModel model, IEdmEntityType entityType, IEdmTerm term,
                                                out IEnumerable <IDictionary <string, IEdmPathExpression> > alternateKeys)
        {
            IEdmEntityType checkingType = entityType;

            while (checkingType != null)
            {
                IEnumerable <IDictionary <string, IEdmPathExpression> > declaredAlternateKeys = GetDeclaredAlternateKeysForType(model, checkingType, term);
                if (declaredAlternateKeys != null)
                {
                    alternateKeys = declaredAlternateKeys;
                    return(true);
                }

                checkingType = checkingType.BaseEntityType();
            }

            alternateKeys = null;
            return(false);
        }
 internal void BuildEpmForType(IEdmEntityType definingEntityType, IEdmEntityType affectedEntityType)
 {
     if (definingEntityType.BaseType != null)
     {
         this.BuildEpmForType(definingEntityType.BaseEntityType(), affectedEntityType);
     }
     ODataEntityPropertyMappingCollection entityPropertyMappings = this.model.GetEntityPropertyMappings(definingEntityType);
     if (entityPropertyMappings != null)
     {
         foreach (EntityPropertyMappingAttribute attribute in entityPropertyMappings)
         {
             this.epmSourceTree.Add(new EntityPropertyMappingInfo(attribute, definingEntityType, affectedEntityType));
             if ((definingEntityType == affectedEntityType) && !PropertyExistsOnType(affectedEntityType, attribute))
             {
                 this.MappingsForInheritedProperties.Add(attribute);
                 this.MappingsForDeclaredProperties.Remove(attribute);
             }
         }
     }
 }
        public void ConvertEntityType_Inheritance()
        {
            var taupoModel = new EntityModelSchema()
            {
                new EntityType("Derived")
                {
                    BaseType = "Base",
                },
                new EntityType("Base")
                {
                    new MemberProperty("p1", EdmDataTypes.Int16)
                    {
                        IsPrimaryKey = true
                    },
                    new MemberProperty("p2", EdmDataTypes.Guid),
                    new MemberProperty("p3", EdmDataTypes.Double),
                },
            }
            .ApplyDefaultNamespace("NS1")
            .Resolve();

            IEdmModel result = this.converter.ConvertToEdmModel(taupoModel);

            Assert.IsNull(result.EntityContainer);
            Assert.AreEqual(2, result.SchemaElements.Count());
            Assert.AreEqual(2, result.SchemaElements.OfType <IEdmEntityType>().Count());

            IEdmEntityType convertedDerived = result.SchemaElements.OfType <IEdmEntityType>().ElementAt(0);
            IEdmEntityType convertedBase    = result.SchemaElements.OfType <IEdmEntityType>().ElementAt(1);

            Assert.AreEqual("NS1.Derived", convertedDerived.FullName());
            Assert.AreEqual(0, convertedDerived.DeclaredStructuralProperties().Count());
            Assert.AreEqual(convertedBase, convertedDerived.BaseEntityType());

            Assert.AreEqual("NS1.Base", convertedBase.FullName());
            Assert.AreEqual(3, convertedBase.DeclaredStructuralProperties().Count());

            Assert.AreEqual(1, convertedDerived.Key().Count());
            Assert.AreEqual(1, convertedBase.DeclaredKey.Count());
            Assert.AreEqual(convertedBase.DeclaredKey.First(), convertedDerived.Key().First());
        }
Ejemplo n.º 21
0
        // Performs overload resolution between a set of matching bindable actions. OData protocol ensures that there
        // cannot be multiple bindable actions with same name and different sets of non-bindable paramters.
        // The resolution logic is simple and is dependant only on the binding parameter and chooses the action that is defined
        // closest to the binding parameter in the inheritance hierarchy.
        private static IEdmFunctionImport FindBest(string actionIdentifier, IEnumerable <IEdmFunctionImport> bindableActions,
                                                   IEdmEntityType bindingParameterType, bool isCollection)
        {
            if (bindingParameterType == null)
            {
                return(null);
            }

            List <IEdmFunctionImport> actionsBoundToThisType = new List <IEdmFunctionImport>();

            foreach (IEdmFunctionImport action in bindableActions)
            {
                IEdmType actionParameterType = action.Parameters.First().Type.Definition;
                if (isCollection)
                {
                    actionParameterType = ((IEdmCollectionType)actionParameterType).ElementType.Definition;
                }

                if (actionParameterType == bindingParameterType)
                {
                    actionsBoundToThisType.Add(action);
                }
            }

            if (actionsBoundToThisType.Count > 1)
            {
                throw Error.Argument(
                          "actionIdentifier",
                          SRResources.ActionResolutionFailed,
                          actionIdentifier,
                          String.Join(", ", actionsBoundToThisType.Select(match => match.Container.FullName() + "." + match.Name)));
            }
            else if (actionsBoundToThisType.Count == 1)
            {
                return(actionsBoundToThisType[0]);
            }
            else
            {
                return(FindBest(actionIdentifier, bindableActions, bindingParameterType.BaseEntityType(), isCollection));
            }
        }
Ejemplo n.º 22
0
        internal void BuildEpmForType(IEdmEntityType definingEntityType, IEdmEntityType affectedEntityType)
        {
            if (definingEntityType.BaseType != null)
            {
                this.BuildEpmForType(definingEntityType.BaseEntityType(), affectedEntityType);
            }
            ODataEntityPropertyMappingCollection entityPropertyMappings = this.model.GetEntityPropertyMappings(definingEntityType);

            if (entityPropertyMappings != null)
            {
                foreach (EntityPropertyMappingAttribute attribute in entityPropertyMappings)
                {
                    this.epmSourceTree.Add(new EntityPropertyMappingInfo(attribute, definingEntityType, affectedEntityType));
                    if ((definingEntityType == affectedEntityType) && !PropertyExistsOnType(affectedEntityType, attribute))
                    {
                        this.MappingsForInheritedProperties.Add(attribute);
                        this.MappingsForDeclaredProperties.Remove(attribute);
                    }
                }
            }
        }
Ejemplo n.º 23
0
        private EntityType ConvertToTaupoEntityType(IEdmEntityType edmEntityType)
        {
            var taupoEntityType = new EntityType(edmEntityType.Namespace, edmEntityType.Name)
            {
                IsAbstract = edmEntityType.IsAbstract,
                IsOpen     = edmEntityType.IsOpen,
            };

            if (edmEntityType.BaseType != null)
            {
                taupoEntityType.BaseType = new EntityTypeReference(edmEntityType.BaseEntityType().Namespace, edmEntityType.BaseEntityType().Name);
            }

            foreach (var edmProperty in edmEntityType.DeclaredStructuralProperties())
            {
                var taupoProperty = this.ConvertToTaupoProperty(edmProperty);
                taupoProperty.IsPrimaryKey = edmEntityType.Key().Contains(edmProperty);
                taupoEntityType.Add(taupoProperty);
            }

            this.ConvertAnnotationsIntoTaupo(edmEntityType, taupoEntityType);
            return(taupoEntityType);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Asserts that a given entity type is derived from the specified base entity type.
        /// </summary>
        /// <param name="derivedType">The derived entity type.</param>
        /// <param name="baseType">The base entity type.</param>
        public static void AssertEntityTypeIsDerivedFrom(IEdmEntityType derivedType, IEdmEntityType baseType)
        {
            ExceptionUtilities.CheckArgumentNotNull(derivedType, "derivedType");
            ExceptionUtilities.CheckArgumentNotNull(baseType, "baseType");

            if (derivedType == baseType)
            {
                return;
            }

            var entityType = derivedType.BaseEntityType();

            while (entityType != null)
            {
                if (entityType == baseType)
                {
                    return;
                }

                entityType = entityType.BaseEntityType();
            }

            ExceptionUtilities.Assert(false, "Expected entity type " + derivedType.FullName() + " to be derived from " + baseType.FullName());
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Gets an enumerable containing the given type and all of its base/ancestor types.
 /// </summary>
 /// <param name="entityType">The starting entity type. Will be included in the returned enumeration.</param>
 /// <returns>An enumerable containing the given type and all of its base/ancestor types.</returns>
 private static IEnumerable <IEdmEntityType> GetBaseTypesAndSelf(IEdmEntityType entityType)
 {
     for (IEdmEntityType currentType = entityType; currentType != null; currentType = currentType.BaseEntityType())
     {
         yield return(currentType);
     }
 }
Ejemplo n.º 26
0
 private static bool HasOwnOrInheritedEpm(this IEdmModel model, IEdmEntityType entityType)
 {
     if (entityType == null)
     {
         return false;
     }
     if (model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType) != null)
     {
         return true;
     }
     LoadEpmAnnotations(model, entityType);
     return ((model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType) != null) || model.HasOwnOrInheritedEpm(entityType.BaseEntityType()));
 }
Ejemplo n.º 27
0
 private static bool HasOwnOrInheritedEpm(this IEdmModel model, IEdmEntityType entityType)
 {
     if (entityType == null)
     {
         return(false);
     }
     if (model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(entityType) != null)
     {
         return(true);
     }
     LoadEpmAnnotations(model, entityType);
     return((model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(entityType) != null) || model.HasOwnOrInheritedEpm(entityType.BaseEntityType()));
 }
Ejemplo n.º 28
0
        // returns -1 if type does not derive from baseType and a positive number representing the distance
        // between them if it does.
        private static int IsDerivedTypeOf(IEdmEntityType type, IEdmEntityType baseType)
        {
            int distance = 0;
            while (type != null)
            {
                if (baseType == type)
                {
                    return distance;
                }

                type = type.BaseEntityType();
                distance++;
            }

            return -1;
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Checks whether the <paramref name="entityType"/> has EPM defined for it (either directly
        /// on the type or on one of the base types).
        /// </summary>
        /// <param name="model">The <see cref="IEdmModel"/> containing the annotation.</param>
        /// <param name="entityType">The <see cref="IEdmEntityType"/> to check.</param>
        /// <returns>true if the <paramref name="entityType"/> has EPM defined; otherwise false.</returns>
        private static bool HasOwnOrInheritedEpm(this IEdmModel model, IEdmEntityType entityType)
        {
            if (entityType == null)
            {
                return false;
            }

            Debug.Assert(model != null, "model != null");

            if (model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType) != null)
            {
                return true;
            }

            // If we don't have an in-memory annotation, try to load the serializable EPM annotations
            LoadEpmAnnotations(model, entityType);
            if (model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType) != null)
            {
                return true;
            }

            return model.HasOwnOrInheritedEpm(entityType.BaseEntityType());
        }
        /// <summary>
        /// Initializes the EPM annotation with EPM information from the specified type.
        /// </summary>
        /// <param name="definingEntityType">Entity type to use the EPM infromation from.</param>
        /// <param name="affectedEntityType">Entity type for this the EPM information is being built.</param>
        internal void BuildEpmForType(IEdmEntityType definingEntityType, IEdmEntityType affectedEntityType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(definingEntityType != null, "definingEntityType != null");
            Debug.Assert(affectedEntityType != null, "affectedEntityType != null");

            if (definingEntityType.BaseType != null)
            {
                this.BuildEpmForType(definingEntityType.BaseEntityType(), affectedEntityType);
            }

            ODataEntityPropertyMappingCollection mappingsForType = this.model.GetEntityPropertyMappings(definingEntityType);
            if (mappingsForType == null)
            {
                return;
            }

            foreach (EntityPropertyMappingAttribute mapping in mappingsForType)
            {
                this.epmSourceTree.Add(new EntityPropertyMappingInfo(mapping, definingEntityType, affectedEntityType));

                if (definingEntityType == affectedEntityType)
                {
                    if (!PropertyExistsOnType(affectedEntityType, mapping))
                    {
                        this.MappingsForInheritedProperties.Add(mapping);
                        this.MappingsForDeclaredProperties.Remove(mapping);
                    }
                }
            }
        }
Ejemplo n.º 31
0
        private EntityType ConvertToTaupoEntityType(IEdmEntityType edmEntityType)
        {
            var taupoEntityType = new EntityType(edmEntityType.Namespace, edmEntityType.Name)
            {
                IsAbstract = edmEntityType.IsAbstract,
                IsOpen = edmEntityType.IsOpen,
            };

            if (edmEntityType.BaseType != null)
            {
                taupoEntityType.BaseType = new EntityTypeReference(edmEntityType.BaseEntityType().Namespace, edmEntityType.BaseEntityType().Name);
            }

            foreach (var edmProperty in edmEntityType.DeclaredStructuralProperties())
            {
                var taupoProperty = this.ConvertToTaupoProperty(edmProperty);
                taupoProperty.IsPrimaryKey = edmEntityType.Key().Contains(edmProperty);
                taupoEntityType.Add(taupoProperty);
            }

            this.ConvertAnnotationsIntoTaupo(edmEntityType, taupoEntityType);
            return taupoEntityType;
        }
Ejemplo n.º 32
0
        // Performs overload resolution between a set of matching bindable actions. OData protocol ensures that there 
        // cannot be multiple bindable actions with same name and different sets of non-bindable paramters. 
        // The resolution logic is simple and is dependant only on the binding parameter and chooses the action that is defined
        // closest to the binding parameter in the inheritance hierarchy.
        private static IEdmFunctionImport FindBest(string actionIdentifier, IEnumerable<IEdmFunctionImport> bindableActions,
            IEdmEntityType bindingParameterType, bool isCollection)
        {
            if (bindingParameterType == null)
            {
                return null;
            }

            List<IEdmFunctionImport> actionsBoundToThisType = new List<IEdmFunctionImport>();
            foreach (IEdmFunctionImport action in bindableActions)
            {
                IEdmType actionParameterType = action.Parameters.First().Type.Definition;
                if (isCollection)
                {
                    actionParameterType = ((IEdmCollectionType)actionParameterType).ElementType.Definition;
                }

                if (actionParameterType == bindingParameterType)
                {
                    actionsBoundToThisType.Add(action);
                }
            }

            if (actionsBoundToThisType.Count > 1)
            {
                throw Error.Argument(
                    "actionIdentifier",
                    SRResources.ActionResolutionFailed,
                    actionIdentifier,
                    String.Join(", ", actionsBoundToThisType.Select(match => match.Container.FullName() + "." + match.Name)));
            }
            else if (actionsBoundToThisType.Count == 1)
            {
                return actionsBoundToThisType[0];
            }
            else
            {
                return FindBest(actionIdentifier, bindableActions, bindingParameterType.BaseEntityType(), isCollection);
            }
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Ensures that an up-to-date EPM cache exists for the specified <paramref name="entityType"/>. 
        /// If no cache exists, a new one will be created based on the public mappings (if any).
        /// If the public mappings have changed (and the cache is thus dirty), the method re-constructs the cache.
        /// If all public mappings have been removed, the method also removes the EPM cache.
        /// </summary>
        /// <param name="model">IEdmModel instance containing the annotations.</param>
        /// <param name="entityType">IEdmEntityType instance for which to ensure the EPM cache.</param>
        /// <param name="maxMappingCount">The maximum allowed number of entity property mappings 
        /// for a given entity type (on the type itself and all its base types).</param>
        /// <param name="cacheModified">true if the cache was modified; otherwise false.</param>
        /// <returns>An instance of <see cref="ODataEntityPropertyMappingCache"/>, if there are any EPM mappings for the given entity type, otherwise returns null.</returns>
        private static ODataEntityPropertyMappingCache EnsureEpmCacheInternal(
            IEdmModel model, 
            IEdmEntityType entityType, 
            int maxMappingCount, 
            out bool cacheModified)
        {
            cacheModified = false;

            if (entityType == null)
            {
                return null;
            }

            // Make sure the EPM of the base type is initialized.
            IEdmEntityType baseEntityType = entityType.BaseEntityType();
            ODataEntityPropertyMappingCache baseCache = null;
            if (baseEntityType != null)
            {
                baseCache = EnsureEpmCacheInternal(model, baseEntityType, maxMappingCount, out cacheModified);
            }

            ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);

            if (model.HasOwnOrInheritedEpm(entityType))
            {
                ODataEntityPropertyMappingCollection mappings = model.GetEntityPropertyMappings(entityType);
                bool needToBuildCache = epmCache == null || cacheModified || epmCache.IsDirty(mappings);
                if (needToBuildCache)
                {
                    cacheModified = true;
                    int totalMappingCount = ValidationUtils.ValidateTotalEntityPropertyMappingCount(baseCache, mappings, maxMappingCount);
                    epmCache = new ODataEntityPropertyMappingCache(mappings, model, totalMappingCount);

                    // Build the EPM tree and validate it
                    try
                    {
                        epmCache.BuildEpmForType(entityType, entityType);
                        epmCache.EpmSourceTree.Validate(entityType);
                        epmCache.EpmTargetTree.Validate();

                        // We set the annotation here, so if anything fails during
                        // building of the cache the annotation will not even be set so
                        // not leaving the type in an inconsistent state.
                        model.SetAnnotationValue(entityType, epmCache);
                    }
                    catch
                    {
                        // Remove an existing EPM cache if it is dirty to make sure we don't leave
                        // stale caches in case building of the cache fails.
                        // NOTE: we do this in the catch block to ensure that we always make a single
                        //       SetAnnotation call to either set or clear the existing annotation
                        //       since the SetAnnotation method is thread-safe
                        model.RemoveEpmCache(entityType);

                        throw;
                    }
                }
            }
            else
            {
                if (epmCache != null)
                {
                    // remove an existing EPM cache if the mappings have been removed from the type
                    cacheModified = true;
                    model.RemoveEpmCache(entityType);
                }
            }

            return epmCache;
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Asserts that a given entity type is derived from the specified base entity type.
        /// </summary>
        /// <param name="derivedType">The derived entity type.</param>
        /// <param name="baseType">The base entity type.</param>
        public static void AssertEntityTypeIsDerivedFrom(IEdmEntityType derivedType, IEdmEntityType baseType)
        {
            ExceptionUtilities.CheckArgumentNotNull(derivedType, "derivedType");
            ExceptionUtilities.CheckArgumentNotNull(baseType, "baseType");

            if (derivedType == baseType)
            {
                return;
            }

            var entityType = derivedType.BaseEntityType();
            while (entityType != null)
            {
                if (entityType == baseType)
                {
                    return;
                }

                entityType = entityType.BaseEntityType();
            }

            ExceptionUtilities.Assert(false, "Expected entity type " + derivedType.FullName() + " to be derived from " + baseType.FullName());
        }
Ejemplo n.º 35
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        public bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // use the cached
            Debug.Assert(context.Singleton != null);
            Debug.Assert(context.Action != null);
            ActionModel action = context.Action;

            string    singletonName = context.Singleton.Name;
            string    prefix        = context.Prefix;
            IEdmModel model         = context.Model;

            string actionMethodName = action.ActionMethod.Name;

            if (IsSupportedActionName(actionMethodName, singletonName))
            {
                ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton));
                action.AddSelector(context.Prefix, context.Model, template);

                // processed
                return(true);
            }

            // type cast
            // Get{SingletonName}From{EntityTypeName} or GetFrom{EntityTypeName}
            int index = actionMethodName.IndexOf("From", StringComparison.Ordinal);

            if (index == -1)
            {
                return(false);
            }

            string actionPrefix = actionMethodName.Substring(0, index);

            if (IsSupportedActionName(actionPrefix, singletonName))
            {
                IEdmEntityType entityType   = context.Singleton.EntityType();
                string         castTypeName = actionMethodName.Substring(index + 4);

                // Shall we cast to base type and the type itself? I think yes.
                IEdmEntityType baseType = entityType;
                while (baseType != null)
                {
                    if (baseType.Name == castTypeName)
                    {
                        ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton),
                                                                           new CastSegmentTemplate(baseType));
                        action.AddSelector(context.Prefix, context.Model, template);

                        return(true);
                    }

                    baseType = baseType.BaseEntityType();
                }

                // shall we cast to derived type
                IEdmEntityType castType = model.FindAllDerivedTypes(entityType).OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == castTypeName);
                if (castType != null)
                {
                    ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton),
                                                                       new CastSegmentTemplate(castType));
                    action.AddSelector(context.Prefix, context.Model, template);

                    return(true);
                }
            }

            return(false);
        }