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
- WebPartUserCapability.cs
- ToolStripContentPanel.cs
- RuleElement.cs
- SHA256Managed.cs
- RegexCharClass.cs
- SchemaTypeEmitter.cs
- RadioButton.cs
- DeflateEmulationStream.cs
- OleDbConnectionFactory.cs
- FixedSchema.cs
- _WinHttpWebProxyDataBuilder.cs
- ObjectStateEntryOriginalDbUpdatableDataRecord.cs
- CodePageEncoding.cs
- OutputCacheProfile.cs
- TypefaceCollection.cs
- basevalidator.cs
- PointAnimationUsingKeyFrames.cs
- Monitor.cs
- EntityContainerEntitySet.cs
- HttpHandlersInstallComponent.cs
- GenericTypeParameterBuilder.cs
- BasePattern.cs
- RequiredArgumentAttribute.cs
- WindowsGraphics.cs
- SqlParameter.cs
- EncodingFallbackAwareXmlTextWriter.cs
- FocusTracker.cs
- SafeViewOfFileHandle.cs
- BamlTreeUpdater.cs
- FirstQueryOperator.cs
- PenThreadWorker.cs
- ReflectionUtil.cs
- Size.cs
- Attributes.cs
- UrlMappingsModule.cs
- GacUtil.cs
- StrokeFIndices.cs
- TextEndOfParagraph.cs
- EndEvent.cs
- BitmapEffectvisualstate.cs
- Utils.cs
- CurrentTimeZone.cs
- XmlIlVisitor.cs
- SelectionProcessor.cs
- _OverlappedAsyncResult.cs
- recordstatefactory.cs
- DataListCommandEventArgs.cs
- ObjectPersistData.cs
- MexTcpBindingElement.cs
- WebEventTraceProvider.cs
- Privilege.cs
- WebBrowserSiteBase.cs
- OuterGlowBitmapEffect.cs
- WindowsEditBoxRange.cs
- ObservableCollectionDefaultValueFactory.cs
- sqlnorm.cs
- HttpProcessUtility.cs
- WeakReferenceKey.cs
- XmlTypeAttribute.cs
- SafeThreadHandle.cs
- odbcmetadatacolumnnames.cs
- XslCompiledTransform.cs
- InputProcessorProfilesLoader.cs
- SimpleMailWebEventProvider.cs
- WS2007HttpBindingElement.cs
- CommonEndpointBehaviorElement.cs
- DesignerEditorPartChrome.cs
- SuppressMessageAttribute.cs
- PathGradientBrush.cs
- Listbox.cs
- ConfigurationManagerInternal.cs
- HandlerFactoryCache.cs
- VersionConverter.cs
- BreadCrumbTextConverter.cs
- _UncName.cs
- X509SecurityTokenAuthenticator.cs
- StringBuilder.cs
- DocumentApplication.cs
- XmlWellformedWriter.cs
- OleDbEnumerator.cs
- DataTableMapping.cs
- PolicyStatement.cs
- Processor.cs
- ImageIndexConverter.cs
- LogExtentCollection.cs
- LayoutEvent.cs
- MinimizableAttributeTypeConverter.cs
- IndexedSelectQueryOperator.cs
- GeneralTransform3DTo2D.cs
- DynamicMethod.cs
- CompoundFileStreamReference.cs
- PreviewPrintController.cs
- AudioStateChangedEventArgs.cs
- SelectionProcessor.cs
- CommaDelimitedStringAttributeCollectionConverter.cs
- MasterPageParser.cs
- SwitchLevelAttribute.cs
- PlatformNotSupportedException.cs
- Certificate.cs
- DataViewSettingCollection.cs