Beispiel #1
0
 public CsdlSemanticsNavigationSource(CsdlSemanticsEntityContainer container, CsdlAbstractNavigationSource navigationSource)
     : base(navigationSource)
 {
     this.container        = container;
     this.navigationSource = navigationSource;
     this.path             = new EdmPathExpression(this.navigationSource.Name);
 }
        public static IEdmNavigationSource FindNavigationTarget(this IEdmNavigationSource navigationSource,
                                                                IEdmNavigationProperty navigationProperty,
                                                                IList <ODataSegmentTemplate> parsedSegments,
                                                                out IEdmPathExpression bindingPath)
        {
            bindingPath = null;

            if (navigationProperty.ContainsTarget)
            {
                return(navigationSource);
            }

            IEnumerable <IEdmNavigationPropertyBinding> bindings =
                navigationSource.FindNavigationPropertyBindings(navigationProperty);

            if (bindings != null)
            {
                foreach (var binding in bindings)
                {
                    if (BindingPathHelper.MatchBindingPath(binding.Path, parsedSegments))
                    {
                        bindingPath = binding.Path;
                        return(binding.Target);
                    }
                }
            }

            return(null);
        }
Beispiel #3
0
        private OdcmProperty PropertyFromPathExpression(IEdmPathExpression pathExpression, OdcmObject odcmObject)
        {
            OdcmClass odcmClass = null;

            if (odcmObject is OdcmProperty)
            {
                var odcmProperty = odcmObject as OdcmProperty;
                odcmClass = odcmProperty.Type as OdcmClass;
            }
            else
            {
                odcmClass = odcmObject as OdcmClass;
            }

            var pathBuilder = new StringBuilder();

            foreach (var path in pathExpression.Path)
            {
                pathBuilder.AppendFormat("{0}.", path);
            }

            pathBuilder.Remove(pathBuilder.Length - 1, 1);

            OdcmProperty navProperty;

            if (!odcmClass.TryFindProperty(pathBuilder.ToString(), out navProperty))
            {
                throw new InvalidOperationException(
                          string.Format(
                              "Unable to find property {0} in class {1}. This can be caused by malformed Capability Annotation on an EntitySet",
                              pathBuilder.ToString(), odcmClass.FullName));
            }

            return(navProperty);
        }
 public CsdlSemanticsNavigationSource(CsdlSemanticsEntityContainer container, CsdlAbstractNavigationSource navigationSource)
     : base(navigationSource)
 {
     this.container = container;
     this.navigationSource = navigationSource;
     this.path = new EdmPathExpression(this.navigationSource.Name);
 }
Beispiel #5
0
        internal static bool TryAssertPathAsType(this IEdmPathExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors)
        {
            IEdmStructuredType structuredContext = context as IEdmStructuredType;

            if (structuredContext != null)
            {
                IEdmType result = context;

                foreach (string segment in expression.Path)
                {
                    IEdmStructuredType structuredResult = result as IEdmStructuredType;
                    if (structuredResult == null)
                    {
                        discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PathIsNotValidForTheGivenContext, Edm.Strings.EdmModel_Validator_Semantic_PathIsNotValidForTheGivenContext(segment)) };
                        return(false);
                    }

                    IEdmProperty resultProperty = structuredResult.FindProperty(segment);
                    result = (resultProperty != null) ? resultProperty.Type.Definition : null;

                    // If the path is not resolved, it could refer to an open type, and we cannot make an assertion about its type.
                    if (result == null)
                    {
                        discoveredErrors = Enumerable.Empty <EdmError>();
                        return(true);
                    }
                }

                return(TestTypeMatch(result, type.Definition, expression.Location(), matchExactly, out discoveredErrors));
            }

            discoveredErrors = Enumerable.Empty <EdmError>();
            return(true);
        }
        public static bool MatchBindingPath(IEdmPathExpression bindingPath, IList <ODataSegmentTemplate> parsedSegments)
        {
            List <string> paths = bindingPath.PathSegments.ToList();

            // If binding path only includes navigation property name, it matches.
            if (paths.Count == 1)
            {
                return(true);
            }

            int pathIndex = paths.Count - 2; // Skip the last segment which is navigation property name.

            // Match from tail to head.
            for (int segmentIndex = parsedSegments.Count - 1; segmentIndex >= 0; segmentIndex--)
            {
                ODataSegmentTemplate segment = parsedSegments[segmentIndex];

                PropertySegmentTemplate   propertySegment   = segment as PropertySegmentTemplate;
                NavigationSegmentTemplate navigationSegment = segment as NavigationSegmentTemplate;
                // Containment navigation property or complex property in binding path.
                if (propertySegment != null ||
                    (navigationSegment != null && navigationSegment.Segment.NavigationSource is IEdmContainedEntitySet))
                {
                    string pathName = propertySegment != null ?
                                      propertySegment.Property.Name :
                                      navigationSegment.NavigationProperty.Name;

                    if (pathIndex < 0 || string.CompareOrdinal(paths[pathIndex], pathName) != 0)
                    {
                        return(false);
                    }

                    pathIndex--;
                }
                else if (segment is CastSegmentTemplate)
                {
                    CastSegmentTemplate cast = (CastSegmentTemplate)segment;
                    // May need match type if the binding path contains type cast.
                    if (pathIndex >= 0 && paths[pathIndex].Contains(".", System.StringComparison.Ordinal))
                    {
                        if (string.CompareOrdinal(paths[pathIndex], cast.CastType.AsElementType().FullTypeName()) != 0)
                        {
                            return(false);
                        }

                        pathIndex--;
                    }
                }
                else if (segment is EntitySetSegmentTemplate ||
                         segment is SingletonSegmentTemplate ||
                         navigationSegment != null)
                {
                    // Containment navigation property in first if statement for NavigationPropertySegment.
                    break;
                }
            }

            // Return true if all the segments in binding path have been matched.
            return(pathIndex == -1 ? true : false);
        }
