コード例 #1
0
 /// <summary>
 /// Reads feed from stream
 /// </summary>
 /// <param name="readStream"></param>
 /// <param name="edmModel"></param>
 /// <param name="entitySet"></param>
 /// <param name="expectedBaseEntityType"></param>
 protected void ReadFeed(Stream readStream, IEdmModel edmModel, IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     readStream.Seek(0, SeekOrigin.Begin);
     using (var messageReader = ODataMessageHelper.CreateMessageReader(readStream, edmModel))
     {
         ODataReader feedReader = messageReader.CreateODataFeedReader(entitySet, expectedBaseEntityType);
         while (feedReader.Read()) { }
     }
 }
コード例 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EntitySetPathSegment" /> class.
        /// </summary>
        /// <param name="entitySet">The entity set being accessed.</param>
        public EntitySetPathSegment(IEdmEntitySetBase entitySet)
        {
            if (entitySet == null)
            {
                throw Error.ArgumentNull("entitySet");
            }

            EntitySetBase = entitySet;
            EntitySetName = entitySet.Name;
        }
コード例 #3
0
        /// <summary>
        /// Writes an OData Feed with number <see cref="numberOfEntries"/> of entries <see cref="entry"/>
        /// </summary>
        /// <param name="writeStream"></param>
        /// <param name="edmModel"></param>
        /// <param name="numberOfEntries"></param>
        /// <param name="entry"></param>
        /// <param name="entitySet"></param>
        /// <returns>The payload size</returns>
        protected Int64 WriteFeed(Stream writeStream, IEdmModel edmModel, long numberOfEntries, ODataEntry entry, IEdmEntitySetBase entitySet)
        {
            using (var messageWriter = ODataMessageHelper.CreateMessageWriter(writeStream, edmModel))
            {
                ODataWriter writer = messageWriter.CreateODataFeedWriter(entitySet);
                writer.WriteStart(new ODataFeed { Id = new Uri("http://www.odata.org/Perf.svc") });
                for (long i = 0; i < numberOfEntries; ++i)
                {
                    writer.WriteStart(entry);
                    writer.WriteEnd();
                }
                writer.WriteEnd();
                writer.Flush();
            }

            return writeStream.Length; // return payload size
        }
コード例 #4
0
        /// <summary>
        /// Build a segment representing a call to an operation - action, function, or service operation.
        /// </summary>
        /// <param name="operation">A single operation import that this segment will represent.</param>
        /// <param name="entitySet">The <see cref="IEdmEntitySetBase"/> containing the entities that this function returns.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the input operation is null.</exception>
        public OperationSegment(IEdmOperation operation, IEdmEntitySetBase entitySet)
            : this()
        {
            ExceptionUtils.CheckArgumentNotNull(operation, "operation");
            this.operations            = new ReadOnlyCollection <IEdmOperation>(new[] { operation });
            this.entitySet             = entitySet;
            this.computedReturnEdmType = operation.ReturnType != null ? operation.ReturnType.Definition : null;
            this.EnsureTypeAndSetAreCompatable();

            if (this.computedReturnEdmType != null)
            {
                this.TargetEdmNavigationSource = entitySet;
                this.TargetEdmType             = computedReturnEdmType;
                this.TargetKind   = this.TargetEdmType.GetTargetKindFromType();
                this.SingleResult = computedReturnEdmType.TypeKind != EdmTypeKind.Collection;
            }
            else
            {
                this.TargetEdmNavigationSource = null;
                this.TargetEdmType             = null;
                this.TargetKind = RequestTargetKind.VoidOperation;
            }
        }
コード例 #5
0
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteFeed(ODataWriter writer, IEnumerable entries, IEdmEntitySetBase entitySet, ODataVersion targetVersion, SelectExpandClause selectExpandClause, long?count, Uri deltaLink, Uri nextPageLink, Dictionary <string, string> incomingHeaders = null)
        {
            var feed = new ODataFeed
            {
                Id           = new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name),
                DeltaLink    = deltaLink,
                NextPageLink = nextPageLink
            };

            if (count.HasValue)
            {
                feed.Count = count;
            }

            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, targetVersion, selectExpandClause, incomingHeaders);
            }

            writer.WriteEnd();
        }
コード例 #6
0
        private static string GetWriterOutput(ODataResource entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType, IServiceProvider container)
        {
            var outputStream = new MemoryStream();
            IODataResponseMessage message = new InMemoryMessage
            {
                Stream    = outputStream,
                Container = container
            };

            message.SetHeader("Content-Type", "application/json");
            var settings = new ODataMessageWriterSettings();

            settings.SetServiceDocumentUri(new Uri("http://test"));

            using (var messageWriter = new ODataMessageWriter(message, settings, model))
            {
                var writer = messageWriter.CreateODataResourceWriter(entitySet, entityType);
                writer.WriteStart(entry);
                writer.WriteEnd();
                outputStream.Seek(0, SeekOrigin.Begin);
                return(new StreamReader(outputStream).ReadToEnd());
            }
        }
コード例 #7
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            IEdmTypeReference resourceSetType = writeContext.GetEdmType(graph, type);

            Contract.Assert(resourceSetType != null);

            IEdmStructuredTypeReference resourceType = GetResourceType(resourceSetType);
            ODataWriter writer = messageWriter.CreateODataResourceSetWriter(entitySet, resourceType.StructuredDefinition());

            WriteObjectInline(graph, resourceSetType, writer, writeContext);
        }
