MemberRestriction.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberRestriction.cs / 1305376 / MemberRestriction.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Collections.Generic; 
using System.Data.Common.Utils.Boolean;
using System.Text;
using System.Data.Common.Utils;
using System.Diagnostics; 
using System.Data.Mapping.ViewGeneration.Utils;
using System.Data.Metadata.Edm; 
using System.Linq; 

namespace System.Data.Mapping.ViewGeneration.Structures 
{

    using DomainBoolExpr = BoolExpr>;
    using DomainTermExpr = TermExpr>; 
    using System.Data.Entity;
 
    // An abstract class that denotes the boolean expression: "var in values" 
    // An object of this type can be partially or fully done -- A partially
    // done object is one whose domain was not created with all possible 
    // values. Partially done classes have a limited set of methods that can
    // be called
    internal abstract class MemberRestriction : BoolLiteral
    { 

        #region Constructors 
        // effects: Creates a "partial" oneOfConst with the meaning "slot = value". "Partial" means 
        // that the CellConstantDomain in this is partial - hence the operations on "this" are limited
        protected MemberRestriction(MemberProjectedSlot slot, Constant value) 
            : this(slot, new Constant[] { value })
        {
        }
 
        // effects: Creates a "partial" oneOfConst with the meaning "slot in values"
        protected MemberRestriction(MemberProjectedSlot slot, IEnumerable values) 
        { 
            m_restrictedMemberSlot = slot;
            m_domain = new Domain(values, values); 
        }

        // effects: Creates an expression of the form "slot in domain"
        protected MemberRestriction(MemberProjectedSlot slot, Domain domain) 
        {
            m_restrictedMemberSlot = slot; 
            m_domain = domain; 
            m_isFullyDone = true;
            Debug.Assert(m_domain.Count != 0, "If you want a boolean that evaluates to false, " + 
                         "use the ConstantBool abstraction");
        }

        // effects: Creates an expression of the form "slot = value" 
        // possibleValues are all the values that slot can take
        protected MemberRestriction(MemberProjectedSlot slot, Constant value, IEnumerable possibleValues) : 
            this(slot, new Domain(value, possibleValues)) 
        {
            Debug.Assert(possibleValues != null); 
        }

        // effects: Creates an expression of the form "slot in domain"
        private static MemberRestriction Factory(MemberProjectedSlot slot, Domain domain, bool isTypeConstant) 
        {
            if (isTypeConstant) 
            { 
                return new TypeRestriction(slot, domain);
            } 
            else
            {
                return new ScalarRestriction(slot, domain);
            } 
        }
 
        // effects: Creates an expression of the form "node in values" 
        // possibleValues are all the values that slot can take
        protected MemberRestriction(MemberProjectedSlot slot, IEnumerable values, 
                             IEnumerable possibleValues) :
            this(slot, new Domain(values, possibleValues))
        {
        } 
        #endregion
 
        #region Fields 
        // State to keep track of "m_slot in m_values"
        private MemberProjectedSlot m_restrictedMemberSlot; 
        private Domain m_domain;
        private bool m_isFullyDone;
        #endregion
 
        #region Properties
        internal bool IsFullyDone 
        { 
            get { return m_isFullyDone; }
        } 

        // effects: Returns the variable in this
        internal MemberProjectedSlot RestrictedMemberSlot
        { 
            get { return m_restrictedMemberSlot; }
        } 
 
        // effects: Returns the values that it is being checked for
        internal Domain Domain 
        {
            get { return m_domain; }
        }
        #endregion 

        #region BoolLiteral Members 
        // effects: Returns a boolean expression that is domain-aware and 
        // ready for optimizations etc. domainMap maps members to the values
        // that each member can take -- it can be null in which case the 
        // possible and actual values are the same
        internal override DomainBoolExpr GetDomainBoolExpression(MemberDomainMap domainMap)
        {
            // Get the variable name from the slot's memberpath and the possible domain values from the slot 

            DomainTermExpr result; 
            if (domainMap != null) 
            {
                // Look up the domain from the domainMap 
                IEnumerable domain = domainMap.GetDomain(m_restrictedMemberSlot.MemberPath);
                result = MakeTermExpression(this, domain, m_domain.Values);
            }
            else 
            {
                result = MakeTermExpression(this, m_domain.AllPossibleValues, m_domain.Values); 
            } 
            return result;
        } 

