Example #1
0
 internal void TrackAction(object target, ResourceSetWrapper container, UpdateOperations action)
 {
     if (container.ChangeInterceptors != null)
     {
         Dictionary<object, UpdateOperations> dictionary;
         UpdateOperations operations;
         if (!this.items.TryGetValue(container, out dictionary))
         {
             if (this.service.Provider.IsV1Provider)
             {
                 dictionary = new Dictionary<object, UpdateOperations>(EqualityComparer<object>.Default);
             }
             else
             {
                 dictionary = new Dictionary<object, UpdateOperations>(ReferenceEqualityComparer<object>.Instance);
             }
             this.items.Add(container, dictionary);
         }
         if (dictionary.TryGetValue(target, out operations))
         {
             if ((action | operations) != operations)
             {
                 dictionary[target] = action | operations;
             }
         }
         else
         {
             dictionary.Add(target, action);
         }
     }
 }
Example #2
0
 public void ApplyConfiguration(DataServiceConfiguration configuration, DataServiceProviderWrapper provider)
 {
     if (this.Kind == OperationKind.ServiceOperation)
     {
         this.serviceOperationRights = configuration.GetServiceOperationRights(this.ServiceOperation);
     }
     else
     {
         this.serviceActionRights = configuration.GetServiceActionRights(this.ServiceAction);
     }
     if (((this.Kind == OperationKind.ServiceOperation) && ((this.serviceOperationRights & ~System.Data.Services.ServiceOperationRights.OverrideEntitySetRights) != System.Data.Services.ServiceOperationRights.None)) || ((this.Kind == OperationKind.Action) && (this.serviceActionRights != System.Data.Services.ServiceActionRights.None)))
     {
         if (this.operation.ResourceSet != null)
         {
             this.resourceSet = provider.TryResolveResourceSet(this.operation.ResourceSet.Name);
             if (this.resourceSet == null)
             {
                 throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_OperationResourceSetNotVisible(this.Name, this.operation.ResourceSet.Name));
             }
         }
         else if (this.ResultSetPathExpression != null)
         {
             this.ResultSetPathExpression.InitializePathSegments(provider);
         }
     }
 }
Example #3
0
        /// <summary>Fires the notification for a single action.</summary>
        /// <param name="service">Service on which methods should be invoked.</param>
        /// <param name="target">Object to be tracked.</param>
        /// <param name="container">Container in which object is changed.</param>
        /// <param name="action">Action affecting target.</param>
        internal static void FireNotification(IDataService service, object target, ResourceSetWrapper container, UpdateOperations action)
        {
            Debug.Assert(service != null, "service != null");
            AssertActionValues(target, container);

            MethodInfo[] methods = container.ChangeInterceptors;
            if (methods != null)
            {
                object[] parameters = new object[2];
                parameters[0] = target;
                parameters[1] = action;
                for (int i = 0; i < methods.Length; i++)
                {
                    try
                    {
                        methods[i].Invoke(service.Instance, parameters);
                    }
                    catch (TargetInvocationException exception)
                    {
                        ErrorHandler.HandleTargetInvocationException(exception);
                        throw;
                    }
                }
            }
        }
 internal void AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet)
 {
     IEdmEntityType elementType = (IEdmEntityType) this.model.EnsureSchemaType(resourceSet.ResourceType);
     IEdmEntitySet target = new EdmEntitySet(this, entitySetName, elementType);
     MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, target);
     this.entitySetCache.Add(entitySetName, target);
 }
Example #5
0
 public void ApplyConfiguration(DataServiceConfiguration configuration, DataServiceProviderWrapper provider)
 {
     if (this.Kind == OperationKind.ServiceOperation)
     {
         this.serviceOperationRights = configuration.GetServiceOperationRights(this.ServiceOperation);
     }
     else
     {
         this.serviceActionRights = configuration.GetServiceActionRights(this.ServiceAction);
     }
     if (((this.Kind == OperationKind.ServiceOperation) && ((this.serviceOperationRights & ~System.Data.Services.ServiceOperationRights.OverrideEntitySetRights) != System.Data.Services.ServiceOperationRights.None)) || ((this.Kind == OperationKind.Action) && (this.serviceActionRights != System.Data.Services.ServiceActionRights.None)))
     {
         if (this.operation.ResourceSet != null)
         {
             this.resourceSet = provider.TryResolveResourceSet(this.operation.ResourceSet.Name);
             if (this.resourceSet == null)
             {
                 throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_OperationResourceSetNotVisible(this.Name, this.operation.ResourceSet.Name));
             }
         }
         else if (this.ResultSetPathExpression != null)
         {
             this.ResultSetPathExpression.InitializePathSegments(provider);
         }
     }
 }
Example #6
0
 internal IEnumerable <ResourceProperty> GetResourceSerializableProperties(ResourceSetWrapper resourceSet, ResourceType resourceType)
 {
     if (resourceType.ResourceTypeKind == ResourceTypeKind.EntityType)
     {
         return(resourceSet.GetEntitySerializableProperties(this, resourceType));
     }
     return(resourceType.Properties);
 }
        internal void AddEntitySet(string entitySetName, ResourceSetWrapper resourceSet)
        {
            IEdmEntityType elementType = (IEdmEntityType)this.model.EnsureSchemaType(resourceSet.ResourceType);
            IEdmEntitySet  target      = new EdmEntitySet(this, entitySetName, elementType);

            MetadataProviderUtils.ConvertCustomAnnotations(this.model, resourceSet.CustomAnnotations, target);
            this.entitySetCache.Add(entitySetName, target);
        }
        /// <summary>
        /// Gets the ResourceAssociationSet instance when given the source association end.
        /// </summary>
        /// <param name="resourceSet">Resource set of the source association end.</param>
        /// <param name="resourceType">Resource type of the source association end.</param>
        /// <param name="resourceProperty">Resource property of the source association end.</param>
        /// <returns>ResourceAssociationSet instance.</returns>
        internal ResourceAssociationSet GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceType != null, "resourceType != null");
            Debug.Assert(resourceProperty != null, "resourceProperty != null");

            return(this.metadataProvider.GetResourceAssociationSet(resourceSet.ResourceSet, resourceType, resourceProperty));
        }
Example #9
0
        internal ResourceSetWrapper GetContainer(ResourceSetWrapper sourceContainer, ResourceType sourceResourceType, ResourceProperty navigationProperty)
        {
            ResourceAssociationSet set = this.GetResourceAssociationSet(sourceContainer, sourceResourceType, navigationProperty);

            if (set != null)
            {
                ResourceAssociationSetEnd end = set.GetRelatedResourceAssociationSetEnd(sourceContainer, sourceResourceType, navigationProperty);
                return(this.ValidateResourceSet(end.ResourceSet));
            }
            return(null);
        }
Example #10
0
        public ConstantExpression GetQueryRootForResourceSet(ResourceSetWrapper resourceSet, DataServiceOperationContext operationContext)
        {
            IQueryable queryRootForResourceSet = this.queryProvider.GetQueryRootForResourceSet(resourceSet.ResourceSet);

            WebUtil.CheckResourceExists(queryRootForResourceSet != null, resourceSet.Name);
            if (!resourceSet.QueryRootType.IsAssignableFrom(queryRootForResourceSet.GetType()))
            {
                throw new InvalidOperationException(System.Data.Services.Strings.DataServiceProviderWrapper_InvalidQueryRootType(resourceSet.Name, resourceSet.QueryRootType.FullName));
            }
            return(Expression.Constant(queryRootForResourceSet));
        }
