Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / BoolExpressionVisitors.cs / 2 / BoolExpressionVisitors.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Entity;
namespace System.Data.Mapping.ViewGeneration.Structures {
using BoolDomainConstraint = DomainConstraint;
using DomainBoolExpr = BoolExpr>;
using DomainTreeExpr = TreeExpr>;
using DomainNotExpr = NotExpr>;
using DomainAndExpr = AndExpr>;
using DomainOrExpr = OrExpr>;
using DomainTermExpr = TermExpr>;
using DomainTrueExpr = TrueExpr>;
using DomainFalseExpr = FalseExpr>;
// This class represents an arbitrary boolean expression
internal partial class BoolExpression : InternalBase {
#region FixRangeVisitor
// A visitor that "fixes" the OneOfConsts according to the value of
// the Range in the DomainConstraint
private class FixRangeVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
private FixRangeVisitor(MemberDomainMap memberDomainMap) {
m_memberDomainMap = memberDomainMap;
}
private MemberDomainMap m_memberDomainMap;
// effects: Given expression and the domains of various members,
// ensures that the range in OneOfConsts is in line with the
// DomainConstraints in expression
internal static DomainBoolExpr FixRange(DomainBoolExpr expression, MemberDomainMap memberDomainMap) {
FixRangeVisitor visitor = new FixRangeVisitor(memberDomainMap);
DomainBoolExpr result = expression.Accept(visitor);
return result;
}
#endregion
#region Visitors
// The real work happens here in the literal's FixRange
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
DomainBoolExpr result = literal.FixRange(expression.Identifier.Range, m_memberDomainMap);
return result;
}
#endregion
}
#endregion
#region IsFinalVisitor
// A Visitor that determines if the OneOfConsts in this are fully
// done or not
private class IsFinalVisitor : Visitor {
internal static bool IsFinal(DomainBoolExpr expression) {
IsFinalVisitor visitor = new IsFinalVisitor();
return expression.Accept(visitor);
}
#region Visitors
internal override bool VisitTrue(DomainTrueExpr expression) {
return true;
}
internal override bool VisitFalse(DomainFalseExpr expression) {
return true;
}
// Check if the oneOfConst is fully done or not
internal override bool VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
OneOfConst oneOfConst = literal as OneOfConst;
bool result = oneOfConst == null || oneOfConst.IsFullyDone == true;
return result;
}
internal override bool VisitNot(DomainNotExpr expression) {
return expression.Child.Accept(this);
}
internal override bool VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression);
}
internal override bool VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression);
}
private bool VisitAndOr(DomainTreeExpr expression) {
// If any child is not final, tree is not final -- we cannot
// have a mix of final and non-final trees!
bool isFirst = true;
bool result = true;
foreach (DomainBoolExpr child in expression.Children) {
if (child as DomainFalseExpr != null || child as DomainTrueExpr != null) {
// Ignore true or false since they carry no information
continue;
}
bool isChildFinal = child.Accept(this);
if (isFirst) {
result = isChildFinal;
}
Debug.Assert(result == isChildFinal, "All children must be final or non-final");
isFirst = false;
}
return result;
}
#endregion
}
#endregion
#region RemapBoolVisitor
// A visitor that remaps the JoinTreeNodes in a bool tree
private class RemapBoolVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
// effects: Creates a visitor with the JoinTreeNode remapping
// information in remap
private RemapBoolVisitor(MemberDomainMap memberDomainMap, Dictionary remap) {
m_remap = remap;
m_memberDomainMap = memberDomainMap;
}
private Dictionary m_remap;
private MemberDomainMap m_memberDomainMap;
internal static DomainBoolExpr RemapJoinTreeNodes(DomainBoolExpr expression, MemberDomainMap memberDomainMap,
Dictionary remap) {
RemapBoolVisitor visitor = new RemapBoolVisitor(memberDomainMap, remap);
DomainBoolExpr result = expression.Accept(visitor);
return result;
}
#endregion
#region Visitors
// The real work happens here in the literal's RemapBool
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
BoolLiteral newLiteral = literal.RemapBool(m_remap);
return newLiteral.GetDomainBoolExpression(m_memberDomainMap);
}
#endregion
}
#endregion
#region RequiredSlotsVisitor
// A visitor that determines the slots required in the whole tree (for
// CQL Generation)
private class RequiredSlotsVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
private RequiredSlotsVisitor(MemberPathMapBase projectedSlotMap, bool[] requiredSlots) {
m_projectedSlotMap = projectedSlotMap;
m_requiredSlots = requiredSlots;
}
private MemberPathMapBase m_projectedSlotMap;
private bool[] m_requiredSlots;
internal static void GetRequiredSlots(DomainBoolExpr expression, MemberPathMapBase projectedSlotMap,
bool[] requiredSlots) {
RequiredSlotsVisitor visitor = new RequiredSlotsVisitor(projectedSlotMap, requiredSlots);
expression.Accept(visitor);
}
#endregion
#region Visitors
// The real work happends here - the slots are obtained from the literal
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
literal.GetRequiredSlots(m_projectedSlotMap, m_requiredSlots);
return expression;
}
#endregion
}
#endregion
// A Visitor that determines the CQL format of this expression
#region AsCqlVisitor
private class AsCqlVisitor : Visitor {
#region Constructor/Fields/Invocation
private AsCqlVisitor(StringBuilder builder, string blockAlias) {
m_builder = builder;
m_blockAlias = blockAlias;
// All boolean expressions can evaluate to true or not true
// (i.e., false or unknown) whether it is in CASE statements
// or WHERE clauses
m_canSkipIsNotNull = true;
}
private StringBuilder m_builder;
private string m_blockAlias;
// We could maintain a stack of bools ratehr than a single
// boolean for the visitor to allow IS NOT NULLs to be not
// generated for some scenarios
private bool m_canSkipIsNotNull;
internal static StringBuilder AsCql(DomainBoolExpr expression, StringBuilder builder, string blockAlias) {
AsCqlVisitor visitor = new AsCqlVisitor(builder, blockAlias);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression) {
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression) {
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression) {
// If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
// node is OR or NOT
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
return literal.AsCql(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
internal override StringBuilder VisitNot(DomainNotExpr expression) {
m_canSkipIsNotNull = false; // Cannot skip in NOTs
m_builder.Append("NOT(");
// We do not need the returned StringBuilder -- it is the same as m_builder
expression.Child.Accept(this);
m_builder.Append(")");
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression, ExprType.And);
}
internal override StringBuilder VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression, ExprType.Or);
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind) {
Debug.Assert(kind == ExprType.Or || kind == ExprType.And);
m_builder.Append('(');
bool isFirstChild = true;
foreach (DomainBoolExpr child in expression.Children) {
if (false == isFirstChild) {
// Add the operator
if (kind == ExprType.And) {
m_builder.Append(" AND ");
} else {
m_builder.Append(" OR ");
}
}
isFirstChild = false;
// Recursively get the CQL for the child
child.Accept(this);
}
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
// A Visitor that produces User understandable string of the given configuration represented by the BooleanExpression
#region AsUserStringVisitor
private class AsUserStringVisitor : Visitor
{
#region Constructor/Fields/Invocation
private AsUserStringVisitor(StringBuilder builder, string blockAlias)
{
m_builder = builder;
m_blockAlias = blockAlias;
// All boolean expressions can evaluate to true or not true
// (i.e., false or unknown) whether it is in CASE statements
// or WHERE clauses
m_canSkipIsNotNull = true;
}
private StringBuilder m_builder;
private string m_blockAlias;
// We could maintain a stack of bools ratehr than a single
// boolean for the visitor to allow IS NOT NULLs to be not
// generated for some scenarios
private bool m_canSkipIsNotNull;
internal static StringBuilder AsUserString(DomainBoolExpr expression, StringBuilder builder, string blockAlias)
{
AsUserStringVisitor visitor = new AsUserStringVisitor(builder, blockAlias);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression)
{
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression)
{
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression)
{
// If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
// node is OR or NOT
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
if (literal is OneOfScalarConst || literal is OneOfTypeConst)
{
return literal.AsUserString(m_builder, Strings.ViewGen_EntityInstanceToken, m_canSkipIsNotNull);
}
return literal.AsUserString(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
internal override StringBuilder VisitNot(DomainNotExpr expression)
{
m_canSkipIsNotNull = false; // Cannot skip in NOTs
DomainTermExpr termExpr = expression.Child as DomainTermExpr;
if (termExpr != null)
{
BoolLiteral literal = BoolExpression.GetBoolLiteral(termExpr);
return literal.AsNegatedUserString(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
else
{
m_builder.Append("NOT(");
// We do not need the returned StringBuilder -- it is the same as m_builder
expression.Child.Accept(this);
m_builder.Append(")");
}
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression)
{
return VisitAndOr(expression, ExprType.And);
}
internal override StringBuilder VisitOr(DomainOrExpr expression)
{
return VisitAndOr(expression, ExprType.Or);
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind)
{
Debug.Assert(kind == ExprType.Or || kind == ExprType.And);
m_builder.Append('(');
bool isFirstChild = true;
foreach (DomainBoolExpr child in expression.Children)
{
if (false == isFirstChild)
{
// Add the operator
if (kind == ExprType.And)
{
m_builder.Append(" AND ");
}
else
{
m_builder.Append(" OR ");
}
}
isFirstChild = false;
// Recursively get the CQL for the child
child.Accept(this);
}
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
// Given an expression that has no NOTs or ORs (if allowAllOperators
// is false in GetTerms), generates the terms in it
#region TermVisitor
private class TermVisitor : Visitor> {
#region Constructor/Fields/Invocation
private TermVisitor(bool allowAllOperators) {
m_allowAllOperators = allowAllOperators;
}
// effectS: Returns all the terms in expression. If
// allowAllOperators is true, ensures that there are no NOTs or ORs
internal static IEnumerable GetTerms(DomainBoolExpr expression, bool allowAllOperators) {
TermVisitor visitor = new TermVisitor(allowAllOperators);
return expression.Accept>(visitor);
}
#endregion
#region Fields
private bool m_allowAllOperators;
#endregion
#region Visitors
internal override IEnumerable VisitTrue(DomainTrueExpr expression) {
yield break; // No Atoms here -- we are not looking for constants
}
internal override IEnumerable VisitFalse(DomainFalseExpr expression) {
yield break; // No Atoms here -- we are not looking for constants
}
internal override IEnumerable VisitTerm(DomainTermExpr expression) {
yield return expression;
}
internal override IEnumerable VisitNot(DomainNotExpr expression) {
Debug.Assert(m_allowAllOperators, "Term should not be called when Nots are present in the expression");
return VisitTreeNode(expression);
}
private IEnumerable VisitTreeNode(DomainTreeExpr expression) {
foreach (DomainBoolExpr child in expression.Children) {
foreach (DomainTermExpr result in child.Accept(this)) {
yield return result;
}
}
}
internal override IEnumerable VisitAnd(DomainAndExpr expression) {
return VisitTreeNode(expression);
}
internal override IEnumerable VisitOr(DomainOrExpr expression) {
Debug.Assert(m_allowAllOperators, "TermVisitor should not be called when Ors are present in the expression");
return VisitTreeNode(expression);
}
#endregion
}
#endregion
#region CompactStringVisitor
// Generates a human readable version of the expression and places it in
// the StringBuilder
private class CompactStringVisitor : Visitor {
#region Constructor/Fields/Invocation
private CompactStringVisitor(StringBuilder builder) {
m_builder = builder;
}
private StringBuilder m_builder;
internal static StringBuilder ToBuilder(DomainBoolExpr expression, StringBuilder builder) {
CompactStringVisitor visitor = new CompactStringVisitor(builder);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression) {
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression) {
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
literal.ToCompactString(m_builder);
return m_builder;
}
internal override StringBuilder VisitNot(DomainNotExpr expression) {
m_builder.Append("NOT(");
expression.Child.Accept(this);
m_builder.Append(")");
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression, "AND");
}
internal override StringBuilder VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression, "OR");
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, string opAsString) {
List childrenStrings = new List();
StringBuilder builder = m_builder;
// Save the old string builder and pass a new one to each child
foreach (DomainBoolExpr child in expression.Children) {
m_builder = new StringBuilder();
child.Accept(this);
childrenStrings.Add(m_builder.ToString());
}
// Now store the children in a sorted manner
m_builder = builder;
m_builder.Append('(');
StringUtil.ToSeparatedStringSorted(m_builder, childrenStrings, " " + opAsString + " ");
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data.Entity;
namespace System.Data.Mapping.ViewGeneration.Structures {
using BoolDomainConstraint = DomainConstraint;
using DomainBoolExpr = BoolExpr>;
using DomainTreeExpr = TreeExpr>;
using DomainNotExpr = NotExpr>;
using DomainAndExpr = AndExpr>;
using DomainOrExpr = OrExpr>;
using DomainTermExpr = TermExpr>;
using DomainTrueExpr = TrueExpr>;
using DomainFalseExpr = FalseExpr>;
// This class represents an arbitrary boolean expression
internal partial class BoolExpression : InternalBase {
#region FixRangeVisitor
// A visitor that "fixes" the OneOfConsts according to the value of
// the Range in the DomainConstraint
private class FixRangeVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
private FixRangeVisitor(MemberDomainMap memberDomainMap) {
m_memberDomainMap = memberDomainMap;
}
private MemberDomainMap m_memberDomainMap;
// effects: Given expression and the domains of various members,
// ensures that the range in OneOfConsts is in line with the
// DomainConstraints in expression
internal static DomainBoolExpr FixRange(DomainBoolExpr expression, MemberDomainMap memberDomainMap) {
FixRangeVisitor visitor = new FixRangeVisitor(memberDomainMap);
DomainBoolExpr result = expression.Accept(visitor);
return result;
}
#endregion
#region Visitors
// The real work happens here in the literal's FixRange
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
DomainBoolExpr result = literal.FixRange(expression.Identifier.Range, m_memberDomainMap);
return result;
}
#endregion
}
#endregion
#region IsFinalVisitor
// A Visitor that determines if the OneOfConsts in this are fully
// done or not
private class IsFinalVisitor : Visitor {
internal static bool IsFinal(DomainBoolExpr expression) {
IsFinalVisitor visitor = new IsFinalVisitor();
return expression.Accept(visitor);
}
#region Visitors
internal override bool VisitTrue(DomainTrueExpr expression) {
return true;
}
internal override bool VisitFalse(DomainFalseExpr expression) {
return true;
}
// Check if the oneOfConst is fully done or not
internal override bool VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
OneOfConst oneOfConst = literal as OneOfConst;
bool result = oneOfConst == null || oneOfConst.IsFullyDone == true;
return result;
}
internal override bool VisitNot(DomainNotExpr expression) {
return expression.Child.Accept(this);
}
internal override bool VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression);
}
internal override bool VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression);
}
private bool VisitAndOr(DomainTreeExpr expression) {
// If any child is not final, tree is not final -- we cannot
// have a mix of final and non-final trees!
bool isFirst = true;
bool result = true;
foreach (DomainBoolExpr child in expression.Children) {
if (child as DomainFalseExpr != null || child as DomainTrueExpr != null) {
// Ignore true or false since they carry no information
continue;
}
bool isChildFinal = child.Accept(this);
if (isFirst) {
result = isChildFinal;
}
Debug.Assert(result == isChildFinal, "All children must be final or non-final");
isFirst = false;
}
return result;
}
#endregion
}
#endregion
#region RemapBoolVisitor
// A visitor that remaps the JoinTreeNodes in a bool tree
private class RemapBoolVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
// effects: Creates a visitor with the JoinTreeNode remapping
// information in remap
private RemapBoolVisitor(MemberDomainMap memberDomainMap, Dictionary remap) {
m_remap = remap;
m_memberDomainMap = memberDomainMap;
}
private Dictionary m_remap;
private MemberDomainMap m_memberDomainMap;
internal static DomainBoolExpr RemapJoinTreeNodes(DomainBoolExpr expression, MemberDomainMap memberDomainMap,
Dictionary remap) {
RemapBoolVisitor visitor = new RemapBoolVisitor(memberDomainMap, remap);
DomainBoolExpr result = expression.Accept(visitor);
return result;
}
#endregion
#region Visitors
// The real work happens here in the literal's RemapBool
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
BoolLiteral newLiteral = literal.RemapBool(m_remap);
return newLiteral.GetDomainBoolExpression(m_memberDomainMap);
}
#endregion
}
#endregion
#region RequiredSlotsVisitor
// A visitor that determines the slots required in the whole tree (for
// CQL Generation)
private class RequiredSlotsVisitor : BasicVisitor {
#region Constructor/Fields/Invocation
private RequiredSlotsVisitor(MemberPathMapBase projectedSlotMap, bool[] requiredSlots) {
m_projectedSlotMap = projectedSlotMap;
m_requiredSlots = requiredSlots;
}
private MemberPathMapBase m_projectedSlotMap;
private bool[] m_requiredSlots;
internal static void GetRequiredSlots(DomainBoolExpr expression, MemberPathMapBase projectedSlotMap,
bool[] requiredSlots) {
RequiredSlotsVisitor visitor = new RequiredSlotsVisitor(projectedSlotMap, requiredSlots);
expression.Accept(visitor);
}
#endregion
#region Visitors
// The real work happends here - the slots are obtained from the literal
internal override DomainBoolExpr VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
literal.GetRequiredSlots(m_projectedSlotMap, m_requiredSlots);
return expression;
}
#endregion
}
#endregion
// A Visitor that determines the CQL format of this expression
#region AsCqlVisitor
private class AsCqlVisitor : Visitor {
#region Constructor/Fields/Invocation
private AsCqlVisitor(StringBuilder builder, string blockAlias) {
m_builder = builder;
m_blockAlias = blockAlias;
// All boolean expressions can evaluate to true or not true
// (i.e., false or unknown) whether it is in CASE statements
// or WHERE clauses
m_canSkipIsNotNull = true;
}
private StringBuilder m_builder;
private string m_blockAlias;
// We could maintain a stack of bools ratehr than a single
// boolean for the visitor to allow IS NOT NULLs to be not
// generated for some scenarios
private bool m_canSkipIsNotNull;
internal static StringBuilder AsCql(DomainBoolExpr expression, StringBuilder builder, string blockAlias) {
AsCqlVisitor visitor = new AsCqlVisitor(builder, blockAlias);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression) {
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression) {
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression) {
// If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
// node is OR or NOT
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
return literal.AsCql(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
internal override StringBuilder VisitNot(DomainNotExpr expression) {
m_canSkipIsNotNull = false; // Cannot skip in NOTs
m_builder.Append("NOT(");
// We do not need the returned StringBuilder -- it is the same as m_builder
expression.Child.Accept(this);
m_builder.Append(")");
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression, ExprType.And);
}
internal override StringBuilder VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression, ExprType.Or);
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind) {
Debug.Assert(kind == ExprType.Or || kind == ExprType.And);
m_builder.Append('(');
bool isFirstChild = true;
foreach (DomainBoolExpr child in expression.Children) {
if (false == isFirstChild) {
// Add the operator
if (kind == ExprType.And) {
m_builder.Append(" AND ");
} else {
m_builder.Append(" OR ");
}
}
isFirstChild = false;
// Recursively get the CQL for the child
child.Accept(this);
}
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
// A Visitor that produces User understandable string of the given configuration represented by the BooleanExpression
#region AsUserStringVisitor
private class AsUserStringVisitor : Visitor
{
#region Constructor/Fields/Invocation
private AsUserStringVisitor(StringBuilder builder, string blockAlias)
{
m_builder = builder;
m_blockAlias = blockAlias;
// All boolean expressions can evaluate to true or not true
// (i.e., false or unknown) whether it is in CASE statements
// or WHERE clauses
m_canSkipIsNotNull = true;
}
private StringBuilder m_builder;
private string m_blockAlias;
// We could maintain a stack of bools ratehr than a single
// boolean for the visitor to allow IS NOT NULLs to be not
// generated for some scenarios
private bool m_canSkipIsNotNull;
internal static StringBuilder AsUserString(DomainBoolExpr expression, StringBuilder builder, string blockAlias)
{
AsUserStringVisitor visitor = new AsUserStringVisitor(builder, blockAlias);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression)
{
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression)
{
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression)
{
// If m_canSkipIsNotNull is true at this point, it means that no ancestor of this
// node is OR or NOT
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
if (literal is OneOfScalarConst || literal is OneOfTypeConst)
{
return literal.AsUserString(m_builder, Strings.ViewGen_EntityInstanceToken, m_canSkipIsNotNull);
}
return literal.AsUserString(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
internal override StringBuilder VisitNot(DomainNotExpr expression)
{
m_canSkipIsNotNull = false; // Cannot skip in NOTs
DomainTermExpr termExpr = expression.Child as DomainTermExpr;
if (termExpr != null)
{
BoolLiteral literal = BoolExpression.GetBoolLiteral(termExpr);
return literal.AsNegatedUserString(m_builder, m_blockAlias, m_canSkipIsNotNull);
}
else
{
m_builder.Append("NOT(");
// We do not need the returned StringBuilder -- it is the same as m_builder
expression.Child.Accept(this);
m_builder.Append(")");
}
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression)
{
return VisitAndOr(expression, ExprType.And);
}
internal override StringBuilder VisitOr(DomainOrExpr expression)
{
return VisitAndOr(expression, ExprType.Or);
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, ExprType kind)
{
Debug.Assert(kind == ExprType.Or || kind == ExprType.And);
m_builder.Append('(');
bool isFirstChild = true;
foreach (DomainBoolExpr child in expression.Children)
{
if (false == isFirstChild)
{
// Add the operator
if (kind == ExprType.And)
{
m_builder.Append(" AND ");
}
else
{
m_builder.Append(" OR ");
}
}
isFirstChild = false;
// Recursively get the CQL for the child
child.Accept(this);
}
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
// Given an expression that has no NOTs or ORs (if allowAllOperators
// is false in GetTerms), generates the terms in it
#region TermVisitor
private class TermVisitor : Visitor> {
#region Constructor/Fields/Invocation
private TermVisitor(bool allowAllOperators) {
m_allowAllOperators = allowAllOperators;
}
// effectS: Returns all the terms in expression. If
// allowAllOperators is true, ensures that there are no NOTs or ORs
internal static IEnumerable GetTerms(DomainBoolExpr expression, bool allowAllOperators) {
TermVisitor visitor = new TermVisitor(allowAllOperators);
return expression.Accept>(visitor);
}
#endregion
#region Fields
private bool m_allowAllOperators;
#endregion
#region Visitors
internal override IEnumerable VisitTrue(DomainTrueExpr expression) {
yield break; // No Atoms here -- we are not looking for constants
}
internal override IEnumerable VisitFalse(DomainFalseExpr expression) {
yield break; // No Atoms here -- we are not looking for constants
}
internal override IEnumerable VisitTerm(DomainTermExpr expression) {
yield return expression;
}
internal override IEnumerable VisitNot(DomainNotExpr expression) {
Debug.Assert(m_allowAllOperators, "Term should not be called when Nots are present in the expression");
return VisitTreeNode(expression);
}
private IEnumerable VisitTreeNode(DomainTreeExpr expression) {
foreach (DomainBoolExpr child in expression.Children) {
foreach (DomainTermExpr result in child.Accept(this)) {
yield return result;
}
}
}
internal override IEnumerable VisitAnd(DomainAndExpr expression) {
return VisitTreeNode(expression);
}
internal override IEnumerable VisitOr(DomainOrExpr expression) {
Debug.Assert(m_allowAllOperators, "TermVisitor should not be called when Ors are present in the expression");
return VisitTreeNode(expression);
}
#endregion
}
#endregion
#region CompactStringVisitor
// Generates a human readable version of the expression and places it in
// the StringBuilder
private class CompactStringVisitor : Visitor {
#region Constructor/Fields/Invocation
private CompactStringVisitor(StringBuilder builder) {
m_builder = builder;
}
private StringBuilder m_builder;
internal static StringBuilder ToBuilder(DomainBoolExpr expression, StringBuilder builder) {
CompactStringVisitor visitor = new CompactStringVisitor(builder);
return expression.Accept(visitor);
}
#endregion
#region Visitors
internal override StringBuilder VisitTrue(DomainTrueExpr expression) {
m_builder.Append("True");
return m_builder;
}
internal override StringBuilder VisitFalse(DomainFalseExpr expression) {
m_builder.Append("False");
return m_builder;
}
internal override StringBuilder VisitTerm(DomainTermExpr expression) {
BoolLiteral literal = BoolExpression.GetBoolLiteral(expression);
literal.ToCompactString(m_builder);
return m_builder;
}
internal override StringBuilder VisitNot(DomainNotExpr expression) {
m_builder.Append("NOT(");
expression.Child.Accept(this);
m_builder.Append(")");
return m_builder;
}
internal override StringBuilder VisitAnd(DomainAndExpr expression) {
return VisitAndOr(expression, "AND");
}
internal override StringBuilder VisitOr(DomainOrExpr expression) {
return VisitAndOr(expression, "OR");
}
private StringBuilder VisitAndOr(DomainTreeExpr expression, string opAsString) {
List childrenStrings = new List();
StringBuilder builder = m_builder;
// Save the old string builder and pass a new one to each child
foreach (DomainBoolExpr child in expression.Children) {
m_builder = new StringBuilder();
child.Accept(this);
childrenStrings.Add(m_builder.ToString());
}
// Now store the children in a sorted manner
m_builder = builder;
m_builder.Append('(');
StringUtil.ToSeparatedStringSorted(m_builder, childrenStrings, " " + opAsString + " ");
m_builder.Append(')');
return m_builder;
}
#endregion
}
#endregion
}
}
// 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
- ParserContext.cs
- autovalidator.cs
- AppModelKnownContentFactory.cs
- DataGridColumnCollection.cs
- ParseHttpDate.cs
- ReplyChannel.cs
- ParenExpr.cs
- SqlDataSourceEnumerator.cs
- TrackPoint.cs
- DataGridViewCellLinkedList.cs
- Queue.cs
- SspiSafeHandles.cs
- EnumCodeDomSerializer.cs
- RepeaterItemEventArgs.cs
- SmtpDigestAuthenticationModule.cs
- BinaryMethodMessage.cs
- Trace.cs
- Handle.cs
- _ListenerAsyncResult.cs
- EntityException.cs
- ViewStateException.cs
- HTTPNotFoundHandler.cs
- SslStream.cs
- StandardToolWindows.cs
- MostlySingletonList.cs
- _ListenerAsyncResult.cs
- Grant.cs
- DrawingContext.cs
- BaseParser.cs
- Condition.cs
- ProviderIncompatibleException.cs
- XmlAtomicValue.cs
- Point.cs
- CodeDelegateCreateExpression.cs
- EditorPartChrome.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- LinkUtilities.cs
- ResourceReader.cs
- PenContext.cs
- ProviderUtil.cs
- Int32CollectionValueSerializer.cs
- DataServiceProcessingPipelineEventArgs.cs
- ToolboxItemCollection.cs
- Path.cs
- AlignmentYValidation.cs
- IdentitySection.cs
- StructuredTypeEmitter.cs
- TreeViewImageIndexConverter.cs
- WorkflowInstance.cs
- MasterPageBuildProvider.cs
- SqlNamer.cs
- CorrelationTokenTypeConvertor.cs
- CodeVariableReferenceExpression.cs
- ViewUtilities.cs
- ExceptionUtil.cs
- DoubleConverter.cs
- ClientBuildManagerTypeDescriptionProviderBridge.cs
- BitmapEffectGeneralTransform.cs
- ProcessThreadCollection.cs
- BuilderPropertyEntry.cs
- EventSetter.cs
- WindowsAuthenticationModule.cs
- x509store.cs
- StateFinalizationDesigner.cs
- RegexInterpreter.cs
- UnionCqlBlock.cs
- Assert.cs
- ServiceInfoCollection.cs
- TraceFilter.cs
- HttpCacheVaryByContentEncodings.cs
- RegexCompiler.cs
- SystemResources.cs
- SchemaImporterExtension.cs
- WaitForChangedResult.cs
- ResourceManager.cs
- DbConnectionPoolOptions.cs
- Wildcard.cs
- WmpBitmapDecoder.cs
- BrowserCapabilitiesFactory35.cs
- IItemContainerGenerator.cs
- PeerUnsafeNativeMethods.cs
- OleDbConnection.cs
- ObfuscationAttribute.cs
- Inline.cs
- MouseButtonEventArgs.cs
- DependencyObjectType.cs
- WindowsClientCredential.cs
- IApplicationTrustManager.cs
- SqlVersion.cs
- XmlSchemaSet.cs
- HttpModuleCollection.cs
- ParameterDataSourceExpression.cs
- FirstQueryOperator.cs
- ItemAutomationPeer.cs
- XmlSchemaGroup.cs
- SafeReadContext.cs
- MethodImplAttribute.cs
- ResourceManagerWrapper.cs
- ScriptIgnoreAttribute.cs
- storepermission.cs