コード例 #8
0
        private static List <MemberExpression> GetKeyExpressions(IEdmEntitySetBase entitySet, OePropertyAccessor[] accessors)
        {
            var propertyExpressions = new List <MemberExpression>();

            foreach (IEdmStructuralProperty key in entitySet.EntityType().Key())
            {
                bool found = false;
                foreach (OePropertyAccessor accessor in accessors)
                {
                    if (String.CompareOrdinal(accessor.EdmProperty.Name, key.Name) == 0)
                    {
                        propertyExpressions.Add(accessor.PropertyExpression);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    throw new InvalidOperationException("Key property " + key.Name + " not found in accessors");
                }
            }
            return(propertyExpressions);
        }
コード例 #9
0
        /// <summary>
        /// Writes the entity collection results to the response message.
        /// </summary>
        /// <param name="graph">The entity collection results.</param>
        /// <param name="type">The type of the entities.</param>
        /// <param name="messageWriter">The message writer.</param>
        /// <param name="writeContext">The writing context.</param>
        public override void WriteObject(
            object graph,
            Type type,
            ODataMessageWriter messageWriter,
            ODataSerializerContext writeContext)
        {
            Ensure.NotNull(messageWriter, "messageWriter");
            Ensure.NotNull(writeContext, "writeContext");

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                throw new SerializationException(Resources.EntitySetMissingForSerialization);
            }

            EntityCollectionResult collectionResult = (EntityCollectionResult)graph;
            IEdmTypeReference      feedType         = collectionResult.EdmType;

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataWriter             writer     = messageWriter.CreateODataFeedWriter(entitySet, entityType.EntityDefinition());

            this.WriteObjectInline(collectionResult.Query, feedType, writer, writeContext);
        }
コード例 #10
0
        public BatchReferenceSegment(string contentId, IEdmType edmType, IEdmEntitySetBase entitySet)
        {
            ExceptionUtils.CheckArgumentNotNull(edmType, "resultingType");
            ExceptionUtils.CheckArgumentNotNull(contentId, "contentId");
            if (!ODataPathParser.ContentIdRegex.IsMatch(contentId))
            {
                throw new ODataException(ODataErrorStrings.BatchReferenceSegment_InvalidContentID(contentId));
            }

            this.edmType   = edmType;
            this.entitySet = entitySet;
            this.contentId = contentId;

            this.Identifier                = this.ContentId;
            this.TargetEdmType             = edmType;
            this.TargetEdmNavigationSource = this.EntitySet;
            this.SingleResult              = true;
            this.TargetKind                = RequestTargetKind.Resource;

            if (entitySet != null)
            {
                UriParserErrorHelper.ThrowIfTypesUnrelated(edmType, entitySet.EntityType(), "BatchReferenceSegments");
            }
        }
コード例 #11
0
        /// <summary>
        /// Creates an EntityCollectionFunctionCallNode to represent a operation call that returns a collection of entities.
        /// </summary>
        /// <param name="name">The name of this operation.</param>
        /// <param name="functions">the list of functions that this node should represent.</param>
        /// <param name="parameters">the list of parameters to this operation</param>
        /// <param name="returnedCollectionTypeReference">the type the entity collection returned by this operation. The element type must be an entity type.</param>
        /// <param name="navigationSource">the set containing entities returned by this operation</param>
        /// <param name="source">the semantically bound parent of this EntityCollectionFunctionCallNode.</param>
        /// <exception cref="System.ArgumentNullException">Throws if the provided name is null.</exception>
        /// <exception cref="System.ArgumentNullException">Throws if the provided collection type reference is null.</exception>
        /// <exception cref="System.ArgumentException">Throws if the element type of the provided collection type reference is not an entity type.</exception>
        /// <exception cref="System.ArgumentNullException">Throws if the input operation imports is null</exception>
        public EntityCollectionFunctionCallNode(string name, IEnumerable <IEdmFunction> functions, IEnumerable <QueryNode> parameters, IEdmCollectionTypeReference returnedCollectionTypeReference, IEdmEntitySetBase navigationSource, QueryNode source)
        {
            ExceptionUtils.CheckArgumentNotNull(name, "name");
            ExceptionUtils.CheckArgumentNotNull(returnedCollectionTypeReference, "returnedCollectionTypeReference");
            this.name       = name;
            this.functions  = new ReadOnlyCollection <IEdmFunction>(functions == null ? new List <IEdmFunction>() : functions.ToList());
            this.parameters = new ReadOnlyCollection <QueryNode>(parameters == null ? new List <QueryNode>() : parameters.ToList());
            this.returnedCollectionTypeReference = returnedCollectionTypeReference;
            this.navigationSource = navigationSource;

            this.entityTypeReference = returnedCollectionTypeReference.ElementType().AsEntityOrNull();
            if (this.entityTypeReference == null)
            {
                throw new ArgumentException(ODataErrorStrings.Nodes_EntityCollectionFunctionCallNode_ItemTypeMustBeAnEntity);
            }

            this.source = source;
        }
コード例 #12
0
 /// <summary>
 /// Creates a segment representing a call to an operation - action, function or service operation.
 /// </summary>
 /// <param name="operationImports">The list of possible FunctionImport overloads for this segment.</param>
 /// <param name="entitySet">The <see cref="IEdmEntitySetBase"/> containing the entities that this function returns.</param>
 /// <param name="parameters">The list of parameters supplied to this segment.</param>
 public OperationImportSegment(IEnumerable <IEdmOperationImport> operationImports, IEdmEntitySetBase entitySet, IEnumerable <OperationSegmentParameter> parameters)
     : this(operationImports, entitySet)
 {
     this.parameters = new ReadOnlyCollection <OperationSegmentParameter>(parameters == null ? new List <OperationSegmentParameter>() : parameters.ToList());
 }
コード例 #13
0
        /// <summary>
        /// Creates an <see cref="ODataReader" /> to read a feed.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read entities for.</param>
        /// <param name="expectedBaseEntityType">The expected base type for the entries in the feed.</param>
        /// <returns>The newly created <see cref="ODataReader"/>.</returns>
        public override ODataReader CreateFeedReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
        {
            this.AssertSynchronous();

            return this.CreateFeedReaderImplementation(entitySet, expectedBaseEntityType);
        }