Example #11
0
 internal ExpandSegment(string name, Expression filter, int maxResultsExpected, ResourceSetWrapper container, ResourceType targetResourceType, ResourceProperty expandedProperty, System.Data.Services.Providers.OrderingInfo orderingInfo)
 {
     WebUtil.CheckArgumentNull<string>(name, "name");
     CheckFilterType(filter);
     this.name = name;
     this.filter = filter;
     this.container = container;
     this.maxResultsExpected = maxResultsExpected;
     this.expandedProperty = expandedProperty;
     this.orderingInfo = orderingInfo;
     this.targetResourceType = targetResourceType;
 }
        /// <summary>Filters a query like a SQL WHERE clause does.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="setForIt">Set for each item in the query if they are entities</param>
        /// <param name="typeForIt">Type for each item in the query in Astoria metadata terms</param>
        /// <param name="source">Original source for query.</param>
        /// <param name="predicate">Predicate to compose.</param>
        /// <returns>The composed query.</returns>
        internal static IQueryable Where(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, IQueryable source, string predicate)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(typeForIt != null, "typeForIt != null");
            Debug.Assert(typeForIt.ResourceTypeKind != ResourceTypeKind.EntityType || setForIt != null, "setForIt cannot be null if typeForIt is an entity type.");
            Debug.Assert(source != null, "source != null");
            Debug.Assert(predicate != null, "predicate != null");

            LambdaExpression lambda = ParseLambdaForWhere(service, setForIt, typeForIt, source.ElementType, predicate);
            return source.Provider.CreateQuery(
                Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, Expression.Quote(lambda)));
        }
 internal ResourceSetWrapper GetTargetSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet)
 {
     ResourceSetWrapper sourceContainer = bindingSet;
     for (int i = 0; (sourceContainer != null) && (i < this.pathSegments.Length); i++)
     {
         PathSegment segment = this.pathSegments[i];
         if (segment.Property != null)
         {
             sourceContainer = provider.GetContainer(sourceContainer, segment.SourceType, segment.Property);
         }
     }
     return sourceContainer;
 }
Example #14
0
 internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
 {
     ResourceAssociationSetEnd end = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);
     if (end == null)
     {
         return null;
     }
     if (end != this.End1)
     {
         return this.End1;
     }
     return this.End2;
 }
Example #15
0
        /// <summary>
        /// Retrieve the related end for the given resource set, type and property.
        /// </summary>
        /// <param name="resourceSet">resource set for the source end</param>
        /// <param name="resourceType">resource type for the source end</param>
        /// <param name="resourceProperty">resource property for the source end</param>
        /// <returns>Related resource association set end for the given parameters</returns>
        internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceType != null, "resourceType != null");

            ResourceAssociationSetEnd thisEnd = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);

            if (thisEnd != null)
            {
                return(thisEnd == this.End1 ? this.End2 : this.End1);
            }

            return(null);
        }
Example #16
0
        internal ResourceSetWrapper GetTargetSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet)
        {
            ResourceSetWrapper sourceContainer = bindingSet;

            for (int i = 0; (sourceContainer != null) && (i < this.pathSegments.Length); i++)
            {
                PathSegment segment = this.pathSegments[i];
                if (segment.Property != null)
                {
                    sourceContainer = provider.GetContainer(sourceContainer, segment.SourceType, segment.Property);
                }
            }
            return(sourceContainer);
        }
Example #17
0
        internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            ResourceAssociationSetEnd end = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);

            if (end == null)
            {
                return(null);
            }
            if (end != this.End1)
            {
                return(this.End1);
            }
            return(this.End2);
        }
Example #18
0
        internal ResourceSetWrapper ValidateResourceSet(ResourceSet resourceSet)
        {
            ResourceSetWrapper wrapper = null;

            if (resourceSet != null)
            {
                if (this.ResourceSetWrapperCache.TryGetValue(resourceSet.Name, out wrapper))
                {
                    return(wrapper);
                }
                wrapper = ResourceSetWrapper.CreateResourceSetWrapper(resourceSet, this, new Func <ResourceType, ResourceType>(this.ValidateResourceType));
                this.ResourceSetWrapperCache[resourceSet.Name] = wrapper;
            }
            return(wrapper);
        }
Example #19
0
        internal static ResourceSetWrapper CreateResourceSetWrapper(System.Data.Services.Providers.ResourceSet resourceSet, DataServiceProviderWrapper provider, Func <System.Data.Services.Providers.ResourceType, System.Data.Services.Providers.ResourceType> resourceTypeValidator)
        {
            if (!resourceSet.IsReadOnly)
            {
                throw new DataServiceException(500, System.Data.Services.Strings.DataServiceProviderWrapper_ResourceContainerNotReadonly(resourceSet.Name));
            }
            ResourceSetWrapper wrapper = new ResourceSetWrapper(resourceSet);

            wrapper.ApplyConfiguration(provider.Configuration);
            if (!wrapper.IsVisible)
            {
                return(null);
            }
            wrapper.resourceType = resourceTypeValidator(resourceSet.ResourceType);
            return(wrapper);
        }
Example #20
0
        internal Version GetMinimumResponseVersion(IDataService service, ResourceSetWrapper resourceSet, bool considerEpmInVersion)
        {
            Version versionToRaise = WebUtil.RaiseVersion(RequestDescription.Version1Dot0, this.GetMinimumProtocolVersion(considerEpmInVersion));

            if (service.Configuration.DataServiceBehavior.ShouldIncludeAssociationLinksInResponse && resourceSet.GetEntitySerializableProperties(service.Provider, this).Any <ResourceProperty>(p => (p.TypeKind == System.Data.Services.Providers.ResourceTypeKind.EntityType)))
            {
                versionToRaise = WebUtil.RaiseVersion(versionToRaise, RequestDescription.Version3Dot0);
            }
            if (this.IsOpenType)
            {
                Version version2          = service.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion();
                Version requestMaxVersion = service.OperationContext.Host.RequestMaxVersion;
                Version targetVersion     = (requestMaxVersion < version2) ? requestMaxVersion : version2;
                versionToRaise = WebUtil.RaiseVersion(versionToRaise, targetVersion);
            }
            return(versionToRaise);
        }
Example #21
0
 internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
 {
     foreach (ResourceAssociationSetEnd end in new ResourceAssociationSetEnd[] { this.end1, this.end2 })
     {
         if ((end.ResourceSet.Name == resourceSet.Name) && end.ResourceType.IsAssignableFrom(resourceType))
         {
             if ((end.ResourceProperty == null) && (resourceProperty == null))
             {
                 return(end);
             }
             if (((end.ResourceProperty != null) && (resourceProperty != null)) && (end.ResourceProperty.Name == resourceProperty.Name))
             {
                 return(end);
             }
         }
     }
     return(null);
 }
Example #22
0
 internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
 {
     foreach (ResourceAssociationSetEnd end in new ResourceAssociationSetEnd[] { this.end1, this.end2 })
     {
         if ((end.ResourceSet.Name == resourceSet.Name) && end.ResourceType.IsAssignableFrom(resourceType))
         {
             if ((end.ResourceProperty == null) && (resourceProperty == null))
             {
                 return end;
             }
             if (((end.ResourceProperty != null) && (resourceProperty != null)) && (end.ResourceProperty.Name == resourceProperty.Name))
             {
                 return end;
             }
         }
     }
     return null;
 }
Example #23
0
        /// <summary>
        /// Creates the wrapper from the given resource set.
        /// </summary>
        /// <param name="resourceSet">Resource set instance whose wrapper needs to get created.</param>
        /// <param name="resourceTypeValidator">Resource type validator.</param>
        /// <returns>Wrapper for the given resource set.</returns>
        public static ResourceSetWrapper CreateResourceSetWrapper(
            ResourceSet resourceSet,
            Func <ResourceType, ResourceType> resourceTypeValidator)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceSet.IsReadOnly, "The resourceSet must be read-only by now.");
            Debug.Assert(resourceTypeValidator != null, "resourceTypeValidator != null");

            ResourceSetWrapper resourceSetWrapper = new ResourceSetWrapper(resourceSet);

#if DEBUG
            resourceSetWrapper.isReadOnly = true;
#endif

            resourceSetWrapper.resourceType = resourceTypeValidator(resourceSet.ResourceType);
            return(resourceSetWrapper);
        }