Beispiel #7
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource)
        {
            Contract.Assert(model != null);
            Contract.Assert(navigationSource != null);

            IEnumerable <IEdmStructuralProperty> cachedProperties;

            if (_concurrencyProperties != null && _concurrencyProperties.TryGetValue(navigationSource, out cachedProperties))
            {
                return(cachedProperties);
            }

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType            entityType   = navigationSource.EntityType();
            IEdmVocabularyAnnotatable annotatable  = navigationSource as IEdmVocabularyAnnotatable;

            IEdmContainedEntitySet navigationSourceAsEntitySet = navigationSource as IEdmContainedEntitySet;

            if (navigationSourceAsEntitySet != null)
            {
                annotatable = navigationSourceAsEntitySet.NavigationProperty as EdmNavigationProperty;
            }

            if (annotatable != null)
            {
                IEdmValueAnnotation annotation = model.FindVocabularyAnnotations <IEdmValueAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm).FirstOrDefault();
                if (annotation != null)
                {
                    IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                    if (properties != null)
                    {
                        foreach (var property in properties.Elements)
                        {
                            IEdmPathExpression pathExpression = property as IEdmPathExpression;
                            if (pathExpression != null)
                            {
                                // So far, we only consider the single path, because only the direct properties from declaring type are used.
                                // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                                string                 propertyName       = pathExpression.Path.Single();
                                IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                                IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                                if (structuralProperty != null)
                                {
                                    results.Add(structuralProperty);
                                }
                            }
                        }
                    }
                }
            }

            if (_concurrencyProperties == null)
            {
                _concurrencyProperties = new ConcurrentDictionary <IEdmNavigationSource, IEnumerable <IEdmStructuralProperty> >();
            }

            _concurrencyProperties[navigationSource] = results;
            return(results);
        }
Beispiel #8
0
        private OdcmProperty SetPathCapability(OdcmObject odcmObject, IEdmPathExpression expression, string annotationTerm)
        {
            var odcmProperty = PropertyFromPathExpression(expression, odcmObject);

            // The term name serves as a tag for this capability
            SetBooleanCapability(odcmProperty, false, annotationTerm);
            return(odcmProperty);
        }
Beispiel #9
0
 /// <summary>
 /// Sets the partner information.
 /// </summary>
 /// <param name="navigationProperty">The partner navigation property.</param>
 /// <param name="navigationPropertyPath">Path to the partner navigation property in the related entity type.</param>
 internal void SetPartner(IEdmNavigationProperty navigationProperty, IEdmPathExpression navigationPropertyPath)
 {
     Debug.Assert(
         DeclaringType is IEdmEntityType,
         "Partner info cannot be set for nav. property on a non-entity type.");
     partner     = navigationProperty;
     PartnerPath = navigationPropertyPath;
 }