コード例 #14
0
ファイル: CreateHandler.cs プロジェクト: larsenjo/odata.net
        private object ProcessPostBody(IODataRequestMessage message, IEdmEntitySetBase entitySet, object queryResults)
        {
            object lastNewInstance = null;

            using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings(), this.DataSource.Model))
            {
                var odataItemStack = new Stack<ODataItem>();
                var entryReader = messageReader.CreateODataEntryReader(entitySet, entitySet.EntityType());
                var currentTargetEntitySet = entitySet;

                while (entryReader.Read())
                {
                    switch (entryReader.State)
                    {
                        case ODataReaderState.EntryStart:
                            odataItemStack.Push(entryReader.Item);
                            break;

                        case ODataReaderState.EntryEnd:
                            {
                                var entry = (ODataEntry)entryReader.Item;

                                // TODO: the code here will be changed to handle following scenarios
                                //       1: non-contained navigation, e.g. People(1)/Friends
                                //       2. general entity set, e.g. People
                                //       3. contained navigation, e.g. People(1)/Trips
                                //       4. upsert, e.g. People(1)/Friends(2)
                                var newInstance = this.DataSource.UpdateProvider.Create(entry.TypeName, queryResults);

                                foreach (var property in entry.Properties)
                                {
                                    if (Utility.IsETagProperty(newInstance, property.Name)) continue;
                                    this.DataSource.UpdateProvider.Update(newInstance, property.Name, property.Value);
                                }

                                var boundNavPropAnnotation = odataItemStack.Pop().GetAnnotation<BoundNavigationPropertyAnnotation>();
                                if (boundNavPropAnnotation != null)
                                {
                                    foreach (var boundProperty in boundNavPropAnnotation.BoundProperties)
                                    {
                                        var isCollection = boundProperty.Item1.IsCollection == true;
                                        var propertyValue = isCollection ? boundProperty.Item2 : ((IEnumerable<object>)boundProperty.Item2).Single();
                                        this.DataSource.UpdateProvider.Update(newInstance, boundProperty.Item1.Name, propertyValue);
                                    }
                                }

                                var parentItem = odataItemStack.Count > 0 ? odataItemStack.Peek() : null;
                                if (parentItem != null)
                                {
                                    // This new entry belongs to a navigation property and/or feed -
                                    // propagate it up the tree for further processing.
                                    AddChildInstanceAnnotation(parentItem, newInstance);
                                }

                                lastNewInstance = newInstance;
                            }

                            break;

                        case ODataReaderState.FeedStart:
                            odataItemStack.Push(entryReader.Item);
                            break;

                        case ODataReaderState.FeedEnd:
                            {
                                var childAnnotation = odataItemStack.Pop().GetAnnotation<ChildInstanceAnnotation>();

                                var parentNavLink = odataItemStack.Count > 0 ? odataItemStack.Peek() as ODataNavigationLink : null;
                                if (parentNavLink != null)
                                {
                                    // This feed belongs to a navigation property -
                                    // propagate it up the tree for further processing.
                                    AddChildInstanceAnnotation(parentNavLink, childAnnotation.ChildInstances ?? new object[0]);
                                }
                            }

                            break;

                        case ODataReaderState.NavigationLinkStart:
                            {
                                odataItemStack.Push(entryReader.Item);
                                var navigationLink = (ODataNavigationLink)entryReader.Item;
                                var navigationProperty = (IEdmNavigationProperty)currentTargetEntitySet.EntityType().FindProperty(navigationLink.Name);

                                // Current model implementation doesn't expose associations otherwise this would be much cleaner.
                                currentTargetEntitySet = this.DataSource.Model.EntityContainer.EntitySets().Single(s => s.EntityType() == navigationProperty.Type.Definition);
                            }

                            break;

                        case ODataReaderState.NavigationLinkEnd:
                            {
                                var navigationLink = (ODataNavigationLink)entryReader.Item;
                                var childAnnotation = odataItemStack.Pop().GetAnnotation<ChildInstanceAnnotation>();
                                if (childAnnotation != null)
                                {
                                    // Propagate the bound entries to the parent entry.
                                    AddBoundNavigationPropertyAnnotation(odataItemStack.Peek(), navigationLink, childAnnotation.ChildInstances);
                                }
                            }

                            break;
                    }
                }
            }

            return lastNewInstance;
        }
コード例 #15
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataDeltaReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataDeltaReader"/>.</returns>
 internal virtual Task <ODataDeltaReader> CreateDeltaReaderAsync(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #16
0
        private async Task WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
                                            ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(resourceSetType != null);

            IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType);
            ODataResourceSet            resourceSet = CreateResourceSet(enumerable, resourceSetType.AsCollection(), writeContext);

            if (resourceSet == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo
                {
                    IsFromCollection = true,
                    NavigationSourceEntityTypeName = elementType.FullName(),
                    NavigationSourceKind           = EdmNavigationSourceKind.UnknownEntitySet,
                    NavigationSourceName           = null
                });
            }

            ODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(writeContext.Context, elementType);

            if (resourceSerializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataOutputFormatter).Name));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = resourceSet.NextPageLink;

            resourceSet.CountOnly    = enumerable is ICountOptionCollection && (enumerable as ITruncatedCollection).OnlyCount;
            resourceSet.NextPageLink = null;

            writer.WriteStart(resourceSet);

            foreach (object item in enumerable)
            {
                if (item == null || item is NullEdmComplexObject)
                {
                    if (elementType.IsEntity())
                    {
                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    // for null complex element, it can be serialized as "null" in the collection.
                    writer.WriteStart(resource: null);
                    writer.WriteEnd();
                }
                else
                {
                    await resourceSerializer.WriteObjectInlineAsync(item, elementType, writer, writeContext);
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(resourceSet),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(resourceSet) but is instead set later on that resourceSet
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.

            if (nextPageLink != null)
            {
                resourceSet.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
コード例 #17
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataDeltaWriter" /> to write a delta response.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to write entities for.</param>
        /// <param name="entityType">The entity type for the entries in the resource set to be written (or null if the entity set base type should be used).</param>
        /// <returns>A running task for the created writer.</returns>
        /// <remarks>The write must flush the output when it's finished (inside the last Write call).</remarks>
        internal override Task <ODataDeltaWriter> CreateODataDeltaWriterAsync(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
        {
            this.AssertAsynchronous();

            return(TaskUtils.GetTaskForSynchronousOperation(() => this.CreateODataDeltaWriterImplementation(entitySet, entityType)));
        }
コード例 #18
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
 /// <returns>The newly created <see cref="ODataDeltaReader"/>.</returns>
 internal virtual ODataDeltaReader CreateDeltaReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #19
0
        private string GetWriterOutputForContentTypeAndKnobValue(ODataEntry entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType)
        {
            MemoryStream outputStream = new MemoryStream();
            IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream };
            message.SetHeader("Content-Type", "application/json;odata.metadata=full");
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                AutoComputePayloadMetadataInJson = true,
            };
            settings.SetServiceDocumentUri(new Uri("http://example.com"));

            string output;
            using (var messageWriter = new ODataMessageWriter(message, settings, model))
            {
                ODataWriter writer = messageWriter.CreateODataEntryWriter(entitySet, entityType);
                writer.WriteStart(entry);
                writer.WriteEnd();
                outputStream.Seek(0, SeekOrigin.Begin);
                output = new StreamReader(outputStream).ReadToEnd();
            }

            return output;
        }
コード例 #20
0
 public override ODataReader CreateFeedReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return new ODataAvroReader(this, true);
 }
コード例 #21
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base type for the entries in the feed.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateFeedReaderImplementation(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return new ODataAtomReader(this, entitySet, expectedBaseEntityType, true);
 }
コード例 #22
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaReader" /> to read a resource set.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataDeltaReader CreateDeltaReaderImplementation(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return(new ODataJsonLightDeltaReader(this, entitySet, expectedBaseEntityType));
 }
コード例 #23
0
        /// <summary>
        /// Gets the target entity set for the given operation import.
        /// </summary>
        /// <param name="operationImport">The operation import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the operation import or null if it could not be determined.</returns>
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperationImport operationImport, IEdmEntitySetBase sourceEntitySet, IEdmModel model)
        {
            IEdmEntitySet targetEntitySet;

            if (operationImport.TryGetStaticEntitySet(out targetEntitySet))
            {
                return(targetEntitySet);
            }

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

            if (operationImport.Operation.IsBound && operationImport.Operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                IEnumerable <IEdmNavigationProperty> path;
                IEnumerable <EdmError> errors;

                if (operationImport.TryGetRelativeEntitySetPath(model, out parameter, out path, out errors))
                {
                    IEdmEntitySetBase currentEntitySet = sourceEntitySet;
                    foreach (var navigation in path)
                    {
                        currentEntitySet = currentEntitySet.FindNavigationTarget(navigation) as IEdmEntitySetBase;
                        if (currentEntitySet == null || currentEntitySet is IEdmUnknownEntitySet)
                        {
                            return(currentEntitySet);
                        }
                    }

                    return(currentEntitySet);
                }
                else
                {
                    bool foundSyntaxError = !errors.Any(e => e.ErrorCode == EdmErrorCode.InvalidPathFirstPathParameterNotMatchingFirstParameterName);
                    ExceptionUtil.ThrowSyntaxErrorIfNotValid(foundSyntaxError);
                }
            }

            return(null);
        }
コード例 #24
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataReader" /> to read a resource set in a Uri operation parameter.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
 public virtual Task <ODataReader> CreateUriParameterResourceSetReaderAsync(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.ResourceSet);
 }
コード例 #25
0
        /// <summary>
        /// Creates an <see cref="ODataReader" /> to read a feed.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read entities for.</param>
        /// <param name="expectedBaseEntityType">The expected base type for the entries in the feed.</param>
        /// <returns>The newly created <see cref="ODataReader"/>.</returns>
        internal override ODataReader CreateFeedReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
        {
            this.AssertSynchronous();

            return(this.CreateFeedReaderImplementation(entitySet, expectedBaseEntityType));
        }
コード例 #26
0
        public static ResourceRangeVariableReferenceNode CreateRangeVariableReferenceNode(IEdmEntitySetBase entitySet, String name = null)
        {
            var entityTypeRef = (IEdmEntityTypeReference)((IEdmCollectionType)entitySet.Type).ElementType;
            var rangeVariable = new ResourceRangeVariable(name ?? "$it", entityTypeRef, entitySet);

            return(new ResourceRangeVariableReferenceNode(name ?? "$it", rangeVariable));
        }
コード例 #27
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the feed.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateFeedReaderImplementation(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return(new ODataJsonLightReader(this, entitySet, expectedBaseEntityType, true, null /*listener*/));
 }
コード例 #28
0
 /// <summary>
 /// Asynchronously creates an <see cref="ODataReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the feed.</param>
 /// <returns>Task which when completed returns the newly created <see cref="ODataReader"/>.</returns>
 public virtual Task<ODataReader> CreateFeedReaderAsync(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #29
0
        private string GetWriterOutputForContentTypeAndKnobValue(
            string contentType,
            bool autoComputePayloadMetadataInJson,
            ODataItem[] itemsToWrite,
            EdmModel edmModel,
            IEdmEntitySetBase edmEntitySet,
            EdmEntityType edmEntityType,
            string selectClause = null,
            string expandClause = null,
            string resourcePath = null,
            bool enableFullValidation = true)
        {
            MemoryStream outputStream = new MemoryStream();
            IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream };
            message.SetHeader("Content-Type", contentType);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                AutoComputePayloadMetadataInJson = autoComputePayloadMetadataInJson,
                EnableFullValidation = enableFullValidation
            };

            var result = new ODataQueryOptionParser(edmModel, edmEntityType, edmEntitySet, new Dictionary<string, string> { { "$expand", expandClause }, { "$select", selectClause } }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot = new Uri("http://example.org/odata.svc"),
                SelectAndExpand = result
            };

            if (resourcePath != null)
            {
                Uri requestUri = new Uri("http://example.org/odata.svc/" + resourcePath);
                odataUri.RequestUri = requestUri;
                odataUri.Path = new ODataUriParser(edmModel, new Uri("http://example.org/odata.svc/"), requestUri).ParsePath();
            }

            settings.ODataUri = odataUri;

            string output;
            using (var messageWriter = new ODataMessageWriter(message, settings, edmModel))
            {
                int currentIdx = 0;

                if (itemsToWrite[currentIdx] is ODataFeed)
                {
                    ODataWriter writer = messageWriter.CreateODataFeedWriter(edmEntitySet, edmEntityType);
                    this.WriteFeed(writer, itemsToWrite, ref currentIdx);
                }
                else if (itemsToWrite[currentIdx] is ODataEntry)
                {
                    ODataWriter writer = messageWriter.CreateODataEntryWriter(edmEntitySet, edmEntityType);
                    this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                }
                else
                {
                    Assert.True(false, "Top level item to write must be entry or feed.");
                }

                currentIdx.Should().Be(itemsToWrite.Length, "Invalid list of items to write.");

                outputStream.Seek(0, SeekOrigin.Begin);
                output = new StreamReader(outputStream).ReadToEnd();
            }

            return output;
        }
