/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { return ODataEntityMetadataBuilder.Null; }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light // reader and it would contain the metadata builder from the reader. Until we give the user the ability to choose whether to write what was reported // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now. return null; }
public void WhitespaceShouldBeTreatedAsEmpty() { SelectedPropertiesNode.Create(" ").Should().BeSameAsEmpty(); }
public void SelectedStreamPropertiesShouldReturnPropertiesBasedOnMetadata() { var entryMetadataContext = ODataResourceMetadataContext.Create(new ODataResource(), new TestFeedAndEntryTypeContext(), /*serializationInfo*/ null, ActualEntityType, new TestMetadataContext(), SelectedPropertiesNode.Create("StreamProp1")); entryMetadataContext.SelectedStreamProperties.ContainsKey("StreamProp1").Should().BeTrue(); }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="state">The writer state of the scope to create.</param> /// <param name="entry">The entry for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> public JsonLightDeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, entry, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri) { }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="entry">The entry for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, entry, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert( state == WriterState.DeltaEntry && entry is ODataEntry || state == WriterState.DeltaDeletedEntry && entry is ODataDeltaDeletedEntry, "entry must be either DeltaEntry or DeltaDeletedEntry."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, /*writingResponse*/ true); this.serializationInfo = serializationInfo; }
/// <summary> /// Constructor to create a new delta link scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="link">The link for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightDeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, link, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri) { }
/// <summary> /// Creates a new JSON Light navigation link scope. /// </summary> /// <param name="writerState">The writer state for the new scope.</param> /// <param name="navLink">The navigation link for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly created JSON Light navigation link scope.</returns> protected override NavigationLinkScope CreateNavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightNavigationLinkScope(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri); }
/// <summary> /// Create a new writer scope. /// </summary> /// <param name="state">The writer state of the scope to create.</param> /// <param name="item">The item attached to the scope to create.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The OdataUri info of this scope.</param> private void PushScope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { Debug.Assert( state == WriterState.Error || state == WriterState.DeltaEntry && item is ODataEntry || state == WriterState.DeltaDeletedEntry && item is ODataDeltaDeletedEntry || state == WriterState.DeltaFeed && item is ODataDeltaFeed || state == WriterState.DeltaLink && item is ODataDeltaLink || state == WriterState.DeltaDeletedLink && item is ODataDeltaDeletedLink || state == WriterState.Start && item == null || state == WriterState.Completed && item == null, "Writer state and associated item do not match."); Scope scope; switch (state) { case WriterState.DeltaEntry: scope = this.CreateDeltaEntryScope(WriterState.DeltaEntry, item, navigationSource, entityType, selectedProperties, odataUri); break; case WriterState.DeltaDeletedEntry: scope = this.CreateDeltaEntryScope(WriterState.DeltaDeletedEntry, item, navigationSource, entityType, selectedProperties, odataUri); break; case WriterState.DeltaFeed: scope = this.CreateDeltaFeedScope(item, navigationSource, entityType, selectedProperties, odataUri); break; case WriterState.DeltaLink: scope = this.CreateDeltaLinkScope(WriterState.DeltaLink, item, navigationSource, entityType, selectedProperties, odataUri); break; case WriterState.DeltaDeletedLink: scope = this.CreateDeltaLinkScope(WriterState.DeltaDeletedLink, item, navigationSource, entityType, selectedProperties, odataUri); break; case WriterState.Start: // fall through case WriterState.Completed: // fall through case WriterState.Error: scope = new Scope(state, item, navigationSource, entityType, selectedProperties, odataUri); break; default: string errorMessage = Strings.General_InternalError(InternalErrorCodes.ODataWriterCore_Scope_Create_UnreachableCodePath); Debug.Assert(false, errorMessage); throw new ODataException(errorMessage); } this.scopes.Push(scope); }
/// <summary> /// Constructor creating a new reader scope. /// </summary> /// <param name="readerState">The reader state of the new scope that is being created.</param> /// <param name="entry">The item attached to this scope.</param> /// <param name="navigationSource">The navigation source we are going to read entities for.</param> /// <param name="expectedEntityType">The expected type for the scope.</param> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker for this entry scope.</param> /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param> /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param> /// <remarks>The <paramref name="expectedEntityType"/> has the following meaning /// it's the expected base type of the entry. If the entry has no type name specified /// this type will be assumed. Otherwise the specified type name must be /// the expected type or a more derived type. /// In all cases the specified type must be an entity type.</remarks> internal JsonLightEntryScope( ODataReaderState readerState, ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(readerState, entry, navigationSource, expectedEntityType, odataUri) { Debug.Assert( readerState == ODataReaderState.EntryStart || readerState == ODataReaderState.EntryEnd, "readerState == ODataReaderState.EntryStart || readerState == ODataReaderState.EntryEnd"); this.DuplicatePropertyNamesChecker = duplicatePropertyNamesChecker; this.SelectedProperties = selectedProperties; }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(typeContext != null, "typeContext != null"); Debug.Assert(selectedProperties != null, "selectedProperties != null"); IODataMetadataContext metadataContext = new ODataMetadataContext( isResponse, this.model, this.NonNullMetadataDocumentUri, odataUri); UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext); ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention); IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties); return new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder); }
public void MalformedSelectClauseShouldFail() { Action action = () => SelectedPropertiesNode.Create("*/Name"); action.ShouldThrow <ODataException>().WithMessage(ErrorStrings.SelectedPropertiesNode_StarSegmentNotLastSegment); }
public void EmptySelectClauseShouldNotIncludeAnyProperties() { SelectedPropertiesNode.Create(string.Empty).Should().BeSameAsEmpty().And.BeEmpty(this.cityType); }
public void NoOperationsShouldBeGeneratedIfNoneAreSelected() { AddMissingOperations(this.entry, this.entityType, SelectedPropertiesNode.Create(string.Empty), this.model, type => this.allOperations, null, e => false); entry.Actions.Should().BeEmpty(); entry.Functions.Should().BeEmpty(); }
private static void AddMissingOperations(ODataResource entry, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, IEdmModel model, Func <IEdmType, IEdmOperation[]> getOperations, Func <ODataResourceBase, ODataResourceMetadataBuilder> getEntityMetadataBuilder = null, Func <IEdmStructuredType, bool> typeIsOpen = null) { var metadataContext = new TestMetadataContext { GetModelFunc = () => model, GetMetadataDocumentUriFunc = () => new Uri("http://temp.org/$metadata"), GetServiceBaseUriFunc = () => new Uri("http://temp.org/"), GetBindableOperationsForTypeFunc = getOperations, GetEntityMetadataBuilderFunc = getEntityMetadataBuilder, OperationsBoundToStructuredTypeMustBeContainerQualifiedFunc = typeIsOpen, }; var entryContext = ODataResourceMetadataContext.Create(entry, new TestFeedAndEntryTypeContext(), /*serializationInfo*/ null, entityType, metadataContext, selectedProperties); var generator = new ODataMissingOperationGenerator(entryContext, metadataContext); List <ODataAction> actions = generator.GetComputedActions().ToList(); List <ODataFunction> functions = generator.GetComputedFunctions().ToList(); actions.ForEach(entry.AddAction); functions.ForEach(entry.AddFunction); }
private void AddMissingOperationsForAll(SelectedPropertiesNode selectedProperties) { AddMissingOperations(this.entry, this.entityType, selectedProperties, this.model, type => this.allOperations, entry => new NoOpResourceMetadataBuilder(entry), e => false); }
public void SelectedBindableOperationsShouldReturnPropertiesBasedOnMetadata() { var metadataContext = new TestMetadataContext { GetBindableOperationsForTypeFunc = type => new IEdmOperation[] { Action1, Action2, Function1, Function2 }, OperationsBoundToStructuredTypeMustBeContainerQualifiedFunc = type => false }; var entryMetadataContext = ODataResourceMetadataContext.Create(new ODataResource(), new TestFeedAndEntryTypeContext(), /*serializationInfo*/ null, ActualEntityType, metadataContext, SelectedPropertiesNode.Create("Action1,Function1")); entryMetadataContext.SelectedBindableOperations.Should().HaveCount(2).And.Contain(Action1).And.Contain(Function1); }
public void SelectedBindableOperationsShouldReturnEmptyWithoutModel() { var metadataContext = new TestMetadataContext { GetBindableOperationsForTypeFunc = type => new IEdmOperation[] { Action1, Action2, Function1, Function2 }, OperationsBoundToStructuredTypeMustBeContainerQualifiedFunc = type => false }; var entryMetadataContext = ODataResourceMetadataContext.Create(new ODataResource(), new TestFeedAndEntryTypeContext(), new ODataResourceSerializationInfo(), /*actualEntityType*/ null, metadataContext, SelectedPropertiesNode.Create("Action1,Function1")); entryMetadataContext.SelectedBindableOperations.Should().BeEmpty(); }
/// <summary> /// Reads the start of the JSON array for the content of the feed and sets up the reader state correctly. /// </summary> /// <param name="feed">The feed to read the contents for.</param> /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param> /// <remarks> /// Pre-Condition: The first node of the feed property value; this method will throw if the node is not /// JsonNodeType.StartArray /// Post-Condition: The reader is positioned on the first item in the feed, or on the end array of the feed. /// </remarks> private void ReadFeedStart(ODataFeed feed, SelectedPropertiesNode selectedProperties) { Debug.Assert(feed != null, "feed != null"); this.jsonLightEntryAndFeedDeserializer.ReadFeedContentStart(); this.EnterScope(new JsonLightFeedScope(feed, this.CurrentNavigationSource, this.CurrentEntityType, selectedProperties, this.CurrentScope.ODataUri)); this.jsonLightEntryAndFeedDeserializer.AssertJsonCondition(JsonNodeType.EndArray, JsonNodeType.StartObject); }
public void WildcardShouldSelectAllPropertiesParsingTest() { SelectedPropertiesNode.Create("*").Should().HaveStreams(this.cityType, "Photo").And.HaveNavigations(this.cityType, "Districts").And.HaveChild(this.cityType, "Districts", c => c.Should().BeSameAsEmpty()); }
/// <summary> /// Create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> protected override FeedScope CreateFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightFeedScope(feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri); }
public void SingleStreamPropertyWithNormalProperty() { SelectedPropertiesNode.Create("Size,Photo").Should().HaveOnlyStreams(this.cityType, "Photo"); }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="entry">The entry for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <param name="enableValidation">Enable validation or not.</param> internal JsonLightEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation) : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri, enableValidation) { }
public void SpecifyingTheSameStreamTwiceShouldNotCauseDuplicates() { SelectedPropertiesNode.Create("Photo,Photo").Should().HaveOnlyStreams(this.cityType, "Photo"); }
/// <summary> /// Create a new delta link scope. /// </summary> /// <param name="state">The writer state of the scope to create.</param> /// <param name="link">The link for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> private DeltaLinkScope CreateDeltaLinkScope(WriterState state, ODataItem link, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightDeltaLinkScope( state, link, this.GetLinkSerializationInfo(link), navigationSource, entityType, this.jsonLightOutputContext.MessageWriterSettings.WriterBehavior, selectedProperties, odataUri); }
public void SpecifyingTheSameNavigationTwiceShouldNotCauseDuplicates() { SelectedPropertiesNode.Create("Districts,Districts").Should().HaveOnlyNavigations(this.cityType, "Districts").And.HaveChild(this.cityType, "Districts", c => c.Should().BeSameAsEntireSubtree()); }
/// <summary> /// Constructor to create a new delta link scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="link">The link for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, link, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(link != null, "link != null"); Debug.Assert( state == WriterState.DeltaLink && link is ODataDeltaLink || state == WriterState.DeltaDeletedLink && link is ODataDeltaDeletedLink, "link must be either DeltaLink or DeltaDeletedLink."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(serializationInfo); }
public void SpecifyingAWildCardShouldNotCauseDuplicates() { SelectedPropertiesNode.Create("Districts,*,Photo").Should().HaveStreams(this.cityType, "Photo").And.HaveNavigations(this.cityType, "Districts").And.HaveChild(this.cityType, "Districts", c => c.Should().BeSameAsEntireSubtree()); }
/// <summary> /// Constructs an instance of <see cref="ODataEntryMetadataContextWithModel"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="metadataContext">The metadata context to use.</param> /// <param name="selectedProperties">The selected properties.</param> internal ODataEntryMetadataContextWithModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties) : base(entry, typeContext) { Debug.Assert(actualEntityType != null, "actualEntityType != null"); Debug.Assert(metadataContext != null, "metadataContext != null"); Debug.Assert(selectedProperties != null, "selectedProperties != null"); this.actualEntityType = actualEntityType; this.metadataContext = metadataContext; this.selectedProperties = selectedProperties; }
public void SelectingANavigationShouldSelectTheEntireTreeIfWildcardAlsoPresent() { SelectedPropertiesNode.Create("Districts,Districts/*").Should().HaveOnlyNavigations(this.cityType, "Districts").And.HaveChild(this.cityType, "Districts", c => c.Should().BeSameAsEntireSubtree()); }
/// <summary> /// Constructor to create a new expanded navigation property scope. /// </summary> /// <param name="navigationLink">The navigation link for the feed.</param> /// <param name="navigationSource">The navigation source of the parent delta entry.</param> /// <param name="entityType">The entity type of the parent delta entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected ExpandedNavigationPropertyScope(ODataItem navigationLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(WriterState.ExpandedNavigationProperty, navigationLink, navigationSource, entityType, selectedProperties, odataUri) { }
public void SimpleTypeSegmentWithStream() { SelectedPropertiesNode.Create("TestModel.City/Photo").Should().HaveOnlyStreams(this.cityType, "Photo"); }
/// <summary> /// Constructor to create a new expanded navigation property scope. /// </summary> /// <param name="navigationLink">The navigation link for the feed.</param> /// <param name="navigationSource">The navigation source of the parent delta entry.</param> /// <param name="entityType">The entity type of the parent delta entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <param name="parentDeltaEntry">The parent delta entry.</param> /// <param name="jsonLightOutputContext">The output context for Json.</param> public JsonLightExpandedNavigationPropertyScope(ODataItem navigationLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri, ODataEntry parentDeltaEntry, ODataJsonLightOutputContext jsonLightOutputContext) : base(navigationLink, navigationSource, entityType, selectedProperties, odataUri) { this.jsonLightExpandedNavigationPropertyWriter = new JsonLightExpandedNavigationPropertyWriter(navigationSource, entityType, parentDeltaEntry, jsonLightOutputContext); }
public void SimpleTypeSegmentWithNavigation() { SelectedPropertiesNode.Create("TestModel.City/Districts").Should().HaveOnlyNavigations(this.cityType, "Districts"); }
/// <summary> /// Starts the entry, initializing the scopes and such. This method starts a non-null entry only. /// </summary> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use for the entry; /// or null if a new one should be created.</param> /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param> private void StartEntry(DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, SelectedPropertiesNode selectedProperties) { this.EnterScope(new JsonLightEntryScope( ODataReaderState.EntryStart, ReaderUtils.CreateNewEntry(), this.CurrentNavigationSource, this.CurrentEntityType, duplicatePropertyNamesChecker ?? this.jsonLightInputContext.CreateDuplicatePropertyNamesChecker(), selectedProperties, this.CurrentScope.ODataUri)); }
public void UnmatchedTypeSegments() { SelectedPropertiesNode.Create("TestModel.Fake/Photo,TestModel.Fake2/Districts").Should().NotHaveStreams(this.cityType).And.NotHaveNavigations(this.cityType); }
/// <summary> /// Constructor creating a new reader scope. /// </summary> /// <param name="feed">The item attached to this scope.</param> /// <param name="navigationSource">The navigation source we are going to read entities for.</param> /// <param name="expectedEntityType">The expected type for the scope.</param> /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param> /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param> /// <remarks>The <paramref name="expectedEntityType"/> has the following meaning /// it's the expected base type of the entries in the feed. /// note that it might be a more derived type than the base type of the entity set for the feed. /// In all cases the specified type must be an entity type.</remarks> internal JsonLightFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(ODataReaderState.FeedStart, feed, navigationSource, expectedEntityType, odataUri) { this.SelectedProperties = selectedProperties; }
public void TypeSegmentWithStreamUsingBaseTypeName() { SelectedPropertiesNode.Create("TestModel.City/Photo").Should().HaveOnlyStreams(this.metropolisType, "Photo"); }
/// <summary> /// Reads the start of an entry and sets up the reader state correctly /// </summary> /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use for the entry; /// or null if a new one should be created.</param> /// <param name="selectedProperties">The selected properties node capturing what properties should be expanded during template evaluation.</param> /// <remarks> /// Pre-Condition: JsonNodeType.StartObject If the entry is in a feed - the start of the entry object /// JsonNodeType.Property If the entry is a top-level entry and has at least one property /// JsonNodeType.EndObject If the entry is a top-level entry and has no properties /// Post-Condition: JsonNodeType.StartObject Start of expanded entry of the navigation link to read next /// JsonNodeType.StartArray Start of expanded feed of the navigation link to read next /// JsonNodeType.PrimitiveValue (null) Expanded null entry of the navigation link to read next /// JsonNodeType.Property Property after deferred link or expanded entity reference /// JsonNodeType.EndObject If no (more) properties exist in the entry's content /// </remarks> private void ReadEntryStart(DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, SelectedPropertiesNode selectedProperties) { this.jsonLightEntryAndFeedDeserializer.AssertJsonCondition(JsonNodeType.StartObject, JsonNodeType.Property, JsonNodeType.EndObject); // If the reader is on StartObject then read over it. This happens for entries in feed. // For top-level entries the reader will be positioned on the first entry property (after odata.context if it was present). if (this.jsonLightEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.StartObject) { this.jsonLightEntryAndFeedDeserializer.JsonReader.Read(); } if (this.ReadingFeed || this.IsExpandedLinkContent) { string contextUriStr = this.jsonLightEntryAndFeedDeserializer.ReadContextUriAnnotation(ODataPayloadKind.Entry, duplicatePropertyNamesChecker, false); if (contextUriStr != null) { contextUriStr = UriUtils.UriToString(this.jsonLightEntryAndFeedDeserializer.ProcessUriFromPayload(contextUriStr)); var parseResult = ODataJsonLightContextUriParser.Parse( this.jsonLightEntryAndFeedDeserializer.Model, contextUriStr, ODataPayloadKind.Entry, this.jsonLightEntryAndFeedDeserializer.MessageReaderSettings.ReaderBehavior, this.jsonLightInputContext.ReadingResponse); if (this.jsonLightInputContext.ReadingResponse && parseResult != null) { ReaderValidationUtils.ValidateFeedOrEntryContextUri(parseResult, this.CurrentScope, false); } } } // Setup the new entry state this.StartEntry(duplicatePropertyNamesChecker, selectedProperties); // Read the odata.type annotation. this.jsonLightEntryAndFeedDeserializer.ReadEntryTypeName(this.CurrentEntryState); // Resolve the type name Debug.Assert( this.CurrentNavigationSource != null || this.readingParameter, "We must always have an expected navigation source for each entry (since we can't deduce that from the type name)."); this.ApplyEntityTypeNameFromPayload(this.CurrentEntry.TypeName); // Validate type with feed validator if available if (this.CurrentFeedValidator != null) { this.CurrentFeedValidator.ValidateEntry(this.CurrentEntityType); } if (this.CurrentEntityType != null) { // NOTE: once we do this for all formats we can do this in ApplyEntityTypeNameFromPayload. this.CurrentEntry.SetAnnotation(new ODataTypeAnnotation(this.CurrentNavigationSource, this.CurrentEntityType)); } // In WCF DS Server mode we must not read ahead and report the type name only. if (this.jsonLightInputContext.UseServerApiBehavior) { this.CurrentEntryState.FirstNavigationLinkInfo = null; } else { this.CurrentEntryState.FirstNavigationLinkInfo = this.jsonLightEntryAndFeedDeserializer.ReadEntryContent(this.CurrentEntryState); } this.jsonLightEntryAndFeedDeserializer.AssertJsonCondition( JsonNodeType.Property, JsonNodeType.StartObject, JsonNodeType.StartArray, JsonNodeType.EndObject, JsonNodeType.PrimitiveValue); }
public void TypeSegmentWithNavigationUsingBaseTypeName() { SelectedPropertiesNode.Create("TestModel.City/Districts").Should().HaveOnlyNavigations(this.metropolisType, "Districts"); }
/// <summary> /// Place where derived writers can perform custom steps before the entry is writen, at the begining of WriteStartEntryImplementation. /// </summary> /// <param name="entry">Entry to write.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> protected override void PrepareEntryForWriteStart(ODataEntry entry, ODataFeedAndEntryTypeContext typeContext, SelectedPropertiesNode selectedProperties) { if (this.jsonLightOutputContext.MessageWriterSettings.AutoComputePayloadMetadataInJson) { EntryScope entryScope = (EntryScope)this.CurrentScope; Debug.Assert(entryScope != null, "entryScope != null"); ODataEntityMetadataBuilder builder = this.jsonLightOutputContext.MetadataLevel.CreateEntityMetadataBuilder( entry, typeContext, entryScope.SerializationInfo, entryScope.EntityType, selectedProperties, this.jsonLightOutputContext.WritingResponse, this.jsonLightOutputContext.MessageWriterSettings.UseKeyAsSegment, this.jsonLightOutputContext.MessageWriterSettings.ODataUri); if (builder is ODataConventionalEntityMetadataBuilder) { builder.ParentMetadataBuilder = this.FindParentEntryMetadataBuilder(); } this.jsonLightOutputContext.MetadataLevel.InjectMetadataBuilder(entry, builder); } }
public void MultipleTypeSegmentsShouldNotProduceDuplicateStreams() { SelectedPropertiesNode.Create("TestModel.Town/Photo,TestModel.City/Photo").Should().HaveOnlyStreams(this.cityType, "Photo"); }
/// <summary> /// Create a new entry scope. /// </summary> /// <param name="entry">The entry for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> protected override EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightEntryScope( entry, this.GetEntrySerializationInfo(entry), navigationSource, entityType, skipWriting, this.jsonLightOutputContext.WritingResponse, this.jsonLightOutputContext.MessageWriterSettings.WriterBehavior, selectedProperties, odataUri, this.jsonLightOutputContext.MessageWriterSettings.EnableFullValidation); }
public void MultipleTypeSegmentsShouldNotProduceDuplicateNavigations() { SelectedPropertiesNode.Create("TestModel.City/Districts,TestModel.Metropolis/Districts").Should().HaveOnlyNavigations(this.metropolisType, "Districts"); }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightFeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri) { }
public void StreamSpecifiedInBothTypeSegmentAndDirectlyShouldNotProduceDuplicates() { SelectedPropertiesNode.Create("TestModel.City/Photo,Photo").Should().HaveOnlyStreams(this.cityType, "Photo"); }
/// <summary> /// Constructor to create a new JSON Light navigation link scope. /// </summary> /// <param name="writerState">The writer state for the new scope.</param> /// <param name="navLink">The navigation link for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightNavigationLinkScope(WriterState writerState, ODataNavigationLink navLink, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(writerState, navLink, navigationSource, entityType, skipWriting, selectedProperties, odataUri) { }
public void NavigationSpecifiedInBothTypeSegmentAndDirectlyShouldNotProduceDuplicates() { SelectedPropertiesNode.Create("TestModel.City/Districts,Districts").Should().HaveOnlyNavigations(this.cityType, "Districts"); }
/// <summary> /// Create a new delta feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> private DeltaFeedScope CreateDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightDeltaFeedScope(feed, navigationSource, entityType, selectedProperties, odataUri); }
public void SubPropertyOfNavigationSpecifiedInBothTypeSegmentAndDirectlyShouldNotProduceDuplicates() { SelectedPropertiesNode.Create("TestModel.City/Districts/Thumbnail,Districts/Thumbnail").Should() .HaveOnlyNavigations(this.cityType, "Districts") .And.HaveChild(this.cityType, "Districts", c => c.Should().HaveOnlyStreams(this.districtType, "Thumbnail")); }
/// <summary> /// Constructor creating a new writer scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="item">The item attached to this scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal Scope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { this.state = state; this.item = item; this.EntityType = entityType; this.NavigationSource = navigationSource; this.selectedProperties = selectedProperties; this.odataUri = odataUri; }
public void WildCardShouldNotIncludeActions() { SelectedPropertiesNode.Create("*").Should().NotHaveAction(this.cityType, this.action); }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="item">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaFeedScope(ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(WriterState.DeltaFeed, item, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(item != null, "item != null"); var feed = item as ODataDeltaFeed; Debug.Assert(feed != null, "feed must be DeltaFeed."); this.serializationInfo = feed.SerializationInfo; }
public void SpecificActionShouldBeNotSelectedForNonMatchingName() { SelectedPropertiesNode.Create("foo").Should().NotHaveAction(this.cityType, this.action); }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source 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> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(feed, navigationSource, entityType, selectedProperties, odataUri) { }
public void SpecificActionShouldBeSelected() { SelectedPropertiesNode.Create("Action").Should().HaveAction(this.cityType, this.action); }
/// <summary> /// Creates an instance of <see cref="ODataEntryMetadataContext"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="metadataContext">The metadata context to use.</param> /// <param name="selectedProperties">The selected properties.</param> /// <returns>A new instance of <see cref="ODataEntryMetadataContext"/>.</returns> internal static ODataEntryMetadataContext Create( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties) { if (serializationInfo != null) { return new ODataEntryMetadataContextWithoutModel(entry, typeContext, serializationInfo); } return new ODataEntryMetadataContextWithModel(entry, typeContext, actualEntityType, metadataContext, selectedProperties); }
public void SpecificActionWithParametersShouldBeSelected() { SelectedPropertiesNode.Create("Action(Edm.Int32)").Should().HaveAction(this.cityType, this.action); }
protected override ODataWriterCore.EntryScope CreateEntryScope(ODataEntry entry, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { throw new NotImplementedException(); }
public void SelectedNaigationPropertiesShouldReturnPropertiesBasedOnSelectAndMetadata() { var entryMetadataContext = ODataResourceMetadataContext.Create(new ODataResource(), new TestFeedAndEntryTypeContext(), /*serializationInfo*/ null, ActualEntityType, new TestMetadataContext(), SelectedPropertiesNode.Create("NavProp1")); entryMetadataContext.SelectedNavigationProperties.Should().HaveCount(1).And.Contain(p => p.Name == "NavProp1"); }