Beispiel #10
0
        private static void AddProcedures(this EdmModel model, IEnumerable <ProcedureConfiguration> configurations, EdmEntityContainer container,
                                          Dictionary <Type, IEdmType> edmTypeMap, IDictionary <string, EdmNavigationSource> edmNavigationSourceMap)
        {
            Contract.Assert(model != null, "Model can't be null");

            ValidateActionOverload(configurations.OfType <ActionConfiguration>());

            foreach (ProcedureConfiguration procedure in configurations)
            {
                IEdmTypeReference returnReference = GetEdmTypeReference(
                    edmTypeMap,
                    procedure.ReturnType,
                    procedure.ReturnType != null && EdmLibHelpers.IsNullable(procedure.ReturnType.ClrType));
                IEdmExpression     expression     = GetEdmEntitySetExpression(edmNavigationSourceMap, procedure);
                IEdmPathExpression pathExpression = procedure.EntitySetPath != null
                    ? new EdmPathExpression(procedure.EntitySetPath)
                    : null;

                EdmOperationImport operationImport;

                switch (procedure.Kind)
                {
                case ProcedureKind.Action:
                    operationImport = CreateActionImport(procedure, container, returnReference, expression, pathExpression);
                    break;

                case ProcedureKind.Function:
                    operationImport = CreateFunctionImport((FunctionConfiguration)procedure, container, returnReference, expression, pathExpression);
                    break;

                case ProcedureKind.ServiceOperation:
                    Contract.Assert(false, "ServiceOperations are not supported.");
                    goto default;

                default:
                    Contract.Assert(false, "Unsupported ProcedureKind");
                    return;
                }

                EdmOperation operation = (EdmOperation)operationImport.Operation;
                if (procedure.IsBindable && procedure.Title != null & procedure.Title != procedure.Name)
                {
                    model.SetOperationTitleAnnotation(operation, new OperationTitleAnnotation(procedure.Title));
                }

                AddProcedureParameters(operation, procedure, edmTypeMap);
                if (procedure.IsBindable)
                {
                    AddProcedureLinkBuilder(model, operation, procedure);
                    ValidateProcedureEntitySetPath(model, operationImport, procedure);
                }
                else
                {
                    container.AddElement(operationImport);
                }
                model.AddElement(operation);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmEntitySet"/> class.
        /// </summary>
        /// <param name="container">An <see cref="IEdmEntityContainer"/> containing this entity set.</param>
        /// <param name="name">Name of the entity set.</param>
        /// <param name="elementType">The entity type of the elements in this entity set.</param>
        public EdmEntitySet(IEdmEntityContainer container, string name, IEdmEntityType elementType)
            : base(name, elementType)
        {
            EdmUtil.CheckArgumentNull(container, "container");

            this.container = container;
            this.type = new EdmCollectionType(new EdmEntityTypeReference(elementType, false));
            this.path = new EdmPathExpression(this.container.FullName() + "." + this.Name);
        }
Beispiel #12
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmNavigationSource navigationSource)
        {
            Contract.Assert(model != null);
            Contract.Assert(navigationSource != null);

            // Ensure that concurrency properties cache is attached to model as an annotation to avoid expensive calculations each time
            ConcurrencyPropertiesAnnotation concurrencyProperties = model.GetAnnotationValue <ConcurrencyPropertiesAnnotation>(model);

            if (concurrencyProperties == null)
            {
                concurrencyProperties = new ConcurrencyPropertiesAnnotation();
                model.SetAnnotationValue(model, concurrencyProperties);
            }

            IEnumerable <IEdmStructuralProperty> cachedProperties;

            if (concurrencyProperties.TryGetValue(navigationSource, out cachedProperties))
            {
                return(cachedProperties);
            }

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType            entityType   = navigationSource.EntityType();
            IEdmVocabularyAnnotatable annotatable  = navigationSource as IEdmVocabularyAnnotatable;

            if (annotatable != null)
            {
                var annotations = model.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(annotatable, CoreVocabularyModel.ConcurrencyTerm);
                IEdmVocabularyAnnotation annotation = annotations.FirstOrDefault();
                if (annotation != null)
                {
                    IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                    if (properties != null)
                    {
                        foreach (var property in properties.Elements)
                        {
                            IEdmPathExpression pathExpression = property as IEdmPathExpression;
                            if (pathExpression != null)
                            {
                                // So far, we only consider the single path, because only the direct properties from declaring type are used.
                                // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                                string                 propertyName       = pathExpression.PathSegments.First();
                                IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                                IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                                if (structuralProperty != null)
                                {
                                    results.Add(structuralProperty);
                                }
                            }
                        }
                    }
                }
            }

            concurrencyProperties[navigationSource] = results;
            return(results);
        }
Beispiel #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmEntitySet"/> class.
        /// </summary>
        /// <param name="container">An <see cref="IEdmEntityContainer"/> containing this entity set.</param>
        /// <param name="name">Name of the entity set.</param>
        /// <param name="elementType">The entity type of the elements in this entity set.</param>
        public EdmEntitySet(IEdmEntityContainer container, string name, IEdmEntityType elementType)
            : this(container, name, elementType, true)
        {
            EdmUtil.CheckArgumentNull(container, "container");

            this.container = container;
            this.type      = new EdmCollectionType(new EdmEntityTypeReference(elementType, false));
            this.path      = new EdmPathExpression(this.container.FullName() + "." + this.Name);
        }
        /// <summary>
        /// Determine if the path of current navigation property is matching the binding path.
        /// The function used in FindNavigationTarget to resolve the navigation target for multi binding.
        /// </summary>
        /// <param name="bindingPath">The binding path.</param>
        /// <param name="parsedSegments">The list of segments in Uri path.</param>
        /// <returns>True if the path of navigation property in current scope is matching the <paramref name="bindingPath"/>.</returns>
        public static bool MatchBindingPath(IEdmPathExpression bindingPath, IList <ODataPathSegment> parsedSegments)
        {
            List <string> paths = bindingPath.PathSegments.ToList();

            // If binding path only includes navigation property name, it matches.
            if (paths.Count == 1)
            {
                return(true);
            }

            int pathIndex    = paths.Count - 2; // Skip the last segment which is navigation property name.
            int segmentIndex = parsedSegments.Count - 1;

            // Match from tail to head.
            for (; segmentIndex >= 0; segmentIndex--)
            {
                ODataPathSegment segment = parsedSegments[segmentIndex];

                // Cache the cast result to avoid CA1800:DoNotCastUnnecessarily.
                bool segmentIsNavigationPropertySegment = segment is NavigationPropertySegment;

                // Containment navigation property or complex property in binding path.
                if (segment is PropertySegment || (segmentIsNavigationPropertySegment && segment.TargetEdmNavigationSource is IEdmContainedEntitySet))
                {
                    if (pathIndex < 0 || string.CompareOrdinal(paths[pathIndex], segment.Identifier) != 0)
                    {
                        return(false);
                    }

                    pathIndex--;
                }
                else if (segment is TypeSegment)
                {
                    // May need match type if the binding path contains type cast.
                    if (pathIndex >= 0 && paths[pathIndex].IndexOf('.') >= 0)
                    {
                        if (string.CompareOrdinal(paths[pathIndex], segment.EdmType.AsElementType().FullTypeName()) != 0)
                        {
                            return(false);
                        }

                        pathIndex--;
                    }
                }
                else if (segmentIsNavigationPropertySegment ||
                         segment is EntitySetSegment ||
                         segment is SingletonSegment)
                {
                    // Containment navigation property in first if statement for NavigationPropertySegment.
                    break;
                }
            }

            // Return true if all the segments in binding path have been matched.
            return(pathIndex == -1 ? true : false);
        }
 public CsdlNavigationProperty(string name, string type, bool?nullable, string partner, bool containsTarget, CsdlOnDelete onDelete, IEnumerable <CsdlReferentialConstraint> referentialConstraints, CsdlDocumentation documentation, CsdlLocation location)
     : base(name, documentation, location)
 {
     this.type                   = type;
     this.nullable               = nullable;
     this.partnerPath            = partner == null ? null : new EdmPathExpression(partner);
     this.containsTarget         = containsTarget;
     this.onDelete               = onDelete;
     this.referentialConstraints = referentialConstraints;
 }
Beispiel #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmSingleton"/> class.
        /// </summary>
        /// <param name="container">An <see cref="IEdmEntityContainer"/> containing this entity set.</param>
        /// <param name="name">Name of the singleton.</param>
        /// <param name="entityType">The entity type of the element of this singleton.</param>
        public EdmSingleton(IEdmEntityContainer container, string name, IEdmEntityType entityType)
            : base(name)
        {
            EdmUtil.CheckArgumentNull(container, "container");
            EdmUtil.CheckArgumentNull(entityType, "entityType");

            this.container = container;
            this.entityType = entityType;
            this.path = new EdmPathExpression(name);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmContainedEntitySet"/> class.
        /// </summary>
        /// <param name="parentNavigationSource">The <see cref="IEdmNavigationSource"/> that container element belongs to</param>
        /// <param name="navigationProperty">An <see cref="IEdmNavigationProperty"/> containing the navigation property definition of the contained element</param>
        /// <param name="navigationPath">The path from the parentNavigationSource to the related resource, concluding with the navigation property name. May traverse complex types and cast segments</param>
        public EdmContainedEntitySet(IEdmNavigationSource parentNavigationSource, IEdmNavigationProperty navigationProperty, IEdmPathExpression navigationPath)
            : base(navigationProperty.Name, navigationProperty.ToEntityType())
        {
            EdmUtil.CheckArgumentNull(parentNavigationSource, "parentNavigationSource");
            EdmUtil.CheckArgumentNull(navigationProperty, "navigationProperty");

            this.parentNavigationSource = parentNavigationSource;
            this.navigationProperty     = navigationProperty;
            this.navigationPath         = navigationPath;
        }
Beispiel #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmEntitySet"/> class.
        /// </summary>
        /// <param name="container">An <see cref="IEdmEntityContainer"/> containing this entity set.</param>
        /// <param name="name">Name of the entity set.</param>
        /// <param name="elementType">The entity type of the elements in this entity set.</param>
        /// <param name="includeInServiceDocument">Indicates whether the entity set is advertised in the service document.</param>
        public EdmEntitySet(IEdmEntityContainer container, string name, IEdmEntityType elementType, bool includeInServiceDocument)
            : base(name, elementType)
        {
            EdmUtil.CheckArgumentNull(container, "container");

            this.container = container;
            this.type      = new EdmCollectionType(new EdmEntityTypeReference(elementType, false));
            this.path      = new EdmPathExpression(this.container.FullName() + "." + this.Name);
            this.includeInServiceDocument = includeInServiceDocument;
        }
Beispiel #19
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmSingleton"/> class.
        /// </summary>
        /// <param name="container">An <see cref="IEdmEntityContainer"/> containing this entity set.</param>
        /// <param name="name">Name of the singleton.</param>
        /// <param name="entityType">The entity type of the element of this singleton.</param>
        public EdmSingleton(IEdmEntityContainer container, string name, IEdmEntityType entityType)
            : base(name)
        {
            EdmUtil.CheckArgumentNull(container, "container");
            EdmUtil.CheckArgumentNull(entityType, "entityType");

            this.container  = container;
            this.entityType = entityType;
            this.path       = new EdmPathExpression(name);
        }
Beispiel #20
0
        public IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty)
        {
            bool isDerived = !this.Type.AsElementType().IsOrInheritsFrom(navigationProperty.DeclaringType);

            IEdmPathExpression bindingPath = isDerived
                ? new EdmPathExpression(navigationProperty.DeclaringType.FullTypeName(), navigationProperty.Name)
                : new EdmPathExpression(navigationProperty.Name);

            return(FindNavigationTarget(navigationProperty, bindingPath));
        }
Beispiel #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmAction"/> class.
        /// </summary>
        /// <param name="namespaceName">Name of the namespace.</param>
        /// <param name="name">The name.</param>
        /// <param name="returnType">Type of the return.</param>
        /// <param name="isBound">if set to <c>true</c> [is bound].</param>
        /// <param name="entitySetPathExpression">The entity set path expression.</param>
        protected EdmOperation(string namespaceName, string name, IEdmTypeReference returnType, bool isBound, IEdmPathExpression entitySetPathExpression)
            : base(name)
        {
            EdmUtil.CheckArgumentNull(namespaceName, "namespaceName");

            this.ReturnType = returnType;
            this.Namespace = namespaceName;
            this.IsBound = isBound;
            this.EntitySetPath = entitySetPathExpression;
        }
        /// <summary>
        /// Finds the navigation source that a navigation property targets.
        /// </summary>
        /// <param name="navigationProperty">The navigation property.</param>
        /// <returns>The navigation source that the navigation proportion targets, or null if no such navigation source exists.</returns>
        public virtual IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty)
        {
            EdmUtil.CheckArgumentNull(navigationProperty, "property");

            bool isDerived = !(navigationProperty.DeclaringType.AsElementType() is IEdmComplexType) && !this.Type.AsElementType().IsOrInheritsFrom(navigationProperty.DeclaringType);

            IEdmPathExpression bindingPath = isDerived
                ? new EdmPathExpression(navigationProperty.DeclaringType.FullTypeName(), navigationProperty.Name)
                : new EdmPathExpression(navigationProperty.Name);

            return(FindNavigationTarget(navigationProperty, bindingPath));
        }