コード例 #30
0
        private static KeySegment BuildKeySegment(IEdmEntityType entityType, IEdmEntitySetBase entitySet, object target)
        {
            if (entityType == null)
            {
                throw new ArgumentNullException("entityType");
            }

            if (entitySet == null)
            {
                throw new ArgumentNullException("entitySet");
            }

            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            KeySegment keySegment = new KeySegment(
                entityType.Key().Select(
                    (key) =>
                    {
                        var keyValue = target.GetType().GetProperty(key.Name).GetValue(target, null);
                        return new KeyValuePair<string, object>(key.Name, keyValue);
                    }),
                entityType,
                entitySet);

            return keySegment;
        }
コード例 #31
0
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entityType">The type of the entity in the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteFeed(ODataWriter writer, IEdmEntityType entityType, IEnumerable entries, IEdmEntitySetBase entitySet, ODataVersion targetVersion, SelectExpandClause selectExpandClause, long? count, Uri deltaLink, Uri nextPageLink, Dictionary<string, string> incomingHeaders = null)
        {
            var feed = new ODataFeed
            {
                Id = entitySet == null ? null : new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name),
                DeltaLink = deltaLink,
                NextPageLink = nextPageLink
            };

            if (entitySet == null)
            {
                feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
                {
                    NavigationSourceEntityTypeName = entityType.FullTypeName(),
                    NavigationSourceName = null,
                    NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet,
                    IsFromCollection = true
                });
            }

            if (count.HasValue)
            {
                feed.Count = count;
            }

            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, targetVersion, selectExpandClause, incomingHeaders);
            }

            writer.WriteEnd();
        }
コード例 #32
0
ファイル: ODataFeedSerializer.cs プロジェクト: ldcdev/WebApi
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
                               ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            IEdmEntityTypeReference elementType = GetEntityType(feedType);
            ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext);

            if (feed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo
                {
                    IsFromCollection = true,
                    NavigationSourceEntityTypeName = elementType.FullName(),
                    NavigationSourceKind           = EdmNavigationSourceKind.UnknownEntitySet,
                    NavigationSourceName           = null
                });
            }

            ODataEdmTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType);

            if (entrySerializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = feed.NextPageLink;

            feed.NextPageLink = null;

            writer.WriteStart(feed);

            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                entrySerializer.WriteObjectInline(entry, elementType, writer, writeContext);
            }

            // Subtle and suprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.

            if (nextPageLink != null)
            {
                feed.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
コード例 #33
0
        /// <summary>
        /// Gets the target entity set for the given operation import.
        /// </summary>
        /// <param name="operationImport">The operation import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the operation import or null if it could not be determined.</returns>
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperationImport operationImport, IEdmEntitySetBase sourceEntitySet, IEdmModel model)
        {
            IEdmEntitySet targetEntitySet;
            if (operationImport.TryGetStaticEntitySet(out targetEntitySet))
            {
                return targetEntitySet;
            }

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

            if (operationImport.Operation.IsBound && operationImport.Operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                IEnumerable<IEdmNavigationProperty> path;
                IEnumerable<EdmError> errors;

                if (operationImport.TryGetRelativeEntitySetPath(model, out parameter, out path, out errors))
                {
                    IEdmEntitySetBase currentEntitySet = sourceEntitySet;
                    foreach (var navigation in path)
                    {
                        currentEntitySet = currentEntitySet.FindNavigationTarget(navigation) as IEdmEntitySetBase;
                        if (currentEntitySet == null || currentEntitySet is IEdmUnknownEntitySet)
                        {
                            return currentEntitySet;
                        }
                    }

                    return currentEntitySet;
                }
                else
                {
                    if (errors.Any(
                        e => e.ErrorCode == EdmErrorCode.InvalidPathFirstPathParameterNotMatchingFirstParameterName))
                    {
                        throw ExceptionUtil.CreateSyntaxError();
                    }
                }
            }

            return null;
        }
コード例 #34
0
        /// <summary>
        /// Writes an OData Feed with number <see cref="numberOfEntries"/> of entries <see cref="entry"/>
        /// </summary>
        /// <param name="writeStream"></param>
        /// <param name="edmModel"></param>
        /// <param name="numberOfEntries"></param>
        /// <param name="entry"></param>
        /// <param name="entitySet"></param>
        /// <returns>The payload size</returns>
        protected Int64 WriteFeed(Stream writeStream, IEdmModel edmModel, long numberOfEntries, ODataEntry entry, IEdmEntitySetBase entitySet)
        {
            using (var messageWriter = ODataMessageHelper.CreateMessageWriter(writeStream, edmModel))
            {
                ODataWriter writer = messageWriter.CreateODataFeedWriter(entitySet);
                writer.WriteStart(new ODataFeed {
                    Id = new Uri("http://www.odata.org/Perf.svc")
                });
                for (long i = 0; i < numberOfEntries; ++i)
                {
                    writer.WriteStart(entry);
                    writer.WriteEnd();
                }
                writer.WriteEnd();
                writer.Flush();
            }

            return(writeStream.Length); // return payload size
        }
コード例 #35
0
        /// <summary>
        /// Creates an <see cref="ODataDeltaReader" /> to read a feed.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read entities for.</param>
        /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
        /// <returns>The newly created <see cref="ODataDeltaReader"/>.</returns>
        internal override ODataDeltaReader CreateDeltaReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
        {
            this.AssertSynchronous();
            this.VerifyCanCreateODataReader(entitySet, expectedBaseEntityType);

            return this.CreateDeltaReaderImplementation(entitySet, expectedBaseEntityType);
        }
