/// <summary> /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>. /// </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> internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo) : base(entry, typeContext) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(serializationInfo != null, "serializationInfo != null"); this.serializationInfo = serializationInfo; }
/// <summary> /// Gets an entity metadata builder for the given entry. /// </summary> /// <param name="entryState">Entry state to use as reference for information needed by the builder.</param> /// <returns>An entity metadata builder.</returns> public ODataEntityMetadataBuilder GetEntityMetadataBuilderForReader(IODataJsonLightReaderEntryState entryState) { Debug.Assert(entryState != null, "entry != null"); // Only apply the conventional template builder on response. On a request we would only report what's on the wire. if (entryState.MetadataBuilder == null) { ODataEntry entry = entryState.Entry; if (this.isResponse) { ODataTypeAnnotation typeAnnotation = entry.GetAnnotation <ODataTypeAnnotation>(); Debug.Assert(typeAnnotation != null, "The JSON light reader should have already set the ODataTypeAnnotation."); IEdmNavigationSource navigationSource = typeAnnotation.NavigationSource; IEdmEntityType navigationSourceElementType = this.edmTypeResolver.GetElementType(navigationSource); IODataFeedAndEntryTypeContext typeContext = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, navigationSource, navigationSourceElementType, entryState.EntityType, this.model, /*throwIfMissingTypeInfo*/ true); IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, /*serializationInfo*/ null, (IEdmEntityType)entry.GetEdmType().Definition, this, entryState.SelectedProperties); UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(/*keyAsSegment*/ null, typeContext); ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(this.ServiceBaseUri, urlConvention); entryState.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, this, uriBuilder); } else { entryState.MetadataBuilder = new NoOpEntityMetadataBuilder(entry); } } return(entryState.MetadataBuilder); }
/// <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)); }
/// <summary> /// Constructs 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> protected ODataEntryMetadataContext(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(typeContext != null, "typeContext != null"); this.entry = entry; this.typeContext = typeContext; }
/// <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> /// <returns>The created metadata builder.</returns> internal abstract ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool?keyAsSegment);
/// <summary> /// Constructs 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> protected ODataEntryMetadataContext(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(entry != null, "entry != null"); Debug.Assert(typeContext != null, "typeContext != null"); this.entry = entry; this.typeContext = typeContext; }
/// <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; }
/// <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 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 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) { // 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); }
/// <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)); }
/// <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; }
/// <summary> /// Compute id for containment scenario. /// </summary> /// <returns> /// The <see cref="Uri"/> of @odata.id. /// </returns> private Uri ComputeIdForContainment() { Uri uri; // check if has parent ODataConventionalEntityMetadataBuilder parent = this.ParentMetadataBuilder as ODataConventionalEntityMetadataBuilder; if (parent != null) { // $expand scenario. Get the parent id uri = parent.GetId(); // And append cast (if needed). // A cast segment if the navigation property is defined on a type derived from the entity // type declared for the entity set IODataFeedAndEntryTypeContext typeContext = parent.entryMetadataContext.TypeContext; if (typeContext.NavigationSourceEntityTypeName != typeContext.ExpectedEntityTypeName) { // Do not append type cast if we know that the navigation property is in base type, not in derived type. ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel typeContextWithModel = typeContext as ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel; if (typeContextWithModel == null || typeContextWithModel.NavigationSourceEntityType.FindProperty(this.entryMetadataContext.TypeContext.NavigationSourceName) == null) { uri = new Uri(Core.UriUtils.EnsureTaillingSlash(uri), parent.entryMetadataContext.ActualEntityTypeName); } } } else { // direct access scenario. uri = this.uriBuilder.BuildBaseUri(); ODataUri odataUri = this.ODataUri ?? this.metadataContext.ODataUri; uri = this.GetContainingEntitySetUri(uri, odataUri); } // A path segment for the containment navigation property uri = this.uriBuilder.BuildEntitySetUri(uri, this.entryMetadataContext.TypeContext.NavigationSourceName); if (this.entryMetadataContext.TypeContext.IsFromCollection) { uri = this.uriBuilder.BuildEntityInstanceUri( uri, this.ComputedKeyProperties, this.entryMetadataContext.ActualEntityTypeName); } return(uri); }
/// <summary> /// Gets the url convention for the given user setting and type context. /// </summary> /// <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="typeContext">The type context for the entry or feed being written.</param> /// <returns>The convention to use when generating URLs.</returns> internal static UrlConvention ForUserSettingAndTypeContext(bool?keyAsSegment, IODataFeedAndEntryTypeContext typeContext) { Debug.Assert(typeContext != null, "typeContext != null"); // The setting from the user is an override, so check if it was set. if (keyAsSegment.HasValue) { return(CreateWithExplicitValue(keyAsSegment.Value)); } return(typeContext.UrlConvention); }
/// <summary> /// Gets the url convention for the given user setting and type context. /// </summary> /// <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="typeContext">The type context for the entry or feed being written.</param> /// <returns>The convention to use when generating URLs.</returns> internal static UrlConvention ForUserSettingAndTypeContext(bool? keyAsSegment, IODataFeedAndEntryTypeContext typeContext) { Debug.Assert(typeContext != null, "typeContext != null"); // The setting from the user is an override, so check if it was set. if (keyAsSegment.HasValue) { return CreateWithExplicitValue(keyAsSegment.Value); } return typeContext.UrlConvention; }
/// <summary> /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>. /// </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> internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo) : base(entry, typeContext) { Debug.Assert(serializationInfo != null, "serializationInfo != null"); this.serializationInfo = serializationInfo; }
/// <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); }
/// <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); }