Beispiel #23
0
 public void SetNavigationPropertyPartner(
     EdmNavigationProperty navigationProperty,
     IEdmPathExpression navigationPropertyPath,
     EdmNavigationProperty partnerNavigationProperty,
     IEdmPathExpression partnerNavigationPropertyPath)
 {
     Debug.Assert(
         this.IsOnSameTypeHierarchyLineWith(navigationProperty.DeclaringType),
         "Nav. property is not defined on this or a derived entity type.");
     navigationProperty.SetPartner(partnerNavigationProperty, partnerNavigationPropertyPath);
     if (partnerNavigationProperty.DeclaringType is IEdmEntityType)
     {
         partnerNavigationProperty.SetPartner(navigationProperty, navigationPropertyPath);
     }
 }
Beispiel #24
0
        private static EdmOperationImport CreateActionImport(
            OperationConfiguration operationConfiguration,
            EdmEntityContainer container,
            IEdmTypeReference returnReference,
            IEdmExpression expression,
            IEdmPathExpression pathExpression)
        {
            EdmAction operation = new EdmAction(
                operationConfiguration.Namespace,
                operationConfiguration.Name,
                returnReference,
                operationConfiguration.IsBindable,
                pathExpression);

            return(new EdmActionImport(container, operationConfiguration.Name, operation, expression));
        }