コード例 #36
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base type for the entries in the feed.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateFeedReaderImplementation(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return(new ODataAtomReader(this, entitySet, expectedBaseEntityType, true));
 }
コード例 #37
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataDeltaReader" /> to read a feed.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to read entities for.</param>
        /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
        /// <returns>Task which when completed returns the newly created <see cref="ODataDeltaReader"/>.</returns>
        internal override Task<ODataDeltaReader> CreateDeltaReaderAsync(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
        {
            this.AssertAsynchronous();
            this.VerifyCanCreateODataReader(entitySet, expectedBaseEntityType);

            // Note that the reading is actually synchronous since we buffer the entire input when getting the stream from the message.
            return TaskUtils.GetTaskForSynchronousOperation(() => this.CreateDeltaReaderImplementation(entitySet, expectedBaseEntityType));
        }
コード例 #38
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataDeltaReader CreateDeltaReaderImplementation(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return new ODataJsonLightDeltaReader(this, entitySet, expectedBaseEntityType);
 }
コード例 #39
0
 public override ODataWriter CreateODataFeedWriter(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     return new ODataAvroWriter(this, value => this.AvroWriter.Write(value), this.AvroWriter.UpdateSchema(null, entityType, true), true);
 }
コード例 #40
0
        public static                          OePropertyAccessor[] CreateFromType(Type clrType, IEdmEntitySetBase entitySet)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Object));
            UnaryExpression     instance  = Expression.Convert(parameter, clrType);
            var propertyAccessors         = new List <OePropertyAccessor>();

            foreach (IEdmStructuralProperty edmProperty in entitySet.EntityType().StructuralProperties())
            {
                MemberExpression expression = Expression.Property(instance, clrType.GetProperty(edmProperty.Name));
                propertyAccessors.Add(CreatePropertyAccessor(edmProperty, expression, parameter, false));
            }
            return(propertyAccessors.ToArray());
        }
コード例 #41
0
ファイル: ResponseWriter.cs プロジェクト: vebin/odata.net
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteFeed(ODataWriter writer, IEnumerable entries, IEdmEntitySetBase entitySet, ODataVersion targetVersion, SelectExpandClause selectExpandClause, long? count, Uri deltaLink, Uri nextPageLink, Dictionary<string, string> incomingHeaders = null)
        {
            var feed = new ODataFeed
            {
                Id = new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name),
                DeltaLink = deltaLink,
                NextPageLink = nextPageLink
            };

            if (count.HasValue)
            {
                feed.Count = count;
            }

            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, targetVersion, selectExpandClause, incomingHeaders);
            }

            writer.WriteEnd();
        }
コード例 #42
0
ファイル: OperationHandler.cs プロジェクト: zhonli/odata.net
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            object result;

            if (this.HttpMethod == HttpMethod.GET)
            {
                // we cannot invoke same action request multiple times, so only Functions are allowed to do the server-driven paging
                this.QueryContext.InitializeServerDrivenPaging(this.PreferenceContext);

                result = this.ProcessFunction();

                if (this.PreferenceContext.MaxPageSize.HasValue)
                {
                    responseMessage.AddPreferenceApplied(string.Format("{0}={1}", ServiceConstants.Preference_MaxPageSize, this.QueryContext.appliedPageSize.Value));
                }
            }
            else
            {
                // TODO: currently ETag feature does not support action operation

                result = this.ProcessAction(requestMessage);
            }

            if (result == null)
            {
                // Protocol 9.1.4 Response Code 204 No Content
                // A request returns 204 No Content if the requested resource has the null value,
                // or if the service applies a return=minimal preference. In this case, the response body MUST be empty.
                ResponseWriter.WriteEmptyResponse(responseMessage);

                return;
            }

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                if (this.QueryContext.Target.TypeKind == EdmTypeKind.None ||
                    this.QueryContext.Target.TypeKind == EdmTypeKind.EntityReference ||
                    this.QueryContext.Target.ElementTypeKind == EdmTypeKind.EntityReference)
                {
                    throw Utility.BuildException(HttpStatusCode.NotImplemented, "Unsupported return type in operation.", null);
                }
                else if (this.QueryContext.Target.TypeKind == EdmTypeKind.Entity || this.QueryContext.Target.ElementTypeKind == EdmTypeKind.Entity ||
                         this.QueryContext.Target.TypeKind == EdmTypeKind.Complex || this.QueryContext.Target.ElementTypeKind == EdmTypeKind.Complex)
                {
                    ODataWriter resultWriter;

                    IEdmNavigationSource entitySource = this.QueryContext.OperationResultSource ?? this.QueryContext.Target.NavigationSource;

                    if (this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                    {
                        IEdmEntitySetBase entitySet = (IEdmEntitySetBase)entitySource;

                        resultWriter = messageWriter.CreateODataResourceSetWriter(entitySet, (IEdmStructuredType)this.QueryContext.Target.ElementType);
                        ResponseWriter.WriteFeed(resultWriter, (IEdmStructuredType)this.QueryContext.Target.ElementType, result as IEnumerable, entitySet, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.QueryContext.TotalCount, null, this.QueryContext.NextLink, this.RequestHeaders);
                    }
                    else
                    {
                        if (this.HttpMethod == HttpMethod.GET)
                        {
                            var currentETag = Utility.GetETagValue(result);
                            // if the current entity has ETag field
                            if (currentETag != null)
                            {
                                string requestETag;
                                if (Utility.TryGetIfNoneMatch(this.RequestHeaders, out requestETag) && (requestETag == ServiceConstants.ETagValueAsterisk || requestETag == currentETag))
                                {
                                    ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.NotModified);
                                    return;
                                }

                                responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                            }
                        }

                        resultWriter = messageWriter.CreateODataResourceWriter(entitySource, (IEdmStructuredType)this.QueryContext.Target.Type);
                        ResponseWriter.WriteEntry(resultWriter, result, entitySource, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.RequestHeaders);
                    }
                }
                else
                {
                    ODataProperty property = new ODataProperty()
                    {
                        Name = "value", Value = ODataObjectModelConverter.CreateODataValue(result)
                    };
                    messageWriter.WriteProperty(property);
                }
            }
        }
