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
- EncoderFallback.cs
- InternalSafeNativeMethods.cs
- HttpBrowserCapabilitiesBase.cs
- MediaEntryAttribute.cs
- NavigationProgressEventArgs.cs
- CommandTreeTypeHelper.cs
- Quaternion.cs
- NegatedConstant.cs
- TypeSchema.cs
- KeyToListMap.cs
- XslAst.cs
- MenuTracker.cs
- Clock.cs
- DataColumnMapping.cs
- StringDictionaryWithComparer.cs
- SqlTypeConverter.cs
- TransformerConfigurationWizardBase.cs
- OdbcPermission.cs
- BasicExpandProvider.cs
- WebPartPersonalization.cs
- SweepDirectionValidation.cs
- PropertyToken.cs
- EnvironmentPermission.cs
- TextDocumentView.cs
- XPathPatternBuilder.cs
- DataChangedEventManager.cs
- WindowsToolbarAsMenu.cs
- PresentationTraceSources.cs
- ObjectDataSourceWizardForm.cs
- TextSelectionHelper.cs
- SchemaHelper.cs
- SHA1Managed.cs
- HttpCachePolicy.cs
- DocumentPageView.cs
- AxParameterData.cs
- NotifyParentPropertyAttribute.cs
- DescendentsWalkerBase.cs
- FactoryRecord.cs
- lengthconverter.cs
- NavigationPropertyEmitter.cs
- EventHandlerList.cs
- XPathSelectionIterator.cs
- PreProcessInputEventArgs.cs
- arclist.cs
- DefaultValueMapping.cs
- TheQuery.cs
- TriggerBase.cs
- StringValueSerializer.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- MobileFormsAuthentication.cs
- PerformanceCounter.cs
- AliasedSlot.cs
- WriteTimeStream.cs
- DataSourceView.cs
- SqlDataSource.cs
- OpCodes.cs
- OutputWindow.cs
- ObjectKeyFrameCollection.cs
- GridSplitter.cs
- DbTransaction.cs
- ListBoxItem.cs
- FrameworkTemplate.cs
- TextEditorThreadLocalStore.cs
- WorkflowRuntimeService.cs
- ConcatQueryOperator.cs
- CheckBoxDesigner.cs
- StringSorter.cs
- PassportAuthenticationEventArgs.cs
- MessageQueueInstaller.cs
- GZipUtils.cs
- returneventsaver.cs
- BooleanFacetDescriptionElement.cs
- MultiPageTextView.cs
- RelationalExpressions.cs
- DataMisalignedException.cs
- EncoderNLS.cs
- BooleanFunctions.cs
- ColumnMap.cs
- KeyBinding.cs
- ComponentEditorForm.cs
- AuthenticationModulesSection.cs
- EdgeProfileValidation.cs
- SelectionWordBreaker.cs
- WebBrowserBase.cs
- FlowDecisionLabelFeature.cs
- RowSpanVector.cs
- SingleStorage.cs
- RandomDelayQueuedSendsAsyncResult.cs
- ADMembershipProvider.cs
- PKCS1MaskGenerationMethod.cs
- ToolStrip.cs
- SystemIPGlobalProperties.cs
- TransactionManager.cs
- TableDesigner.cs
- UdpSocketReceiveManager.cs
- EditorAttribute.cs
- __ConsoleStream.cs
- BamlResourceContent.cs
- FixedSOMFixedBlock.cs
- KeysConverter.cs