Example #24
0
        /// <summary>
        /// Retrieve the end for the given resource set, type and property.
        /// </summary>
        /// <param name="resourceSet">resource set for the end</param>
        /// <param name="resourceType">resource type for the end</param>
        /// <param name="resourceProperty">resource property for the end</param>
        /// <returns>Resource association set end for the given parameters</returns>
        internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceType != null, "resourceType != null");

            foreach (ResourceAssociationSetEnd end in new[] { this.end1, this.end2 })
            {
                if (end.ResourceSet.Name == resourceSet.Name && end.ResourceType.IsAssignableFrom(resourceType))
                {
                    if ((end.ResourceProperty == null && resourceProperty == null) ||
                        (end.ResourceProperty != null && resourceProperty != null && end.ResourceProperty.Name == resourceProperty.Name))
                    {
                        return(end);
                    }
                }
            }

            return(null);
        }
Example #25
0
 internal static void FireNotification(IDataService service, object target, ResourceSetWrapper container, UpdateOperations action)
 {
     MethodInfo[] changeInterceptors = container.ChangeInterceptors;
     if (changeInterceptors != null)
     {
         object[] parameters = new object[] { target, action };
         for (int i = 0; i < changeInterceptors.Length; i++)
         {
             try
             {
                 changeInterceptors[i].Invoke(service.Instance, parameters);
             }
             catch (TargetInvocationException exception)
             {
                 ErrorHandler.HandleTargetInvocationException(exception);
                 throw;
             }
         }
     }
 }
Example #26
0
 private IEnumerable <ResourceType> GetReachableTypesFromSet(ResourceSetWrapper resourceSet, HashSet <ResourceType> visitedTypes)
 {
     if (this.HasDerivedTypes(resourceSet.ResourceType))
     {
         foreach (ResourceType iteratorVariable0 in this.GetDerivedTypes(resourceSet.ResourceType))
         {
             foreach (ResourceType iteratorVariable1 in this.GetResourceTypeAndReachableComplexTypes(iteratorVariable0, visitedTypes))
             {
                 yield return(iteratorVariable1);
             }
         }
     }
     for (ResourceType iteratorVariable2 = resourceSet.ResourceType; iteratorVariable2 != null; iteratorVariable2 = iteratorVariable2.BaseType)
     {
         foreach (ResourceType iteratorVariable3 in this.GetResourceTypeAndReachableComplexTypes(iteratorVariable2, visitedTypes))
         {
             yield return(iteratorVariable3);
         }
     }
 }
Example #27
0
 internal ResourceSetWrapper GetResultSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet)
 {
     if (this.resourceSet != null)
     {
         return this.resourceSet;
     }
     if (this.ResultSetPathExpression == null)
     {
         return null;
     }
     if (bindingSet == null)
     {
         throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_PathExpressionRequiresBindingSet(this.Name));
     }
     ResourceSetWrapper targetSet = this.ResultSetPathExpression.GetTargetSet(provider, bindingSet);
     if (targetSet == null)
     {
         throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_TargetSetFromPathExpressionNotNotVisible(this.Name, this.ResultSetPathExpression.PathExpression, bindingSet.Name));
     }
     return targetSet;
 }
Example #28
0
        internal ResourceSetWrapper GetResultSet(DataServiceProviderWrapper provider, ResourceSetWrapper bindingSet)
        {
            if (this.resourceSet != null)
            {
                return(this.resourceSet);
            }
            if (this.ResultSetPathExpression == null)
            {
                return(null);
            }
            if (bindingSet == null)
            {
                throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_PathExpressionRequiresBindingSet(this.Name));
            }
            ResourceSetWrapper targetSet = this.ResultSetPathExpression.GetTargetSet(provider, bindingSet);

            if (targetSet == null)
            {
                throw new InvalidOperationException(System.Data.Services.Strings.OperationWrapper_TargetSetFromPathExpressionNotNotVisible(this.Name, this.ResultSetPathExpression.PathExpression, bindingSet.Name));
            }
            return(targetSet);
        }
        /// <summary>
        /// Validates that <paramref name="resourceSet"/> is cached and read only.
        /// </summary>
        /// <param name="resourceSet">Resource set to be validated.</param>
        /// <returns>Validated resource set, null if the resource set is not supposed to be visible.</returns>
        internal ResourceSetWrapper ValidateResourceSet(ResourceSet resourceSet)
        {
            DebugUtils.CheckNoExternalCallers();

            ResourceSetWrapper resourceSetWrapper = null;

            if (resourceSet != null)
            {
                // For IDSP, we want to make sure the metadata object instance stays the same within
                // a request because we do reference comparisons.  Note the provider can return
                // different metadata instances within the same request. The Validate*() methods
                // will make sure to return the first cached instance.
                if (!this.resourceSetCache.TryGetValue(resourceSet.Name, out resourceSetWrapper))
                {
                    ValidateResourceSetReadOnly(resourceSet);
                    resourceSetWrapper = ResourceSetWrapper.CreateResourceSetWrapper(resourceSet, this.ValidateResourceType);
                    this.resourceSetCache[resourceSet.Name] = resourceSetWrapper;
                }
            }

            return(resourceSetWrapper);
        }
Example #30
0
        /// <summary>Creates new instance of node representing expanded navigation property.</summary>
        /// <param name="propertyName">The name of the property to project and expand.</param>
        /// <param name="property">The <see cref="ResourceProperty"/> for this property. Can only be null for the root node.</param>
        /// <param name="resourceSetWrapper">The resource set to which the expansion leads.</param>
        /// <param name="orderingInfo">The ordering info for this node. null means no ordering to be applied.</param>
        /// <param name="filter">The filter for this node. null means no filter to be applied.</param>
        /// <param name="skipCount">Number of results to skip. null means no results to be skipped.</param>
        /// <param name="takeCount">Maximum number of results to return. null means return all available results.</param>
        /// <param name="maxResultsExpected">Maximum number of expected results. Hint that the provider should return
        /// at least maxResultsExpected + 1 results (if available).</param>
        internal ExpandedProjectionNode(
            string propertyName,
            ResourceProperty property,
            ResourceSetWrapper resourceSetWrapper,
            OrderingInfo orderingInfo,
            Expression filter,
            int?skipCount,
            int?takeCount,
            int?maxResultsExpected)
            : base(propertyName, property)
        {
            Debug.Assert(resourceSetWrapper != null, "resourceSetWrapper != null");
            Debug.Assert(property != null || propertyName.Length == 0, "We don't support open navigation properties.");

            this.resourceSetWrapper = resourceSetWrapper;
            this.orderingInfo       = orderingInfo;
            this.filter             = filter;
            this.skipCount          = skipCount;
            this.takeCount          = takeCount;
            this.maxResultsExpected = maxResultsExpected;
            this.nodes = new List <ProjectionNode>();
        }
