Example #1
0
        /// <summary>
        /// Creates the value for the named stream's link relation attribute.
        /// </summary>
        /// <param name="namedStream">The named stream to create the relation for.</param>
        /// <param name="forEditLink">'true' if the relation is computed for an edit link; otherwise 'false'.</param>
        /// <returns>The relation attribute value for the named stream's link relation.</returns>
        internal static string ComputeNamedStreamRelation(ODataMediaResource namedStream, bool forEditLink)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(namedStream != null, "namedStream != null");
            Debug.Assert(!string.IsNullOrEmpty(namedStream.Name), "!string.IsNullOrEmpty(namedStream.Name)");

            string segmentName = forEditLink ? AtomConstants.ODataNamedStreamsEditMediaSegmentName : AtomConstants.ODataNamedStreamsMediaResourceSegmentName;
            return string.Join("/", new string[] { AtomConstants.ODataNamespace, segmentName, namedStream.Name });
        }
Example #2
0
        /// <summary>
        /// Creates the value for the named stream's link relation attribute.
        /// </summary>
        /// <param name="namedStream">The named stream to create the relation for.</param>
        /// <param name="forEditLink">'true' if the relation is computed for an edit link; otherwise 'false'.</param>
        /// <returns>The relation attribute value for the named stream's link relation.</returns>
        internal static string ComputeNamedStreamRelation(ODataMediaResource namedStream, bool forEditLink)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(namedStream != null, "namedStream != null");
            Debug.Assert(!string.IsNullOrEmpty(namedStream.Name), "!string.IsNullOrEmpty(namedStream.Name)");

            string segmentName = forEditLink ? AtomConstants.ODataNamedStreamsEditMediaSegmentName : AtomConstants.ODataNamedStreamsMediaResourceSegmentName;

            return(string.Join("/", new string[] { AtomConstants.ODataNamespace, segmentName, namedStream.Name }));
        }
Example #3
0
        /// <summary>
        /// Validates a named stream to ensure it's not null and it's name if correct.
        /// </summary>
        /// <param name="namedStream">The named stream to validate.</param>
        /// <param name="version">The version of the OData protocol used for checking.</param>
        internal static void ValidateNamedStream(ODataMediaResource namedStream, ODataVersion version)
        {
            DebugUtils.CheckNoExternalCallers();
            ODataVersionChecker.CheckNamedStreams(version);

            if (namedStream == null)
            {
                throw new ODataException(Strings.ODataWriter_NamedStreamMustNotBeNull);
            }

            if (string.IsNullOrEmpty(namedStream.Name))
            {
                throw new ODataException(Strings.ODataWriter_NamedStreamMustHaveNonEmptyName);
            }
        }