Beispiel #25
0
        /// <summary>
        /// Constructs a SingleNavigationNode.
        /// </summary>
        /// <param name="navigationSource">The navigation source that this of the previous segment.</param>
        /// <param name="navigationProperty">The navigation property this node represents.</param>
        /// <param name="bindingPath">The binding path of navigation property</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input navigationProperty.</exception>
        /// <exception cref="ArgumentException">Throws if the input navigationProperty targets more than one entity.</exception>
        internal SingleNavigationNode(IEdmNavigationSource navigationSource, IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
        {
            ExceptionUtils.CheckArgumentNotNull(navigationProperty, "navigationProperty");

            EdmMultiplicity multiplicity = navigationProperty.TargetMultiplicity();

            if (multiplicity != EdmMultiplicity.One && multiplicity != EdmMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_CollectionNavigationNode_MustHaveSingleMultiplicity);
            }

            this.navigationProperty  = navigationProperty;
            this.entityTypeReference = (IEdmEntityTypeReference)this.NavigationProperty.Type;
            this.bindingPath         = bindingPath;
            this.navigationSource    = navigationSource != null?navigationSource.FindNavigationTarget(navigationProperty, bindingPath) : null;
        }
        /// <summary>
        /// Translates V3 CollectionNavigationNode to V4 CollectionNavigationNode
        /// </summary>
        /// <param name="nodeIn">V3 CollectionNavigationNode</param>
        /// <returns>V4 CollectionNavigationNode</returns>
        public override QueryNode Visit(Data.OData.Query.SemanticAst.CollectionNavigationNode nodeIn)
        {
            IEdmPathExpression pathExpr = null;
            if (nodeIn.EntitySet != null)
            {
                IEdmNavigationSource navigationSource = v4model.FindDeclaredNavigationSource(nodeIn.EntitySet.Name);
                pathExpr = navigationSource.Path;
            }

            IEdmStructuredType v4Type = v4model.GetV4Definition(nodeIn.NavigationProperty.DeclaringType) as IEdmStructuredType;
            ExceptionUtil.IfNullThrowException(v4Type, "Unable to locate v4 structured type " + nodeIn.NavigationProperty.DeclaringType.GetFullTypeName());

            IEdmNavigationProperty v4navProperty = v4Type.FindProperty(nodeIn.NavigationProperty.Name) as IEdmNavigationProperty;
            ExceptionUtil.IfNullThrowException(v4navProperty, "Unable to locate property " + nodeIn.NavigationProperty.Name);
            return new CollectionNavigationNode((SingleResourceNode)nodeIn.Source.Accept(this), v4navProperty, pathExpr);
        }