Example #31
0
        public ResourceAssociationSet GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            ResourceAssociationSet set;

            resourceType = GetDeclaringTypeForProperty(resourceType, resourceProperty, null);
            string key = string.Concat(new object[] { resourceSet.Name, '_', resourceType.FullName, '_', resourceProperty.Name });

            if (!this.ResourceAssociationSetCache.TryGetValue(key, out set))
            {
                set = this.metadataProvider.GetResourceAssociationSet(resourceSet.ResourceSet, resourceType, resourceProperty);
                if (set != null)
                {
                    ResourceAssociationSetEnd end     = set.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);
                    ResourceAssociationSetEnd end2    = set.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);
                    ResourceSetWrapper        wrapper = this.ValidateResourceSet(end2.ResourceSet);
                    if (wrapper == null)
                    {
                        set = null;
                    }
                    else
                    {
                        ResourceType     type     = this.ValidateResourceType(end2.ResourceType);
                        ResourceProperty property = null;
                        if (end2.ResourceProperty != null)
                        {
                            ResourcePropertyKind stream = ResourcePropertyKind.Stream;
                            property = type.TryResolvePropertyName(end2.ResourceProperty.Name, stream);
                        }
                        resourceType = this.ValidateResourceType(end.ResourceType);
                        if ((((end.ResourceSet != resourceSet.ResourceSet) || (end.ResourceType != resourceType)) || ((end.ResourceProperty != resourceProperty) || (end2.ResourceSet != wrapper.ResourceSet))) || ((end2.ResourceType != type) || (end2.ResourceProperty != property)))
                        {
                            set = new ResourceAssociationSet(set.Name, new ResourceAssociationSetEnd(resourceSet.ResourceSet, resourceType, resourceProperty), new ResourceAssociationSetEnd(wrapper.ResourceSet, type, property));
                        }
                    }
                }
                this.ResourceAssociationSetCache.Add(key, set);
            }
            return(set);
        }
        /// <summary>Creates new root node for the projection tree.</summary>
        /// <param name="resourceSetWrapper">The resource set of the root level of the query.</param>
        /// <param name="orderingInfo">The ordering info for this node. null means no ordering to be applied.</param>
        /// <param name="filter">The filter for this node. null means no filter to be applied.</param>
        /// <param name="skipCount">Number of results to skip. null means no results to be skipped.</param>
        /// <param name="takeCount">Maximum number of results to return. null means return all available results.</param>
        /// <param name="maxResultsExpected">Maximum number of expected results. Hint that the provider should return
        /// at least maxResultsExpected + 1 results (if available).</param>
        /// <param name="expandPaths">The list of expanded paths.</param>
        /// <param name="baseResourceType">The resource type for all entities in this query.</param>
        internal RootProjectionNode(
            ResourceSetWrapper resourceSetWrapper,
            OrderingInfo orderingInfo,
            Expression filter,
            int? skipCount,
            int? takeCount,
            int? maxResultsExpected,
            List<ExpandSegmentCollection> expandPaths,
            ResourceType baseResourceType)
            : base(
                String.Empty,
                null,
                resourceSetWrapper,
                orderingInfo,
                filter,
                skipCount,
                takeCount,
                maxResultsExpected)
        {
            Debug.Assert(baseResourceType != null, "baseResourceType != null");

            this.expandPaths = expandPaths;
            this.baseResourceType = baseResourceType;
        }
Example #33
0
        /// <summary>Creates new root node for the projection tree.</summary>
        /// <param name="resourceSetWrapper">The resource set of the root level of the query.</param>
        /// <param name="orderingInfo">The ordering info for this node. null means no ordering to be applied.</param>
        /// <param name="filter">The filter for this node. null means no filter to be applied.</param>
        /// <param name="skipCount">Number of results to skip. null means no results to be skipped.</param>
        /// <param name="takeCount">Maximum number of results to return. null means return all available results.</param>
        /// <param name="maxResultsExpected">Maximum number of expected results. Hint that the provider should return
        /// at least maxResultsExpected + 1 results (if available).</param>
        /// <param name="expandPaths">The list of expanded paths.</param>
        /// <param name="baseResourceType">The resource type for all entities in this query.</param>
        internal RootProjectionNode(
            ResourceSetWrapper resourceSetWrapper,
            OrderingInfo orderingInfo,
            Expression filter,
            int?skipCount,
            int?takeCount,
            int?maxResultsExpected,
            List <ExpandSegmentCollection> expandPaths,
            ResourceType baseResourceType)
            : base(
                String.Empty,
                null,
                resourceSetWrapper,
                orderingInfo,
                filter,
                skipCount,
                takeCount,
                maxResultsExpected)
        {
            Debug.Assert(baseResourceType != null, "baseResourceType != null");

            this.expandPaths      = expandPaths;
            this.baseResourceType = baseResourceType;
        }
        /// <summary>
        /// Apply the given configuration to the resource set.
        /// </summary>
        /// <param name="configuration">data service configuration instance.</param>
        /// <param name="provider">data service provider wrapper instance for accessibility validation.</param>
        public void ApplyConfiguration(DataServiceConfiguration configuration, DataServiceProviderWrapper provider)
        {
#if DEBUG
            Debug.Assert(!this.isReadOnly, "Can only apply the configuration once.");
#endif
            this.rights = configuration.GetServiceOperationRights(this.serviceOperation);

            if ((this.rights & ~ServiceOperationRights.OverrideEntitySetRights) != ServiceOperationRights.None)
            {
                if (this.serviceOperation.ResourceSet != null)
                {
                    // If the result type is an entity type, we need to make sure its entity set is visible.
                    // If the entity set is hidden, we need to make sure that we throw an exception.
                    this.resourceSet = provider.TryResolveResourceSet(this.serviceOperation.ResourceSet.Name);
                    if (this.resourceSet == null)
                    {
                        throw new InvalidOperationException(Strings.BaseServiceProvider_ServiceOperationTypeHasNoContainer(this.serviceOperation.Name, this.serviceOperation.ResultType.FullName));
                    }
                }
            }
#if DEBUG
            this.isReadOnly = true;
#endif
        }
Example #35
0
        private void PairUpNavigationProperty(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty navigationProperty)
        {
            string key = string.Concat(new object[] { resourceSet.Name, '_', resourceType.FullName, '_', navigationProperty.Name });

            if (!this.associationSetByKeyCache.ContainsKey(key))
            {
                ResourceAssociationSet resourceAssociationSet = this.MetadataProvider.GetResourceAssociationSet(resourceSet, resourceType, navigationProperty);
                if (resourceAssociationSet != null)
                {
                    string str2;
                    string str3;
                    ResourceAssociationSetEnd end = resourceAssociationSet.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, navigationProperty);
                    if (end.ResourceProperty != null)
                    {
                        ResourceAssociationSet set2 = this.MetadataProvider.GetResourceAssociationSet(this.MetadataProvider.ValidateResourceSet(end.ResourceSet), end.ResourceType, end.ResourceProperty);
                        if ((set2 == null) || (resourceAssociationSet.Name != set2.Name))
                        {
                            throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_BidirectionalAssociationMustReturnSameResourceAssociationSetFromBothEnd);
                        }
                    }
                    if (end.ResourceProperty != null)
                    {
                        str2 = string.Concat(new object[] { end.ResourceSet.Name, '_', end.ResourceType.FullName, '_', end.ResourceProperty.Name });
                    }
                    else
                    {
                        str2 = string.Concat(new object[] { end.ResourceSet.Name, "_Null_", resourceType.FullName, '_', navigationProperty.Name });
                    }
                    if (this.associationSetByKeyCache.TryGetValue(str2, out str3))
                    {
                        throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_MultipleAssociationSetsForTheSameAssociationTypeMustNotReferToSameEndSets(str3, resourceAssociationSet.Name, end.ResourceSet.Name));
                    }
                    ResourceAssociationType resourceAssociationType = resourceAssociationSet.ResourceAssociationType;
                    this.PairUpNavigationPropertyWithResourceAssociationSet(entityContainer, resourceAssociationSet, resourceAssociationType, resourceType, navigationProperty);
                    this.associationSetByKeyCache.Add(str2, resourceAssociationSet.Name);
                    this.associationSetByKeyCache.Add(key, resourceAssociationSet.Name);
                }
            }
        }