Example #4
0
        /// <summary>
        /// Validates an <see cref="ODataEntry"/> to ensure all required information is specified and valid.
        /// </summary>
        /// <param name="entry">The entry to validate.</param>
        internal static void ValidateEntry(ODataEntry entry)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entry != null, "entry != null");

            // Verify non-empty ID (entries can have no (null) ID for insert scenarios; empty IDs are not allowed)
            if (entry.Id != null && entry.Id.Length == 0)
            {
                throw new ODataException(Strings.ODataWriter_EntriesMustHaveNonEmptyId);
            }

            // Type name is verified in the format writers since it's shared with other non-entity types
            // and verifying it here would mean doing it twice.

            // Verify the default stream if it's present
            ODataMediaResource defaultStream = entry.MediaResource;

            if (defaultStream != null)
            {
                if (defaultStream.Name != null)
                {
                    throw new ODataException(Strings.ODataWriter_DefaultStreamMustNotHaveName);
                }

                if (string.IsNullOrEmpty(defaultStream.ContentType))
                {
                    throw new ODataException(Strings.ODataWriter_DefaultStreamMustHaveNonEmptyContentType);
                }

                if (defaultStream.ReadLink == null)
                {
                    throw new ODataException(Strings.ODataWriter_DefaultStreamMustHaveReadLink);
                }

                if (defaultStream.EditLink == null && defaultStream.ETag != null)
                {
                    throw new ODataException(Strings.ODataWriter_DefaultStreamMustHaveEditLinkToHaveETag);
                }
            }
        }
        /// <summary>
        /// Writes a named stream to the ATOM payload including an 
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="namedStream">The named stream to create the payload for.</param>
        internal static void WriteNamedStream(XmlWriter writer, Uri baseUri, ODataMediaResource namedStream)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(namedStream != null, "Named stream must not be null.");

            // <atom:link rel="...2007/08/dataservices/mediaresource/name">
            writer.WriteStartElement(
                AtomConstants.AtomNamespacePrefix,
                AtomConstants.AtomLinkElementName,
                AtomConstants.AtomNamespace);

            writer.WriteAttributeString(
                AtomConstants.AtomLinkRelationAttributeName,
                AtomUtils.ComputeNamedStreamRelation(namedStream, false));

            writer.WriteAttributeString(
                AtomConstants.AtomTitleElementName,
                namedStream.Name);

            Uri readLink = namedStream.ReadLink;
            if (readLink != null)
            {
                // TODO, ckerer: should we throw when no source link is provided?
                writer.WriteAttributeString(
                    AtomConstants.AtomHRefAttributeName,
                    AtomUtils.ToUrlAttributeValue(readLink, baseUri));
            }

            writer.WriteAttributeString(
                AtomConstants.AtomTypeAttributeName,
                namedStream.ContentType);

            writer.WriteEndElement();

            if (namedStream.EditLink != null)
            {
                // <atom:link rel="...2007/08/dataservices/edit-media/name">
                writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomLinkElementName,
                    AtomConstants.AtomNamespace);

                writer.WriteAttributeString(
                    AtomConstants.AtomLinkRelationAttributeName,
                    AtomUtils.ComputeNamedStreamRelation(namedStream, true));

                writer.WriteAttributeString(
                    AtomConstants.AtomTitleElementName,
                    namedStream.Name);

                Uri editLink = namedStream.EditLink;
                if (editLink != null)
                {
                    writer.WriteAttributeString(
                        AtomConstants.AtomHRefAttributeName,
                        AtomUtils.ToUrlAttributeValue(editLink, baseUri));
                }

                writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    namedStream.ContentType);

                string etag = namedStream.ETag;
                if (etag != null)
                {
                    WriteETag(writer, etag);
                }

                writer.WriteEndElement();
            }
        }