        // oneOfConst can be partial
        // effects: Creates a OneOfConst based on existing oneofconst with
        // possible values for the domain being given by possibleValues 
        internal static MemberRestriction CreateFullOneOfConst(MemberRestriction restriction, IEnumerable possibleValues)
        { 
            if (restriction is TypeRestriction) 
            {
                return new TypeRestriction(restriction.RestrictedMemberSlot, new Domain(restriction.Domain.Values, possibleValues)); 
            }
            else
            {
                return new ScalarRestriction(restriction.RestrictedMemberSlot, new Domain(restriction.Domain.Values, possibleValues)); 
            }
        } 
 
        // effects: See BoolLiteral.GetRequiredSlots
        internal override void GetRequiredSlots(MemberProjectionIndex projectedSlotMap, bool[] requiredSlots) 
        {
            // Simply get the slot for the variable var in "var in values"
            MemberPath member = RestrictedMemberSlot.MemberPath;
            int slotNum = projectedSlotMap.IndexOf(member); 
            requiredSlots[slotNum] = true;
        } 
 
        // oneOfConst can be partial
        // effects: see BoolLiteral.IsEqualTo 
        protected override bool IsEqualTo(BoolLiteral right)
        {
            MemberRestriction rightOneOfConst = right as MemberRestriction;
            if (rightOneOfConst == null) 
            {
                return false; 
            } 
            if (object.ReferenceEquals(this, rightOneOfConst))
            { 
                return true;
            }
            if (false == MemberProjectedSlot.EqualityComparer.Equals(m_restrictedMemberSlot, rightOneOfConst.m_restrictedMemberSlot))
            { 
                return false;
            } 
 
            return m_domain.IsEqualTo(rightOneOfConst.m_domain);
        } 

        // effects: see BoolLiteral.RemapBool
        internal override BoolLiteral RemapBool(Dictionary remap)
        { 
            MemberProjectedSlot newVar = (MemberProjectedSlot)RestrictedMemberSlot.RemapSlot(remap);
            return MemberRestriction.Factory(newVar, Domain, this.GetType() == typeof(TypeRestriction)); 
        } 

        // oneOfConst can be partial 
        // effects: see BoolLiteral.GetHash
        protected override int GetHash()
        {
            int result = MemberProjectedSlot.EqualityComparer.GetHashCode(m_restrictedMemberSlot); 
            result ^= m_domain.GetHash();
            return result; 
        } 

        // oneOfConst can be partial 
        // effects: see BoolLiteral.IsIdentifierEqualTo
        protected override bool IsIdentifierEqualTo(BoolLiteral right)
        {
            MemberRestriction rightOneOfConst = right as MemberRestriction; 
            if (rightOneOfConst == null)
            { 
                return false; 
            }
            if (object.ReferenceEquals(this, rightOneOfConst)) 
            {
                return true;
            }
            return MemberProjectedSlot.EqualityComparer.Equals(m_restrictedMemberSlot, rightOneOfConst.m_restrictedMemberSlot); 
        }
 
        // oneOfConst can be partial 
        // effects: see BoolLiteral.GetIdentifierHash
        protected override int GetIdentifierHash() 
        {
            int result = MemberProjectedSlot.EqualityComparer.GetHashCode(m_restrictedMemberSlot);
            return result;
        } 
        #endregion
 