Example #36
0
 private void PairUpNavigationProperty(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty navigationProperty)
 {
     string key = string.Concat(new object[] { resourceSet.Name, '_', resourceType.FullName, '_', navigationProperty.Name });
     if (!this.associationSetByKeyCache.ContainsKey(key))
     {
         ResourceAssociationSet resourceAssociationSet = this.MetadataProvider.GetResourceAssociationSet(resourceSet, resourceType, navigationProperty);
         if (resourceAssociationSet != null)
         {
             string str2;
             string str3;
             ResourceAssociationSetEnd end = resourceAssociationSet.GetRelatedResourceAssociationSetEnd(resourceSet, resourceType, navigationProperty);
             if (end.ResourceProperty != null)
             {
                 ResourceAssociationSet set2 = this.MetadataProvider.GetResourceAssociationSet(this.MetadataProvider.ValidateResourceSet(end.ResourceSet), end.ResourceType, end.ResourceProperty);
                 if ((set2 == null) || (resourceAssociationSet.Name != set2.Name))
                 {
                     throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_BidirectionalAssociationMustReturnSameResourceAssociationSetFromBothEnd);
                 }
             }
             if (end.ResourceProperty != null)
             {
                 str2 = string.Concat(new object[] { end.ResourceSet.Name, '_', end.ResourceType.FullName, '_', end.ResourceProperty.Name });
             }
             else
             {
                 str2 = string.Concat(new object[] { end.ResourceSet.Name, "_Null_", resourceType.FullName, '_', navigationProperty.Name });
             }
             if (this.associationSetByKeyCache.TryGetValue(str2, out str3))
             {
                 throw new InvalidOperationException(System.Data.Services.Strings.ResourceAssociationSet_MultipleAssociationSetsForTheSameAssociationTypeMustNotReferToSameEndSets(str3, resourceAssociationSet.Name, end.ResourceSet.Name));
             }
             ResourceAssociationType resourceAssociationType = resourceAssociationSet.ResourceAssociationType;
             this.PairUpNavigationPropertyWithResourceAssociationSet(entityContainer, resourceAssociationSet, resourceAssociationType, resourceType, navigationProperty);
             this.associationSetByKeyCache.Add(str2, resourceAssociationSet.Name);
             this.associationSetByKeyCache.Add(key, resourceAssociationSet.Name);
         }
     }
 }
        /// <summary>Parses a lambda expression.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="setForIt">Resource set for "it" contextual variable.</param>
        /// <param name="typeForIt">Type for "it" contextual variable.</param>
        /// <param name="queryElementType">Actual (clr) element type for the sequence</param>
        /// <param name="expression">Expression to parse.</param>
        /// <returns>The parsed expression.</returns>
        private static LambdaExpression ParseLambdaForWhere(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, Type queryElementType, string expression)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(typeForIt != null, "typeForIt != null");
            Debug.Assert(typeForIt.ResourceTypeKind != ResourceTypeKind.EntityType || setForIt != null, "setForIt cannot be null if typeForIt is an entity type.");
            Debug.Assert(queryElementType != null, "queryElementType != null");
            Debug.Assert(expression != null, "expression != null");
            Debug.Assert(typeForIt.InstanceType == queryElementType, "typeForIt.InstanceType == queryElementType");

            ParameterExpression parameterForIt = Expression.Parameter(queryElementType, "it");
            ExpressionParser parser = new ExpressionParser(service, setForIt, typeForIt, parameterForIt, expression);
            return Expression.Lambda(parser.ParseWhere(), parameterForIt);
        }
Example #38
0
 private void PairUpNavigationPropertiesForEntitySet(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet)
 {
     foreach (ResourceType type in this.MetadataProvider.GetDerivedTypes(resourceSet.ResourceType))
     {
         this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type);
     }
     for (ResourceType type2 = resourceSet.ResourceType; type2 != null; type2 = type2.BaseType)
     {
         this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type2);
     }
 }
Example #39
0
        private void PairUpNavigationPropertiesForEntitySetAndType(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType)
        {
            IEnumerable <ResourceProperty> allVisiblePropertiesDeclaredInThisType = this.GetAllVisiblePropertiesDeclaredInThisType(resourceType);

            if (allVisiblePropertiesDeclaredInThisType != null)
            {
                foreach (ResourceProperty property in from p in allVisiblePropertiesDeclaredInThisType
                         where p.TypeKind == ResourceTypeKind.EntityType
                         select p)
                {
                    this.PairUpNavigationProperty(entityContainer, resourceSet, resourceType, property);
                }
            }
        }