Beispiel #27
0
        private static EdmOperationImport CreateFunctionImport(
            FunctionConfiguration function,
            EdmEntityContainer container,
            IEdmTypeReference returnReference,
            IEdmExpression expression,
            IEdmPathExpression pathExpression)
        {
            EdmFunction operation = new EdmFunction(
                function.Namespace,
                function.Name,
                returnReference,
                function.IsBindable,
                pathExpression,
                function.IsComposable);

            return(new EdmFunctionImport(container, function.Name, operation, expression, includeInServiceDocument: function.IncludeInServiceDocument));
        }
        /// <summary>
        /// Get the property path from the record using the given property name.
        /// </summary>
        /// <param name="record">The record expression.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The property path or null.</returns>
        public static string GetPropertyPath(this IEdmRecordExpression record, string propertyName)
        {
            Utils.CheckArgumentNull(record, nameof(record));
            Utils.CheckArgumentNull(propertyName, nameof(propertyName));

            if (record.Properties != null)
            {
                IEdmPropertyConstructor property = record.Properties.FirstOrDefault(e => e.Name == propertyName);
                if (property != null)
                {
                    IEdmPathExpression value = property.Value as IEdmPathExpression;
                    if (value != null)
                    {
                        return(value.Path);
                    }
                }
            }

            return(null);
        }
Beispiel #29
0
        /// <summary>
        /// Initializes a new <see cref="IEdmOperationImport"/> instance.
        /// </summary>
        /// <param name="name">name of the service operation.</param>
        /// <param name="function">Function imported in.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation.</param>
        public EdmFunctionImport AddFunctionAndFunctionImport(string name, IEdmTypeReference bindingType, IEdmTypeReference resultType, IEdmEntitySet resultSet, bool isBindable)
        {
            var edmFunction = new EdmFunction(this.Namespace, name, resultType, isBindable, null, false /*isComposable*/);

            if (isBindable)
            {
                edmFunction.AddParameter("bindingparameter", bindingType);
            }

            IEdmPathExpression entitySetExpression = null;

            if (resultSet != null)
            {
                entitySetExpression = new EdmPathExpression(resultSet.Name);
            }

            this.AddOperation(edmFunction);
            var functionImport = new EdmFunctionImport(this, name, edmFunction, entitySetExpression, false);

            this.AddOperationImport(name, functionImport);
            return(functionImport);
        }
 internal void WriteFunctionImportElementHeader(IEdmFunctionImport functionImport)
 {
     this.xmlWriter.WriteStartElement("FunctionImport");
     this.WriteRequiredAttribute <string>("Name", functionImport.Name, new Func <string, string>(EdmValueWriter.StringAsXml));
     this.WriteOptionalAttribute <IEdmTypeReference>("ReturnType", functionImport.ReturnType, new Func <IEdmTypeReference, string>(this.TypeReferenceAsXml));
     if (functionImport.IsComposable && functionImport.IsSideEffecting || !functionImport.IsComposable && !functionImport.IsSideEffecting)
     {
         this.WriteRequiredAttribute <bool>("IsSideEffecting", functionImport.IsSideEffecting, new Func <bool, string>(EdmValueWriter.BooleanAsXml));
     }
     this.WriteOptionalAttribute <bool>("IsComposable", functionImport.IsComposable, false, new Func <bool, string>(EdmValueWriter.BooleanAsXml));
     this.WriteOptionalAttribute <bool>("IsBindable", functionImport.IsBindable, false, new Func <bool, string>(EdmValueWriter.BooleanAsXml));
     if (functionImport.EntitySet == null)
     {
         return;
     }
     else
     {
         IEdmEntitySetReferenceExpression entitySet = functionImport.EntitySet as IEdmEntitySetReferenceExpression;
         if (entitySet == null)
         {
             IEdmPathExpression edmPathExpression = functionImport.EntitySet as IEdmPathExpression;
             if (edmPathExpression == null)
             {
                 throw new InvalidOperationException(Strings.EdmModel_Validator_Semantic_FunctionImportEntitySetExpressionIsInvalid(functionImport.Name));
             }
             else
             {
                 this.WriteOptionalAttribute <IEnumerable <string> >("EntitySetPath", edmPathExpression.Path, new Func <IEnumerable <string>, string>(EdmModelCsdlSchemaWriter.PathAsXml));
                 return;
             }
         }
         else
         {
             this.WriteOptionalAttribute <string>("EntitySet", entitySet.ReferencedEntitySet.Name, new Func <string, string>(EdmValueWriter.StringAsXml));
             return;
         }
     }
 }