        #region Other Methods 
        // effects: Converts this to a user-understandable
        // string. invertOutput indicates whether the text needs to say "x in 
        // .. or x in NOT ...  (i.e., the latter if invertOutput is true)
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal void ToUserString(bool invertOutput, StringBuilder builder, MetadataWorkspace workspace)
        { 

            // If there is a negated cell constant, get the inversion of the domain 
            NegatedConstant negatedConstant = null; 
            foreach (Constant constant in Domain.Values)
            { 
                negatedConstant = constant as NegatedConstant;
                if (negatedConstant != null)
                {
                    break; 
                }
            } 
 
            Set constants;
            if (negatedConstant != null) 
            {
                // Invert the domain and invert "invertOutput"
                invertOutput = !invertOutput;
                // Add all the values to negatedConstant's values to get the 
                // final set of constants
                constants = new Set(negatedConstant.Elements, Constant.EqualityComparer); 
                foreach (Constant constant in Domain.Values) 
                {
                    if (!(constant is NegatedConstant)) 
                    {
                        Debug.Assert(constants.Contains(constant), "Domain of negated constant does not have positive constant");
                        constants.Remove(constant);
                    } 
                }
            } 
            else 
            {
                constants = new Set(Domain.Values, Constant.EqualityComparer); 
            }

            // Determine the resource to use
            Debug.Assert(constants.Count > 0, "one of const is false?"); 
            bool isNull = constants.Count == 1 && constants.Single().IsNull();
            bool isTypeConstant = this is TypeRestriction; 
 
            Func resourceName0 = null;
            Func resourceName1 = null; 

            if (invertOutput)
            {
                if (isNull) 
                {
                    resourceName0 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_IsNonNullable_0 : (Func)Strings.ViewGen_OneOfConst_MustBeNonNullable_0; 
                } 
                else if (constants.Count == 1)
                { 
                    resourceName1 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_IsNotEqualTo_1 : (Func)Strings.ViewGen_OneOfConst_MustNotBeEqualTo_1;
                }
                else
                { 
                    resourceName1 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_IsNotOneOf_1 : (Func)Strings.ViewGen_OneOfConst_MustNotBeOneOf_1;
                } 
            } 
            else
            { 
                if (isNull)
                {
                    resourceName0 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_MustBeNull_0 : (Func)Strings.ViewGen_OneOfConst_MustBeNull_0;
                } 
                else if (constants.Count == 1)
                { 
                    resourceName1 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_IsEqualTo_1 : (Func)Strings.ViewGen_OneOfConst_MustBeEqualTo_1; 
                }
                else 
                {
                    resourceName1 = isTypeConstant ? (Func)Strings.ViewGen_OneOfConst_IsOneOf_1 : (Func)Strings.ViewGen_OneOfConst_MustBeOneOf_1;
                }
            } 

            // Get the constants 
            StringBuilder constantBuilder = new StringBuilder(); 
            Constant.ConstantsToUserString(constantBuilder, constants);
 
            Debug.Assert((resourceName0 == null) != (resourceName1 == null),
                         "Both resources must not have been set or be null");
            string variableName = m_restrictedMemberSlot.MemberPath.PathToString(false);
            if (isTypeConstant) 
            {
                variableName = "TypeOf(" + variableName + ")"; 
            } 

            if (resourceName0 != null) 
            {
                builder.Append(resourceName0(variableName));
            }
            else 
            {
                builder.Append(resourceName1(variableName, constantBuilder.ToString())); 
            } 

            if (invertOutput && isTypeConstant) 
            {
                InvertOutputStringForTypeConstant(builder, constants, workspace);
            }
        } 

        // effects: Given the fact that constants are typeConstants, modifies builder to contain a message for inverting the 
        // typeConstants, i.e., NOT(p in Person) becomes p in Customer 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        private void InvertOutputStringForTypeConstant(StringBuilder builder, Set constants, MetadataWorkspace workspace) 
        {
            // Get all the types that this type can take (i.e., all
            // subtypes - the types present in this
            StringBuilder typeBuilder = new StringBuilder(); 
            Set allTypes = new Set();
 
            // Get all types 
            EdmType memberType = RestrictedMemberSlot.MemberPath.EdmType;
            foreach (EdmType type in MetadataHelper.GetTypeAndSubtypesOf(memberType, workspace, false)) 
            {
                allTypes.Add(type);
            }
 
            // Get the types in this
            Set oneOfTypes = new Set(); 
            foreach (Constant constant in constants) 
            {
                TypeConstant typeConstant = (TypeConstant)constant; 
                oneOfTypes.Add(typeConstant.CdmType);
            }

            // Get the difference 
            allTypes.Subtract(oneOfTypes);
            bool isFirst = true; 
            foreach (EdmType type in allTypes) 
            {
                if (isFirst == false) 
                {
                    typeBuilder.Append(System.Data.Entity.Strings.ViewGen_CommaBlank);
                }
                isFirst = false; 
                typeBuilder.Append(type.Name);
            } 
            builder.Append(Strings.ViewGen_OneOfConst_IsOneOfTypes_0(typeBuilder.ToString())); 
        }
 
        internal override StringBuilder AsUserString(StringBuilder builder, string blockAlias, bool canSkipIsNotNull)
        {
            return AsCql(builder, blockAlias, canSkipIsNotNull);
        } 

        internal override StringBuilder AsNegatedUserString(StringBuilder builder, string blockAlias, bool canSkipIsNotNull) 
        { 
            builder.Append("NOT(");
            builder = AsUserString(builder, blockAlias, canSkipIsNotNull); 
            builder.Append(")");
            return builder;
        }
        #endregion 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK