Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataWeb / Server / System / Data / Services / Providers / ResourceContainer.cs / 1 / ResourceContainer.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Contains information about a resource container.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Providers
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
///
/// Structure to keep information about a resource container
///
[DebuggerDisplay("{Name}: {ElementType}")]
internal class ResourceContainer
{
/// Reference to resource type that this resource container is a collection of
private readonly ResourceType elementType;
/// Name of the resource container.
private readonly string name;
/// List of entity types which are disallowed since they have navigation properties.
private readonly HashSet disallowedDerivedTypes;
#if ASTORIA_CONTAINMENT
///
/// If this container has a canonical access path, this is the parent
/// container.
///
private ResourceContainer containmentCanonicalParent;
///
/// If this container has a canonical access path, this is the parent
/// container's containing property.
///
private ResourceProperty containmentCanonicalProperty;
#endif
/// Methods to be called when composing read queries to allow authorization.
private MethodInfo[] readAuthorizationMethods;
/// Cached delegate to read an IQueryable from the context.
private Func readFromContextDelegate;
/// Access rights to this resource container.
private EntitySetRights rights;
#if ASTORIA_CONTAINMENT
/// Whether top-level access is available for this resource set.
private bool topLevelAccess;
#endif
/// Methods to be called when validating write methods to allow authorization.
private MethodInfo[] writeAuthorizationMethods;
///
/// Constructs a new instance of Astoria type using the specified clr type
///
/// name of the resource container
/// Reference to clr type that this resource container is a collection of
internal ResourceContainer(string name, ResourceType elementType)
{
Debug.Assert(!String.IsNullOrEmpty(name), "name of entity set can never be null or empty");
Debug.Assert(elementType != null, "elementType of an entity set can never be null");
this.name = name;
this.elementType = elementType;
this.disallowedDerivedTypes = new HashSet(EqualityComparer.Default);
}
#if ASTORIA_CONTAINMENT
///
/// If this container has a canonical access path, this is the parent
/// container.
///
internal ResourceContainer ContainmentCanonicalParent
{
[DebuggerStepThrough]
get { return this.containmentCanonicalParent; }
}
///
/// If this container has a canonical access path, this is the parent
/// container's containing property.
///
internal ResourceProperty ContainmentCanonicalProperty
{
[DebuggerStepThrough]
get { return this.containmentCanonicalProperty; }
}
#endif
/// Reference to clr type that this resource container is a collection of
internal Type ElementType
{
get
{
return this.elementType.Type;
}
}
/// Cached delegate to read an IQueryable from the context.
internal Func ReadFromContextDelegate
{
get { return this.readFromContextDelegate; }
set { this.readFromContextDelegate = value; }
}
/// Reference to resource type that this resource container is a collection of
internal ResourceType ResourceType
{
get
{
return this.elementType;
}
}
/// Whether the resource container is visible to service consumers.
internal bool IsHidden
{
get { return this.rights == EntitySetRights.None; }
}
/// Name of the resource container.
internal string Name
{
get
{
return this.name;
}
}
/// Access rights to this resource container.
internal EntitySetRights Rights
{
get { return this.rights; }
set { this.rights = value; }
}
/// Methods to be called when composing read queries to allow authorization (possibly null).
internal MethodInfo[] ReadAuthorizationMethods
{
[DebuggerStepThrough]
get { return this.readAuthorizationMethods; }
}
#if ASTORIA_CONTAINMENT
/// Whether top-level access is available for this resource set.
internal bool TopLevelAccess
{
[DebuggerStepThrough]
get { return this.topLevelAccess; }
}
#endif
/// Methods to be called when validating write methods to allow authorization (possibly null).
internal MethodInfo[] WriteAuthorizationMethods
{
[DebuggerStepThrough]
get { return this.writeAuthorizationMethods; }
}
///
/// Adds the specified to the list of read
/// authorization methods for this resource container.
///
/// Method to add.
internal void AddReadAuthorizationMethod(MethodInfo method)
{
Debug.Assert(method != null, "method != null");
AppendMethod(method, ref this.readAuthorizationMethods);
}
///
/// Adds the specified to the list of write
/// authorization methods for this resource container.
///
/// Method to add.
internal void AddWriteAuthorizationMethod(MethodInfo method)
{
Debug.Assert(method != null, "method != null");
AppendMethod(method, ref this.writeAuthorizationMethods);
}
#if ASTORIA_CONTAINMENT
///
/// Sets all properties for the canonical path in a containment relationship.
///
/// Resource set that contains the canonical path.
/// Property in that contains the canonical path.
/// Whether top-level access is available.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "topLevelAccess", Justification = "1:1 mapping")]
internal void SetupCanonicalAccessPath(ResourceContainer container, ResourceProperty property, bool topLevelAccess)
{
Debug.Assert(container != null, "container != null");
Debug.Assert(property != null, "property != null");
Debug.Assert(
this.containmentCanonicalParent == null,
"this.containmentCanonicalParent == null -- otherwise, more than one canonical path is being set.");
this.containmentCanonicalParent = container;
this.containmentCanonicalProperty = property;
this.topLevelAccess = topLevelAccess;
}
#endif
///
/// Add the given resource type to the disallowed list, so that we can check during serialization
///
/// resource type that is disallowed for the given entity set.
internal void AddDisallowedDerivedType(ResourceType resourceType)
{
Debug.Assert(resourceType != null, "resourceType != null");
Debug.Assert(resourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "expecting entity types");
Debug.Assert(resourceType.Type.IsSubclassOf(this.ResourceType.Type), "the type must be a derived type for the given entity set");
this.disallowedDerivedTypes.Add(resourceType);
}
///
/// Checks whether the given resource type is not allowed for this entity set or not.
///
/// resourceType which needs to be checked
/// returns true if the given resource type is not allowed for this entity set. Otherwise returns false.
internal bool IsEntityDisallowed(ResourceType resourceType)
{
return this.disallowedDerivedTypes.Contains(resourceType);
}
/// Appends a method to the specified array.
/// Method to append.
/// Array to append to.
private static void AppendMethod(MethodInfo method, ref MethodInfo[] methods)
{
if (methods == null)
{
methods = new MethodInfo[1];
}
else
{
MethodInfo[] newArray = new MethodInfo[methods.Length + 1];
Array.Copy(methods, newArray, methods.Length);
methods = newArray;
}
methods[methods.Length - 1] = method;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Contains information about a resource container.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Providers
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
///
/// Structure to keep information about a resource container
///
[DebuggerDisplay("{Name}: {ElementType}")]
internal class ResourceContainer
{
/// Reference to resource type that this resource container is a collection of
private readonly ResourceType elementType;
/// Name of the resource container.
private readonly string name;
/// List of entity types which are disallowed since they have navigation properties.
private readonly HashSet disallowedDerivedTypes;
#if ASTORIA_CONTAINMENT
///
/// If this container has a canonical access path, this is the parent
/// container.
///
private ResourceContainer containmentCanonicalParent;
///
/// If this container has a canonical access path, this is the parent
/// container's containing property.
///
private ResourceProperty containmentCanonicalProperty;
#endif
/// Methods to be called when composing read queries to allow authorization.
private MethodInfo[] readAuthorizationMethods;
/// Cached delegate to read an IQueryable from the context.
private Func readFromContextDelegate;
/// Access rights to this resource container.
private EntitySetRights rights;
#if ASTORIA_CONTAINMENT
/// Whether top-level access is available for this resource set.
private bool topLevelAccess;
#endif
/// Methods to be called when validating write methods to allow authorization.
private MethodInfo[] writeAuthorizationMethods;
///
/// Constructs a new instance of Astoria type using the specified clr type
///
/// name of the resource container
/// Reference to clr type that this resource container is a collection of
internal ResourceContainer(string name, ResourceType elementType)
{
Debug.Assert(!String.IsNullOrEmpty(name), "name of entity set can never be null or empty");
Debug.Assert(elementType != null, "elementType of an entity set can never be null");
this.name = name;
this.elementType = elementType;
this.disallowedDerivedTypes = new HashSet(EqualityComparer.Default);
}
#if ASTORIA_CONTAINMENT
///
/// If this container has a canonical access path, this is the parent
/// container.
///
internal ResourceContainer ContainmentCanonicalParent
{
[DebuggerStepThrough]
get { return this.containmentCanonicalParent; }
}
///
/// If this container has a canonical access path, this is the parent
/// container's containing property.
///
internal ResourceProperty ContainmentCanonicalProperty
{
[DebuggerStepThrough]
get { return this.containmentCanonicalProperty; }
}
#endif
/// Reference to clr type that this resource container is a collection of
internal Type ElementType
{
get
{
return this.elementType.Type;
}
}
/// Cached delegate to read an IQueryable from the context.
internal Func ReadFromContextDelegate
{
get { return this.readFromContextDelegate; }
set { this.readFromContextDelegate = value; }
}
/// Reference to resource type that this resource container is a collection of
internal ResourceType ResourceType
{
get
{
return this.elementType;
}
}
/// Whether the resource container is visible to service consumers.
internal bool IsHidden
{
get { return this.rights == EntitySetRights.None; }
}
/// Name of the resource container.
internal string Name
{
get
{
return this.name;
}
}
/// Access rights to this resource container.
internal EntitySetRights Rights
{
get { return this.rights; }
set { this.rights = value; }
}
/// Methods to be called when composing read queries to allow authorization (possibly null).
internal MethodInfo[] ReadAuthorizationMethods
{
[DebuggerStepThrough]
get { return this.readAuthorizationMethods; }
}
#if ASTORIA_CONTAINMENT
/// Whether top-level access is available for this resource set.
internal bool TopLevelAccess
{
[DebuggerStepThrough]
get { return this.topLevelAccess; }
}
#endif
/// Methods to be called when validating write methods to allow authorization (possibly null).
internal MethodInfo[] WriteAuthorizationMethods
{
[DebuggerStepThrough]
get { return this.writeAuthorizationMethods; }
}
///
/// Adds the specified to the list of read
/// authorization methods for this resource container.
///
/// Method to add.
internal void AddReadAuthorizationMethod(MethodInfo method)
{
Debug.Assert(method != null, "method != null");
AppendMethod(method, ref this.readAuthorizationMethods);
}
///
/// Adds the specified to the list of write
/// authorization methods for this resource container.
///
/// Method to add.
internal void AddWriteAuthorizationMethod(MethodInfo method)
{
Debug.Assert(method != null, "method != null");
AppendMethod(method, ref this.writeAuthorizationMethods);
}
#if ASTORIA_CONTAINMENT
///
/// Sets all properties for the canonical path in a containment relationship.
///
/// Resource set that contains the canonical path.
/// Property in that contains the canonical path.
/// Whether top-level access is available.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "topLevelAccess", Justification = "1:1 mapping")]
internal void SetupCanonicalAccessPath(ResourceContainer container, ResourceProperty property, bool topLevelAccess)
{
Debug.Assert(container != null, "container != null");
Debug.Assert(property != null, "property != null");
Debug.Assert(
this.containmentCanonicalParent == null,
"this.containmentCanonicalParent == null -- otherwise, more than one canonical path is being set.");
this.containmentCanonicalParent = container;
this.containmentCanonicalProperty = property;
this.topLevelAccess = topLevelAccess;
}
#endif
///
/// Add the given resource type to the disallowed list, so that we can check during serialization
///
/// resource type that is disallowed for the given entity set.
internal void AddDisallowedDerivedType(ResourceType resourceType)
{
Debug.Assert(resourceType != null, "resourceType != null");
Debug.Assert(resourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "expecting entity types");
Debug.Assert(resourceType.Type.IsSubclassOf(this.ResourceType.Type), "the type must be a derived type for the given entity set");
this.disallowedDerivedTypes.Add(resourceType);
}
///
/// Checks whether the given resource type is not allowed for this entity set or not.
///
/// resourceType which needs to be checked
/// returns true if the given resource type is not allowed for this entity set. Otherwise returns false.
internal bool IsEntityDisallowed(ResourceType resourceType)
{
return this.disallowedDerivedTypes.Contains(resourceType);
}
/// Appends a method to the specified array.
/// Method to append.
/// Array to append to.
private static void AppendMethod(MethodInfo method, ref MethodInfo[] methods)
{
if (methods == null)
{
methods = new MethodInfo[1];
}
else
{
MethodInfo[] newArray = new MethodInfo[methods.Length + 1];
Array.Copy(methods, newArray, methods.Length);
methods = newArray;
}
methods[methods.Length - 1] = method;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.