Example #6
0
        /// <summary>
        /// Writes the __metadata property and its content for an entry
        /// </summary>
        /// <param name="entry">The entry for which to write the metadata.</param>
        /// <returns>The resource type of the entry or null if no metadata is available.</returns>
        private ResourceType WriteEntryMetadata(ODataEntry entry)
        {
            Debug.Assert(entry != null, "entry != null");

            // Write the "__metadata" for the entry
            this.jsonWriter.WriteName(JsonConstants.ODataMetadataName);
            this.jsonWriter.StartObjectScope();

            // Write the "uri": "edit/read-link-uri"
            Uri uriValue = entry.EditLink;

            if (uriValue == null)
            {
                uriValue = entry.ReadLink;
            }

            if (uriValue != null)
            {
                this.jsonWriter.WriteName(JsonConstants.ODataMetadataUriName);
                this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(uriValue, this.BaseUri));
            }

            // Write the "etag": "ETag value"
            // TODO: if this is a top-level entry also put the ETag into the headers.
            string etag = entry.ETag;

            if (etag != null)
            {
                this.jsonWriter.WriteName(JsonConstants.ODataMetadataETagName);
                this.jsonWriter.WriteValue(etag);
            }

            // Write the "type": "typename"
            string       typeName  = entry.TypeName;
            ResourceType entryType = ValidationUtils.ValidateTypeName(this.MetadataProvider, typeName, ResourceTypeKind.EntityType, false);

            if (typeName != null)
            {
                this.jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName);
                this.jsonWriter.WriteValue(typeName);
            }

            // Write MLE metadata
            ODataMediaResource mediaResource = entry.MediaResource;

            if (mediaResource != null)
            {
                // Write the "edit_media": "url"
                Uri mediaEditLink = mediaResource.EditLink;
                if (mediaEditLink != null)
                {
                    this.jsonWriter.WriteName(JsonConstants.ODataMetadataEditMediaName);
                    this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(mediaEditLink, this.BaseUri));
                }

                // Write the "media_src": "url"
                Debug.Assert(mediaResource.ReadLink != null, "The default stream read link should have been validated by now.");
                this.jsonWriter.WriteName(JsonConstants.ODataMetadataMediaUriName);
                this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(mediaResource.ReadLink, this.BaseUri));

                // Write the "content_type": "type"
                Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now.");
                this.jsonWriter.WriteName(JsonConstants.ODataMetadataContentTypeName);
                this.jsonWriter.WriteValue(mediaResource.ContentType);

                // Write the "media_etag": "etag"
                string mediaETag = mediaResource.ETag;
                if (mediaETag != null)
                {
                    Debug.Assert(mediaEditLink != null, "The default stream edit link and etag should have been validated by now.");
                    this.jsonWriter.WriteName(JsonConstants.ODataMetadataMediaETagName);
                    this.jsonWriter.WriteValue(mediaETag);
                }
            }

            // Write properties metadata
            // For now only association links are supported here
            IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks;

            if (associationLinks != null)
            {
                bool firstAssociationLink = true;

                foreach (ODataAssociationLink associationLink in associationLinks)
                {
                    ValidationUtils.ValidateAssociationLink(associationLink, this.Version);

                    if (firstAssociationLink)
                    {
                        // Write the "properties": {
                        this.jsonWriter.WriteName(JsonConstants.ODataMetadataPropertiesName);
                        this.jsonWriter.StartObjectScope();

                        firstAssociationLink = false;
                    }

                    // Write the "LinkName": {
                    this.jsonWriter.WriteName(associationLink.Name);
                    this.jsonWriter.StartObjectScope();

                    // Write the "__associationuri": "url"
                    this.jsonWriter.WriteName(JsonConstants.ODataMetadataPropertiesAssociationUriName);
                    this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(associationLink.Url, this.BaseUri));

                    // Close the "LinkName" object
                    this.jsonWriter.EndObjectScope();
                }

                if (!firstAssociationLink)
                {
                    // Close the "properties" object
                    this.jsonWriter.EndObjectScope();
                }
            }

            // Close the __metadata object scope
            this.jsonWriter.EndObjectScope();

            return(entryType);
        }
        /// <summary>
        /// Writes a named stream to the ATOM payload including an
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="baseUri">The base Uri of the document or null if none was specified.</param>
        /// <param name="namedStream">The named stream to create the payload for.</param>
        internal static void WriteNamedStream(XmlWriter writer, Uri baseUri, ODataMediaResource namedStream)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(namedStream != null, "Named stream must not be null.");

            // <atom:link rel="...2007/08/dataservices/mediaresource/name">
            writer.WriteStartElement(
                AtomConstants.AtomNamespacePrefix,
                AtomConstants.AtomLinkElementName,
                AtomConstants.AtomNamespace);

            writer.WriteAttributeString(
                AtomConstants.AtomLinkRelationAttributeName,
                AtomUtils.ComputeNamedStreamRelation(namedStream, false));

            writer.WriteAttributeString(
                AtomConstants.AtomTitleElementName,
                namedStream.Name);

            Uri readLink = namedStream.ReadLink;

            if (readLink != null)
            {
                // TODO, ckerer: should we throw when no source link is provided?
                writer.WriteAttributeString(
                    AtomConstants.AtomHRefAttributeName,
                    AtomUtils.ToUrlAttributeValue(readLink, baseUri));
            }

            writer.WriteAttributeString(
                AtomConstants.AtomTypeAttributeName,
                namedStream.ContentType);

            writer.WriteEndElement();

            if (namedStream.EditLink != null)
            {
                // <atom:link rel="...2007/08/dataservices/edit-media/name">
                writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomLinkElementName,
                    AtomConstants.AtomNamespace);

                writer.WriteAttributeString(
                    AtomConstants.AtomLinkRelationAttributeName,
                    AtomUtils.ComputeNamedStreamRelation(namedStream, true));

                writer.WriteAttributeString(
                    AtomConstants.AtomTitleElementName,
                    namedStream.Name);

                Uri editLink = namedStream.EditLink;
                if (editLink != null)
                {
                    writer.WriteAttributeString(
                        AtomConstants.AtomHRefAttributeName,
                        AtomUtils.ToUrlAttributeValue(editLink, baseUri));
                }

                writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    namedStream.ContentType);

                string etag = namedStream.ETag;
                if (etag != null)
                {
                    WriteETag(writer, etag);
                }

                writer.WriteEndElement();
            }
        }