コード例 #43
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaWriter" /> to write a delta response.
 /// </summary>
 /// <returns>The created writer.</returns>
 /// <param name="entitySet">The entity set we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <remarks>The write must flush the output when it's finished (inside the last Write call).</remarks>
 internal override ODataDeltaWriter CreateODataDeltaWriter(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     this.AssertSynchronous();
     return this.CreateODataDeltaWriterImplementation(entitySet, entityType);
 }
コード例 #44
0
        public OperationImportSegment(IEnumerable <IEdmOperationImport> operationImports, IEdmEntitySetBase entitySet)
            : this()
        {
            // DEVNOTE: This ctor is only used in Select and Expand currently.
            ExceptionUtils.CheckArgumentNotNull(operationImports, "operations");
            this.operationImports = new ReadOnlyCollection <IEdmOperationImport>(operationImports.ToList());

            // check for empty after we copy locally, so that we don't do multiple enumeration of input
            ExceptionUtils.CheckArgumentCollectionNotNullOrEmpty(this.operationImports, "operations");

            // Determine the return type of the operation. This is only possible if all the candidate operations agree on the return type.
            // TODO: Because we work on types and not type references, if there are nullability differences we'd ignore them...
            IEdmType typeSoFar = this.operationImports.First().Operation.ReturnType != null
                                     ? this.operationImports.First().Operation.ReturnType.Definition
                                     : null;

            if (typeSoFar == null)
            {
                // This is for void operations
                if (this.operationImports.Any(operation => operation.Operation.ReturnType != null))
                {
                    typeSoFar = UnknownSentinel;
                }
            }
            else if (this.operationImports.Any(operationImport => !typeSoFar.IsEquivalentTo(operationImport.Operation.ReturnType.Definition)))
            {
                typeSoFar = UnknownSentinel;
            }

            this.computedReturnEdmType = typeSoFar;
            this.entitySet             = entitySet;
            this.EnsureTypeAndSetAreCompatable();
        }
コード例 #45
0
        /// <summary>
        /// Asynchronously creates an <see cref="ODataDeltaWriter" /> to write a delta response.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to write entities for.</param>
        /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
        /// <returns>A running task for the created writer.</returns>
        /// <remarks>The write must flush the output when it's finished (inside the last Write call).</remarks>
        internal override Task<ODataDeltaWriter> CreateODataDeltaWriterAsync(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
        {
            this.AssertAsynchronous();

            return TaskUtils.GetTaskForSynchronousOperation(() => this.CreateODataDeltaWriterImplementation(entitySet, entityType));
        }
コード例 #46
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a resource set.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
 /// <param name="readingParameter">true means reading a resource set in uri operation parameter, false reading a resource set in other payloads.</param>
 /// <param name="readingDelta">true if reading a delta resource set.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 private ODataReader CreateResourceSetReaderImplementation(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType, bool readingParameter, bool readingDelta)
 {
     return(new ODataJsonLightReader(this, entitySet, expectedResourceType, /*readingResourceSet*/ true, readingParameter, readingDelta));
 }
コード例 #47
0
        //// Raw value is not supported by JsonLight.

        /// <summary>
        /// Creates an <see cref="ODataWriter" /> to write a feed.
        /// </summary>
        /// <param name="entitySet">The entity set we are going to write entities for.</param>
        /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
        /// <returns>The created writer.</returns>
        private ODataWriter CreateODataFeedWriterImplementation(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
        {
            ODataJsonLightWriter odataJsonWriter = new ODataJsonLightWriter(this, entitySet, entityType, /*writingFeed*/true);
            this.outputInStreamErrorListener = odataJsonWriter;
            return odataJsonWriter;
        }
コード例 #48
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a delta resource set.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read resources for.</param>
 /// <param name="expectedResourceType">The expected structured type for the items in the resource set.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 public virtual ODataReader CreateDeltaResourceSetReader(IEdmEntitySetBase entitySet, IEdmStructuredType expectedResourceType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.ResourceSet);
 }
コード例 #49
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaWriter" /> to write a delta response.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <returns>The created writer.</returns>
 private ODataDeltaWriter CreateODataDeltaWriterImplementation(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     ODataJsonLightDeltaWriter odataJsonDeltaWriter = new ODataJsonLightDeltaWriter(this, entitySet, entityType);
     this.outputInStreamErrorListener = odataJsonDeltaWriter;
     return odataJsonDeltaWriter;
 }
コード例 #50
0
 /// <summary>
 /// Creates an <see cref="ODataDeltaReader" /> to read a resource set.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the delta response.</param>
 /// <returns>The newly created <see cref="ODataDeltaReader"/>.</returns>
 internal virtual ODataDeltaReader CreateDeltaReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.ResourceSet);
 }
コード例 #51
0
ファイル: ODataOutputContext.cs プロジェクト: TomDu/odata.net
 /// <summary>
 /// Creates an <see cref="ODataWriter" /> to write a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <returns>The created writer.</returns>
 /// <remarks>The write must flush the output when it's finished (inside the last Write call).</remarks>
 public virtual ODataWriter CreateODataFeedWriter(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #52
0
 public override ODataReader CreateFeedReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     return(new ODataAvroReader(this, true));
 }
