Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Epm / EpmContentSerializer.cs / 1305376 / EpmContentSerializer.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Class used for serializing EntityPropertyMappingAttribute content.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Common
{
#region Namespaces
using System.Collections.Generic;
using System.Data.Services.Internal;
using System.Data.Services.Providers;
using System.Data.Services.Serializers;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel.Syndication;
#endregion
///
/// Publically visible interface of the Content serializer, acts as container for both Custom and Syndication content serializers
///
internal sealed class EpmContentSerializer : IDisposable
{
/// for which this serializer works
private readonly ResourceType resourceType;
///
/// Syndication specific content serializer
///
private readonly EpmSyndicationContentSerializer epmSyndicationSerializer;
///
/// Custom content serializer
///
private readonly EpmCustomContentSerializer epmCustomSerializer;
///
/// Target syndication item to which we add serialized content
///
private SyndicationItem targetItem;
/// Collection of null valued properties for this current serialization
private EpmNullValuedPropertyTree nullValuedProperties;
///
/// Constructor creates contained serializers
///
/// Resource type being serialized
/// Instance of
/// SyndicationItem to which content will be added
/// Data Service provider used for rights verification.
internal EpmContentSerializer(ResourceType resourceType, Object value, SyndicationItem targetItem, DataServiceProviderWrapper provider)
{
this.resourceType = resourceType;
this.targetItem = targetItem;
this.nullValuedProperties = new EpmNullValuedPropertyTree(provider, value);
if (this.NeedEpmSerialization)
{
this.epmSyndicationSerializer = new EpmSyndicationContentSerializer(this.resourceType.EpmTargetTree, value, targetItem, this.nullValuedProperties);
this.epmCustomSerializer = new EpmCustomContentSerializer(this.resourceType.EpmTargetTree, value, targetItem, this.nullValuedProperties, provider);
}
}
/// Does this type have any entity property mappings at all
private bool NeedEpmSerialization
{
get
{
Debug.Assert(this.resourceType != null, "Must have a valid ResourceType");
return this.resourceType.HasEntityPropertyMappings;
}
}
///
/// Cleansup visitor specific state of the target tree
///
public void Dispose()
{
if (this.NeedEpmSerialization)
{
Debug.Assert(this.epmSyndicationSerializer != null, "ResourceType with mapping implies a valid syndication content serializer");
this.epmSyndicationSerializer.Dispose();
Debug.Assert(this.epmCustomSerializer != null, "ResourceType with mapping implies a valid custom content serializer");
this.epmCustomSerializer.Dispose();
}
}
/// Delegates to each of custom and syndication serializers for serializing content
/// Content in which to write null valued properties
/// Data Service provider used for rights verification.
internal void Serialize(DictionaryContent content, DataServiceProviderWrapper provider)
{
if (this.NeedEpmSerialization)
{
Debug.Assert(this.epmSyndicationSerializer != null, "ResourceType with mapping implies a valid syndication content serializer");
this.epmSyndicationSerializer.Serialize(provider);
Debug.Assert(this.epmCustomSerializer != null, "ResourceType with mapping implies a valid custom content serializer");
this.epmCustomSerializer.Serialize(provider);
this.nullValuedProperties.AddNullValuesToContent(content);
}
else
{
Debug.Assert(this.targetItem != null, "Must always have target content item");
this.targetItem.Authors.Add(new SyndicationPerson(null, String.Empty, null));
}
}
/// Tree representing null valued properties for an instance
internal sealed class EpmNullValuedPropertyTree
{
/// Root of the tree
private EpmNullValuedPropertyNode root;
/// Provider wrapper instance
private DataServiceProviderWrapper provider;
/// Object whose properties we will read
private object element;
/// Constructor that creates the root of the tree
/// Provider wrapper instance
/// Object whose properties we will read
internal EpmNullValuedPropertyTree(DataServiceProviderWrapper provider, object element)
{
this.root = new EpmNullValuedPropertyNode { Name = null };
this.provider = provider;
this.element = element;
}
/// Adds a property to the null valued collection
/// EpmInfo containing the property information such as path
internal void Add(EntityPropertyMappingInfo epmInfo)
{
Debug.Assert(epmInfo != null, "epmInfo != null");
EpmNullValuedPropertyNode current = this.root;
ResourceType currentType = epmInfo.DefiningType;
object currentValue = this.element;
// We are here because the epm path points to a null value. If the path is multiple level deep, we need to
// know the first level the null value begins and we don't need to serialize deeper than that.
// To serialize the complex properties correctly in the case they are not already in content, we also need
// to find the type for each segment from root to the first segment that has the null property value.
foreach (var segment in epmInfo.Attribute.SourcePath.Split('/'))
{
EpmNullValuedPropertyNode child = current.Children.FirstOrDefault(c => c.Name == segment);
if (child != null)
{
// The current segment is already added to the tree, reuse it.
current = child;
currentValue = child.Element;
currentType = child.ResourceType;
}
else
{
EpmNullValuedPropertyNode newNode = new EpmNullValuedPropertyNode { Name = segment };
Debug.Assert(currentType != null, "currentType != null");
ResourceProperty property = currentType.TryResolvePropertyName(segment);
Debug.Assert(currentValue != null, "currentValue != null");
ProjectedWrapper projectedValue = currentValue as ProjectedWrapper;
if (projectedValue == null)
{
if (property != null)
{
currentValue = this.provider.GetPropertyValue(currentValue, property, currentType);
currentValue = currentValue == DBNull.Value ? null : currentValue;
currentType = property.ResourceType;
}
else
{
// Handle open property...
currentValue = this.provider.GetOpenPropertyValue(currentValue, segment);
currentValue = currentValue == DBNull.Value ? null : currentValue;
if (currentValue != null)
{
// Get the type from the instance.
currentType = this.provider.GetResourceType(currentValue);
}
else
{
// We have a null open property at hand, we don't know its type.
// Default the type to string so that we will omit the type name
// and just write out null. i.e.
currentType = ResourceType.PrimitiveStringResourceType;
}
}
}
else
{
currentValue = projectedValue.GetProjectedPropertyValue(segment);
currentValue = currentValue == DBNull.Value ? null : currentValue;
if (property != null)
{
currentType = property.ResourceType;
}
else
{
// Handle open property...
if (currentValue == null)
{
// We have a null open property at hand, we don't know its type.
// Default the type to string so that we will omit the type name
// and just write out null. i.e.
currentType = ResourceType.PrimitiveStringResourceType;
}
else
{
projectedValue = currentValue as ProjectedWrapper;
if (projectedValue != null)
{
// Get the type from the project wrapper.
currentType = this.provider.TryResolveResourceType(projectedValue.ResourceTypeName);
}
else
{
// Get the type from the instance.
currentType = this.provider.GetResourceType(currentValue);
}
}
}
}
Debug.Assert(currentType != null, "currentType != null");
Debug.Assert(currentValue != DBNull.Value, "currentValue != DBNull.Value -- we have converted DBNull to null");
newNode.ResourceType = currentType;
newNode.Element = currentValue;
current.Children.Add(newNode);
current = newNode;
}
if (current.Element == null)
{
// If the current element is null, we don't need to go further since that is the obvious reason
// that the children properties are null.
break;
}
}
}
/// Adds the null valued properties to the content section
/// Content to which null properties are to be added
internal void AddNullValuesToContent(DictionaryContent content)
{
this.AddNullValuesToContent(this.root, content);
}
/// Adds the null valued properties to the content section of a syndication entry
/// Current root node
/// Current collection to which property is to be added
private void AddNullValuesToContent(EpmNullValuedPropertyNode currentRoot, DictionaryContent currentContent)
{
foreach (EpmNullValuedPropertyNode node in currentRoot.Children)
{
bool found;
DictionaryContent c = currentContent.Lookup(node.Name, out found);
Debug.Assert(node.ResourceType != null, "node.ResourceType != null");
switch (node.ResourceType.ResourceTypeKind)
{
case ResourceTypeKind.ComplexType:
if (!found)
{
// If a complex property is not found in content, it is either not being projected
// or all of its properties are mapped and all of them have KeepInContent=false
Debug.Assert(c == null, "when look up not found, c should be null.");
if (node.Element != null)
{
Debug.Assert(node.Children.Count > 0, "If the property represented by the current node is not null, there must be children nodes.");
// The complex property is not null, but some of its descendant properties are null.
// We need to serialize the type name of the complex property.
c = new DictionaryContent();
currentContent.Add(node.Name, node.ResourceType.FullName, c);
}
else
{
Debug.Assert(node.Children.Count == 0, "If the property represented by the current node is not null, there must not be any children node.");
// The complex property is null, we write out m:null='true'.
currentContent.AddNull(node.ResourceType.FullName, node.Name);
}
}
if (c != null)
{
// Only add the children properties if the complex property is not null.
this.AddNullValuesToContent(node, c);
}
break;
case ResourceTypeKind.Primitive:
Debug.Assert(c == null, "DictionaryContent not expected for primitive properties.");
Debug.Assert(node.Element == null, "node.Element == null");
if (!found)
{
currentContent.AddNull(node.ResourceType.FullName, node.Name);
}
// if found, use the value in currentContent, we don't need to do anything here.
break;
case ResourceTypeKind.EntityType:
Debug.Assert(false, "We cannot map navigation properties with friendly feeds.");
break;
}
}
}
///
/// Representation for a node in the
///
private sealed class EpmNullValuedPropertyNode
{
/// Children of current node
private List children;
/// Name of the property
internal String Name
{
get;
set;
}
/// ResourceType corresponding to the node
internal ResourceType ResourceType
{
get;
set;
}
/// Object whose element we will read
internal object Element
{
get;
set;
}
/// Lazily creates the children collection and returns the collection
internal ICollection Children
{
get
{
if (this.children == null)
{
this.children = new List();
}
return this.children;
}
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- _AutoWebProxyScriptHelper.cs
- ReadOnlyCollectionBase.cs
- TextParagraphCache.cs
- HttpValueCollection.cs
- HoistedLocals.cs
- DateTimeValueSerializer.cs
- SelectionListDesigner.cs
- PropertyMappingExceptionEventArgs.cs
- VersionValidator.cs
- UnsafePeerToPeerMethods.cs
- FormatSettings.cs
- ResourceContainer.cs
- WindowsComboBox.cs
- BackStopAuthenticationModule.cs
- AppDomainFactory.cs
- HtmlInputRadioButton.cs
- NamedObject.cs
- KeyedPriorityQueue.cs
- GC.cs
- ValueTable.cs
- CookielessHelper.cs
- TempFiles.cs
- XmlLinkedNode.cs
- ReferentialConstraint.cs
- UnsafeCollabNativeMethods.cs
- wgx_render.cs
- ObjectListDataBindEventArgs.cs
- QueryableDataSource.cs
- ComponentCommands.cs
- cache.cs
- DataSourceViewSchemaConverter.cs
- Transform3DGroup.cs
- TrimSurroundingWhitespaceAttribute.cs
- ResourceReferenceExpressionConverter.cs
- SqlCaseSimplifier.cs
- TextRange.cs
- MediaSystem.cs
- Module.cs
- SkipStoryboardToFill.cs
- Rfc2898DeriveBytes.cs
- AudioFormatConverter.cs
- Point.cs
- Aes.cs
- OpenFileDialog.cs
- MemoryMappedFile.cs
- Transform3DGroup.cs
- XmlNamespaceManager.cs
- DbConnectionPoolGroup.cs
- XPathException.cs
- UniformGrid.cs
- RequestCacheManager.cs
- BulletedList.cs
- DbConnectionClosed.cs
- RegistrySecurity.cs
- TimeSpanValidatorAttribute.cs
- AnnotationAdorner.cs
- OleDbConnectionInternal.cs
- XmlWrappingReader.cs
- WorkflowApplicationCompletedException.cs
- ConfigurationSchemaErrors.cs
- TimeEnumHelper.cs
- RegexCapture.cs
- IdentifierService.cs
- FactoryId.cs
- QilReplaceVisitor.cs
- OutputCacheProfileCollection.cs
- RegexCharClass.cs
- QilNode.cs
- ZipIORawDataFileBlock.cs
- EntityPropertyMappingAttribute.cs
- ExtensionFile.cs
- NativeMethods.cs
- ParserContext.cs
- ApplicationId.cs
- CustomValidator.cs
- LicenseManager.cs
- AnchoredBlock.cs
- AnnotationComponentChooser.cs
- TextEditorParagraphs.cs
- EntityDataSourceMemberPath.cs
- Gdiplus.cs
- ToolboxItem.cs
- PriorityChain.cs
- PhysicalOps.cs
- XmlElementList.cs
- PrimarySelectionAdorner.cs
- DoWorkEventArgs.cs
- DEREncoding.cs
- Message.cs
- AssociatedControlConverter.cs
- ChainOfDependencies.cs
- ObjectDataSourceSelectingEventArgs.cs
- Point3D.cs
- TextPointer.cs
- X509SecurityTokenProvider.cs
- GlyphsSerializer.cs
- TreeViewImageIndexConverter.cs
- FontFamily.cs
- VisemeEventArgs.cs
- Cell.cs