Expression.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Expressions » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Expressions » Expression.cs
#region License

/*
 * Copyright  2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using Spring.Expressions.Parser;
using Spring.Expressions.Parser.antlr;
using Spring.Expressions.Parser.antlr.collections;
using Spring.Core;
using Spring.Reflection.Dynamic;
using Spring.Util;
using StringUtilsSpring.Util.StringUtils;

namespace Spring.Expressions{
    /// <summary>
    /// Container object for the parsed expression.
    /// </summary>
    /// <remarks>
    /// <p>
    /// Preparing this object once and reusing it many times for expression
    /// evaluation can result in significant performance improvements, as 
    /// expression parsing and reflection lookups are only performed once. 
    /// </p>
    /// </remarks>
    /// <author>Aleksandar Seovic</author>
    [Serializable]
    public class Expression : BaseNode
    {
        /// <summary>
        /// Contains a list of reserved variable names.
        /// You must not use any variable names with the reserved prefix!
        /// </summary>
        public class ReservedVariableNames
        {
            /// <summary>
            /// Variable Names using this prefix are reserved for internal framework use
            /// </summary>
            public static readonly string RESERVEDPREFIX = "____spring_";

            /// <summary>
            /// variable name of the currently processed object factory, if any
            /// </summary>
            internal static readonly string CurrentObjectFactory = RESERVEDPREFIX + "CurrentObjectFactory";
        }

        private class ASTNodeCreator : Parser.antlr.ASTNodeCreator
        {
            private readonly SafeConstructor ctor;
            private readonly string name;

            public ASTNodeCreator(ConstructorInfo ctor)
            {
                this.ctor = new SafeConstructor(ctor);
                this.name = ctor.DeclaringType.FullName;
            }

            public override AST Create()
            {
                return (AST) ctor.Invoke(new object[0]);
            }

            public override string ASTNodeTypeName
            {
                get { return name; }
            }
        }

        private class SpringASTFactory : ASTFactory
        {
            private static readonly Type BASENODE_TYPE;
            private static readonly Hashtable Typename2Creator;

            static SpringASTFactory()
            {
                BASENODE_TYPE = typeof (SpringAST);

                Typename2Creator = new Hashtable();
                foreach (Type type in typeof(SpringASTFactory).Assembly.GetTypes())
                {
                    if (BASENODE_TYPE.IsAssignableFrom(type))
                    {
                        ConstructorInfo ctor = type.GetConstructor(new Type[0]);
                        if (ctor != null)
                        {
                            ASTNodeCreator creator = new ASTNodeCreator(ctor);
                            Typename2Creator[creator.ASTNodeTypeName] = creator;
                        }
                    }
                }
                Typename2Creator[BASENODE_TYPE.FullName] = SpringAST.Creator;
            }

            public SpringASTFactory() : base(BASENODE_TYPE)
            {
                base.defaultASTNodeTypeObject_ = BASENODE_TYPE;
                base.typename2creator_ = Typename2Creator;
            }
        }

        private class SpringExpressionParser : ExpressionParser
        {
            public SpringExpressionParser( TokenStream lexer )
                : base( lexer )
            {
                base.astFactory = new SpringASTFactory();
                base.initialize();
            }
        }

        static Expression()
        {
            // Ensure antlr is loaded (fixes GAC issues)!
            Assembly antlrAss = typeof( Parser.antlr.LLkParser ).Assembly;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Expression"/> class
        /// by parsing specified expression string.
        /// </summary>
        /// <param name="expression">Expression to parse.</param>
        public static IExpression Parse( string expression )
        {
            if (StringUtils.HasText( expression ))
            {
                ExpressionLexer lexer = new ExpressionLexer( new StringReader( expression ) );
                ExpressionParser parser = new SpringExpressionParser( lexer );

                try
                {
                    parser.expr();
                }
                catch (TokenStreamRecognitionException ex)
                {
                    throw new SyntaxErrorException( ex.recog.Message, ex.recog.getLine(), ex.recog.getColumn(), expression );
                }
                return (IExpression)parser.getAST();
            }
            else
            {
                return new Expression();
            }
        }

        /// <summary>
        /// Registers lambda expression under the specified <paramref name="functionName"/>.
        /// </summary>
        /// <param name="functionName">Function name to register expression as.</param>
        /// <param name="lambdaExpression">Lambda expression to register.</param>
        /// <param name="variables">Variables dictionary that the function will be registered in.</param>
        public static void RegisterFunction( string functionName, string lambdaExpression, IDictionary variables )
        {
            AssertUtils.ArgumentHasText( functionName, "functionName" );
            AssertUtils.ArgumentHasText( lambdaExpression, "lambdaExpression" );

            ExpressionLexer lexer = new ExpressionLexer( new StringReader( lambdaExpression ) );
            ExpressionParser parser = new SpringExpressionParser( lexer );

            try
            {
                parser.lambda();
            }
            catch (TokenStreamRecognitionException ex)
            {
                throw new SyntaxErrorException( ex.recog.Message, ex.recog.getLine(), ex.recog.getColumn(), lambdaExpression );
            }
            variables[functionName] = parser.getAST();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Expression"/> class
        /// by parsing specified primary expression string.
        /// </summary>
        /// <param name="expression">Primary expression to parse.</param>
        internal static IExpression ParsePrimary( string expression )
        {
            if (StringUtils.HasText( expression ))
            {
                ExpressionLexer lexer = new ExpressionLexer( new StringReader( expression ) );
                ExpressionParser parser = new SpringExpressionParser( lexer );

                try
                {
                    parser.primaryExpression();
                }
                catch (TokenStreamRecognitionException ex)
                {
                    throw new SyntaxErrorException( ex.recog.Message, ex.recog.getLine(), ex.recog.getColumn(), expression );
                }
                return (IExpression)parser.getAST();
            }
            else
            {
                return new Expression();
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Expression"/> class
        /// by parsing specified property expression string.
        /// </summary>
        /// <param name="expression">Property expression to parse.</param>
        internal static IExpression ParseProperty( string expression )
        {
            if (StringUtils.HasText( expression ))
            {
                ExpressionLexer lexer = new ExpressionLexer( new StringReader( expression ) );
                ExpressionParser parser = new SpringExpressionParser( lexer );

                try
                {
                    parser.property();
                }
                catch (TokenStreamRecognitionException ex)
                {
                    throw new SyntaxErrorException( ex.recog.Message, ex.recog.getLine(), ex.recog.getColumn(), expression );
                }
                return (IExpression)parser.getAST();
            }
            else
            {
                return new Expression();
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Expression"/> class.
        /// </summary>
        public Expression()
        { }

        /// <summary>
        /// Create a new instance from SerializationInfo
        /// </summary>
        protected Expression( SerializationInfo info, StreamingContext context )
            : base( info, context )
        { }

        /// <summary>
        /// Evaluates this expression for the specified root object and returns 
        /// value of the last node.
        /// </summary>
        /// <param name="context">Context to evaluate expressions against.</param>
        /// <param name="evalContext">Current expression evaluation context.</param>
        /// <returns>Value of the last node.</returns>
        protected override object Get(object context, EvaluationContext evalContext)
        {
            object result = context;

            if (this.getNumberOfChildren() > 0)
            {
                AST node = this.getFirstChild();
                while (node != null)
                {
                    result = GetValue(((BaseNode)node), result, evalContext );

                    node = node.getNextSibling();
                }
            }

            return result;
        }

        /// <summary>
        /// Evaluates this expression for the specified root object and sets 
        /// value of the last node.
        /// </summary>
        /// <param name="context">Context to evaluate expressions against.</param>
        /// <param name="evalContext">Current expression evaluation context.</param>
        /// <param name="newValue">Value to set last node to.</param>
        /// <exception cref="NotSupportedException">If navigation expression is empty.</exception>
        protected override void Set( object context, EvaluationContext evalContext, object newValue )
        {
            object target = context;

            if (this.getNumberOfChildren() > 0)
            {
                AST node = this.getFirstChild();

                for (int i = 0; i < this.getNumberOfChildren() - 1; i++)
                {
                    try
                    {
                        target = GetValue(((BaseNode)node), target, evalContext);
                        node = node.getNextSibling();
                    }
                    catch (NotReadablePropertyException e)
                    {
                        throw new NotWritablePropertyException( "Cannot read the value of '" + node.getText() + "' property in the expression.", e );
                    }
                }
                SetValue(((BaseNode)node), target, evalContext, newValue);
            }
            else
            {
                throw new NotSupportedException( "You cannot set the value for an empty expression." );
            }
        }

        /// <summary>
        /// Evaluates this expression for the specified root object and returns 
        /// <see cref="PropertyInfo"/> of the last node, if possible.
        /// </summary>
        /// <param name="context">Context to evaluate expression against.</param>
        /// <param name="variables">Expression variables map.</param>
        /// <returns>Value of the last node.</returns>
        internal PropertyInfo GetPropertyInfo( object context, IDictionary variables )
        {
            if (this.getNumberOfChildren() > 0)
            {
                object target = context;
                AST node = this.getFirstChild();

                for (int i = 0; i < this.getNumberOfChildren() - 1; i++)
                {
                    target = ((IExpression)node).GetValue( target, variables );
                    node = node.getNextSibling();
                }

                if (node is PropertyOrFieldNode)
                {
                    return (PropertyInfo)((PropertyOrFieldNode)node).GetMemberInfo( target );
                }
                else if (node is IndexerNode)
                {
                    return ((IndexerNode)node).GetPropertyInfo( target, variables );
                }
                else
                {
                    throw new FatalReflectionException( "Cannot obtain PropertyInfo from an expression that does not resolve to a property or an indexer." );
                }
            }

            throw new FatalReflectionException( "Cannot obtain PropertyInfo for empty property name." );
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.