Example #40
0
 private void PairUpNavigationPropertiesForEntitySet(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet)
 {
     foreach (ResourceType type in this.MetadataProvider.GetDerivedTypes(resourceSet.ResourceType))
     {
         this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type);
     }
     for (ResourceType type2 = resourceSet.ResourceType; type2 != null; type2 = type2.BaseType)
     {
         this.PairUpNavigationPropertiesForEntitySetAndType(entityContainer, resourceSet, type2);
     }
 }
        /// <summary>
        /// Populate the properties of the given resource
        /// </summary>
        /// <param name="jsonObject">JsonObjectRecords containing property name and values</param>
        /// <param name="resource">instance of the resource whose properties needs to be populated</param>
        /// <param name="parentResourceSet">resource set where <paramref name="resource"/> belongs to</param>
        /// <param name="parentResourceType">resource type whose properties needs to be populated</param>
        /// <returns>true if any properties were set; false otherwise.</returns>
        private bool PopulateProperties(JsonReader.JsonObjectRecords jsonObject, object resource, ResourceSetWrapper parentResourceSet, ResourceType parentResourceType)
        {
            // Update all the properties specified in the payload. 
            // Don't touch the properties which are not specified. Its upto the provider to interpret
            // the meaning of things which are not specified
            bool changed = false;
            List<ResourceProperty> navProperties = new List<ResourceProperty>();
            List<object> navPropertyValues = new List<object>();

            #region Handle Non-Nav Properties
            foreach (string propertyName in jsonObject.OrderedKeys)
            {
                // Ignore the metadata property
                if (propertyName == XmlConstants.JsonMetadataString)
                {
                    continue;
                }

                // Check if the property exists and try and set the value
                ResourceProperty resourceProperty = parentResourceType.TryResolvePropertyName(propertyName);
                if (resourceProperty == null && parentResourceType.IsOpenType == false)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(propertyName, parentResourceType.FullName));
                }

                // Get the property value, set it appropriately, and mark the object as changed.
                object propertyValue = jsonObject.Entries[propertyName];
                bool existingRelationship;

                // If its a open property
                if (resourceProperty == null)
                {
                    this.HandleOpenTypeProperties(resource, propertyName, propertyValue);
                    changed = true;
                }
                else if (resourceProperty.TypeKind == ResourceTypeKind.ComplexType)
                {
                    SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, null, true /* singleResult */);
                    segmentInfo.TargetKind = RequestTargetKind.ComplexObject;
                    propertyValue = this.CreateObject(propertyValue, segmentInfo, false /*topLevel*/, out existingRelationship);
                    SetPropertyValue(resourceProperty, resource, propertyValue, ContentFormat.Json, this.Service);
                    changed = true;
                }
                else if (resourceProperty.TypeKind == ResourceTypeKind.Primitive)
                {
                    // Ignoring the value of key properties in PUT payload
                    if (!this.Update || !resourceProperty.IsOfKind(ResourcePropertyKind.Key))
                    {
                        SetPropertyValue(resourceProperty, resource, propertyValue, ContentFormat.Json, this.Service);
                    }

                    changed = true;
                }
                else
                {
                    Debug.Assert(ResourceTypeKind.EntityType == resourceProperty.TypeKind, "only expecting nav properties");

                    if (IsDeferredElement(propertyValue))
                    {
                        // Skip the deferred element
                        continue;
                    }
                    else
                    {
                        navProperties.Add(resourceProperty);
                        navPropertyValues.Add(propertyValue);
                    }
                }
            }

            #endregion Non-Navigation Properties

            #region Handle Navigation Properties

            Debug.Assert(navProperties.Count == navPropertyValues.Count, "nav properties and nav property values count must be the same");
            
            // The reason why we need to do this is so that we can gaurantee that the nav properties are getting set at the end.
            // This is nice, since we already do this in the atom deserializer. Hence its consistent. Second, we wanted to
            // give a gaurantee that when FK and nav properties are specified in the payload, nav properties always win.
            for (int i = 0; i < navProperties.Count; i++)
            {
                this.HandleNavigationProperty(parentResourceSet, parentResourceType, resource, navProperties[i], navPropertyValues[i]);
                changed = true;
            }            
            
            #endregion Handle Navigation Properties

            return changed;
        }
        /// <summary>
        /// Retrieve the related end for the given resource set, type and property.
        /// </summary>
        /// <param name="resourceSet">resource set for the source end</param>
        /// <param name="resourceType">resource type for the source end</param>
        /// <param name="resourceProperty">resource property for the source end</param>
        /// <returns>Related resource association set end for the given parameters</returns>
        internal ResourceAssociationSetEnd GetRelatedResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceType != null, "resourceType != null");

            ResourceAssociationSetEnd thisEnd = this.GetResourceAssociationSetEnd(resourceSet, resourceType, resourceProperty);

            if (thisEnd != null)
            {
                return thisEnd == this.End1 ? this.End2 : this.End1;
            }

            return null;
        }
        /// <summary>
        /// Retrieve the end for the given resource set, type and property.
        /// </summary>
        /// <param name="resourceSet">resource set for the end</param>
        /// <param name="resourceType">resource type for the end</param>
        /// <param name="resourceProperty">resource property for the end</param>
        /// <returns>Resource association set end for the given parameters</returns>
        internal ResourceAssociationSetEnd GetResourceAssociationSetEnd(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
        {
            Debug.Assert(resourceSet != null, "resourceSet != null");
            Debug.Assert(resourceType != null, "resourceType != null");

            foreach (ResourceAssociationSetEnd end in new[] { this.end1, this.end2 })
            {
                if (end.ResourceSet.Name == resourceSet.Name && end.ResourceType.IsAssignableFrom(resourceType))
                {
                    if ((end.ResourceProperty == null && resourceProperty == null) ||
                        (end.ResourceProperty != null && resourceProperty != null && end.ResourceProperty.Name == resourceProperty.Name))
                    {
                        return end;
                    }
                }
            }

            return null;
        }
Example #44
0
        /// <summary>Creates new instance of node representing expanded navigation property.</summary>
        /// <param name="propertyName">The name of the property to project and expand.</param>
        /// <param name="property">The <see cref="ResourceProperty"/> for this property. Can only be null for the root node.</param>
        /// <param name="resourceSetWrapper">The resource set to which the expansion leads.</param>
        /// <param name="orderingInfo">The ordering info for this node. null means no ordering to be applied.</param>
        /// <param name="filter">The filter for this node. null means no filter to be applied.</param>
        /// <param name="skipCount">Number of results to skip. null means no results to be skipped.</param>
        /// <param name="takeCount">Maximum number of results to return. null means return all available results.</param>
        /// <param name="maxResultsExpected">Maximum number of expected results. Hint that the provider should return
        /// at least maxResultsExpected + 1 results (if available).</param>
        internal ExpandedProjectionNode(
            string propertyName,
            ResourceProperty property,
            ResourceSetWrapper resourceSetWrapper,
            OrderingInfo orderingInfo,
            Expression filter,
            int? skipCount,
            int? takeCount,
            int? maxResultsExpected)
            : base(propertyName, property)
        {
            Debug.Assert(resourceSetWrapper != null, "resourceSetWrapper != null");
            Debug.Assert(property != null || propertyName.Length == 0, "We don't support open navigation properties.");

            this.resourceSetWrapper = resourceSetWrapper;
            this.orderingInfo = orderingInfo;
            this.filter = filter;
            this.skipCount = skipCount;
            this.takeCount = takeCount;
            this.maxResultsExpected = maxResultsExpected;
            this.nodes = new List<ProjectionNode>();
        }
        /// <summary>
        /// Handle the contents under the link element
        /// </summary>
        /// <param name="link">syndication link element</param>
        /// <param name="parentResource">parent resource which contains the link.</param>
        /// <param name="parentResourceSet">resource set of the parent resource</param>
        /// <param name="parentResourceType">resource type of the parent resource</param>
        /// <param name="property">property representing the link.</param>
        /// <param name="typeParameterValue">type parameter value as specified in the type attribute.</param>
        /// <param name="propertyName">name of the property that this link represents.</param>
        /// <returns>returns whether there are child elements under link element.</returns>
        private LinkContent HandleLinkContent(
            SyndicationLink link,
            object parentResource,
            ResourceSetWrapper parentResourceSet,
            ResourceType parentResourceType,
            ResourceProperty property,
            string typeParameterValue,
            string propertyName)
        {
            Debug.Assert(parentResource != null, "parent resource cannot be null");
            Debug.Assert(property != null, "property != null");
            Debug.Assert(link != null, "link != null");

            LinkContent linkContent = LinkContent.NoInlineElementSpecified;
            foreach (var e in link.ElementExtensions)
            {
                // link can contain other elements apart from the inline elements.
                if (e.OuterNamespace != XmlConstants.DataWebMetadataNamespace ||
                    e.OuterName != XmlConstants.AtomInlineElementName)
                {
                    continue;
                }

                // Deep payload cannot be specified for update
                if (this.Update)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_DeepUpdateNotSupported);
                }

                linkContent = LinkContent.EmptyInlineElementSpecified;
                using (XmlReader linkReader = e.GetReader())
                {
                    while (linkReader.Read())
                    {
                        if (linkReader.NodeType == XmlNodeType.Element)
                        {
                            string elementName = linkReader.LocalName;
                            string namespaceUri = linkReader.NamespaceURI;
                            if (namespaceUri != XmlConstants.AtomNamespace)
                            {
                                throw DataServiceException.CreateBadRequestError(
                                    Strings.BadRequest_InlineElementMustContainValidElement(
                                        elementName,
                                        XmlConstants.AtomInlineElementName,
                                        XmlConstants.AtomFeedElementName,
                                        XmlConstants.AtomEntryElementName));
                            }

                            ResourceSetWrapper targetSet = this.Service.Provider.GetContainer(parentResourceSet, parentResourceType, property);
                            if (targetSet == null)
                            {
                                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(propertyName, parentResourceType.FullName));
                            }

                            // FeatureVersion needs to be 2.0 if any of the property in the types contained in the resource set has KeepInContent false
                            this.RequestDescription.UpdateAndCheckEpmFeatureVersion(targetSet, this.Service);

                            linkContent = LinkContent.InlineElementContainsData;
                            if (elementName == XmlConstants.AtomEntryElementName)
                            {
                                if (property.Kind != ResourcePropertyKind.ResourceReference)
                                {
                                    throw DataServiceException.CreateBadRequestError(Strings.Syndication_EntryElementForReferenceProperties(e.OuterName, propertyName));
                                }

                                // Make sure if the media type is specified. If its specified, it should better be link
                                SyndicationItem propertyItem;
                                propertyItem = ReadSyndicationItem(this.factory.CreateSyndicationItemFormatter(), linkReader);

                                SegmentInfo propertySegment = CreateSegment(property, propertyName, targetSet, true /* singleResult */);
                                Debug.Assert(propertySegment.TargetKind != RequestTargetKind.OpenProperty, "Open navigation properties are not supported on OpenTypes.");

                                object propertyValue = this.CreateObject(propertySegment, false /* topLevel */, propertyItem);
                                this.Updatable.SetReference(parentResource, propertyName, propertyValue);
                            }
                            else if (elementName == XmlConstants.AtomFeedElementName)
                            {
                                    if (property.Kind != ResourcePropertyKind.ResourceSetReference)
                                    {
                                        throw DataServiceException.CreateBadRequestError(Strings.Syndication_FeedElementForCollections(e.OuterName, propertyName));
                                    }

                                SyndicationFeed propertyFeed;
                                propertyFeed = ReadSyndicationFeed(this.factory.CreateSyndicationFeedFormatter(), linkReader);

                                SegmentInfo propertySegment = CreateSegment(property, propertyName, targetSet, false /* singleResult */);
                                Debug.Assert(propertySegment.TargetKind != RequestTargetKind.OpenProperty, "Open navigation properties are not supported on OpenTypes.");

                                foreach (SyndicationItem item in propertyFeed.Items)
                                {
                                    object propertyValue = this.CreateObject(propertySegment, false /* topLevel */, item);
                                    if (propertyValue == null)
                                    {
                                        if (propertySegment.ProjectedProperty != null &&
                                            propertySegment.ProjectedProperty.Kind == ResourcePropertyKind.ResourceSetReference)
                                        {
                                            throw DataServiceException.CreateBadRequestError(
                                                Strings.BadRequest_CannotSetCollectionsToNull(propertyName));
                                        }
                                    }

                                    Debug.Assert(
                                            propertySegment.TargetSource == RequestTargetSource.Property &&
                                            propertySegment.TargetKind == RequestTargetKind.Resource &&
                                            propertySegment.SingleResult == false,
                                            "Must be navigation set property.");

                                    this.Updatable.AddReferenceToCollection(parentResource, propertyName, propertyValue);
                                }
                            }
                            else
                            {
                                throw DataServiceException.CreateBadRequestError(
                                    Strings.BadRequest_InlineElementMustContainValidElement(
                                        elementName,
                                        XmlConstants.AtomInlineElementName,
                                        XmlConstants.AtomFeedElementName,
                                        XmlConstants.AtomEntryElementName));
                            }
                        }
                    }
                }
            }

            return linkContent;
        }
        /// <summary>Applies the information from a link to the specified resource.</summary>
        /// <param name='link'>LinkDescriptor with information to apply.</param>
        /// <param name="resourceSet">Set for the target resource.</param>
        /// <param name='resourceType'>Type for the target resource.</param>
        /// <param name='resource'>Target resource to which information will be applied.</param>
        /// <param name="propertyName">Name of the property that this link represents.</param>
        private void ApplyLink(SyndicationLink link, ResourceSetWrapper resourceSet, ResourceType resourceType, object resource, string propertyName)
        {
            Debug.Assert(link != null, "link != null");
            Debug.Assert(resourceType != null, "resourceType != null");
            Debug.Assert(resource != null, "resource != null");

            ResourceProperty property = resourceType.TryResolvePropertyName(propertyName);
            if (property == null)
            {
                // Open navigation properties are not supported on OpenTypes
                throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName));
            }

            if (property.TypeKind != ResourceTypeKind.EntityType)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidNavigationPropertyName(propertyName, resourceType.FullName));
            }

            string typeParameterValue = ValidateTypeParameterForNonOpenTypeProperties(link.MediaType, property);
            LinkContent linkContent = this.HandleLinkContent(link, resource, resourceSet, resourceType, property, typeParameterValue, propertyName);

            #region Handle bind/unbind operation
            // If the href was specified empty or an empty inline element was specified, then we will set the 
            // reference to null - this helps in overrriding if there was a default non-value for this property
            // else if only link element was specified, and then href points to a single result, then we will
            // perform a bind operation
            if ((linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && String.IsNullOrEmpty(link.Uri.OriginalString)) ||
                linkContent == LinkContent.EmptyInlineElementSpecified)
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();
                if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(propertyName));
                }

                // For open properties, we will assume that this is a reference property and set it to null
                this.Updatable.SetReference(resource, propertyName, null);
            }
            else if (linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && !String.IsNullOrEmpty(link.Uri.OriginalString))
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();

                // If the link points to a reference navigation property, then update the link
                Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(link.Uri.OriginalString, this.Service.OperationContext);
                RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service);
                if (!description.IsSingleResult)
                {
                    if (property != null && property.Kind == ResourcePropertyKind.ResourceReference)
                    {
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequest_LinkHrefMustReferToSingleResource(propertyName));
                    }

                    return;
                }

                // no need to check for null. For collection properties, they can never be null and that
                // check has been added below. For reference properties, if they are null, it means unbind
                // and hence no need to check for null.
                // Get the resource
                object targetResource = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (property.Kind == ResourcePropertyKind.ResourceReference)
                {
                    this.Updatable.SetReference(resource, propertyName, targetResource);
                }
                else
                {
                    WebUtil.CheckResourceExists(targetResource != null, description.LastSegmentInfo.Identifier);
                    this.Updatable.AddReferenceToCollection(resource, propertyName, targetResource);
                }
            }
            #endregion Handle bind/unbind operation
        }
Example #47
0
        /// <summary>
        /// Tracks the specified <paramref name="target"/> for a 
        /// given <paramref name="action "/> on the <paramref name="container"/>.
        /// </summary>
        /// <param name="target">Object to be tracked.</param>
        /// <param name="container">Container in which object is changed.</param>
        /// <param name="action">Action affecting target.</param>
        /// <remarks>
        /// If <paramref name="target"/> was already being tracked, the actions are OR'ed together.
        /// </remarks>
        internal void TrackAction(object target, ResourceSetWrapper container, UpdateOperations action)
        {
            AssertActionValues(target, container);
            Debug.Assert(this.items != null, "this.items != null - otherwise FireNotification has already been called");

            // If it won't be necessary for us to fire authorizatio methods,
            // skip tracking altogether.
            if (container.ChangeInterceptors == null)
            {
                return;
            }

            // Get the container for which the change has taken place.
            Dictionary<object, UpdateOperations> changedItems;
            if (!this.items.TryGetValue(container, out changedItems))
            {
                // In order to mantain backwards compatibility, we are going to use default comparer for V1
                // providers. However, for V2 providers we are going to do reference equality comparisons.
                if (this.service.Provider.IsV1Provider)
                {
                    changedItems = new Dictionary<object, UpdateOperations>(EqualityComparer<object>.Default);
                }
                else
                {
                    changedItems = new Dictionary<object, UpdateOperations>(ReferenceEqualityComparer<object>.Instance);
                }

                this.items.Add(container, changedItems);
            }

            UpdateOperations existingAction;
            if (changedItems.TryGetValue(target, out existingAction))
            {
                if ((action | existingAction) != existingAction)
                {
                    changedItems[target] = action | existingAction;
                }
            }
            else
            {
                changedItems.Add(target, action);
            }
        }
Example #48
0
 internal RootProjectionNode(ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int? skipCount, int? takeCount, int? maxResultsExpected, List<ExpandSegmentCollection> expandPaths, System.Data.Services.Providers.ResourceType baseResourceType) : base(string.Empty, null, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected)
 {
     this.expandPaths = expandPaths;
     this.baseResourceType = baseResourceType;
 }
