/// <summary> /// Set a property of atom:contributor element. atom:contributor is created if does not exist. /// </summary> /// <param name="propertyToSet">Property to be set.</param> /// <param name="textPropertyValue">Value of the property.</param> private void SetContributorProperty(SyndicationItemProperty propertyToSet, string textPropertyValue) { if (this.Target.Contributors.Count == 0) { this.Target.Contributors.Add(new SyndicationPerson()); } // We can have at most one contributor switch (propertyToSet) { case SyndicationItemProperty.ContributorEmail: this.Target.Contributors[0].Email = textPropertyValue; break; case SyndicationItemProperty.ContributorName: this.Target.Contributors[0].Name = textPropertyValue; break; case SyndicationItemProperty.ContributorUri: this.Target.Contributors[0].Uri = textPropertyValue; break; default: Debug.Fail("propertyToSet is not a Contributor property."); break; } Debug.Assert(this.Target.Contributors.Count == 1, "There should be one and only one contributor."); }
public EntityPropertyMappingAttribute(string sourcePath, string targetPath, string targetNamespacePrefix, string targetNamespaceUri, bool keepInContent) { Uri uri; if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("sourcePath")); } this.sourcePath = sourcePath; if (string.IsNullOrEmpty(targetPath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetPath")); } if (targetPath[0] == '@') { throw new ArgumentException(Strings.EntityPropertyMapping_InvalidTargetPath(targetPath)); } this.targetPath = targetPath; this.targetSyndicationItem = SyndicationItemProperty.CustomProperty; this.targetTextContentKind = SyndicationTextContentKind.Plaintext; this.targetNamespacePrefix = targetNamespacePrefix; if (string.IsNullOrEmpty(targetNamespaceUri)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetNamespaceUri")); } this.targetNamespaceUri = targetNamespaceUri; if (!Uri.TryCreate(targetNamespaceUri, UriKind.Absolute, out uri)) { throw new ArgumentException(Strings.EntityPropertyMapping_TargetNamespaceUriNotValid(targetNamespaceUri)); } this.keepInContent = keepInContent; }
/// <summary> /// Returns a value indicating whether the given syndication item property supports extension attributes /// </summary> /// <param name="itemProperty">The syndication item property</param> /// <returns>True if the property is Title, Summary, Rights, or Custom</returns> public static bool SupportsExtensionAttributes(this SyndicationItemProperty itemProperty) { return(itemProperty == SyndicationItemProperty.Title || itemProperty == SyndicationItemProperty.Summary || itemProperty == SyndicationItemProperty.Rights || itemProperty == SyndicationItemProperty.CustomProperty); }
/// <summary> /// Given a <paramref name="targetPath"/> gets the corresponding syndication property. /// </summary> /// <param name="targetPath">Target path in the form of syndication property name</param> /// <returns> /// Enumerated value of a SyndicationItemProperty or SyndicationItemProperty.CustomProperty if the <paramref name="targetPath"/> /// does not map to any syndication property name. /// </returns> private static SyndicationItemProperty MapEpmTargetPathToSyndicationProperty(String targetPath) { Debug.Assert(Enum.GetNames(typeof(SyndicationItemProperty)).Count() == 12, "Any addition to SyndicationItemPropery enum requires updating this method."); SyndicationItemProperty targetSyndicationItem = SyndicationItemProperty.CustomProperty; switch (targetPath) { case System.Data.Services.XmlConstants.SyndAuthorEmail: targetSyndicationItem = SyndicationItemProperty.AuthorEmail; break; case System.Data.Services.XmlConstants.SyndAuthorName: targetSyndicationItem = SyndicationItemProperty.AuthorName; break; case System.Data.Services.XmlConstants.SyndAuthorUri: targetSyndicationItem = SyndicationItemProperty.AuthorUri; break; case System.Data.Services.XmlConstants.SyndContributorEmail: targetSyndicationItem = SyndicationItemProperty.ContributorEmail; break; case System.Data.Services.XmlConstants.SyndContributorName: targetSyndicationItem = SyndicationItemProperty.ContributorName; break; case System.Data.Services.XmlConstants.SyndContributorUri: targetSyndicationItem = SyndicationItemProperty.ContributorUri; break; case System.Data.Services.XmlConstants.SyndUpdated: targetSyndicationItem = SyndicationItemProperty.Updated; break; case System.Data.Services.XmlConstants.SyndPublished: targetSyndicationItem = SyndicationItemProperty.Published; break; case System.Data.Services.XmlConstants.SyndRights: targetSyndicationItem = SyndicationItemProperty.Rights; break; case System.Data.Services.XmlConstants.SyndSummary: targetSyndicationItem = SyndicationItemProperty.Summary; break; case System.Data.Services.XmlConstants.SyndTitle: targetSyndicationItem = SyndicationItemProperty.Title; break; default: targetSyndicationItem = SyndicationItemProperty.CustomProperty; break; } return(targetSyndicationItem); }
public static string ToElementOrAttributeName(this SyndicationItemProperty itemProperty) { return(itemProperty.ToString().ToLowerInvariant() .Replace(ODataConstants.LinkElementName, string.Empty) .Replace(ODataConstants.CategoryElementName, string.Empty) .Replace(ODataConstants.AuthorElementName, string.Empty) .Replace(ODataConstants.ContributorElementName, string.Empty)); }
private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior) { Debug.Assert( writerBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient, "CreateDateTimeValue should not be used in WCF DS client mode."); if (propertyValue == null) { return(DateTimeOffset.Now); } if (propertyValue is DateTimeOffset) { return((DateTimeOffset)propertyValue); } if (propertyValue is DateTime) { // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up // with datetime without timezone info mapped to atom:updated or atom:published element. return(new DateTimeOffset((DateTime)propertyValue)); } string stringValue = propertyValue as string; if (stringValue != null) { DateTimeOffset date; if (!DateTimeOffset.TryParse(stringValue, out date)) { DateTime result; if (!DateTime.TryParse(stringValue, out result)) { throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return(new DateTimeOffset(result)); } return(date); } try { return(new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture))); } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } }
public EntityPropertyMappingAttribute(string sourcePath, SyndicationItemProperty targetSyndicationItem, SyndicationTextContentKind targetTextContentKind, bool keepInContent) { if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("sourcePath")); } this.sourcePath = sourcePath; this.targetPath = targetSyndicationItem.ToTargetPath(); this.targetSyndicationItem = targetSyndicationItem; this.targetTextContentKind = targetTextContentKind; this.targetNamespacePrefix = "atom"; this.targetNamespaceUri = "http://www.w3.org/2005/Atom"; this.keepInContent = keepInContent; }
public static string ToParentElementName(this SyndicationItemProperty itemProperty) { string[] parentElements = new[] { ODataConstants.LinkElementName, ODataConstants.CategoryElementName, ODataConstants.AuthorElementName, ODataConstants.ContributorElementName }; var stringValue = itemProperty.ToString().ToLowerInvariant(); foreach (var parent in parentElements) { if (stringValue.StartsWith(parent, StringComparison.Ordinal)) { return(parent); } } return(null); }
public EntityPropertyMappingAttribute(String sourcePath, SyndicationItemProperty targetSyndicationItem, SyndicationTextContentKind targetTextContentKind, bool keepInContent) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("sourcePath")); } this.sourcePath = sourcePath; this.targetPath = SyndicationItemPropertyToPath(targetSyndicationItem); this.targetSyndicationItem = targetSyndicationItem; this.targetTextContentKind = targetTextContentKind; this.targetNamespacePrefix = EntityPropertyMappingAttribute.AtomNamespacePrefix; this.targetNamespaceUri = XmlConstants.AtomNamespace; this.keepInContent = keepInContent; }
/// <summary> /// Used for mapping a resource property to syndication content /// </summary> /// <param name="sourcePath">Source property path</param> /// <param name="targetSyndicationItem">Syndication item to which the <see cref="sourcePath"/> is mapped</param> /// <param name="targetTextContentKind">Syndication content kind for <see cref="targetSyndicationItem"/></param> /// <param name="keepInContent">If true the property value is kept in the content section as before, /// when false the property value is only placed at the mapped location</param> public EntityPropertyMappingAttribute(String sourcePath, SyndicationItemProperty targetSyndicationItem, SyndicationTextContentKind targetTextContentKind, bool keepInContent) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("sourcePath")); } this.sourcePath = sourcePath; this.targetPath = SyndicationItemPropertyToPath(targetSyndicationItem); this.targetSyndicationItem = targetSyndicationItem; this.targetTextContentKind = targetTextContentKind; this.targetNamespacePrefix = EntityPropertyMappingAttribute.AtomNamespacePrefix; this.targetNamespaceUri = XmlConstants.AtomNamespace; this.keepInContent = keepInContent; }
/// <summary> /// Creates a Syndication EPM annotation on the <paramref name="annotatable"/>. /// </summary> /// <typeparam name="T">The type of the annotatable being passed in.</typeparam> /// <param name="annotatable">The annotatable to add the EPM annotation to.</param> /// <param name="sourcePath">The source path to be used in the mapping.</param> /// <param name="targetSyndicationItem">The syndication item to be used in the mapping (defaults to AuthorName).</param> /// <param name="targetTextContentKind">The target content kind (defaults to plain text).</param> /// <param name="keepInContent">true to keep the mapped value in content; otherwise false (defaults to true).</param> /// <returns>The <paramref name="annotatable"/> being passed in for composability.</returns> public static T EntityPropertyMapping <T>( this T annotatable, string sourcePath, SyndicationItemProperty targetSyndicationItem = SyndicationItemProperty.AuthorName, SyndicationTextContentKind targetTextContentKind = SyndicationTextContentKind.Plaintext, bool keepInContent = true) where T : AnnotatedItem { ExceptionUtilities.CheckArgumentNotNull(annotatable, "annotatable"); ExceptionUtilities.CheckArgumentNotNull(sourcePath, "sourcePath"); ExceptionUtilities.Assert(annotatable is EntityType, "Entity Property Mappings should only be applied to entity types"); annotatable.Add(new PropertyMappingAnnotation(sourcePath, targetSyndicationItem, targetTextContentKind, keepInContent)); return(annotatable); }
private static EntityPropertyMappingAttribute ValidateAnnotationValues(EpmAnnotationValues annotationValues, string typeName, IEdmProperty property) { if (annotationValues.TargetPath == null) { string str = "FC_TargetPath" + annotationValues.AttributeSuffix; string message = (property == null) ? Microsoft.Data.OData.Strings.EpmExtensionMethods_MissingAttributeOnType(str, typeName) : Microsoft.Data.OData.Strings.EpmExtensionMethods_MissingAttributeOnProperty(str, property.Name, typeName); throw new ODataException(message); } bool result = true; if ((annotationValues.KeepInContent != null) && !bool.TryParse(annotationValues.KeepInContent, out result)) { string str3 = "FC_KeepInContent" + annotationValues.AttributeSuffix; throw new InvalidOperationException((property == null) ? Microsoft.Data.OData.Strings.EpmExtensionMethods_InvalidKeepInContentOnType(str3, typeName) : Microsoft.Data.OData.Strings.EpmExtensionMethods_InvalidKeepInContentOnProperty(str3, property.Name, typeName)); } SyndicationItemProperty targetSyndicationItem = MapTargetPathToSyndicationProperty(annotationValues.TargetPath); if (targetSyndicationItem == SyndicationItemProperty.CustomProperty) { if (annotationValues.ContentKind != null) { string str4 = "FC_ContentKind" + annotationValues.AttributeSuffix; string str5 = (property == null) ? Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForCustomMappingOnType(str4, typeName) : Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForCustomMappingOnProperty(str4, property.Name, typeName); throw new ODataException(str5); } return(new EntityPropertyMappingAttribute(annotationValues.SourcePath, annotationValues.TargetPath, annotationValues.NamespacePrefix, annotationValues.NamespaceUri, result)); } if (annotationValues.NamespaceUri != null) { string str6 = "FC_NsUri" + annotationValues.AttributeSuffix; string str7 = (property == null) ? Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForAtomPubMappingOnType(str6, typeName) : Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForAtomPubMappingOnProperty(str6, property.Name, typeName); throw new ODataException(str7); } if (annotationValues.NamespacePrefix != null) { string str8 = "FC_NsPrefix" + annotationValues.AttributeSuffix; string str9 = (property == null) ? Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForAtomPubMappingOnType(str8, typeName) : Microsoft.Data.OData.Strings.EpmExtensionMethods_AttributeNotAllowedForAtomPubMappingOnProperty(str8, property.Name, typeName); throw new ODataException(str9); } SyndicationTextContentKind plaintext = SyndicationTextContentKind.Plaintext; if (annotationValues.ContentKind != null) { plaintext = MapContentKindToSyndicationTextContentKind(annotationValues.ContentKind, annotationValues.AttributeSuffix, typeName, (property == null) ? null : property.Name); } return(new EntityPropertyMappingAttribute(annotationValues.SourcePath, targetSyndicationItem, plaintext, result)); }
private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior) { DateTimeOffset offset; DateTime time; if (propertyValue == null) { return(DateTimeOffset.Now); } if (propertyValue is DateTimeOffset) { return((DateTimeOffset)propertyValue); } if (propertyValue is DateTime) { return(new DateTimeOffset((DateTime)propertyValue)); } string input = propertyValue as string; if (input == null) { DateTimeOffset offset2; try { offset2 = new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture)); } catch (Exception exception) { if (!ExceptionUtils.IsCatchableExceptionType(exception)) { throw; } throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return(offset2); } if (DateTimeOffset.TryParse(input, out offset)) { return(offset); } if (!DateTime.TryParse(input, out time)) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return(new DateTimeOffset(time)); }
/// <summary> /// Applies EPM mapping to the specified entity type on the model and returns it for composablity. /// </summary> /// <param name="model">Model to use</param> /// <param name="entityTypeName">Entity type name</param> /// <param name="sourcePath">Source path</param> /// <param name="targetSyndicationItem">TargetSyndicationItem to use</param> /// <param name="targetTextContentKind">TargetTextContentKind to use</param> /// <param name="keepInContent">true to keep the mapped value in content; otherwise false (defaults to true).</param> /// <returns>Enity Model Schema with the mapping applied</returns> public static EntityModelSchema EntityPropertyMapping( this EntityModelSchema model, string entityTypeName, string sourcePath, SyndicationItemProperty targetSyndicationItem = SyndicationItemProperty.AuthorName, SyndicationTextContentKind targetTextContentKind = SyndicationTextContentKind.Plaintext, bool keepInContent = true) { ExceptionUtilities.CheckArgumentNotNull(model, "model"); ExceptionUtilities.CheckArgumentNotNull(entityTypeName, "entityTypeName"); ExceptionUtilities.CheckArgumentNotNull(sourcePath, "sourcePath"); var entityType = model.GetEntityType(entityTypeName); ExceptionUtilities.CheckObjectNotNull(entityType, "There are no entity types matching the name:{0} in the model", entityTypeName); entityType.EntityPropertyMapping(sourcePath, targetSyndicationItem, targetTextContentKind, keepInContent); return(model); }
private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior) { DateTimeOffset offset; DateTime time; if (propertyValue == null) { return DateTimeOffset.Now; } if (propertyValue is DateTimeOffset) { return (DateTimeOffset) propertyValue; } if (propertyValue is DateTime) { return new DateTimeOffset((DateTime) propertyValue); } string input = propertyValue as string; if (input == null) { DateTimeOffset offset2; try { offset2 = new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture)); } catch (Exception exception) { if (!ExceptionUtils.IsCatchableExceptionType(exception)) { throw; } throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return offset2; } if (DateTimeOffset.TryParse(input, out offset)) { return offset; } if (!DateTime.TryParse(input, out time)) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return new DateTimeOffset(time); }
/// <summary> /// Maps the enumeration of allowed <see cref="SyndicationItemProperty"/> values to their string representations /// </summary> /// <param name="targetSyndicationItem">Value of the <see cref="SyndicationItemProperty"/> given in /// the <see cref="EntityPropertyMappingAttribute"/> contstructor</param> /// <returns>String representing the xml element path in the syndication property</returns> internal static String SyndicationItemPropertyToPath(SyndicationItemProperty targetSyndicationItem) { switch (targetSyndicationItem) { case SyndicationItemProperty.AuthorEmail: return("author/email"); case SyndicationItemProperty.AuthorName: return("author/name"); case SyndicationItemProperty.AuthorUri: return("author/uri"); case SyndicationItemProperty.ContributorEmail: return("contributor/email"); case SyndicationItemProperty.ContributorName: return("contributor/name"); case SyndicationItemProperty.ContributorUri: return("contributor/uri"); case SyndicationItemProperty.Updated: return("updated"); case SyndicationItemProperty.Published: return("published"); case SyndicationItemProperty.Rights: return("rights"); case SyndicationItemProperty.Summary: return("summary"); case SyndicationItemProperty.Title: return("title"); default: throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetSyndicationItem")); } }
/// <summary> /// Used for conditional mapping to atom:link[@href] and atom:category[@term]. /// </summary> /// <param name="sourcePath">Source property path.</param> /// <param name="targetSyndicationItem">Syndication item to which the <see cref="sourcePath"/> is mapped.</param> /// <param name="keepInContent">If true the property value is kept in the content section as before, /// when false the property value is only placed at the mapped location.</param> /// <param name="criteriaValue">Criteria value that is used as a condition.</param> public EntityPropertyMappingAttribute(String sourcePath, SyndicationItemProperty targetSyndicationItem, bool keepInContent, String criteriaValue) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("sourcePath")); } this.sourcePath = sourcePath; if (String.IsNullOrEmpty(criteriaValue)) { throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("criteriaValue")); } this.criteriaValue = criteriaValue; this.targetPath = SyndicationItemPropertyToPath(targetSyndicationItem); this.targetSyndicationItem = targetSyndicationItem; this.targetTextContentKind = SyndicationTextContentKind.Plaintext; this.targetNamespacePrefix = AtomConstants.NonEmptyAtomNamespacePrefix; this.targetNamespaceUri = AtomConstants.AtomNamespace; this.keepInContent = keepInContent; }
private static string ToAttributeValue(this SyndicationItemProperty syndicationItemProperty) { switch (syndicationItemProperty) { case SyndicationItemProperty.AuthorEmail: return("SyndicationAuthorEmail"); case SyndicationItemProperty.AuthorName: return("SyndicationAuthorName"); case SyndicationItemProperty.AuthorUri: return("SyndicationAuthorUri"); case SyndicationItemProperty.ContributorEmail: return("SyndicationContributorEmail"); case SyndicationItemProperty.ContributorName: return("SyndicationContributorName"); case SyndicationItemProperty.ContributorUri: return("SyndicationContributorUri"); case SyndicationItemProperty.Updated: return("SyndicationUpdated"); case SyndicationItemProperty.Published: return("SyndicationPublished"); case SyndicationItemProperty.Rights: return("SyndicationRights"); case SyndicationItemProperty.Summary: return("SyndicationSummary"); case SyndicationItemProperty.Title: return("SyndicationTitle"); } throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.EpmExtensionMethods_ToAttributeValue_SyndicationItemProperty)); }
public PropertyMappingAnnotation( string sourcePath, SyndicationItemProperty targetSyndicationItem, SyndicationTextContentKind targetTextContentKind, bool keepInContent) : this(sourcePath, keepInContent) { this.SyndicationItemProperty = targetSyndicationItem; this.SyndicationTextContentKind = targetTextContentKind; this.TargetPath = targetSyndicationItem.ToString().ToLowerInvariant(); if (this.TargetPath.StartsWith(ODataConstants.AuthorElementName, StringComparison.Ordinal)) { this.TargetPath = this.TargetPath.Insert(ODataConstants.AuthorElementName.Length, "/"); } else if (this.TargetPath.StartsWith(ODataConstants.ContributorElementName, StringComparison.Ordinal)) { this.TargetPath = this.TargetPath.Insert(ODataConstants.ContributorElementName.Length, "/"); } this.TargetNamespacePrefix = null; this.TargetNamespaceUri = ODataConstants.AtomNamespaceName; }
internal static string MapSyndicationPropertyToEpmTargetPath(SyndicationItemProperty property) { return syndicationItemToTargetPath[(int) property]; }
/// <summary> /// Maps the enumeration of allowed <see cref="SyndicationItemProperty"/> values to their string representations /// </summary> /// <param name="targetSyndicationItem">Value of the <see cref="SyndicationItemProperty"/> given in /// the <see cref="EntityPropertyMappingAttribute"/> contstructor</param> /// <returns>String representing the xml element path in the syndication property</returns> internal static String SyndicationItemPropertyToPath(SyndicationItemProperty targetSyndicationItem) { switch (targetSyndicationItem) { case SyndicationItemProperty.AuthorEmail: return "author/email"; case SyndicationItemProperty.AuthorName: return "author/name"; case SyndicationItemProperty.AuthorUri: return "author/uri"; case SyndicationItemProperty.ContributorEmail: return "contributor/email"; case SyndicationItemProperty.ContributorName: return "contributor/name"; case SyndicationItemProperty.ContributorUri: return "contributor/uri"; case SyndicationItemProperty.Updated: return "updated"; case SyndicationItemProperty.Published: return "published"; case SyndicationItemProperty.Rights: return "rights"; case SyndicationItemProperty.Summary: return "summary"; case SyndicationItemProperty.Title: return "title"; default: throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetSyndicationItem")); } }
internal void Add(EntityPropertyMappingInfo epmInfo) { DebugUtils.CheckNoExternalCallers(); List <EpmSourcePathSegment> pathToCurrentSegment = new List <EpmSourcePathSegment>(); EpmSourcePathSegment currentSourceSegment = this.Root; EpmSourcePathSegment foundSourceSegment = null; ResourceType currentType = epmInfo.ActualPropertyType; EpmSourcePathSegment multiValuePropertySegment = null; Debug.Assert(!string.IsNullOrEmpty(epmInfo.Attribute.SourcePath), "Invalid source path"); string[] propertyPath = epmInfo.Attribute.SourcePath.Split('/'); if (epmInfo.CriteriaValue != null) { ValidateConditionalMapping(epmInfo); } Debug.Assert(propertyPath.Length > 0, "Must have been validated during EntityPropertyMappingAttribute construction"); for (int sourcePropertyIndex = 0; sourcePropertyIndex < propertyPath.Length; sourcePropertyIndex++) { string propertyName = propertyPath[sourcePropertyIndex]; if (propertyName.Length == 0) { throw new ODataException(Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.Name, epmInfo.Attribute.SourcePath)); } bool isMultiValueProperty; currentType = GetPropertyType(currentType, propertyName, out isMultiValueProperty); foundSourceSegment = currentSourceSegment.SubProperties.SingleOrDefault(e => e.PropertyName == propertyName); if (foundSourceSegment != null) { currentSourceSegment = foundSourceSegment; } else { EpmSourcePathSegment newSourceSegment = new EpmSourcePathSegment(propertyName); currentSourceSegment.SubProperties.Add(newSourceSegment); currentSourceSegment = newSourceSegment; } pathToCurrentSegment.Add(currentSourceSegment); if (isMultiValueProperty) { Debug.Assert( currentSourceSegment.EpmInfo == null || currentSourceSegment.EpmInfo.MultiValueStatus == EntityPropertyMappingMultiValueStatus.MultiValueProperty, "MultiValue property must have EpmInfo marked as MultiValue or none at all."); Debug.Assert( currentSourceSegment.EpmInfo != null || foundSourceSegment == null, "The only way to get a propety without info attached yet on a MultiValue property is when we just created it."); if (multiValuePropertySegment != null) { // Nested MultiValue - not allowed to be mapped throw new ODataException(Strings.EpmSourceTree_NestedMultiValue( multiValuePropertySegment.EpmInfo.Attribute.SourcePath, multiValuePropertySegment.EpmInfo.DefiningType.Name, epmInfo.Attribute.SourcePath)); } multiValuePropertySegment = currentSourceSegment; // MultiValue properties can only be mapped to a top-level element, so we can blindly use the first part // of the target path as the target path for the MultiValue property. Debug.Assert(!string.IsNullOrEmpty(epmInfo.Attribute.TargetPath), "Target path should have been checked by the EpmAttribute constructor."); string multiValuePropertyTargetPath = epmInfo.Attribute.TargetPath.Split('/')[0]; if (currentSourceSegment.EpmInfo == null || !currentSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo)) { if (currentSourceSegment.EpmInfo != null) { Debug.Assert(!currentSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo), "Just verifying that the ifs are correct."); Debug.Assert(foundSourceSegment != null, "Can't have existing node with EpmInfo on it here and not found it before."); // If the MultiValue property we're trying to add is from a different type than the one we already have // just overwrite the epm info. This means that the derived type defines a different mapping for the property than the base type. // We also need to walk all the children of the base type mapping here and remove them from the target tree // since we're overriding the entire MultiValue property mapping (not just one item property) // Note that for MultiValue properties, removing the MultiValue property node itself will remove all the MultiValue item properties as well // as they have to be children of the MultiValue property node in the target tree. this.epmTargetTree.Remove(foundSourceSegment.EpmInfo); // We also need to remove all children of the MultiValue property node from the source tree // as the derived type is overriding it completely. If the derived type doesn't override all of the properties // we should fail as if it did't map all of them. currentSourceSegment.SubProperties.Clear(); } // This is the first time we've seen this MultiValue property mapped // (on this type, we might have seen it on the base type, but that has been removed) // The source path is the path we have so far for the property string multiValuePropertySourcePath = string.Join("/", propertyPath, 0, sourcePropertyIndex + 1); if (!epmInfo.IsSyndicationMapping) { // Custom EPM for MultiValue is not supported yet // Note: This has already been implemented, but then removed from the code. To see what it takes to implement this // please see the change which adds this comment into the sources. throw new ODataException(Strings.EpmSourceTree_MultiValueNotAllowedInCustomMapping( multiValuePropertySourcePath, epmInfo.DefiningType.Name)); } // Create a new EPM attribute to represent the MultiValue property mapping // note that this attribute is basically implicitly declared whenever the user declares EPM attribute // for a property from some MultiValue property. (the declaration happens right here) EntityPropertyMappingAttribute multiValueEpmAttribute = new EntityPropertyMappingAttribute( multiValuePropertySourcePath, multiValuePropertyTargetPath, epmInfo.Attribute.TargetNamespacePrefix, epmInfo.Attribute.TargetNamespaceUri, epmInfo.Attribute.KeepInContent); // Create a special EpmInfo from the above special attribute which represents just the MultiValue property itself EntityPropertyMappingInfo multiValueEpmInfo = new EntityPropertyMappingInfo( multiValueEpmAttribute, epmInfo.DefiningType, epmInfo.ActualPropertyType); multiValueEpmInfo.MultiValueStatus = EntityPropertyMappingMultiValueStatus.MultiValueProperty; multiValueEpmInfo.MultiValueItemType = currentType; // We need to mark the info as syndication/custom mapping explicitely since the attribute we create (From which it's infered) is always custom mapping Debug.Assert(epmInfo.IsSyndicationMapping, "Only syndication mapping is allowed for MultiValue properties."); multiValueEpmInfo.SetMultiValuePropertySyndicationMapping(); multiValueEpmInfo.SetPropertyValuePath(pathToCurrentSegment.ToArray()); multiValueEpmInfo.Criteria = epmInfo.Criteria; multiValueEpmInfo.CriteriaValue = epmInfo.CriteriaValue; // Now associate the current source tree segment with the new info object (or override the one from base) currentSourceSegment.EpmInfo = multiValueEpmInfo; // And add the new info to the target tree this.epmTargetTree.Add(multiValueEpmInfo); // And continue with the walk of the source path. // This means that the EPM attribute specified as the input to this method is still to be added // It might be added to the source tree if the path is longer (property on an item in the MultiValue property of complex types) // or it might not be added to the source tree if this segment is the last (MultiValue property of primitive types). // In any case it will be added to the target tree (so even if the MultiValue property itself is mapped to the top-level element only // the items in the MultiValue property can be mapped to child element/attribute of that top-level element). } else { Debug.Assert(currentSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo), "The condition in the surrounding if is broken."); // We have already found a MultiValue property mapped from this source node. // If it's on the same defining type we need to make sure that it's the same MultiValue property being mapped // First verify that the mapping for the other property has the same top-level element for the MultiValue property // since we only allow properties from one MultiValue property to be mapped to the same top-level element if (multiValuePropertyTargetPath != currentSourceSegment.EpmInfo.Attribute.TargetPath || epmInfo.Attribute.TargetNamespacePrefix != currentSourceSegment.EpmInfo.Attribute.TargetNamespacePrefix || epmInfo.Attribute.TargetNamespaceUri != currentSourceSegment.EpmInfo.Attribute.TargetNamespaceUri || epmInfo.Criteria != currentSourceSegment.EpmInfo.Criteria || String.Compare(epmInfo.Attribute.CriteriaValue, currentSourceSegment.EpmInfo.CriteriaValue, StringComparison.OrdinalIgnoreCase) != 0) { throw new ODataException(Strings.EpmSourceTree_PropertiesFromSameMultiValueMappedToDifferentTopLevelElements(currentSourceSegment.EpmInfo.Attribute.SourcePath, currentSourceSegment.EpmInfo.DefiningType.Name)); } // Second verify that the mappings for both properties have the same KeepInContent value if (epmInfo.Attribute.KeepInContent != currentSourceSegment.EpmInfo.Attribute.KeepInContent) { throw new ODataException(Strings.EpmSourceTree_PropertiesFromSameMultiValueMappedWithDifferentKeepInContent(currentSourceSegment.EpmInfo.Attribute.SourcePath, currentSourceSegment.EpmInfo.DefiningType.Name)); } } } } // The last segment is the one being mapped from by the user specified attribute. // It must be a primitive type - we don't allow mappings of anything else than primitive properties directly. // Note that we can only verify this for non-open properties, for open properties we must assume it's a primitive type // and we will make this check later during serialization again when we actually have the value of the property. if (currentType != null) { if (currentType.ResourceTypeKind != ResourceTypeKind.Primitive) { throw new ODataException(Strings.EpmSourceTree_EndsWithNonPrimitiveType(currentSourceSegment.PropertyName)); } SyndicationItemProperty targetSyndicationItem = epmInfo.Attribute.TargetSyndicationItem; if (targetSyndicationItem == SyndicationItemProperty.LinkRel || targetSyndicationItem == SyndicationItemProperty.CategoryScheme) { if (PrimitiveStringResourceType != currentType) { throw new InvalidOperationException(Strings.EpmSourceTree_NonStringPropertyMappedToConditionAttribute( currentSourceSegment.PropertyName, epmInfo.DefiningType.FullName, targetSyndicationItem.ToString())); } } } if (multiValuePropertySegment == currentSourceSegment) { // If the MultiValue property is the last segment it means that the MultiValue property itself is being mapped (and it must be a MultiValue of primitive types). // If we found the MultiValue property already in the tree, here we actually want the item of the MultiValue property (as the MultiValue one was processed above already) // If we have the item value already in the tree use it as the foundProperty so that we correctly check the duplicate mappings below if (foundSourceSegment != null) { Debug.Assert(foundSourceSegment == currentSourceSegment, "If we found an existing segment it must be the current one."); foundSourceSegment = currentSourceSegment.SubProperties.SingleOrDefault(e => e.IsMultiValueItemValue); } if (foundSourceSegment == null) { // This is a bit of a special case. In the source tree we will create a special node to represent the item value (we need that to be able to tell // if it was not mapped twice). // In the target tree, we will also create a special node which will hold the information specific // to serialization of the item value (for example the exact syndication mapping target and so on). // The creation of the special node is done in the target tree Add method. EpmSourcePathSegment newSegment = EpmSourcePathSegment.CreateMultiValueItemValueSegment(); currentSourceSegment.SubProperties.Add(newSegment); currentSourceSegment = newSegment; } else { currentSourceSegment = foundSourceSegment; } } // Note that once we're here the EpmInfo we have is never the MultiValue property itself, it's always either a non-MultiValue property // or MultiValue item property. Debug.Assert(foundSourceSegment == null || foundSourceSegment.EpmInfo != null, "Can't have a leaf node in the tree without EpmInfo."); // Two EpmAttributes with same PropertyName in the same ResourceType, this could be a result of inheritance if (foundSourceSegment != null) { Debug.Assert(Object.ReferenceEquals(foundSourceSegment, currentSourceSegment), "currentSourceSegment variable should have been updated already to foundSourceSegment"); Debug.Assert( foundSourceSegment.EpmInfo.MultiValueStatus != EntityPropertyMappingMultiValueStatus.MultiValueProperty, "We should never get here with a MultiValue property itself, we should have a node represent its item or property on the item instead."); // Check for duplicates on the same entity type Debug.Assert(foundSourceSegment.SubProperties.Count == 0, "If non-leaf, it means we allowed complex type to be a leaf node"); if (foundSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo)) { throw new ODataException(Strings.EpmSourceTree_DuplicateEpmAttrsWithSameSourceName(epmInfo.Attribute.SourcePath, epmInfo.DefiningType.Name)); } // In case of inheritance, we need to remove the node from target tree which was mapped to base type property this.epmTargetTree.Remove(foundSourceSegment.EpmInfo); } epmInfo.SetPropertyValuePath(pathToCurrentSegment.ToArray()); currentSourceSegment.EpmInfo = epmInfo; if (multiValuePropertySegment != null) { Debug.Assert(multiValuePropertySegment.EpmInfo != null, "All MultiValue property segments must have EpmInfo assigned."); // We are mapping a MultiValue property - so mark the info as a MultiValue item property (since the MultiValue property itself was added above) epmInfo.MultiValueStatus = EntityPropertyMappingMultiValueStatus.MultiValueItemProperty; // Set the item type on each of the item properties, so that the segmented path know from which type to start epmInfo.MultiValueItemType = multiValuePropertySegment.EpmInfo.MultiValueItemType; // And trim its property value path to start from the MultiValue item. This path is basically a list of properties to traverse // when access the value of the property on the specified resource. For non-MultiValue and MultiValue properties themselves // this path starts with the entity instance. For MultiValue item properties this path starts with the MultiValue item instance. // Note that if it's a MultiValue of primitive types, the path is going to be empty meaning that the value is the item instance itself. epmInfo.TrimMultiValueItemPropertyPath(multiValuePropertySegment.EpmInfo); #if DEBUG // Check that if the MultiValue item is of primitive type, we can only ever add a single child source segment which points directly to the MultiValue property itself // If we would allow this here, we would fail later, but with a much weirder error message Debug.Assert( multiValuePropertySegment.EpmInfo.MultiValueItemType.ResourceTypeKind != ResourceTypeKind.Primitive || epmInfo.PropertyValuePath.Length == 0, "We shoud have failed to map a subproperty of a primitive MultiValue item."); #endif } this.epmTargetTree.Add(epmInfo); }
/// <summary> /// Obtains the epm information for a single property by reading csdl content /// </summary> /// <param name="extendedProperties">Collection of extended metadata properties for a resource</param> /// <param name="typeName">Type for which we are reading the metadata properties</param> /// <param name="memberName">Member for which we are reading the metadata properties</param> /// <returns>EpmPropertyInformation corresponding to read metadata properties</returns> private static IEnumerable <EpmPropertyInformation> GetEpmPropertyInformation(IEnumerable <MetadataProperty> extendedProperties, String typeName, String memberName) { EpmAttributeNameBuilder epmAttributeNameBuilder = new EpmAttributeNameBuilder(); while (true) { bool pathGiven = true; // EpmTargetPath is the only non-optional EPM attribute. If it is declared we need to take care of mapping. MetadataProperty epmTargetPathProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmTargetPath, typeName, memberName); if (epmTargetPathProperty != null) { // By default, we keep the copy in content for backwards compatibility bool epmKeepInContent = true; MetadataProperty epmKeepInContentProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmKeepInContent, typeName, memberName); if (epmKeepInContentProperty != null) { if (!Boolean.TryParse(Convert.ToString(epmKeepInContentProperty.Value, CultureInfo.InvariantCulture), out epmKeepInContent)) { throw new InvalidOperationException(memberName == null ? Strings.ObjectContext_InvalidValueForEpmPropertyType(epmAttributeNameBuilder.EpmKeepInContent, typeName) : Strings.ObjectContext_InvalidValueForEpmPropertyMember(epmAttributeNameBuilder.EpmKeepInContent, memberName, typeName)); } } MetadataProperty epmSourcePathProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmSourcePath, typeName, memberName); String epmSourcePath; if (epmSourcePathProperty == null) { if (memberName == null) { throw new InvalidOperationException(Strings.ObjectContext_MissingExtendedAttributeType(epmAttributeNameBuilder.EpmSourcePath, typeName)); } pathGiven = false; epmSourcePath = memberName; } else { epmSourcePath = Convert.ToString(epmSourcePathProperty.Value, CultureInfo.InvariantCulture); } String epmTargetPath = Convert.ToString(epmTargetPathProperty.Value, CultureInfo.InvariantCulture); // if the property is not a sydication property MapEpmTargetPathToSyndicationProperty // will return SyndicationItemProperty.CustomProperty SyndicationItemProperty targetSyndicationItem = MapEpmTargetPathToSyndicationProperty(epmTargetPath); MetadataProperty epmContentKindProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmContentKind, typeName, memberName); MetadataProperty epmNsPrefixProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmNsPrefix, typeName, memberName); MetadataProperty epmNsUriProperty = FindSingletonExtendedProperty( extendedProperties, epmAttributeNameBuilder.EpmNsUri, typeName, memberName); // ContentKind is mutually exclusive with NsPrefix and NsUri properties if (epmContentKindProperty != null) { if (epmNsPrefixProperty != null || epmNsUriProperty != null) { string epmPropertyName = epmNsPrefixProperty != null ? epmAttributeNameBuilder.EpmNsPrefix : epmAttributeNameBuilder.EpmNsUri; throw new InvalidOperationException(memberName == null ? Strings.ObjectContext_InvalidAttributeForNonSyndicationItemsType(epmPropertyName, typeName) : Strings.ObjectContext_InvalidAttributeForNonSyndicationItemsMember(epmPropertyName, memberName, typeName)); } } // epmNsPrefixProperty and epmNsUriProperty can be non-null only for non-Atom mapping. Since they are optional we need to check // if it was possible to map the target path to a syndication item name. if it was not (i.e. targetSyndicationItem == SyndicationItemProperty.CustomProperty) // this is a non-Atom kind of mapping. if (epmNsPrefixProperty != null || epmNsUriProperty != null || targetSyndicationItem == SyndicationItemProperty.CustomProperty) { String epmNsPrefix = epmNsPrefixProperty != null?Convert.ToString(epmNsPrefixProperty.Value, CultureInfo.InvariantCulture) : null; String epmNsUri = epmNsUriProperty != null?Convert.ToString(epmNsUriProperty.Value, CultureInfo.InvariantCulture) : null; yield return(new EpmPropertyInformation { IsAtom = false, KeepInContent = epmKeepInContent, SourcePath = epmSourcePath, PathGiven = pathGiven, TargetPath = epmTargetPath, NsPrefix = epmNsPrefix, NsUri = epmNsUri }); } else { SyndicationTextContentKind syndicationContentKind; if (epmContentKindProperty != null) { syndicationContentKind = MapEpmContentKindToSyndicationTextContentKind( Convert.ToString(epmContentKindProperty.Value, CultureInfo.InvariantCulture), typeName, memberName); } else { syndicationContentKind = SyndicationTextContentKind.Plaintext; } yield return(new EpmPropertyInformation { IsAtom = true, KeepInContent = epmKeepInContent, SourcePath = epmSourcePath, PathGiven = pathGiven, SyndicationItem = targetSyndicationItem, ContentKind = syndicationContentKind }); } epmAttributeNameBuilder.MoveNext(); } else { yield break; } } }
/// <summary> /// Converts test enum SyndicationItemProperty to product enum. /// </summary> /// <param name="item">test enum value</param> /// <returns>product enum</returns> public static AtomSyndicationItemProperty ToProductEnum(this SyndicationItemProperty item) { return(ConvertEnum <SyndicationItemProperty, AtomSyndicationItemProperty>(item)); }
/// <summary> /// Maps the enumeration of allowed <see cref="SyndicationItemProperty"/> values to their string representations. /// </summary> /// <param name="targetSyndicationItem">Value of the <see cref="SyndicationItemProperty"/> given in /// the <see cref="EntityPropertyMappingAttribute"/> contstructor.</param> /// <returns>String representing the xml element path in the syndication property.</returns> internal static String SyndicationItemPropertyToPath(SyndicationItemProperty targetSyndicationItem) { DebugUtils.CheckNoExternalCallers(); switch (targetSyndicationItem) { case SyndicationItemProperty.AuthorEmail: return "author/email"; case SyndicationItemProperty.AuthorName: return "author/name"; case SyndicationItemProperty.AuthorUri: return "author/uri"; case SyndicationItemProperty.ContributorEmail: return "contributor/email"; case SyndicationItemProperty.ContributorName: return "contributor/name"; case SyndicationItemProperty.ContributorUri: return "contributor/uri"; case SyndicationItemProperty.Updated: return "updated"; case SyndicationItemProperty.Published: return "published"; case SyndicationItemProperty.Rights: return "rights"; case SyndicationItemProperty.Summary: return "summary"; case SyndicationItemProperty.Title: return "title"; case SyndicationItemProperty.CategoryLabel: return "category/@label"; case SyndicationItemProperty.CategoryScheme: return "category/@scheme"; case SyndicationItemProperty.CategoryTerm: return "category/@term"; case SyndicationItemProperty.LinkHref: return "link/@href"; case SyndicationItemProperty.LinkHrefLang: return "link/@hreflang"; case SyndicationItemProperty.LinkLength: return "link/@length"; case SyndicationItemProperty.LinkRel: return "link/@rel"; case SyndicationItemProperty.LinkTitle: return "link/@title"; case SyndicationItemProperty.LinkType: return "link/@type"; default: throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetSyndicationItem")); } }
private static IEnumerable <EpmPropertyInformation> GetEpmPropertyInformation(MetadataItem metadataItem, string typeName, string memberName) { EpmAttributeNameBuilder iteratorVariable0 = new EpmAttributeNameBuilder(); while (true) { string iteratorVariable6; bool iteratorVariable1 = true; MetadataProperty iteratorVariable2 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmTargetPath); if (iteratorVariable2 == null) { break; } bool result = true; MetadataProperty iteratorVariable4 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmKeepInContent); if ((iteratorVariable4 != null) && !bool.TryParse(Convert.ToString(iteratorVariable4.Value, CultureInfo.InvariantCulture), out result)) { throw new InvalidOperationException((memberName == null) ? Strings.ObjectContext_InvalidValueForEpmPropertyType(iteratorVariable0.EpmKeepInContent, typeName) : Strings.ObjectContext_InvalidValueForEpmPropertyMember(iteratorVariable0.EpmKeepInContent, memberName, typeName)); } MetadataProperty iteratorVariable5 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmSourcePath); if (iteratorVariable5 == null) { if (memberName == null) { throw new InvalidOperationException(Strings.ObjectContext_MissingExtendedAttributeType(iteratorVariable0.EpmSourcePath, typeName)); } iteratorVariable1 = false; iteratorVariable6 = memberName; } else { iteratorVariable6 = Convert.ToString(iteratorVariable5.Value, CultureInfo.InvariantCulture); } string targetPath = Convert.ToString(iteratorVariable2.Value, CultureInfo.InvariantCulture); SyndicationItemProperty iteratorVariable8 = EpmTranslate.MapEpmTargetPathToSyndicationProperty(targetPath); MetadataProperty iteratorVariable9 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmContentKind); MetadataProperty iteratorVariable10 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmNsPrefix); MetadataProperty iteratorVariable11 = EdmUtil.FindExtendedProperty(metadataItem, iteratorVariable0.EpmNsUri); if ((iteratorVariable9 != null) && ((iteratorVariable10 != null) || (iteratorVariable11 != null))) { string str = (iteratorVariable10 != null) ? iteratorVariable0.EpmNsPrefix : iteratorVariable0.EpmNsUri; throw new InvalidOperationException((memberName == null) ? Strings.ObjectContext_InvalidAttributeForNonSyndicationItemsType(str, typeName) : Strings.ObjectContext_InvalidAttributeForNonSyndicationItemsMember(str, memberName, typeName)); } if (((iteratorVariable10 != null) || (iteratorVariable11 != null)) || (iteratorVariable8 == SyndicationItemProperty.CustomProperty)) { string iteratorVariable12 = (iteratorVariable10 != null) ? Convert.ToString(iteratorVariable10.Value, CultureInfo.InvariantCulture) : null; string iteratorVariable13 = (iteratorVariable11 != null) ? Convert.ToString(iteratorVariable11.Value, CultureInfo.InvariantCulture) : null; EpmPropertyInformation iteratorVariable14 = new EpmPropertyInformation { IsAtom = false, KeepInContent = result, SourcePath = iteratorVariable6, PathGiven = iteratorVariable1, TargetPath = targetPath, NsPrefix = iteratorVariable12, NsUri = iteratorVariable13 }; yield return(iteratorVariable14); } else { SyndicationTextContentKind plaintext; if (iteratorVariable9 != null) { plaintext = EpmTranslate.MapEpmContentKindToSyndicationTextContentKind(Convert.ToString(iteratorVariable9.Value, CultureInfo.InvariantCulture), typeName, memberName); } else { plaintext = SyndicationTextContentKind.Plaintext; } EpmPropertyInformation iteratorVariable16 = new EpmPropertyInformation { IsAtom = true, KeepInContent = result, SourcePath = iteratorVariable6, PathGiven = iteratorVariable1, SyndicationItem = iteratorVariable8, ContentKind = plaintext }; yield return(iteratorVariable16); } iteratorVariable0.MoveNext(); } }
/// <summary> /// Given an object returns the corresponding DateTimeOffset value through conversions. /// </summary> /// <param name="propertyValue">Object containing property value.</param> /// <param name="targetProperty">The target syndication property for the mapping (used for exception messages).</param> /// <param name="version">The version of the OData protocol to use.</param> /// <returns>DateTimeOffset after conversion.</returns> private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataVersion version) { if (propertyValue == null) { // In V3 we are to use m:null extension attribute to mark null values. Due to that we need to fail // because syndication API doesn't allow us to put extension attributes on publish or updated ATOM elements // (even though the spec allows it) and the product used syndication APIs. In future version of the protocol we might be able // to lift the restriction, but for now we have to keep this for backward compat. if (version >= ODataVersion.V3) { throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyHasNullValue(targetProperty.ToString())); } else { return DateTimeOffset.Now; } } if (propertyValue is DateTimeOffset) { return (DateTimeOffset)propertyValue; } else if (propertyValue is DateTime) { // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up // with datetime without timezone info mapped to atom:updated or atom:published element. return new DateTimeOffset((DateTime)propertyValue); } string stringValue = propertyValue as string; if (stringValue != null) { DateTimeOffset date; if (!DateTimeOffset.TryParse(stringValue, out date)) { DateTime result; if (!DateTime.TryParse(stringValue, out result)) { throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return new DateTimeOffset(result); } return date; } else { try { return new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture)); } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } } }
/// <summary> /// Given an object returns the corresponding DateTimeOffset value through conversions. /// </summary> /// <param name="propertyValue">Object containing property value.</param> /// <param name="targetProperty">The target syndication property for the mapping (used for exception messages).</param> /// <param name="version">The version of the OData protocol to use.</param> /// <returns>DateTimeOffset after conversion.</returns> private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataVersion version) { if (propertyValue == null) { // In V3 we are to use m:null extension attribute to mark null values. Due to that we need to fail // because syndication API doesn't allow us to put extension attributes on publish or updated ATOM elements // (even though the spec allows it) and the product used syndication APIs. In future version of the protocol we might be able // to lift the restriction, but for now we have to keep this for backward compat. if (version >= ODataVersion.V3) { throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyHasNullValue(targetProperty.ToString())); } else { return(DateTimeOffset.Now); } } if (propertyValue is DateTimeOffset) { return((DateTimeOffset)propertyValue); } else if (propertyValue is DateTime) { // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up // with datetime without timezone info mapped to atom:updated or atom:published element. return(new DateTimeOffset((DateTime)propertyValue)); } string stringValue = propertyValue as string; if (stringValue != null) { DateTimeOffset date; if (!DateTimeOffset.TryParse(stringValue, out date)) { DateTime result; if (!DateTime.TryParse(stringValue, out result)) { throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return(new DateTimeOffset(result)); } return(date); } else { try { return(new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture))); } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw new ODataException(Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } } }
internal static string MapSyndicationPropertyToEpmTargetPath(SyndicationItemProperty property) { return(syndicationItemToTargetPath[(int)property]); }
/// <summary> /// Maps the enumeration of allowed <see cref="SyndicationItemProperty"/> values to their string representations. /// </summary> /// <param name="targetSyndicationItem">Value of the <see cref="SyndicationItemProperty"/> given in /// the <see cref="EntityPropertyMappingAttribute"/> contstructor.</param> /// <returns>String representing the xml element path in the syndication property.</returns> internal static String SyndicationItemPropertyToPath(SyndicationItemProperty targetSyndicationItem) { DebugUtils.CheckNoExternalCallers(); switch (targetSyndicationItem) { case SyndicationItemProperty.AuthorEmail: return("author/email"); case SyndicationItemProperty.AuthorName: return("author/name"); case SyndicationItemProperty.AuthorUri: return("author/uri"); case SyndicationItemProperty.ContributorEmail: return("contributor/email"); case SyndicationItemProperty.ContributorName: return("contributor/name"); case SyndicationItemProperty.ContributorUri: return("contributor/uri"); case SyndicationItemProperty.Updated: return("updated"); case SyndicationItemProperty.Published: return("published"); case SyndicationItemProperty.Rights: return("rights"); case SyndicationItemProperty.Summary: return("summary"); case SyndicationItemProperty.Title: return("title"); case SyndicationItemProperty.CategoryLabel: return("category/@label"); case SyndicationItemProperty.CategoryScheme: return("category/@scheme"); case SyndicationItemProperty.CategoryTerm: return("category/@term"); case SyndicationItemProperty.LinkHref: return("link/@href"); case SyndicationItemProperty.LinkHrefLang: return("link/@hreflang"); case SyndicationItemProperty.LinkLength: return("link/@length"); case SyndicationItemProperty.LinkRel: return("link/@rel"); case SyndicationItemProperty.LinkTitle: return("link/@title"); case SyndicationItemProperty.LinkType: return("link/@type"); default: throw new ArgumentException(Strings.EntityPropertyMapping_EpmAttribute("targetSyndicationItem")); } }
private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior) { Debug.Assert( writerBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient, "CreateDateTimeValue should not be used in WCF DS client mode."); if (propertyValue == null) { return DateTimeOffset.Now; } if (propertyValue is DateTimeOffset) { return (DateTimeOffset)propertyValue; } if (propertyValue is DateTime) { // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up // with datetime without timezone info mapped to atom:updated or atom:published element. return new DateTimeOffset((DateTime)propertyValue); } string stringValue = propertyValue as string; if (stringValue != null) { DateTimeOffset date; if (!DateTimeOffset.TryParse(stringValue, out date)) { DateTime result; if (!DateTime.TryParse(stringValue, out result)) { throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } return new DateTimeOffset(result); } return date; } try { return new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture)); } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString())); } }