コード例 #53
0
ファイル: ODataOutputContext.cs プロジェクト: TomDu/odata.net
 /// <summary>
 /// Asynchronously creates an <see cref="ODataDeltaWriter" /> to write a delta response.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <returns>A running task for the created writer.</returns>
 /// <remarks>The write must flush the output when it's finished (inside the last Write call).</remarks>
 internal virtual Task<ODataDeltaWriter> CreateODataDeltaWriterAsync(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #54
0
 /// <summary>
 /// Creates an <see cref="ODataReader" /> to read a feed.
 /// </summary>
 /// <param name="entitySet">The entity set we are going to read entities for.</param>
 /// <param name="expectedBaseEntityType">The expected base entity type for the entries in the feed.</param>
 /// <returns>The newly created <see cref="ODataReader"/>.</returns>
 public virtual ODataReader CreateFeedReader(IEdmEntitySetBase entitySet, IEdmEntityType expectedBaseEntityType)
 {
     throw this.CreatePayloadKindNotSupportedException(ODataPayloadKind.Feed);
 }
コード例 #55
0
ファイル: ODataPathParser.cs プロジェクト: sabyabr/odata.net
 /// <summary>
 /// Determines the entity set for segment.
 /// </summary>
 /// <param name="identifier">The identifier.</param>
 /// <param name="returnType">Type of the return.</param>
 /// <param name="segment">The segment.</param>
 /// <param name="targetset">The targetset.</param>
 /// <param name="singleOperation">The single operation.</param>
 /// <exception cref="ODataException">Throws and exception if entity set not specified.</exception>
 private static void DetermineEntitySetForSegment(string identifier, IEdmTypeReference returnType, ODataPathSegment segment, IEdmEntitySetBase targetset, IEdmOperation singleOperation)
 {
     if (returnType != null)
     {
         segment.TargetEdmNavigationSource = targetset;
         segment.TargetEdmType = returnType.Definition;
         segment.TargetKind = TargetKindFromType(segment.TargetEdmType);
         segment.SingleResult = !singleOperation.ReturnType.IsCollection();
     }
     else
     {
         segment.TargetEdmNavigationSource = null;
         segment.TargetEdmType = null;
         segment.TargetKind = RequestTargetKind.VoidOperation;
     }
 }
コード例 #56
0
        /// <summary>
        /// Try to bind an identifier to a FunctionCallNode
        /// </summary>
        /// <param name="identifier">the identifier to bind</param>
        /// <param name="arguments">the semantically bound list of arguments.</param>
        /// <param name="parent">a semantically bound parent node.</param>
        /// <param name="state">the current state of the binding algorithm</param>
        /// <param name="boundFunction">a single value function call node representing this function call, if we found one.</param>
        /// <returns>true if we found a function for this token.</returns>
        private bool TryBindIdentifier(string identifier, IEnumerable <FunctionParameterToken> arguments, QueryNode parent, BindingState state, out QueryNode boundFunction)
        {
            boundFunction = null;

            IEdmType        bindingType       = null;
            SingleValueNode singleValueParent = parent as SingleValueNode;

            if (singleValueParent != null)
            {
                if (singleValueParent.TypeReference != null)
                {
                    bindingType = singleValueParent.TypeReference.Definition;
                }
            }
            else
            {
                CollectionNode collectionValueParent = parent as CollectionNode;
                if (collectionValueParent != null)
                {
                    bindingType = collectionValueParent.CollectionType.Definition;
                }
            }

            if (!UriEdmHelpers.IsBindingTypeValid(bindingType))
            {
                return(false);
            }

            // All functions should be fully qualified, if they aren't they they aren't functions.
            // When using extension, there may be function call with unqualified name. So loose the restriction here.
            if (identifier.IndexOf(".", StringComparison.Ordinal) == -1 && this.Resolver.GetType() == typeof(ODataUriResolver))
            {
                return(false);
            }

            IEdmOperation operation;
            List <FunctionParameterToken> syntacticArguments = arguments == null ? new List <FunctionParameterToken>() : arguments.ToList();

            if (!FunctionOverloadResolver.ResolveOperationFromList(identifier, syntacticArguments.Select(ar => ar.ParameterName).ToList(), bindingType, state.Model, out operation, this.Resolver))
            {
                // TODO: FunctionOverloadResolver.ResolveOperationFromList() looks up the function by parameter names, but it shouldn't ignore parameter types. (test case ParseFilter_AliasInFunction_PropertyAsValue_TypeMismatch should fail)
                return(false);
            }

            if (singleValueParent != null && singleValueParent.TypeReference == null)
            {
                // if the parent exists, but has no type information, then we're in open type land, and we
                // shouldn't go any farther.
                throw new ODataException(ODataErrorStrings.FunctionCallBinder_CallingFunctionOnOpenProperty(identifier));
            }

            if (operation.IsAction())
            {
                return(false);
            }

            IEdmFunction function = (IEdmFunction)operation;

            // TODO:  $filter $orderby parameter expression which contains complex or collection should NOT be supported in this way
            //     but should be parsed into token tree, and binded to node tree: parsedParameters.Select(p => this.bindMethod(p));
            ICollection <FunctionParameterToken> parsedParameters = HandleComplexOrCollectionParameterValueIfExists(state.Configuration.Model, function, syntacticArguments, state.Configuration.Resolver.EnableCaseInsensitive);

            IEnumerable <QueryNode> boundArguments = parsedParameters.Select(p => this.bindMethod(p));

            boundArguments = boundArguments.ToList(); // force enumerable to run : will immediately evaluate all this.bindMethod(p).
            IEdmTypeReference  returnType       = function.ReturnType;
            IEdmEntitySetBase  returnSet        = null;
            SingleResourceNode singleEntityNode = parent as SingleResourceNode;

            if (singleEntityNode != null)
            {
                returnSet = function.GetTargetEntitySet(singleEntityNode.NavigationSource, state.Model);
            }

            string functionName = function.FullName();

            if (returnType.IsEntity())
            {
                boundFunction = new SingleResourceFunctionCallNode(functionName, new[] { function }, boundArguments, (IEdmEntityTypeReference)returnType.Definition.ToTypeReference(), returnSet, parent);
            }
            else if (returnType.IsStructuredCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new CollectionResourceFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, returnSet, parent);
            }
            else if (returnType.IsCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new CollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, parent);
            }
            else
            {
                boundFunction = new SingleValueFunctionCallNode(functionName, new[] { function }, boundArguments,
                                                                returnType, parent);
            }

            return(true);
        }
コード例 #57
0
 public override ODataWriter CreateODataFeedWriter(IEdmEntitySetBase entitySet, IEdmEntityType entityType)
 {
     return new CsvWriter(this, entityType);
 }