UriWriter.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 / DataWeb / Client / System / Data / Services / Client / ALinq / UriWriter.cs / 1305376 / UriWriter.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Translates resource bound expression trees into URIs.
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client
{
    #region Namespaces. 

    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
 
    #endregion Namespaces.
 
    ///  
    /// Translates resource bound expression trees into URIs.
    ///  
    internal class UriWriter : DataServiceALinqExpressionVisitor
    {
        /// Data context used to generate type names for types.
        private readonly DataServiceContext context; 

        /// stringbuilder for constructed URI 
        private readonly StringBuilder uriBuilder; 

        /// the data service version for the uri 
        private Version uriVersion;

        /// the leaf resourceset for the URI being written
        private ResourceSetExpression leafResourceSet; 

        ///  
        /// Private constructor for creating UriWriter 
        /// 
        /// Data context used to generate type names for types. 
        private UriWriter(DataServiceContext context)
        {
            Debug.Assert(context != null, "context != null");
            this.context = context; 
            this.uriBuilder = new StringBuilder();
            this.uriVersion = Util.DataServiceVersion1; 
        } 

        ///  
        /// Translates resource bound expression tree to a URI.
        /// 
        /// Data context used to generate type names for types.
        /// flag to indicate whether generated URI should include () if leaf is ResourceSet 
        /// The expression to translate
        /// uri 
        /// version for query 
        internal static void Translate(DataServiceContext context, bool addTrailingParens, Expression e, out Uri uri, out Version version)
        { 
            var writer = new UriWriter(context);
            writer.leafResourceSet = addTrailingParens ? (e as ResourceSetExpression) : null;
            writer.Visit(e);
            uri = Util.CreateUri(context.BaseUriWithSlash, Util.CreateUri(writer.uriBuilder.ToString(), UriKind.Relative)); 
            version = writer.uriVersion;
        } 
 
        /// 
        /// MethodCallExpression visit method 
        /// 
        /// The MethodCallExpression expression to visit
        /// The visited MethodCallExpression expression 
        internal override Expression VisitMethodCall(MethodCallExpression m) 
        {
            throw Error.MethodNotSupported(m); 
        } 

        ///  
        /// UnaryExpression visit method
        /// 
        /// The UnaryExpression expression to visit
        /// The visited UnaryExpression expression  
        internal override Expression VisitUnary(UnaryExpression u)
        { 
            throw new NotSupportedException(Strings.ALinq_UnaryNotSupported(u.NodeType.ToString())); 
        }
 
        /// 
        /// BinaryExpression visit method
        /// 
        /// The BinaryExpression expression to visit 
        /// The visited BinaryExpression expression 
        internal override Expression VisitBinary(BinaryExpression b) 
        { 
            throw new NotSupportedException(Strings.ALinq_BinaryNotSupported(b.NodeType.ToString()));
        } 

        /// 
        /// ConstantExpression visit method
        ///  
        /// The ConstantExpression expression to visit
        /// The visited ConstantExpression expression  
        internal override Expression VisitConstant(ConstantExpression c) 
        {
            throw new NotSupportedException(Strings.ALinq_ConstantNotSupported(c.Value)); 
        }

        /// 
        /// TypeBinaryExpression visit method 
        /// 
        /// The TypeBinaryExpression expression to visit 
        /// The visited TypeBinaryExpression expression  
        internal override Expression VisitTypeIs(TypeBinaryExpression b)
        { 
            throw new NotSupportedException(Strings.ALinq_TypeBinaryNotSupported);
        }

        ///  
        /// ConditionalExpression visit method
        ///  
        /// The ConditionalExpression expression to visit 
        /// The visited ConditionalExpression expression 
        internal override Expression VisitConditional(ConditionalExpression c) 
        {
            throw new NotSupportedException(Strings.ALinq_ConditionalNotSupported);
        }
 
        /// 
        /// ParameterExpression visit method 
        ///  
        /// The ParameterExpression expression to visit
        /// The visited ParameterExpression expression  
        internal override Expression VisitParameter(ParameterExpression p)
        {
            throw new NotSupportedException(Strings.ALinq_ParameterNotSupported);
        } 

        ///  
        /// MemberExpression visit method 
        /// 
        /// The MemberExpression expression to visit 
        /// The visited MemberExpression expression 
        internal override Expression VisitMemberAccess(MemberExpression m)
        {
            throw new NotSupportedException(Strings.ALinq_MemberAccessNotSupported(m.Member.Name)); 
        }
 
        ///  
        /// LambdaExpression visit method
        ///  
        /// The LambdaExpression to visit
        /// The visited LambdaExpression
        internal override Expression VisitLambda(LambdaExpression lambda)
        { 
            throw new NotSupportedException(Strings.ALinq_LambdaNotSupported);
        } 
 
        /// 
        /// NewExpression visit method 
        /// 
        /// The NewExpression to visit
        /// The visited NewExpression
        internal override NewExpression VisitNew(NewExpression nex) 
        {
            throw new NotSupportedException(Strings.ALinq_NewNotSupported); 
        } 

        ///  
        /// MemberInitExpression visit method
        /// 
        /// The MemberInitExpression to visit
        /// The visited MemberInitExpression 
        internal override Expression VisitMemberInit(MemberInitExpression init)
        { 
            throw new NotSupportedException(Strings.ALinq_MemberInitNotSupported); 
        }
 
        /// 
        /// ListInitExpression visit method
        /// 
        /// The ListInitExpression to visit 
        /// The visited ListInitExpression
        internal override Expression VisitListInit(ListInitExpression init) 
        { 
            throw new NotSupportedException(Strings.ALinq_ListInitNotSupported);
        } 

        /// 
        /// NewArrayExpression visit method
        ///  
        /// The NewArrayExpression to visit
        /// The visited NewArrayExpression 
        internal override Expression VisitNewArray(NewArrayExpression na) 
        {
            throw new NotSupportedException(Strings.ALinq_NewArrayNotSupported); 
        }

        /// 
        /// InvocationExpression visit method 
        /// 
        /// The InvocationExpression to visit 
        /// The visited InvocationExpression 
        internal override Expression VisitInvocation(InvocationExpression iv)
        { 
            throw new NotSupportedException(Strings.ALinq_InvocationNotSupported);
        }

        ///  
        /// NavigationPropertySingletonExpression visit method.
        ///  
        /// NavigationPropertySingletonExpression expression to visit 
        /// Visited NavigationPropertySingletonExpression expression
        internal override Expression VisitNavigationPropertySingletonExpression(NavigationPropertySingletonExpression npse) 
        {
            this.Visit(npse.Source);
            this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(this.ExpressionToString(npse.MemberExpression));
            this.VisitQueryOptions(npse); 
            return npse;
        } 
 
        /// 
        /// ResourceSetExpression visit method. 
        /// 
        /// ResourceSetExpression expression to visit
        /// Visited ResourceSetExpression expression
        internal override Expression VisitResourceSetExpression(ResourceSetExpression rse) 
        {
            if ((ResourceExpressionType)rse.NodeType == ResourceExpressionType.ResourceNavigationProperty) 
            { 
                this.Visit(rse.Source);
                this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(this.ExpressionToString(rse.MemberExpression)); 
            }
            else
            {
                this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append((string)((ConstantExpression)rse.MemberExpression).Value); 
            }
 
            if (rse.KeyPredicate != null) 
            {
                this.uriBuilder.Append(UriHelper.LEFTPAREN); 
                if (rse.KeyPredicate.Count == 1)
                {
                    this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First()));
                } 
                else
                { 
                    bool addComma = false; 
                    foreach (var kvp in rse.KeyPredicate)
                    { 
                        if (addComma)
                        {
                            this.uriBuilder.Append(UriHelper.COMMA);
                        } 

                        this.uriBuilder.Append(kvp.Key.Name); 
                        this.uriBuilder.Append(UriHelper.EQUALSSIGN); 
                        this.uriBuilder.Append(this.ExpressionToString(kvp.Value));
                        addComma = true; 
                    }
                }

                this.uriBuilder.Append(UriHelper.RIGHTPAREN); 
            }
            else if (rse == this.leafResourceSet) 
            { 
                // if resourceset is on the leaf, append ()
                this.uriBuilder.Append(UriHelper.LEFTPAREN); 
                this.uriBuilder.Append(UriHelper.RIGHTPAREN);
            }

            if (rse.CountOption == CountOption.ValueOnly) 
            {
                // append $count segment: /$count 
                this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT); 
                this.EnsureMinimumVersion(2, 0);
            } 

            this.VisitQueryOptions(rse);
            return rse;
        } 

        ///  
        /// Visit Query options for Resource 
        /// 
        /// Resource Expression with query options 
        internal void VisitQueryOptions(ResourceExpression re)
        {
            bool needAmpersand = false;
 
            if (re.HasQueryOptions)
            { 
                this.uriBuilder.Append(UriHelper.QUESTIONMARK); 

                ResourceSetExpression rse = re as ResourceSetExpression; 
                if (rse != null)
                {
                    IEnumerator options = rse.SequenceQueryOptions.GetEnumerator();
                    while (options.MoveNext()) 
                    {
                        if (needAmpersand) 
                        { 
                            this.uriBuilder.Append(UriHelper.AMPERSAND);
                        } 

                        Expression e = ((Expression)options.Current);
                        ResourceExpressionType et = (ResourceExpressionType)e.NodeType;
                        switch (et) 
                        {
                            case ResourceExpressionType.SkipQueryOption: 
                                this.VisitQueryOptionExpression((SkipQueryOptionExpression)e); 
                                break;
                            case ResourceExpressionType.TakeQueryOption: 
                                this.VisitQueryOptionExpression((TakeQueryOptionExpression)e);
                                break;
                            case ResourceExpressionType.OrderByQueryOption:
                                this.VisitQueryOptionExpression((OrderByQueryOptionExpression)e); 
                                break;
                            case ResourceExpressionType.FilterQueryOption: 
                                this.VisitQueryOptionExpression((FilterQueryOptionExpression)e); 
                                break;
                            default: 
                                Debug.Assert(false, "Unexpected expression type " + (int)et);
                                break;
                        }
 
                        needAmpersand = true;
                    } 
                } 

                if (re.ExpandPaths.Count > 0) 
                {
                    if (needAmpersand)
                    {
                        this.uriBuilder.Append(UriHelper.AMPERSAND); 
                    }
 
                    this.VisitExpandOptions(re.ExpandPaths); 
                    needAmpersand = true;
                } 

                if (re.Projection != null && re.Projection.Paths.Count > 0)
                {
                    if (needAmpersand) 
                    {
                        this.uriBuilder.Append(UriHelper.AMPERSAND); 
                    } 

                    this.VisitProjectionPaths(re.Projection.Paths); 
                    needAmpersand = true;
                }

                if (re.CountOption == CountOption.InlineAll) 
                {
                    if (needAmpersand) 
                    { 
                        this.uriBuilder.Append(UriHelper.AMPERSAND);
                    } 

                    this.VisitCountOptions();
                    needAmpersand = true;
                } 

                if (re.CustomQueryOptions.Count > 0) 
                { 
                    if (needAmpersand)
                    { 
                        this.uriBuilder.Append(UriHelper.AMPERSAND);
                    }

                    this.VisitCustomQueryOptions(re.CustomQueryOptions); 
                    needAmpersand = true;
                } 
            } 
        }
 
        /// 
        /// SkipQueryOptionExpression visit method.
        /// 
        /// SkipQueryOptionExpression expression to visit 
        internal void VisitQueryOptionExpression(SkipQueryOptionExpression sqoe)
        { 
            this.uriBuilder.Append(UriHelper.DOLLARSIGN); 
            this.uriBuilder.Append(UriHelper.OPTIONSKIP);
            this.uriBuilder.Append(UriHelper.EQUALSSIGN); 
            this.uriBuilder.Append(this.ExpressionToString(sqoe.SkipAmount));
        }

        ///  
        /// TakeQueryOptionExpression visit method.
        ///  
        /// TakeQueryOptionExpression expression to visit 
        internal void VisitQueryOptionExpression(TakeQueryOptionExpression tqoe)
        { 
            this.uriBuilder.Append(UriHelper.DOLLARSIGN);
            this.uriBuilder.Append(UriHelper.OPTIONTOP);
            this.uriBuilder.Append(UriHelper.EQUALSSIGN);
            this.uriBuilder.Append(this.ExpressionToString(tqoe.TakeAmount)); 
        }
 
        ///  
        /// FilterQueryOptionExpression visit method.
        ///  
        /// FilterQueryOptionExpression expression to visit
        internal void VisitQueryOptionExpression(FilterQueryOptionExpression fqoe)
        {
            this.uriBuilder.Append(UriHelper.DOLLARSIGN); 
            this.uriBuilder.Append(UriHelper.OPTIONFILTER);
            this.uriBuilder.Append(UriHelper.EQUALSSIGN); 
            this.uriBuilder.Append(this.ExpressionToString(fqoe.Predicate)); 
        }
 
        /// 
        /// OrderByQueryOptionExpression visit method.
        /// 
        /// OrderByQueryOptionExpression expression to visit 
        internal void VisitQueryOptionExpression(OrderByQueryOptionExpression oboe)
        { 
            this.uriBuilder.Append(UriHelper.DOLLARSIGN); 
            this.uriBuilder.Append(UriHelper.OPTIONORDERBY);
            this.uriBuilder.Append(UriHelper.EQUALSSIGN); 

            int ii = 0;
            while (true)
            { 
                var selector = oboe.Selectors[ii];
 
                this.uriBuilder.Append(this.ExpressionToString(selector.Expression)); 
                if (selector.Descending)
                { 
                    this.uriBuilder.Append(UriHelper.SPACE);
                    this.uriBuilder.Append(UriHelper.OPTIONDESC);
                }
 
                if (++ii == oboe.Selectors.Count)
                { 
                    break; 
                }
 
                this.uriBuilder.Append(UriHelper.COMMA);
            }
        }
 
        /// 
        /// VisitExpandOptions visit method. 
        ///  
        /// Expand Paths
        internal void VisitExpandOptions(List paths) 
        {
            this.uriBuilder.Append(UriHelper.DOLLARSIGN);
            this.uriBuilder.Append(UriHelper.OPTIONEXPAND);
            this.uriBuilder.Append(UriHelper.EQUALSSIGN); 

            int ii = 0; 
            while (true) 
            {
                this.uriBuilder.Append(paths[ii]); 

                if (++ii == paths.Count)
                {
                    break; 
                }
 
                this.uriBuilder.Append(UriHelper.COMMA); 
            }
        } 

        /// 
        /// ProjectionPaths visit method.
        ///  
        /// Projection Paths
        internal void VisitProjectionPaths(List paths) 
        { 
            this.uriBuilder.Append(UriHelper.DOLLARSIGN);
            this.uriBuilder.Append(UriHelper.OPTIONSELECT); 
            this.uriBuilder.Append(UriHelper.EQUALSSIGN);

            int ii = 0;
            while (true) 
            {
                string path = paths[ii]; 
 
                this.uriBuilder.Append(path);
 
                if (++ii == paths.Count)
                {
                    break;
                } 

                this.uriBuilder.Append(UriHelper.COMMA); 
            } 

            this.EnsureMinimumVersion(2, 0); 
        }

        /// 
        /// VisitCountOptions visit method. 
        /// 
        internal void VisitCountOptions() 
        { 
            this.uriBuilder.Append(UriHelper.DOLLARSIGN);
            this.uriBuilder.Append(UriHelper.OPTIONCOUNT); 
            this.uriBuilder.Append(UriHelper.EQUALSSIGN);
            this.uriBuilder.Append(UriHelper.COUNTALL);
            this.EnsureMinimumVersion(2, 0);
        } 

        ///  
        /// VisitCustomQueryOptions visit method. 
        /// 
        /// Custom query options 
        internal void VisitCustomQueryOptions(Dictionary options)
        {
            List keys = options.Keys.ToList();
            List values = options.Values.ToList(); 

            int ii = 0; 
            while (true) 
            {
                this.uriBuilder.Append(keys[ii].Value); 
                this.uriBuilder.Append(UriHelper.EQUALSSIGN);
                this.uriBuilder.Append(values[ii].Value);

                if (keys[ii].Value.ToString().Equals(UriHelper.DOLLARSIGN + UriHelper.OPTIONCOUNT, StringComparison.OrdinalIgnoreCase)) 
                {
                    this.EnsureMinimumVersion(2, 0); 
                } 

                if (++ii == keys.Count) 
                {
                    break;
                }
 
                this.uriBuilder.Append(UriHelper.AMPERSAND);
            } 
        } 

        /// Serializes an expression to a string. 
        /// Expression to serialize
        /// The serialized expression.
        private string ExpressionToString(Expression expression)
        { 
            return ExpressionWriter.ExpressionToString(this.context, expression);
        } 
 
        /// 
        /// Ensure that the translated uri has the required minimum version associated with it 
        /// 
        /// The major number for the version. 
        /// The minor number for the version. 
        private void EnsureMinimumVersion(int major, int minor) 
        {
            if (major > this.uriVersion.Major || 
                (major == this.uriVersion.Major && minor > this.uriVersion.Minor)) 
            {
                this.uriVersion = new Version(major, minor); 
            }
        }
    }
} 

// 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