Example #8
0
        /// <summary>
        /// Write the content of the given entry.
        /// </summary>
        /// <param name="entry">The entry for which to write properties.</param>
        /// <param name="entryType">The <see cref="ResourceType"/> of the entry (or null if not metadata is available).</param>
        /// <param name="propertiesValueCache">The cache of properties.</param>
        /// <param name="rootSourcePathSegment">The root of the EPM source tree, if there's an EPM applied.</param>
        private void WriteEntryContent(ODataEntry entry, ResourceType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(propertiesValueCache != null, "propertiesValueCache != null");

            ODataMediaResource mediaResource = entry.MediaResource;

            if (mediaResource == null)
            {
                // <content type="application/xml">
                this.writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                this.writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    MimeConstants.MimeApplicationXml);

                // <m:properties>
                // we always write the <m:properties> element even if there are no properties
                this.writer.WriteStartElement(
                    AtomConstants.ODataMetadataNamespacePrefix,
                    AtomConstants.AtomPropertiesElementName,
                    AtomConstants.ODataMetadataNamespace);

                ODataAtomWriterUtils.WriteProperties(
                    this.writer,
                    this.MetadataProvider,
                    entryType,
                    propertiesValueCache.EntryProperties,
                    this.Version,
                    false,
                    propertiesValueCache,
                    rootSourcePathSegment);

                // </m:properties>
                this.writer.WriteEndElement();

                // </content>
                this.writer.WriteEndElement();
            }
            else
            {
                Uri mediaEditLink = mediaResource.EditLink;
                if (mediaEditLink != null)
                {
                    // <link rel="edit-media" href="href" />
                    this.writer.WriteStartElement(
                        AtomConstants.AtomNamespacePrefix,
                        AtomConstants.AtomLinkElementName,
                        AtomConstants.AtomNamespace);

                    this.writer.WriteAttributeString(
                        AtomConstants.AtomLinkRelationAttributeName,
                        AtomConstants.AtomEditMediaRelationAttributeValue);

                    this.writer.WriteAttributeString(
                        AtomConstants.AtomHRefAttributeName,
                        AtomUtils.ToUrlAttributeValue(mediaEditLink, this.BaseUri));

                    string mediaETag = mediaResource.ETag;
                    if (mediaETag != null)
                    {
                        this.writer.WriteAttributeString(
                            AtomConstants.ODataMetadataNamespacePrefix,
                            AtomConstants.ODataETagAttributeName,
                            AtomConstants.ODataMetadataNamespace,
                            mediaETag);
                    }

                    // </link>
                    this.writer.WriteEndElement();
                }

                Debug.Assert(mediaEditLink != null || mediaResource.ETag == null, "The default stream edit link and etag should have been validated by now.");

                // <content type="type" src="src">
                this.writer.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now.");
                this.writer.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    mediaResource.ContentType);

                Debug.Assert(mediaResource.ReadLink != null, "The default stream read link should have been validated by now.");
                this.writer.WriteAttributeString(
                    AtomConstants.MediaLinkEntryContentSourceAttributeName,
                    AtomUtils.ToUrlAttributeValue(mediaResource.ReadLink, this.BaseUri));

                // </content>
                this.writer.WriteEndElement();

                // <m:properties>
                // we always write the <m:properties> element even if there are no properties
                this.writer.WriteStartElement(
                    AtomConstants.ODataMetadataNamespacePrefix,
                    AtomConstants.AtomPropertiesElementName,
                    AtomConstants.ODataMetadataNamespace);

                ODataAtomWriterUtils.WriteProperties(
                    this.writer,
                    this.MetadataProvider,
                    entryType,
                    propertiesValueCache.EntryProperties,
                    this.Version,
                    false,
                    propertiesValueCache,
                    rootSourcePathSegment);

                // </m:properties>
                this.writer.WriteEndElement();
            }
        }
        /// <summary>
        /// Validates a named stream to ensure it's not null and it's name if correct.
        /// </summary>
        /// <param name="namedStream">The named stream to validate.</param>
        /// <param name="version">The version of the OData protocol used for checking.</param>
        internal static void ValidateNamedStream(ODataMediaResource namedStream, ODataVersion version)
        {
            DebugUtils.CheckNoExternalCallers();
            ODataVersionChecker.CheckNamedStreams(version);

            if (namedStream == null)
            {
                throw new ODataException(Strings.ODataWriter_NamedStreamMustNotBeNull);
            }

            if (string.IsNullOrEmpty(namedStream.Name))
            {
                throw new ODataException(Strings.ODataWriter_NamedStreamMustHaveNonEmptyName);
            }
        }