Example #49
0
 internal void SetETagValues(object resourceCookie, ResourceSetWrapper container)
 {
     DataServiceHostWrapper host = this.service.OperationContext.Host;
     object obj2 = this.ResolveResource(resourceCookie);
     ResourceType nonPrimitiveResourceType = WebUtil.GetNonPrimitiveResourceType(this.service.Provider, obj2);
     IList<ResourceProperty> eTagProperties = this.service.Provider.GetETagProperties(container.Name, nonPrimitiveResourceType);
     if (eTagProperties.Count == 0)
     {
         if (!string.IsNullOrEmpty(host.RequestIfMatch))
         {
             throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.Serializer_NoETagPropertiesForType);
         }
     }
     else
     {
         IDataServiceUpdateProvider updateProvider = this.updateProvider as IDataServiceUpdateProvider;
         if (updateProvider != null)
         {
             IEnumerable<KeyValuePair<string, object>> emptyKeyValuePairStringObject;
             bool? checkForEquality = null;
             if (!string.IsNullOrEmpty(host.RequestIfMatch))
             {
                 checkForEquality = true;
                 emptyKeyValuePairStringObject = ParseETagValue(eTagProperties, host.RequestIfMatch);
             }
             else
             {
                 emptyKeyValuePairStringObject = WebUtil.EmptyKeyValuePairStringObject;
             }
             updateProvider.SetConcurrencyValues(resourceCookie, checkForEquality, emptyKeyValuePairStringObject);
         }
         else
         {
             if (string.IsNullOrEmpty(host.RequestIfMatch))
             {
                 throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.DataService_CannotPerformOperationWithoutETag(nonPrimitiveResourceType.FullName));
             }
             if ((host.RequestIfMatch != "*") && (WebUtil.GetETagValue(resourceCookie, nonPrimitiveResourceType, eTagProperties, this.service, false) != host.RequestIfMatch))
             {
                 throw DataServiceException.CreatePreConditionFailedError(System.Data.Services.Strings.Serializer_ETagValueDoesNotMatch);
             }
         }
     }
 }
            /// <summary>Initializes a new <see cref="ExpressionParser"/>.</summary>
            /// <param name="service">Service with data and configuration.</param>
            /// <param name="setForIt">Resource set for "it" contextual variable</param>
            /// <param name="typeForIt">Type for "it" contextual variable</param>
            /// <param name="parameterForIt">Parameters for the current "it" context.</param>
            /// <param name="expression">Expression to parse.</param>
            internal ExpressionParser(IDataService service, ResourceSetWrapper setForIt, ResourceType typeForIt, ParameterExpression parameterForIt, string expression)
            {
                Debug.Assert(service != null, "service != null");

                // For Open types, we could potentially have typeForIt parameter set to null value,
                // However, we have decided not support ordering on Open properties which also implies
                // that we can not have entity typed properties on Open types 
                Debug.Assert(typeForIt != null, "typeForIt != null");

                Debug.Assert(expression != null, "expression != null");
                Debug.Assert(parameterForIt != null, "parameterForIt != null");

                this.service = service;
                this.provider = service.Provider;
                this.nullPropagationRequired = this.provider.NullPropagationRequired;
                this.literals = new Dictionary<Expression, string>(ReferenceEqualityComparer<Expression>.Instance);
                this.setForIt = setForIt;
                this.typeForIt = typeForIt;
                this.it = parameterForIt;
                this.lexer = new ExpressionLexer(expression);
            }
        /// <summary>
        /// Handle the navigation properties as specified in the payload
        /// </summary>
        /// <param name="parentResourceSet">resource set where <paramref name="resource"/> belongs to</param>        
        /// <param name="parentResourceType">resource type declaring the navigation property.</param>
        /// <param name="resource">instance of the resource declaring the navigation property.</param>
        /// <param name="resourceProperty">resource property containing metadata about the navigation property.</param>
        /// <param name="propertyValue">value of the navigation property.</param>
        private void HandleNavigationProperty(ResourceSetWrapper parentResourceSet, ResourceType parentResourceType, object resource, ResourceProperty resourceProperty, object propertyValue)
        {
            Debug.Assert(parentResourceSet != null, "parentResourceSet != null");
            Debug.Assert(parentResourceType != null, "parentResourceType != null");
            Debug.Assert(resourceProperty != null && resourceProperty.TypeKind == ResourceTypeKind.EntityType, "its must be a nav property");

            bool existingRelationship;
            Deserializer.CheckForBindingInPutOperations(this.Service.OperationContext.Host.AstoriaHttpVerb);

            ResourceSetWrapper propertySet = this.Service.Provider.GetContainer(parentResourceSet, parentResourceType, resourceProperty);
            if (propertySet == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidPropertyNameSpecified(resourceProperty.Name, parentResourceType.FullName));
            }

            // FeatureVersion needs to be 2.0 if any of the property in the types contained in the resource set has KeepInContent false
            this.RequestDescription.UpdateAndCheckEpmFeatureVersion(propertySet, this.Service);

            if (resourceProperty.Kind == ResourcePropertyKind.ResourceReference)
            {
                SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */);
                segmentInfo.TargetKind = RequestTargetKind.Resource;

                // For navigation property, allow both inserts and binding in this case
                propertyValue = this.CreateObject(propertyValue, segmentInfo, false /*topLevel*/, out existingRelationship);
                if (!existingRelationship)
                {
                    this.Updatable.SetReference(resource, resourceProperty.Name, propertyValue);
                }
            }
            else if (resourceProperty.Kind == ResourcePropertyKind.ResourceSetReference)
            {
                if (propertyValue == null)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(resourceProperty.Name));
                }

                ArrayList resourceCollection = GetArrayList(propertyValue);
                SegmentInfo segmentInfo = CreateSegment(resourceProperty, resourceProperty.Name, propertySet, true /* singleResult */);
                foreach (object resourceObject in resourceCollection)
                {
                    object resourceInstance = this.CreateObject(resourceObject, segmentInfo, false /*topLevel*/, out existingRelationship);
                    Debug.Assert(resourceInstance != null, "resourceInstance != null");

                    if (!existingRelationship)
                    {
                        this.Updatable.AddReferenceToCollection(resource, resourceProperty.Name, resourceInstance);
                    }
                }
            }
        }
 /// <summary>Constructor.</summary>
 /// <param name="resourceType">Type for current segment.</param>
 /// <param name="resourceSet">Set for current segment.</param>
 /// <param name="isCollection">Does current segment property refer to a collection.</param>
 public SegmentTypeInfo(ResourceType resourceType, ResourceSetWrapper resourceSet, bool isCollection)
 {
     this.ResourceType = resourceType;
     this.ResourceSet = resourceSet;
     this.IsCollection = isCollection;
 }
Example #53
0
 private void PairUpNavigationPropertiesForEntitySetAndType(MetadataProviderEdmEntityContainer entityContainer, ResourceSetWrapper resourceSet, ResourceType resourceType)
 {
     IEnumerable<ResourceProperty> allVisiblePropertiesDeclaredInThisType = this.GetAllVisiblePropertiesDeclaredInThisType(resourceType);
     if (allVisiblePropertiesDeclaredInThisType != null)
     {
         foreach (ResourceProperty property in from p in allVisiblePropertiesDeclaredInThisType
             where p.TypeKind == ResourceTypeKind.EntityType
             select p)
         {
             this.PairUpNavigationProperty(entityContainer, resourceSet, resourceType, property);
         }
     }
 }
Example #54
0
 private static void AssertActionValues(object target, ResourceSetWrapper container)
 {
     Debug.Assert(target != null, "target != null");
     Debug.Assert(container != null, "container != null");
 }
 /// <summary>Initializes a new <see cref="ExpandSegment"/> instance.</summary>
 /// <param name="name">Segment name.</param>
 /// <param name="filter">Filter expression for segment, possibly null.</param>
 /// <param name="maxResultsExpected">
 /// Expand providers may choose to return at most MaxResultsExpected + 1 elements to allow the
 /// data service to detect a failure to meet this constraint.
 /// </param>
 /// <param name="container">Container to which the segment belongs; possibly null.</param>
 /// <param name="expandedProperty">Property expanded by this expand segment</param>
 /// <param name="orderingInfo">Collection of ordering information for this segment, used for paging</param>
 internal ExpandSegment(
     string name, 
     Expression filter, 
     int maxResultsExpected, 
     ResourceSetWrapper container, 
     ResourceProperty expandedProperty, 
     OrderingInfo orderingInfo)
 {
     WebUtil.CheckArgumentNull(name, "name");
     CheckFilterType(filter);
     this.name = name;
     this.filter = filter;
     this.container = container;
     this.maxResultsExpected = maxResultsExpected;
     this.expandedProperty = expandedProperty;
     this.orderingInfo = orderingInfo;
 }
Example #56
0
 internal RootProjectionNode(ResourceSetWrapper resourceSetWrapper, OrderingInfo orderingInfo, Expression filter, int?skipCount, int?takeCount, int?maxResultsExpected, List <ExpandSegmentCollection> expandPaths, System.Data.Services.Providers.ResourceType baseResourceType) : base(string.Empty, null, null, resourceSetWrapper, orderingInfo, filter, skipCount, takeCount, maxResultsExpected)
 {
     this.expandPaths      = expandPaths;
     this.baseResourceType = baseResourceType;
 }