Beispiel #31
0
        /// <summary>
        ///     Maps an IEdmDelayedVAlue to an instance of an object.
        ///     In the case that the delayedValue object represents a navigation path,
        ///     performs additional work to map the navigation path to a delayedValue
        /// </summary>
        /// <param name="delayedValue">DelayedValue that is an element of the list</param>
        /// <returns>The object representation of the delayedValue</returns>
        private static object MapListElements(IEdmDelayedValue delayedValue)
        {
            IEdmValue edmValue;

            try
            {
                edmValue = delayedValue.Value;
                return(MapToClr(edmValue));
            }
            catch (ArgumentNullException)
            {
                // This is a painful hack to deal with the fact that parsing the navigation
                // property returned a delayedValue that evaluates a NullException when you call .Value
                // Attempt to obtain the inner expression because we don't have access to the type of the Delayed Collection
                var innerExpression = delayedValue.GetPropertyByName <IEdmExpression>("Expression");

                switch (innerExpression.ExpressionKind)
                {
                case EdmExpressionKind.NavigationPropertyPath:
                {
                    IEdmPathExpression pe = innerExpression as IEdmPathExpression;
                    if (pe == null)
                    {
                        throw new ArgumentNullException("delayedValue",
                                                        "A IEdmExpression of delayedValue type NavigationPropertyPath was unable to be cast correctly to a IEdmNavigationPropertyPath");
                    }

                    // Map navigation properties to strings for convenience
                    return(string.Join("/", pe.Path));
                }

                default:
                    throw new NotImplementedException(
                              string.Format("A custom mapping for ExpressionKind {0} has not yet been implemented.",
                                            innerExpression.ExpressionKind));
                }
            }
        }
Beispiel #32
0
        public static IEnumerable <IEdmStructuralProperty> GetConcurrencyProperties(this IEdmModel model, IEdmEntitySet entitySet)
        {
            Contract.Assert(model != null);
            Contract.Assert(entitySet != null);

            IList <IEdmStructuralProperty> results = new List <IEdmStructuralProperty>();
            IEdmEntityType      entityType         = entitySet.EntityType();
            var                 annotations        = model.FindVocabularyAnnotations <IEdmValueAnnotation>(entitySet, CoreVocabularyModel.ConcurrencyTerm);
            IEdmValueAnnotation annotation         = annotations.FirstOrDefault();

            if (annotation != null)
            {
                IEdmCollectionExpression properties = annotation.Value as IEdmCollectionExpression;
                if (properties != null)
                {
                    foreach (var property in properties.Elements)
                    {
                        IEdmPathExpression pathExpression = property as IEdmPathExpression;
                        if (pathExpression != null)
                        {
                            // So far, we only consider the single path, because only the direct properties from declaring type are used.
                            // However we have an issue tracking on: https://github.com/OData/WebApi/issues/472
                            string                 propertyName       = pathExpression.Path.Single();
                            IEdmProperty           edmProperty        = entityType.FindProperty(propertyName);
                            IEdmStructuralProperty structuralProperty = edmProperty as IEdmStructuralProperty;
                            if (structuralProperty != null)
                            {
                                results.Add(structuralProperty);
                            }
                        }
                    }
                }
            }

            return(results);
        }
Beispiel #33
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmFunction"/> class.
 /// </summary>
 /// <param name="namespaceName">Name of the namespace.</param>
 /// <param name="name">The name.</param>
 /// <param name="returnType">Type of the return.</param>
 /// <param name="isBound">if set to <c>true</c> [is bound].</param>
 /// <param name="entitySetPathExpression">The entity set path expression.</param>
 /// <param name="isComposable">A value indicating if the function is composable or not.</param>
 public EdmFunction(string namespaceName, string name, IEdmTypeReference returnType, bool isBound, IEdmPathExpression entitySetPathExpression, bool isComposable)
     : base(namespaceName, name, returnType, isBound, entitySetPathExpression)
 {
     EdmUtil.CheckArgumentNull(returnType, "returnType");
     this.IsComposable = isComposable;
 }
        /// <summary>
        /// Finds the entity set that a navigation property targets.
        /// </summary>
        /// <param name="navigationProperty">The navigation property.</param>
        /// <param name="bindingPath">The binding path of the navigation property</param>
        /// <returns>The entity set that the navigation property targets</returns>
        public override IEdmNavigationSource FindNavigationTarget(IEdmNavigationProperty navigationProperty, IEdmPathExpression bindingPath)
        {
            // 7.4.1 expected the path to be prefixed with the path to the contained navigation source.
            // For backward compatibility, if the binding path received starts with the path to this contained resource,
            // we trim it off and then treat the remainder as the path to the target. This logic should be removed in
            // the next breaking change as it could be ambiguous in the case that the prefix of the path to the contained
            // source matches a valid path to the target of the contained source.
            if (bindingPath != null)
            {
                if (bindingPath.Path.Length > this.FullNavigationPath.Length && bindingPath.Path.StartsWith(this.FullNavigationPath, System.StringComparison.Ordinal))
                {
                    bindingPath = new EdmPathExpression(bindingPath.Path.Substring(this.FullNavigationPath.Length + 1));
                }
            }

            IEdmNavigationSource navigationTarget = base.FindNavigationTarget(navigationProperty, bindingPath);

            if (navigationTarget is IEdmUnknownEntitySet)
            {
                IEnumerable <string> segments = (bindingPath == null || string.IsNullOrEmpty(bindingPath.Path)) ? new string[] { navigationProperty.Name } : bindingPath.PathSegments;
                bindingPath = new EdmPathExpression(this.NavigationPath.PathSegments.Concat(segments));

                return(this.parentNavigationSource.FindNavigationTarget(navigationProperty, bindingPath));
            }

            return(navigationTarget);
        }
Beispiel #35
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmAction"/> class.
 /// </summary>
 /// <param name="namespaceName">Name of the namespace.</param>
 /// <param name="name">The name.</param>
 /// <param name="returnType">Type of the return.</param>
 /// <param name="isBound">if set to <c>true</c> [is bound].</param>
 /// <param name="entitySetPathExpression">The entity set path expression.</param>
 public EdmAction(string namespaceName, string name, IEdmTypeReference returnType, bool isBound, IEdmPathExpression entitySetPathExpression)
     : base(namespaceName, name, returnType, isBound, entitySetPathExpression)
 {
 }
        /// <summary>
        /// Adds the action.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="boundType">Type of the bound.</param>
        /// <param name="resultType">Type of the result.</param>
        /// <param name="isBound">if set to <c>true</c> [is bound].</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public EdmAction AddAction(string name, IEdmTypeReference boundType, IEdmTypeReference resultType, bool isBound, IEdmPathExpression entitySetPathExpression, params Tuple<string, IEdmTypeReference>[] parameters)
        {
            var action = new EdmAction(namespaceName, name, resultType, isBound, entitySetPathExpression);
            if (isBound)
            {
                action.AddParameter(new EdmOperationParameter(action, "bindingparameter", boundType));
            }

            this.AddOperation(action);
            return action;
        }
 private static EdmOperationImport CreateFunctionImport(
     FunctionConfiguration function,
     EdmEntityContainer container,
     IEdmTypeReference returnReference,
     IEdmExpression expression,
     IEdmPathExpression pathExpression)
 {
     EdmFunction operation = new EdmFunction(
             container.Namespace,
             function.Name,
             returnReference,
             function.IsBindable,
             pathExpression,
             function.IsComposable);
     return new EdmFunctionImport(container, function.Name, operation, expression, includeInServiceDocument: function.IncludeInServiceDocument);
 }
 private static EdmOperationImport CreateActionImport(
     ProcedureConfiguration procedure,
     EdmEntityContainer container,
     IEdmTypeReference returnReference,
     IEdmExpression expression,
     IEdmPathExpression pathExpression)
 {
     EdmAction operation = new EdmAction(
         container.Namespace,
         procedure.Name,
         returnReference,
         procedure.IsBindable,
         pathExpression);
     return new EdmActionImport(container, procedure.Name, operation, expression);
 }
        /// <summary>
        /// Adds the function.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="boundType">Type of the bound.</param>
        /// <param name="resultType">Type of the result.</param>
        /// <param name="isBound">if set to <c>true</c> [is bound].</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public EdmFunction AddFunction(string name, IEdmTypeReference boundType, IEdmTypeReference returnType, bool isBound, IEdmPathExpression entitySetPathExpression, bool isComposable)
        {
            var function = new EdmFunction(namespaceName, name, returnType, isBound, entitySetPathExpression, isComposable);
            if (isBound)
            {
                function.AddParameter("bindingparameter", boundType);
            }

            this.AddOperation(function);
            return function;
        }
Beispiel #40
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmAction"/> class.
 /// </summary>
 /// <param name="namespaceName">Name of the namespace.</param>
 /// <param name="name">The name.</param>
 /// <param name="returnType">Type of the return.</param>
 /// <param name="isBound">if set to <c>true</c> [is bound].</param>
 /// <param name="entitySetPathExpression">The entity set path expression.</param>
 public EdmAction(string namespaceName, string name, IEdmTypeReference returnType, bool isBound, IEdmPathExpression entitySetPathExpression)
     : base(namespaceName, name, returnType, isBound, entitySetPathExpression)
 {
 }