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
- Context.cs
- X509ChainElement.cs
- MimeMultiPart.cs
- IUnknownConstantAttribute.cs
- ComponentResourceKeyConverter.cs
- panel.cs
- WindowsSecurityTokenAuthenticator.cs
- IPipelineRuntime.cs
- LabelExpression.cs
- NameValueCollection.cs
- HtmlWindow.cs
- DataGridViewControlCollection.cs
- IntSecurity.cs
- DecimalAnimationUsingKeyFrames.cs
- IPipelineRuntime.cs
- DateTimeUtil.cs
- CodeConditionStatement.cs
- ProtocolState.cs
- AuthenticatedStream.cs
- ConstantProjectedSlot.cs
- HtmlInputCheckBox.cs
- BinHexEncoding.cs
- EditCommandColumn.cs
- Stream.cs
- XmlSchemaObjectCollection.cs
- StdRegProviderWrapper.cs
- Function.cs
- ExpressionServices.cs
- XmlSchemaInfo.cs
- DataGridViewCellPaintingEventArgs.cs
- PackWebResponse.cs
- SafeViewOfFileHandle.cs
- ParsedAttributeCollection.cs
- EventLogPermissionEntry.cs
- WpfPayload.cs
- StorageEntityContainerMapping.cs
- ScriptHandlerFactory.cs
- QuadraticBezierSegment.cs
- DataRecord.cs
- CodeAttributeArgument.cs
- MessagePropertyDescription.cs
- ConnectionManagementSection.cs
- ReachPrintTicketSerializer.cs
- Char.cs
- PartialCachingControl.cs
- WindowsSlider.cs
- SHA1CryptoServiceProvider.cs
- WindowsRichEditRange.cs
- TabPanel.cs
- StringUtil.cs
- DriveNotFoundException.cs
- FormsAuthenticationUserCollection.cs
- SelectionUIHandler.cs
- CryptographicAttribute.cs
- WindowsGrip.cs
- PanningMessageFilter.cs
- CustomErrorsSectionWrapper.cs
- GradientBrush.cs
- MasterPage.cs
- RegisteredArrayDeclaration.cs
- PageVisual.cs
- HtmlControl.cs
- QilReplaceVisitor.cs
- XmlILModule.cs
- ExpressionDumper.cs
- WebPartConnectionsCancelVerb.cs
- ConfigXmlAttribute.cs
- CachedBitmap.cs
- UnSafeCharBuffer.cs
- CommentAction.cs
- ProcessHostServerConfig.cs
- EffectiveValueEntry.cs
- WebPartDisplayModeCollection.cs
- ValidatedControlConverter.cs
- OrderedDictionary.cs
- StringExpressionSet.cs
- SortExpressionBuilder.cs
- PrintEvent.cs
- QueryableFilterUserControl.cs
- KeyboardEventArgs.cs
- CopyCodeAction.cs
- TextServicesManager.cs
- Error.cs
- ZoneIdentityPermission.cs
- ResourceProperty.cs
- TextBoxLine.cs
- DynamicHyperLink.cs
- TraceContextRecord.cs
- BitmapMetadataEnumerator.cs
- HMAC.cs
- AuthenticationSection.cs
- DrawingContext.cs
- RuntimeIdentifierPropertyAttribute.cs
- precedingsibling.cs
- CookieParameter.cs
- DataErrorValidationRule.cs
- ClonableStack.cs
- RayHitTestParameters.cs
- MetadataArtifactLoaderFile.cs
- AdCreatedEventArgs.cs