Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Epm / EpmTargetTree.cs / 1305376 / EpmTargetTree.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Tree for managing TargetNames on EntityPropertyMappingAttributes
// for a ResourceType.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Common
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
#if ASTORIA_CLIENT
using System.Data.Services.Client;
#else
using System.Data.Services;
#endif
///
/// Tree representing the targetName properties in all the EntityPropertyMappingAttributes for a resource type
///
internal sealed class EpmTargetTree
{
/// Number of properties that have KeepInContent false
private int countOfNonContentProperties;
/// Initializes the sub-trees for syndication and non-syndication content
internal EpmTargetTree()
{
this.SyndicationRoot = new EpmTargetPathSegment();
this.NonSyndicationRoot = new EpmTargetPathSegment();
}
/// Root of the sub-tree for syndication content
internal EpmTargetPathSegment SyndicationRoot
{
get;
private set;
}
/// Root of the sub-tree for custom content
internal EpmTargetPathSegment NonSyndicationRoot
{
get;
private set;
}
///
/// Does the target tree serialize data in V1 compatible manner
///
internal bool IsV1Compatible
{
get
{
return this.countOfNonContentProperties == 0;
}
}
///
/// Adds a path to the tree which is obtained by looking at the EntityPropertyMappingAttribute in the
///
/// EnitityPropertyMappingInfo holding the target path
internal void Add(EntityPropertyMappingInfo epmInfo)
{
String targetName = epmInfo.Attribute.TargetPath;
bool isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
String namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;
EpmTargetPathSegment currentSegment = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
IList activeSubSegments = currentSegment.SubSegments;
Debug.Assert(!String.IsNullOrEmpty(targetName), "Must have been validated during EntityPropertyMappingAttribute construction");
String[] targetSegments = targetName.Split('/');
for (int i = 0; i < targetSegments.Length; i++)
{
String targetSegment = targetSegments[i];
if (targetSegment.Length == 0)
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
{
throw new InvalidOperationException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
}
EpmTargetPathSegment foundSegment = activeSubSegments.SingleOrDefault(
segment => segment.SegmentName == targetSegment &&
(isSyndication || segment.SegmentNamespaceUri == namespaceUri));
if (foundSegment != null)
{
currentSegment = foundSegment;
}
else
{
currentSegment = new EpmTargetPathSegment(targetSegment, namespaceUri, namespacePrefix, currentSegment);
if (targetSegment[0] == '@')
{
activeSubSegments.Insert(0, currentSegment);
}
else
{
activeSubSegments.Add(currentSegment);
}
}
activeSubSegments = currentSegment.SubSegments;
}
// Two EpmAttributes with same TargetName in the inheritance hierarchy
if (currentSegment.HasContent)
{
throw new ArgumentException(Strings.EpmTargetTree_DuplicateEpmAttrsWithSameTargetName(EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), currentSegment.EpmInfo.DefiningType.Name, currentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath));
}
// Increment the number of properties for which KeepInContent is false
if (!epmInfo.Attribute.KeepInContent)
{
this.countOfNonContentProperties++;
}
currentSegment.EpmInfo = epmInfo;
// Mixed content is dis-allowed. Since root has no ancestor, pass in false for ancestorHasContent
if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, false))
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
}
///
/// Removes a path in the tree which is obtained by looking at the EntityPropertyMappingAttribute in the
///
/// EnitityPropertyMappingInfo holding the target path
internal void Remove(EntityPropertyMappingInfo epmInfo)
{
String targetName = epmInfo.Attribute.TargetPath;
bool isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
EpmTargetPathSegment currentSegment = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
List activeSubSegments = currentSegment.SubSegments;
Debug.Assert(!String.IsNullOrEmpty(targetName), "Must have been validated during EntityPropertyMappingAttribute construction");
String[] targetSegments = targetName.Split('/');
for (int i = 0; i < targetSegments.Length; i++)
{
String targetSegment = targetSegments[i];
if (targetSegment.Length == 0)
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
{
throw new InvalidOperationException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
}
EpmTargetPathSegment foundSegment = activeSubSegments.FirstOrDefault(
segment => segment.SegmentName == targetSegment &&
(isSyndication || segment.SegmentNamespaceUri == namespaceUri));
if (foundSegment != null)
{
currentSegment = foundSegment;
}
else
{
return;
}
activeSubSegments = currentSegment.SubSegments;
}
// Recursively remove all the parent segments which will have no more children left
// after removal of the current segment node
if (currentSegment.HasContent)
{
// Since we are removing a property with KeepInContent false, we should decrement the count
if (!currentSegment.EpmInfo.Attribute.KeepInContent)
{
this.countOfNonContentProperties--;
}
do
{
EpmTargetPathSegment parentSegment = currentSegment.ParentSegment;
parentSegment.SubSegments.Remove(currentSegment);
currentSegment = parentSegment;
}
while (currentSegment.ParentSegment != null && !currentSegment.HasContent && currentSegment.SubSegments.Count == 0);
}
}
/// Checks if mappings could potentially result in mixed content and dis-allows it.
/// Segment being processed.
/// Does any of the ancestors have content.
/// boolean indicating if the tree is valid or not.
private static bool HasMixedContent(EpmTargetPathSegment currentSegment, bool ancestorHasContent)
{
foreach (EpmTargetPathSegment childSegment in currentSegment.SubSegments.Where(s => !s.IsAttribute))
{
if (childSegment.HasContent && ancestorHasContent)
{
return true;
}
if (HasMixedContent(childSegment, childSegment.HasContent || ancestorHasContent))
{
return true;
}
}
return false;
}
///
/// Given an gives the correct target path for it
///
/// Given
/// String with the correct value for the target path
private static String GetPropertyNameFromEpmInfo(EntityPropertyMappingInfo epmInfo)
{
#if ASTORIA_SERVER
if (epmInfo.IsEFProvider)
{
if (epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty)
{
return System.Data.Services.Providers.ObjectContextServiceProvider.MapSyndicationPropertyToEpmTargetPath(epmInfo.Attribute.TargetSyndicationItem);
}
else
{
return epmInfo.Attribute.TargetPath;
}
}
else
#endif
{
if (epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty)
{
return epmInfo.Attribute.TargetSyndicationItem.ToString();
}
else
{
return epmInfo.Attribute.TargetPath;
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Tree for managing TargetNames on EntityPropertyMappingAttributes
// for a ResourceType.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Common
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
#if ASTORIA_CLIENT
using System.Data.Services.Client;
#else
using System.Data.Services;
#endif
///
/// Tree representing the targetName properties in all the EntityPropertyMappingAttributes for a resource type
///
internal sealed class EpmTargetTree
{
/// Number of properties that have KeepInContent false
private int countOfNonContentProperties;
/// Initializes the sub-trees for syndication and non-syndication content
internal EpmTargetTree()
{
this.SyndicationRoot = new EpmTargetPathSegment();
this.NonSyndicationRoot = new EpmTargetPathSegment();
}
/// Root of the sub-tree for syndication content
internal EpmTargetPathSegment SyndicationRoot
{
get;
private set;
}
/// Root of the sub-tree for custom content
internal EpmTargetPathSegment NonSyndicationRoot
{
get;
private set;
}
///
/// Does the target tree serialize data in V1 compatible manner
///
internal bool IsV1Compatible
{
get
{
return this.countOfNonContentProperties == 0;
}
}
///
/// Adds a path to the tree which is obtained by looking at the EntityPropertyMappingAttribute in the
///
/// EnitityPropertyMappingInfo holding the target path
internal void Add(EntityPropertyMappingInfo epmInfo)
{
String targetName = epmInfo.Attribute.TargetPath;
bool isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
String namespacePrefix = epmInfo.Attribute.TargetNamespacePrefix;
EpmTargetPathSegment currentSegment = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
IList activeSubSegments = currentSegment.SubSegments;
Debug.Assert(!String.IsNullOrEmpty(targetName), "Must have been validated during EntityPropertyMappingAttribute construction");
String[] targetSegments = targetName.Split('/');
for (int i = 0; i < targetSegments.Length; i++)
{
String targetSegment = targetSegments[i];
if (targetSegment.Length == 0)
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
{
throw new InvalidOperationException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
}
EpmTargetPathSegment foundSegment = activeSubSegments.SingleOrDefault(
segment => segment.SegmentName == targetSegment &&
(isSyndication || segment.SegmentNamespaceUri == namespaceUri));
if (foundSegment != null)
{
currentSegment = foundSegment;
}
else
{
currentSegment = new EpmTargetPathSegment(targetSegment, namespaceUri, namespacePrefix, currentSegment);
if (targetSegment[0] == '@')
{
activeSubSegments.Insert(0, currentSegment);
}
else
{
activeSubSegments.Add(currentSegment);
}
}
activeSubSegments = currentSegment.SubSegments;
}
// Two EpmAttributes with same TargetName in the inheritance hierarchy
if (currentSegment.HasContent)
{
throw new ArgumentException(Strings.EpmTargetTree_DuplicateEpmAttrsWithSameTargetName(EpmTargetTree.GetPropertyNameFromEpmInfo(currentSegment.EpmInfo), currentSegment.EpmInfo.DefiningType.Name, currentSegment.EpmInfo.Attribute.SourcePath, epmInfo.Attribute.SourcePath));
}
// Increment the number of properties for which KeepInContent is false
if (!epmInfo.Attribute.KeepInContent)
{
this.countOfNonContentProperties++;
}
currentSegment.EpmInfo = epmInfo;
// Mixed content is dis-allowed. Since root has no ancestor, pass in false for ancestorHasContent
if (EpmTargetTree.HasMixedContent(this.NonSyndicationRoot, false))
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
}
///
/// Removes a path in the tree which is obtained by looking at the EntityPropertyMappingAttribute in the
///
/// EnitityPropertyMappingInfo holding the target path
internal void Remove(EntityPropertyMappingInfo epmInfo)
{
String targetName = epmInfo.Attribute.TargetPath;
bool isSyndication = epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
String namespaceUri = epmInfo.Attribute.TargetNamespaceUri;
EpmTargetPathSegment currentSegment = isSyndication ? this.SyndicationRoot : this.NonSyndicationRoot;
List activeSubSegments = currentSegment.SubSegments;
Debug.Assert(!String.IsNullOrEmpty(targetName), "Must have been validated during EntityPropertyMappingAttribute construction");
String[] targetSegments = targetName.Split('/');
for (int i = 0; i < targetSegments.Length; i++)
{
String targetSegment = targetSegments[i];
if (targetSegment.Length == 0)
{
throw new InvalidOperationException(Strings.EpmTargetTree_InvalidTargetPath(targetName));
}
if (targetSegment[0] == '@' && i != targetSegments.Length - 1)
{
throw new InvalidOperationException(Strings.EpmTargetTree_AttributeInMiddle(targetSegment));
}
EpmTargetPathSegment foundSegment = activeSubSegments.FirstOrDefault(
segment => segment.SegmentName == targetSegment &&
(isSyndication || segment.SegmentNamespaceUri == namespaceUri));
if (foundSegment != null)
{
currentSegment = foundSegment;
}
else
{
return;
}
activeSubSegments = currentSegment.SubSegments;
}
// Recursively remove all the parent segments which will have no more children left
// after removal of the current segment node
if (currentSegment.HasContent)
{
// Since we are removing a property with KeepInContent false, we should decrement the count
if (!currentSegment.EpmInfo.Attribute.KeepInContent)
{
this.countOfNonContentProperties--;
}
do
{
EpmTargetPathSegment parentSegment = currentSegment.ParentSegment;
parentSegment.SubSegments.Remove(currentSegment);
currentSegment = parentSegment;
}
while (currentSegment.ParentSegment != null && !currentSegment.HasContent && currentSegment.SubSegments.Count == 0);
}
}
/// Checks if mappings could potentially result in mixed content and dis-allows it.
/// Segment being processed.
/// Does any of the ancestors have content.
/// boolean indicating if the tree is valid or not.
private static bool HasMixedContent(EpmTargetPathSegment currentSegment, bool ancestorHasContent)
{
foreach (EpmTargetPathSegment childSegment in currentSegment.SubSegments.Where(s => !s.IsAttribute))
{
if (childSegment.HasContent && ancestorHasContent)
{
return true;
}
if (HasMixedContent(childSegment, childSegment.HasContent || ancestorHasContent))
{
return true;
}
}
return false;
}
///
/// Given an gives the correct target path for it
///
/// Given
/// String with the correct value for the target path
private static String GetPropertyNameFromEpmInfo(EntityPropertyMappingInfo epmInfo)
{
#if ASTORIA_SERVER
if (epmInfo.IsEFProvider)
{
if (epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty)
{
return System.Data.Services.Providers.ObjectContextServiceProvider.MapSyndicationPropertyToEpmTargetPath(epmInfo.Attribute.TargetSyndicationItem);
}
else
{
return epmInfo.Attribute.TargetPath;
}
}
else
#endif
{
if (epmInfo.Attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty)
{
return epmInfo.Attribute.TargetSyndicationItem.ToString();
}
else
{
return epmInfo.Attribute.TargetPath;
}
}
}
}
}
// 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
- HttpRawResponse.cs
- CatalogZoneBase.cs
- ContextMenuAutomationPeer.cs
- PageThemeParser.cs
- DependencyPropertyDescriptor.cs
- IndexedGlyphRun.cs
- Size.cs
- OTFRasterizer.cs
- UnauthorizedAccessException.cs
- DateTimeFormatInfo.cs
- CannotUnloadAppDomainException.cs
- SchemaNamespaceManager.cs
- _DynamicWinsockMethods.cs
- CodeParameterDeclarationExpression.cs
- CqlWriter.cs
- InstanceHandleReference.cs
- WaitHandleCannotBeOpenedException.cs
- MetadataSource.cs
- ExpressionConverter.cs
- ListViewContainer.cs
- TableAdapterManagerGenerator.cs
- SystemEvents.cs
- WindowsSolidBrush.cs
- PointUtil.cs
- DateTimeOffsetConverter.cs
- ButtonStandardAdapter.cs
- CacheSection.cs
- SqlWorkflowPersistenceService.cs
- TransactionManager.cs
- SafeSystemMetrics.cs
- InfoCardTraceRecord.cs
- TextEditorCharacters.cs
- OleDbMetaDataFactory.cs
- SafeRegistryHandle.cs
- EnumerableRowCollectionExtensions.cs
- Configuration.cs
- StylusPlugin.cs
- AppSettingsExpressionBuilder.cs
- WinEventQueueItem.cs
- SQLDecimal.cs
- DesignerAttribute.cs
- UiaCoreTypesApi.cs
- Serializer.cs
- GeneralTransformCollection.cs
- _StreamFramer.cs
- SqlNotificationRequest.cs
- HtmlShimManager.cs
- EventLogInternal.cs
- OutputCacheSettingsSection.cs
- OciHandle.cs
- RadialGradientBrush.cs
- Pts.cs
- SecurityException.cs
- DefaultTypeArgumentAttribute.cs
- COM2PictureConverter.cs
- backend.cs
- GridViewRow.cs
- RayHitTestParameters.cs
- BufferedStream2.cs
- SplineQuaternionKeyFrame.cs
- TextRangeEditLists.cs
- RenderCapability.cs
- Form.cs
- AssertValidation.cs
- StringUtil.cs
- DbConnectionPoolIdentity.cs
- WSFederationHttpSecurity.cs
- Rect3D.cs
- TypeReference.cs
- DataKey.cs
- Assert.cs
- HtmlTableRow.cs
- MasterPageBuildProvider.cs
- ColumnCollection.cs
- PageParserFilter.cs
- PolicyLevel.cs
- SQLConvert.cs
- ClientTarget.cs
- TrueReadOnlyCollection.cs
- BitmapImage.cs
- Selector.cs
- MemberAccessException.cs
- NewItemsContextMenuStrip.cs
- ApplicationManager.cs
- DispatcherHooks.cs
- UniqueIdentifierService.cs
- SubstitutionList.cs
- Attribute.cs
- AstNode.cs
- WCFBuildProvider.cs
- Helpers.cs
- RequestQueue.cs
- RectAnimation.cs
- GeneratedContractType.cs
- DefaultCommandExtensionCallback.cs
- ArrayEditor.cs
- Native.cs
- ProfileProvider.cs
- DataGridViewRowConverter.cs
- SqlMethodAttribute.cs