diff --git a/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs b/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs deleted file mode 100644 index e33bcaed..00000000 --- a/src/Spring/Spring.Core/Expressions/DateLiteralNode.cs +++ /dev/null @@ -1,84 +0,0 @@ -#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.Globalization; -using System.Runtime.Serialization; -using Spring.Expressions.Parser.antlr.collections; - -namespace Spring.Expressions -{ - /// - /// Represents parsed node in the navigation expression. - /// - /// Aleksandar Seovic - [Serializable] - public class DateLiteralNode : BaseNode - { - private object nodeValue; - - /// - /// Create a new instance - /// - public DateLiteralNode():base() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected DateLiteralNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - if (nodeValue == null) - { - lock (this) - { - if (nodeValue == null) - { - AST dateString = this.getFirstChild(); - if (getNumberOfChildren() == 2) - { - AST dateFormat = dateString.getNextSibling(); - nodeValue = - DateTime.ParseExact(dateString.getText(), dateFormat.getText(), - CultureInfo.InvariantCulture); - } - else - { - nodeValue = DateTime.Parse(dateString.getText()); - } - } - } - } - return nodeValue; - } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Expression.g b/src/Spring/Spring.Core/Expressions/Expression.g index cfc0a2c6..31393286 100644 --- a/src/Spring/Spring.Core/Expressions/Expression.g +++ b/src/Spring/Spring.Core/Expressions/Expression.g @@ -154,7 +154,7 @@ node : | firstSelection | lastSelection | exprList - | DOT! + | DOT! )+ ; @@ -173,15 +173,17 @@ localFunctionOrVar | localVar ; -localFunction : DOLLAR! ID^ methodArgs +localFunction + : DOLLAR! ID^ methodArgs ; -localVar : DOLLAR! ID^ ; +localVar + : DOLLAR! ID^ + ; methodOrProperty - : (ID LPAREN)=> - ID^ methodArgs - | property + : (ID LPAREN)=> ID^ methodArgs + | property ; methodArgs @@ -301,7 +303,6 @@ literal | REAL_LITERAL | STRING_LITERAL | boolLiteral - | dateLiteral ; boolLiteral @@ -309,11 +310,6 @@ boolLiteral | FALSE ; -dateLiteral - : "date"^ - LPAREN! STRING_LITERAL (COMMA! STRING_LITERAL)? RPAREN! - ; - relationalOperator : EQUAL | NOT_EQUAL @@ -329,6 +325,7 @@ relationalOperator ; + class ExpressionLexer extends Lexer; options { diff --git a/src/Spring/Spring.Core/Expressions/MethodNode.cs b/src/Spring/Spring.Core/Expressions/MethodNode.cs index 98078214..f308ed42 100644 --- a/src/Spring/Spring.Core/Expressions/MethodNode.cs +++ b/src/Spring/Spring.Core/Expressions/MethodNode.cs @@ -1,5 +1,5 @@ -#region License - +#region License + /* * Copyright © 2002-2005 the original author or authors. * @@ -14,258 +14,260 @@ * 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.Reflection; -using System.Runtime.Serialization; -using Spring.Expressions.Processors; -using Spring.Util; -using Spring.Reflection.Dynamic; - -namespace Spring.Expressions -{ - /// - /// Represents parsed method node in the navigation expression. - /// - /// Aleksandar Seovic - [Serializable] - public class MethodNode : NodeWithArguments - { - private const BindingFlags BINDING_FLAGS - = BindingFlags.Public | BindingFlags.NonPublic - | BindingFlags.Instance | BindingFlags.Static - | BindingFlags.IgnoreCase; - - private static readonly IDictionary collectionProcessorMap = new Hashtable(); - - private bool initialized = false; - private bool isParamArray = false; - private Type paramArrayType; - private int argumentCount; - private SafeMethod method; - private int methodHash; - private bool isCollectionProcessor = false; - private ICollectionProcessor collectionProcessor; - - /// - /// Static constructor. Initializes a map of special collection processor methods. - /// - static MethodNode() - { - collectionProcessorMap.Add("count", new CountAggregator()); - collectionProcessorMap.Add("sum", new SumAggregator()); - collectionProcessorMap.Add("max", new MaxAggregator()); - collectionProcessorMap.Add("min", new MinAggregator()); - collectionProcessorMap.Add("average", new AverageAggregator()); - collectionProcessorMap.Add("sort", new SortProcessor()); - collectionProcessorMap.Add("orderBy", new OrderByProcessor()); - collectionProcessorMap.Add("distinct", new DistinctProcessor()); - collectionProcessorMap.Add("nonNull", new NonNullProcessor()); - collectionProcessorMap.Add("convert", new ConversionProcessor()); - collectionProcessorMap.Add("reverse", new ReverseProcessor()); - } - - /// - /// Create a new instance - /// - public MethodNode() - { - } - - /// - /// Create a new instance from SerializationInfo - /// - protected MethodNode(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - /// - /// Returns node's value for the given context. - /// - /// Context to evaluate expressions against. - /// Current expression evaluation context. - /// Node's value. - protected override object Get(object context, EvaluationContext evalContext) - { - object[] argValues = ResolveArguments(evalContext); - - ICollectionProcessor localCollectionProcessor = null; - SafeMethod localMethod = null; - - // resolve method, if necessary - lock (this) - { - if (!isCollectionProcessor) - { - if ((context == null || context is ICollection)) - { - string methodName = this.getText(); - - // predefined collection processor? - collectionProcessor = (ICollectionProcessor)collectionProcessorMap[methodName]; - isCollectionProcessor = (collectionProcessor != null); - localCollectionProcessor = collectionProcessor; - - if (!isCollectionProcessor && evalContext.Variables != null) - { - localCollectionProcessor = evalContext.Variables[methodName] as ICollectionProcessor; - } - } - } - else - { - localCollectionProcessor = collectionProcessor; - } - - if (localCollectionProcessor == null) - { - if (context == null) - { - throw new ArgumentNullException("Context for method invocation cannot be null."); - } - - // calculate checksum, if the cached method matches the current context - if (initialized) - { - int calculatedHash = CalculateMethodHash(context.GetType(), argValues); - initialized = (calculatedHash == methodHash); - } - - if (!initialized) - { - string methodName = this.getText(); - Initialize(methodName, argValues, context); - initialized = true; - } - - localMethod = method; - } - } - - // invoke method - if (localCollectionProcessor != null) - { - return localCollectionProcessor.Process((ICollection)context, argValues); - } - else - { - object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues); - return localMethod.Invoke(context, paramValues); - } - } - - private int CalculateMethodHash(Type contextType, object[] argValues) - { - int hash = contextType.GetHashCode(); - for (int i = 0; i < argValues.Length; i++) - { - object arg = argValues[i]; - if (arg != null) hash += s_primes[i] * arg.GetType().GetHashCode(); - } - return hash; - } - - private void Initialize(string methodName, object[] argValues, object context) - { - Type contextType = (context is Type ? context as Type : context.GetType()); - - // check the context type first - MethodInfo mi = GetBestMethod(contextType, methodName, BINDING_FLAGS, argValues); - - // if not found, probe the Type's type - if (mi == null) - { - mi = GetBestMethod(typeof(Type), methodName, BINDING_FLAGS, argValues); - } - - if (mi == null) - { - throw new ArgumentException( - string.Format("Method '{0}' with the specified number and types of arguments does not exist.", - methodName)); - } - else - { - ParameterInfo[] parameters = mi.GetParameters(); - if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; - if (isParamArray) - { - paramArrayType = lastParameter.ParameterType.GetElementType(); - argumentCount = parameters.Length; - } - } - - method = new SafeMethod(mi); - methodHash = CalculateMethodHash(contextType, argValues); - } - } - - /// - /// Gets the best method given the name, argument values, for a given type. - /// - /// The type on which to search for the method. - /// Name of the method. - /// The binding flags. - /// The arg values. - /// Best matching method or null if none found. - public static MethodInfo GetBestMethod(Type type, string methodName, BindingFlags bindingFlags, object[] argValues) - { - MethodInfo mi = null; - try - { - mi = type.GetMethod(methodName, bindingFlags | BindingFlags.FlattenHierarchy); - } - catch (AmbiguousMatchException) - { - - MethodInfo[] overloads = GetCandidateMethods(type, methodName, bindingFlags, argValues.Length); - if (overloads.Length > 0) - { - mi = ReflectionUtils.GetMethodByArgumentValues(overloads, argValues); - } - } - return mi; - } - - - - private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount) - { - MethodInfo[] methods = type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy); - ArrayList matches = new ArrayList(); - - foreach (MethodInfo method in methods) - { - if (method.Name == methodName) - { - ParameterInfo[] parameters = method.GetParameters(); - if (parameters.Length == argCount) - { - matches.Add(method); - } - else if (parameters.Length > 0) - { - ParameterInfo lastParameter = parameters[parameters.Length - 1]; - if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) - { - matches.Add(method); - } - } - } - } - - return (MethodInfo[])matches.ToArray(typeof(MethodInfo)); - } - - // used to calculate signature hash while caring for arg positions + */ + +#endregion + +using System; +using System.Collections; +using System.Reflection; +using System.Runtime.Serialization; +using Spring.Expressions.Processors; +using Spring.Util; +using Spring.Reflection.Dynamic; + +namespace Spring.Expressions +{ + /// + /// Represents parsed method node in the navigation expression. + /// + /// Aleksandar Seovic + [Serializable] + public class MethodNode : NodeWithArguments + { + private const BindingFlags BINDING_FLAGS + = BindingFlags.Public | BindingFlags.NonPublic + | BindingFlags.Instance | BindingFlags.Static + | BindingFlags.IgnoreCase; + + private static readonly IDictionary collectionProcessorMap = new Hashtable(); + private static readonly IDictionary extensionMethodProcessorMap = new Hashtable(); + + private bool initialized = false; + private bool cachedIsParamArray = false; + private Type paramArrayType; + private int argumentCount; + private SafeMethod cachedInstanceMethod; + private int cachedInstanceMethodHash; + + /// + /// Static constructor. Initializes a map of special collection processor methods. + /// + static MethodNode() + { + collectionProcessorMap.Add("count", new CountAggregator()); + collectionProcessorMap.Add("sum", new SumAggregator()); + collectionProcessorMap.Add("max", new MaxAggregator()); + collectionProcessorMap.Add("min", new MinAggregator()); + collectionProcessorMap.Add("average", new AverageAggregator()); + collectionProcessorMap.Add("sort", new SortProcessor()); + collectionProcessorMap.Add("orderBy", new OrderByProcessor()); + collectionProcessorMap.Add("distinct", new DistinctProcessor()); + collectionProcessorMap.Add("nonNull", new NonNullProcessor()); + collectionProcessorMap.Add("reverse", new ReverseProcessor()); + collectionProcessorMap.Add("convert", new ConversionProcessor()); + + extensionMethodProcessorMap.Add("date", new DateConversionProcessor()); + } + + /// + /// Create a new instance + /// + public MethodNode() + { + } + + /// + /// Create a new instance from SerializationInfo + /// + protected MethodNode(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Returns node's value for the given context. + /// + /// Context to evaluate expressions against. + /// Current expression evaluation context. + /// Node's value. + protected override object Get(object context, EvaluationContext evalContext) + { + string methodName = this.getText(); + object[] argValues = ResolveArguments(evalContext); + + // resolve method, if necessary + lock (this) + { + // check if it is a collection and the methodname denotes a collection processor + if ((context == null || context is ICollection)) + { + ICollectionProcessor localCollectionProcessor; + // predefined collection processor? + localCollectionProcessor = (ICollectionProcessor) collectionProcessorMap[methodName]; + + // user-defined collection processor? + if (localCollectionProcessor == null && evalContext.Variables != null) + { + localCollectionProcessor = evalContext.Variables[methodName] as ICollectionProcessor; + } + + if (localCollectionProcessor != null) + { + return localCollectionProcessor.Process((ICollection) context, argValues); + } + } + + // try extension methods + IMethodCallProcessor methodCallProcessor = (IMethodCallProcessor)extensionMethodProcessorMap[methodName]; + { + // user-defined extension method processor? + if (methodCallProcessor == null && evalContext.Variables != null) + { + methodCallProcessor = evalContext.Variables[methodName] as IMethodCallProcessor; + } + + if (methodCallProcessor != null) + { + return methodCallProcessor.Process(context, argValues); + } + } + + // try instance method + if (context != null) + { + // calculate checksum, if the cached method matches the current context + if (initialized) + { + int calculatedHash = CalculateMethodHash(context.GetType(), argValues); + initialized = (calculatedHash == cachedInstanceMethodHash); + } + + if (!initialized) + { + Initialize(methodName, argValues, context); + initialized = true; + } + + if (cachedInstanceMethod != null) + { + object[] paramValues = (cachedIsParamArray) + ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) + : argValues; + return cachedInstanceMethod.Invoke(context, paramValues); + } + } + } + + throw new ArgumentException(string.Format("Method '{0}' with the specified number and types of arguments does not exist.", methodName)); + } + + private int CalculateMethodHash(Type contextType, object[] argValues) + { + int hash = contextType.GetHashCode(); + for (int i = 0; i < argValues.Length; i++) + { + object arg = argValues[i]; + if (arg != null) + hash += s_primes[i] * arg.GetType().GetHashCode(); + } + return hash; + } + + private void Initialize(string methodName, object[] argValues, object context) + { + Type contextType = (context is Type ? context as Type : context.GetType()); + + // check the context type first + MethodInfo mi = GetBestMethod(contextType, methodName, BINDING_FLAGS, argValues); + + // if not found, probe the Type's type + if (mi == null) + { + mi = GetBestMethod(typeof(Type), methodName, BINDING_FLAGS, argValues); + } + + if (mi == null) + { + return; + } + else + { + ParameterInfo[] parameters = mi.GetParameters(); + if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + cachedIsParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0; + if (cachedIsParamArray) + { + paramArrayType = lastParameter.ParameterType.GetElementType(); + argumentCount = parameters.Length; + } + } + + cachedInstanceMethod = new SafeMethod(mi); + cachedInstanceMethodHash = CalculateMethodHash(contextType, argValues); + } + } + + /// + /// Gets the best method given the name, argument values, for a given type. + /// + /// The type on which to search for the method. + /// Name of the method. + /// The binding flags. + /// The arg values. + /// Best matching method or null if none found. + public static MethodInfo GetBestMethod(Type type, string methodName, BindingFlags bindingFlags, object[] argValues) + { + MethodInfo mi = null; + try + { + mi = type.GetMethod(methodName, bindingFlags | BindingFlags.FlattenHierarchy); + } + catch (AmbiguousMatchException) + { + + MethodInfo[] overloads = GetCandidateMethods(type, methodName, bindingFlags, argValues.Length); + if (overloads.Length > 0) + { + mi = ReflectionUtils.GetMethodByArgumentValues(overloads, argValues); + } + } + return mi; + } + + + + private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount) + { + MethodInfo[] methods = type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy); + ArrayList matches = new ArrayList(); + + foreach (MethodInfo method in methods) + { + if (method.Name == methodName) + { + ParameterInfo[] parameters = method.GetParameters(); + if (parameters.Length == argCount) + { + matches.Add(method); + } + else if (parameters.Length > 0) + { + ParameterInfo lastParameter = parameters[parameters.Length - 1]; + if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) + { + matches.Add(method); + } + } + } + } + + return (MethodInfo[])matches.ToArray(typeof(MethodInfo)); + } + + // used to calculate signature hash while caring for arg positions private static readonly int[] s_primes = { 17, 19, 23, 29 @@ -281,6 +283,6 @@ namespace Spring.Expressions , 547, 557, 563, 569, 571, 577, 587, 593, 599, 601 , 607, 613, 617, 619, 631, 641, 643, 647, 653, 659 , 661, 673, 677, 683, 691, 701, 709, 719, 727, 733 - }; - } -} + }; + } +} diff --git a/src/Spring/Spring.Core/Expressions/Parser/ExpressionLexer.cs b/src/Spring/Spring.Core/Expressions/Parser/ExpressionLexer.cs index bb39482d..c488b998 100644 --- a/src/Spring/Spring.Core/Expressions/Parser/ExpressionLexer.cs +++ b/src/Spring/Spring.Core/Expressions/Parser/ExpressionLexer.cs @@ -84,25 +84,24 @@ namespace Spring.Expressions.Parser public const int INTEGER_LITERAL = 51; public const int HEXADECIMAL_INTEGER_LITERAL = 52; public const int REAL_LITERAL = 53; - public const int LITERAL_date = 54; - public const int EQUAL = 55; - public const int NOT_EQUAL = 56; - public const int LESS_THAN = 57; - public const int LESS_THAN_OR_EQUAL = 58; - public const int GREATER_THAN = 59; - public const int GREATER_THAN_OR_EQUAL = 60; - public const int WS = 61; - public const int BACKTICK = 62; - public const int BACKSLASH = 63; - public const int DOT_ESCAPED = 64; - public const int APOS = 65; - public const int NUMERIC_LITERAL = 66; - public const int DECIMAL_DIGIT = 67; - public const int INTEGER_TYPE_SUFFIX = 68; - public const int HEX_DIGIT = 69; - public const int EXPONENT_PART = 70; - public const int SIGN = 71; - public const int REAL_TYPE_SUFFIX = 72; + public const int EQUAL = 54; + public const int NOT_EQUAL = 55; + public const int LESS_THAN = 56; + public const int LESS_THAN_OR_EQUAL = 57; + public const int GREATER_THAN = 58; + public const int GREATER_THAN_OR_EQUAL = 59; + public const int WS = 60; + public const int BACKTICK = 61; + public const int BACKSLASH = 62; + public const int DOT_ESCAPED = 63; + public const int APOS = 64; + public const int NUMERIC_LITERAL = 65; + public const int DECIMAL_DIGIT = 66; + public const int INTEGER_TYPE_SUFFIX = 67; + public const int HEX_DIGIT = 68; + public const int EXPONENT_PART = 69; + public const int SIGN = 70; + public const int REAL_TYPE_SUFFIX = 71; // CLOVER:OFF @@ -138,7 +137,6 @@ namespace Spring.Expressions.Parser literals.Add("is", 12); literals.Add("like", 14); literals.Add("new", 49); - literals.Add("date", 54); literals.Add("false", 6); } @@ -1010,11 +1008,11 @@ tryAgain: } else { - goto _loop163_breakloop; + goto _loop161_breakloop; } } -_loop163_breakloop: ; +_loop161_breakloop: ; } // ( ... )* _saveIndex = text.Length; mQUOTE(false); @@ -1127,11 +1125,11 @@ _loop163_breakloop: ; } default: { - goto _loop168_breakloop; + goto _loop166_breakloop; } } } -_loop168_breakloop: ; +_loop166_breakloop: ; } // ( ... )* _ttype = testLiteralsTable(_ttype); if (_createToken && (null == _token) && (_ttype != Token.SKIP)) @@ -1147,11 +1145,11 @@ _loop168_breakloop: ; int _ttype; IToken _token=null; int _begin=text.Length; _ttype = NUMERIC_LITERAL; - bool synPredMatched171 = false; + bool synPredMatched169 = false; if (((cached_LA1=='.') && ((cached_LA2 >= '0' && cached_LA2 <= '9')))) { - int _m171 = mark(); - synPredMatched171 = true; + int _m169 = mark(); + synPredMatched169 = true; inputState.guessing++; try { { @@ -1161,16 +1159,16 @@ _loop168_breakloop: ; } catch (RecognitionException) { - synPredMatched171 = false; + synPredMatched169 = false; } - rewind(_m171); + rewind(_m169); inputState.guessing--; } - if ( synPredMatched171 ) + if ( synPredMatched169 ) { match('.'); { // ( ... )+ - int _cnt173=0; + int _cnt171=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1179,12 +1177,12 @@ _loop168_breakloop: ; } else { - if (_cnt173 >= 1) { goto _loop173_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt171 >= 1) { goto _loop171_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt173++; + _cnt171++; } -_loop173_breakloop: ; +_loop171_breakloop: ; } // ( ... )+ { if ((cached_LA1=='E'||cached_LA1=='e')) @@ -1210,16 +1208,16 @@ _loop173_breakloop: ; } } else { - bool synPredMatched179 = false; + bool synPredMatched177 = false; if ((((cached_LA1 >= '0' && cached_LA1 <= '9')) && (tokenSet_1_.member(cached_LA2)))) { - int _m179 = mark(); - synPredMatched179 = true; + int _m177 = mark(); + synPredMatched177 = true; inputState.guessing++; try { { { // ( ... )+ - int _cnt178=0; + int _cnt176=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1228,12 +1226,12 @@ _loop173_breakloop: ; } else { - if (_cnt178 >= 1) { goto _loop178_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt176 >= 1) { goto _loop176_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt178++; + _cnt176++; } -_loop178_breakloop: ; +_loop176_breakloop: ; } // ( ... )+ match('.'); mDECIMAL_DIGIT(false); @@ -1241,13 +1239,31 @@ _loop178_breakloop: ; } catch (RecognitionException) { - synPredMatched179 = false; + synPredMatched177 = false; } - rewind(_m179); + rewind(_m177); inputState.guessing--; } - if ( synPredMatched179 ) + if ( synPredMatched177 ) { + { // ( ... )+ + int _cnt179=0; + for (;;) + { + if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) + { + mDECIMAL_DIGIT(false); + } + else + { + if (_cnt179 >= 1) { goto _loop179_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + } + + _cnt179++; + } +_loop179_breakloop: ; + } // ( ... )+ + match('.'); { // ( ... )+ int _cnt181=0; for (;;) @@ -1264,24 +1280,6 @@ _loop178_breakloop: ; _cnt181++; } _loop181_breakloop: ; - } // ( ... )+ - match('.'); - { // ( ... )+ - int _cnt183=0; - for (;;) - { - if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) - { - mDECIMAL_DIGIT(false); - } - else - { - if (_cnt183 >= 1) { goto _loop183_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } - } - - _cnt183++; - } -_loop183_breakloop: ; } // ( ... )+ { if ((cached_LA1=='E'||cached_LA1=='e')) @@ -1307,16 +1305,16 @@ _loop183_breakloop: ; } } else { - bool synPredMatched190 = false; + bool synPredMatched188 = false; if ((((cached_LA1 >= '0' && cached_LA1 <= '9')) && (tokenSet_4_.member(cached_LA2)))) { - int _m190 = mark(); - synPredMatched190 = true; + int _m188 = mark(); + synPredMatched188 = true; inputState.guessing++; try { { { // ( ... )+ - int _cnt188=0; + int _cnt186=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1325,12 +1323,12 @@ _loop183_breakloop: ; } else { - if (_cnt188 >= 1) { goto _loop188_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt186 >= 1) { goto _loop186_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt188++; + _cnt186++; } -_loop188_breakloop: ; +_loop186_breakloop: ; } // ( ... )+ { mEXPONENT_PART(false); @@ -1339,15 +1337,15 @@ _loop188_breakloop: ; } catch (RecognitionException) { - synPredMatched190 = false; + synPredMatched188 = false; } - rewind(_m190); + rewind(_m188); inputState.guessing--; } - if ( synPredMatched190 ) + if ( synPredMatched188 ) { { // ( ... )+ - int _cnt192=0; + int _cnt190=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1356,12 +1354,12 @@ _loop188_breakloop: ; } else { - if (_cnt192 >= 1) { goto _loop192_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt190 >= 1) { goto _loop190_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt192++; + _cnt190++; } -_loop192_breakloop: ; +_loop190_breakloop: ; } // ( ... )+ { mEXPONENT_PART(false); @@ -1381,16 +1379,16 @@ _loop192_breakloop: ; } } else { - bool synPredMatched199 = false; + bool synPredMatched197 = false; if ((((cached_LA1 >= '0' && cached_LA1 <= '9')) && (tokenSet_5_.member(cached_LA2)))) { - int _m199 = mark(); - synPredMatched199 = true; + int _m197 = mark(); + synPredMatched197 = true; inputState.guessing++; try { { { // ( ... )+ - int _cnt197=0; + int _cnt195=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1399,12 +1397,12 @@ _loop192_breakloop: ; } else { - if (_cnt197 >= 1) { goto _loop197_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt195 >= 1) { goto _loop195_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt197++; + _cnt195++; } -_loop197_breakloop: ; +_loop195_breakloop: ; } // ( ... )+ { mREAL_TYPE_SUFFIX(false); @@ -1413,15 +1411,15 @@ _loop197_breakloop: ; } catch (RecognitionException) { - synPredMatched199 = false; + synPredMatched197 = false; } - rewind(_m199); + rewind(_m197); inputState.guessing--; } - if ( synPredMatched199 ) + if ( synPredMatched197 ) { { // ( ... )+ - int _cnt201=0; + int _cnt199=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1430,12 +1428,12 @@ _loop197_breakloop: ; } else { - if (_cnt201 >= 1) { goto _loop201_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt199 >= 1) { goto _loop199_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt201++; + _cnt199++; } -_loop201_breakloop: ; +_loop199_breakloop: ; } // ( ... )+ { mREAL_TYPE_SUFFIX(false); @@ -1447,7 +1445,7 @@ _loop201_breakloop: ; } else if (((cached_LA1 >= '0' && cached_LA1 <= '9')) && (true)) { { // ( ... )+ - int _cnt204=0; + int _cnt202=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1456,12 +1454,12 @@ _loop201_breakloop: ; } else { - if (_cnt204 >= 1) { goto _loop204_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt202 >= 1) { goto _loop202_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt204++; + _cnt202++; } -_loop204_breakloop: ; +_loop202_breakloop: ; } // ( ... )+ { if ((tokenSet_6_.member(cached_LA1))) @@ -1530,14 +1528,14 @@ _loop204_breakloop: ; } else { - goto _loop216_breakloop; + goto _loop214_breakloop; } } -_loop216_breakloop: ; +_loop214_breakloop: ; } // ( ... )* { // ( ... )+ - int _cnt218=0; + int _cnt216=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1546,12 +1544,12 @@ _loop216_breakloop: ; } else { - if (_cnt218 >= 1) { goto _loop218_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt216 >= 1) { goto _loop216_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt218++; + _cnt216++; } -_loop218_breakloop: ; +_loop216_breakloop: ; } // ( ... )+ break; } @@ -1567,14 +1565,14 @@ _loop218_breakloop: ; } else { - goto _loop220_breakloop; + goto _loop218_breakloop; } } -_loop220_breakloop: ; +_loop218_breakloop: ; } // ( ... )* { // ( ... )+ - int _cnt222=0; + int _cnt220=0; for (;;) { if (((cached_LA1 >= '0' && cached_LA1 <= '9'))) @@ -1583,12 +1581,12 @@ _loop220_breakloop: ; } else { - if (_cnt222 >= 1) { goto _loop222_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt220 >= 1) { goto _loop220_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt222++; + _cnt220++; } -_loop222_breakloop: ; +_loop220_breakloop: ; } // ( ... )+ break; } @@ -1719,7 +1717,7 @@ _loop222_breakloop: ; match("0x"); { // ( ... )+ - int _cnt208=0; + int _cnt206=0; for (;;) { if ((tokenSet_7_.member(cached_LA1))) @@ -1728,12 +1726,12 @@ _loop222_breakloop: ; } else { - if (_cnt208 >= 1) { goto _loop208_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } + if (_cnt206 >= 1) { goto _loop206_breakloop; } else { throw new NoViableAltForCharException(cached_LA1, getFilename(), getLine(), getColumn());; } } - _cnt208++; + _cnt206++; } -_loop208_breakloop: ; +_loop206_breakloop: ; } // ( ... )+ { if ((tokenSet_6_.member(cached_LA1))) diff --git a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParser.cs b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParser.cs index a5677a09..29d44bd3 100644 --- a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParser.cs +++ b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParser.cs @@ -78,25 +78,24 @@ namespace Spring.Expressions.Parser public const int INTEGER_LITERAL = 51; public const int HEXADECIMAL_INTEGER_LITERAL = 52; public const int REAL_LITERAL = 53; - public const int LITERAL_date = 54; - public const int EQUAL = 55; - public const int NOT_EQUAL = 56; - public const int LESS_THAN = 57; - public const int LESS_THAN_OR_EQUAL = 58; - public const int GREATER_THAN = 59; - public const int GREATER_THAN_OR_EQUAL = 60; - public const int WS = 61; - public const int BACKTICK = 62; - public const int BACKSLASH = 63; - public const int DOT_ESCAPED = 64; - public const int APOS = 65; - public const int NUMERIC_LITERAL = 66; - public const int DECIMAL_DIGIT = 67; - public const int INTEGER_TYPE_SUFFIX = 68; - public const int HEX_DIGIT = 69; - public const int EXPONENT_PART = 70; - public const int SIGN = 71; - public const int REAL_TYPE_SUFFIX = 72; + public const int EQUAL = 54; + public const int NOT_EQUAL = 55; + public const int LESS_THAN = 56; + public const int LESS_THAN_OR_EQUAL = 57; + public const int GREATER_THAN = 58; + public const int GREATER_THAN_OR_EQUAL = 59; + public const int WS = 60; + public const int BACKTICK = 61; + public const int BACKSLASH = 62; + public const int DOT_ESCAPED = 63; + public const int APOS = 64; + public const int NUMERIC_LITERAL = 65; + public const int DECIMAL_DIGIT = 66; + public const int INTEGER_TYPE_SUFFIX = 67; + public const int HEX_DIGIT = 68; + public const int EXPONENT_PART = 69; + public const int SIGN = 70; + public const int REAL_TYPE_SUFFIX = 71; // CLOVER:OFF @@ -1190,7 +1189,6 @@ _loop29_breakloop: ; case INTEGER_LITERAL: case HEXADECIMAL_INTEGER_LITERAL: case REAL_LITERAL: - case LITERAL_date: { literal(); if (0 == inputState.guessing) @@ -1892,16 +1890,6 @@ _loop67_breakloop: ; literal_AST = (Spring.Expressions.SpringAST)currentAST.root; break; } - case LITERAL_date: - { - dateLiteral(); - if (0 == inputState.guessing) - { - astFactory.addASTChild(ref currentAST, (AST)returnAST); - } - literal_AST = (Spring.Expressions.SpringAST)currentAST.root; - break; - } default: { throw new NoViableAltException(LT(1), getFilename()); @@ -3261,58 +3249,6 @@ _loop96_breakloop: ; returnAST = boolLiteral_AST; } - public void dateLiteral() //throws RecognitionException, TokenStreamException -{ - - returnAST = null; - ASTPair currentAST = new ASTPair(); - Spring.Expressions.SpringAST dateLiteral_AST = null; - - try { // for error handling - Spring.Expressions.DateLiteralNode tmp112_AST = null; - tmp112_AST = (Spring.Expressions.DateLiteralNode) astFactory.create(LT(1), "Spring.Expressions.DateLiteralNode"); - astFactory.makeASTRoot(ref currentAST, (AST)tmp112_AST); - match(LITERAL_date); - match(LPAREN); - Spring.Expressions.SpringAST tmp114_AST = null; - tmp114_AST = (Spring.Expressions.SpringAST) astFactory.create(LT(1)); - astFactory.addASTChild(ref currentAST, (AST)tmp114_AST); - match(STRING_LITERAL); - { - if ((LA(1)==COMMA)) - { - match(COMMA); - Spring.Expressions.SpringAST tmp116_AST = null; - tmp116_AST = (Spring.Expressions.SpringAST) astFactory.create(LT(1)); - astFactory.addASTChild(ref currentAST, (AST)tmp116_AST); - match(STRING_LITERAL); - } - else if ((LA(1)==RPAREN)) { - } - else - { - throw new NoViableAltException(LT(1), getFilename()); - } - - } - match(RPAREN); - dateLiteral_AST = (Spring.Expressions.SpringAST)currentAST.root; - } - catch (RecognitionException ex) - { - if (0 == inputState.guessing) - { - reportError(ex); - recover(ex,tokenSet_2_); - } - else - { - throw ex; - } - } - returnAST = dateLiteral_AST; - } - public new Spring.Expressions.SpringAST getAST() { return (Spring.Expressions.SpringAST) returnAST; @@ -3328,7 +3264,7 @@ _loop96_breakloop: ; } static public void initializeASTFactory( ASTFactory factory ) { - factory.setMaxNodeType(72); + factory.setMaxNodeType(71); } public static readonly string[] tokenNames_ = new string[] { @@ -3386,7 +3322,6 @@ _loop96_breakloop: ; @"""INTEGER_LITERAL""", @"""HEXADECIMAL_INTEGER_LITERAL""", @"""REAL_LITERAL""", - @"""date""", @"""EQUAL""", @"""NOT_EQUAL""", @"""LESS_THAN""", @@ -3421,7 +3356,7 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_1_ = new BitSet(mk_tokenSet_1_()); private static long[] mk_tokenSet_2_() { - long[] data = { 2269831713112653570L, 0L}; + long[] data = { 1134924607015288578L, 0L}; return data; } public static readonly BitSet tokenSet_2_ = new BitSet(mk_tokenSet_2_()); @@ -3445,7 +3380,7 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_5_ = new BitSet(mk_tokenSet_5_()); private static long[] mk_tokenSet_6_() { - long[] data = { 2269814212194793472L, 0L}; + long[] data = { 1134907106097428480L, 0L}; return data; } public static readonly BitSet tokenSet_6_ = new BitSet(mk_tokenSet_6_()); @@ -3457,37 +3392,37 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_7_ = new BitSet(mk_tokenSet_7_()); private static long[] mk_tokenSet_8_() { - long[] data = { 2269815620960583426L, 0L}; + long[] data = { 1134908514863218434L, 0L}; return data; } public static readonly BitSet tokenSet_8_ = new BitSet(mk_tokenSet_8_()); private static long[] mk_tokenSet_9_() { - long[] data = { 35710725750194368L, 0L}; + long[] data = { 17696327240712384L, 0L}; return data; } public static readonly BitSet tokenSet_9_ = new BitSet(mk_tokenSet_9_()); private static long[] mk_tokenSet_10_() { - long[] data = { 2269815621010915074L, 0L}; + long[] data = { 1134908514913550082L, 0L}; return data; } public static readonly BitSet tokenSet_10_ = new BitSet(mk_tokenSet_10_()); private static long[] mk_tokenSet_11_() { - long[] data = { 2269815621480677122L, 0L}; + long[] data = { 1134908515383312130L, 0L}; return data; } public static readonly BitSet tokenSet_11_ = new BitSet(mk_tokenSet_11_()); private static long[] mk_tokenSet_12_() { - long[] data = { 35710724626120896L, 0L}; + long[] data = { 17696326116638912L, 0L}; return data; } public static readonly BitSet tokenSet_12_ = new BitSet(mk_tokenSet_12_()); private static long[] mk_tokenSet_13_() { - long[] data = { 2269815622017548034L, 0L}; + long[] data = { 1134908515920183042L, 0L}; return data; } public static readonly BitSet tokenSet_13_ = new BitSet(mk_tokenSet_13_()); @@ -3511,7 +3446,7 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_16_ = new BitSet(mk_tokenSet_16_()); private static long[] mk_tokenSet_17_() { - long[] data = { -35184381001744L, 511L, 0L, 0L}; + long[] data = { -35184381001744L, 255L, 0L, 0L}; return data; } public static readonly BitSet tokenSet_17_ = new BitSet(mk_tokenSet_17_()); @@ -3529,7 +3464,7 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_19_ = new BitSet(mk_tokenSet_19_()); private static long[] mk_tokenSet_20_() { - long[] data = { 2270957613019496194L, 0L}; + long[] data = { 1136050506922131202L, 0L}; return data; } public static readonly BitSet tokenSet_20_ = new BitSet(mk_tokenSet_20_()); @@ -3541,7 +3476,7 @@ _loop96_breakloop: ; public static readonly BitSet tokenSet_21_ = new BitSet(mk_tokenSet_21_()); private static long[] mk_tokenSet_22_() { - long[] data = { 2305806450443419584L, 0L}; + long[] data = { 1152884945836572608L, 0L}; return data; } public static readonly BitSet tokenSet_22_ = new BitSet(mk_tokenSet_22_()); diff --git a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.cs b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.cs index 8a4384db..7d3fb74d 100644 --- a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.cs +++ b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.cs @@ -56,25 +56,24 @@ namespace Spring.Expressions.Parser public const int INTEGER_LITERAL = 51; public const int HEXADECIMAL_INTEGER_LITERAL = 52; public const int REAL_LITERAL = 53; - public const int LITERAL_date = 54; - public const int EQUAL = 55; - public const int NOT_EQUAL = 56; - public const int LESS_THAN = 57; - public const int LESS_THAN_OR_EQUAL = 58; - public const int GREATER_THAN = 59; - public const int GREATER_THAN_OR_EQUAL = 60; - public const int WS = 61; - public const int BACKTICK = 62; - public const int BACKSLASH = 63; - public const int DOT_ESCAPED = 64; - public const int APOS = 65; - public const int NUMERIC_LITERAL = 66; - public const int DECIMAL_DIGIT = 67; - public const int INTEGER_TYPE_SUFFIX = 68; - public const int HEX_DIGIT = 69; - public const int EXPONENT_PART = 70; - public const int SIGN = 71; - public const int REAL_TYPE_SUFFIX = 72; + public const int EQUAL = 54; + public const int NOT_EQUAL = 55; + public const int LESS_THAN = 56; + public const int LESS_THAN_OR_EQUAL = 57; + public const int GREATER_THAN = 58; + public const int GREATER_THAN_OR_EQUAL = 59; + public const int WS = 60; + public const int BACKTICK = 61; + public const int BACKSLASH = 62; + public const int DOT_ESCAPED = 63; + public const int APOS = 64; + public const int NUMERIC_LITERAL = 65; + public const int DECIMAL_DIGIT = 66; + public const int INTEGER_TYPE_SUFFIX = 67; + public const int HEX_DIGIT = 68; + public const int EXPONENT_PART = 69; + public const int SIGN = 70; + public const int REAL_TYPE_SUFFIX = 71; } } diff --git a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.txt b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.txt index 5af0bd5e..bd2a5021 100644 --- a/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.txt +++ b/src/Spring/Spring.Core/Expressions/Parser/ExpressionParserTokenTypes.txt @@ -50,22 +50,21 @@ LCURLY=50 INTEGER_LITERAL=51 HEXADECIMAL_INTEGER_LITERAL=52 REAL_LITERAL=53 -LITERAL_date="date"=54 -EQUAL=55 -NOT_EQUAL=56 -LESS_THAN=57 -LESS_THAN_OR_EQUAL=58 -GREATER_THAN=59 -GREATER_THAN_OR_EQUAL=60 -WS=61 -BACKTICK=62 -BACKSLASH=63 -DOT_ESCAPED=64 -APOS=65 -NUMERIC_LITERAL=66 -DECIMAL_DIGIT=67 -INTEGER_TYPE_SUFFIX=68 -HEX_DIGIT=69 -EXPONENT_PART=70 -SIGN=71 -REAL_TYPE_SUFFIX=72 +EQUAL=54 +NOT_EQUAL=55 +LESS_THAN=56 +LESS_THAN_OR_EQUAL=57 +GREATER_THAN=58 +GREATER_THAN_OR_EQUAL=59 +WS=60 +BACKTICK=61 +BACKSLASH=62 +DOT_ESCAPED=63 +APOS=64 +NUMERIC_LITERAL=65 +DECIMAL_DIGIT=66 +INTEGER_TYPE_SUFFIX=67 +HEX_DIGIT=68 +EXPONENT_PART=69 +SIGN=70 +REAL_TYPE_SUFFIX=71 diff --git a/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs index 0f3df3e5..01d2dcbf 100644 --- a/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs +++ b/src/Spring/Spring.Core/Expressions/Processors/ConversionProcessor.cs @@ -57,7 +57,7 @@ namespace Spring.Expressions.Processors Type targetType = typeof(double); if (args == null || args.Length == 0) { - throw new ArgumentNullException("convert() processor requires a Type value argument."); + throw new ArgumentNullException("args", "convert() processor requires a Type value argument."); } else if (args.Length == 1) { diff --git a/src/Spring/Spring.Core/Expressions/Processors/DateConversionProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/DateConversionProcessor.cs new file mode 100644 index 00000000..91b9127a --- /dev/null +++ b/src/Spring/Spring.Core/Expressions/Processors/DateConversionProcessor.cs @@ -0,0 +1,46 @@ +#region License + +/* + * Copyright 2002-2009 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.Globalization; + +namespace Spring.Expressions.Processors +{ + /// + /// Converts a string literal to a instance. + /// + /// Erich Eichinger + public class DateConversionProcessor : IMethodCallProcessor + { + public object Process(object context, object[] args) + { + int argc = args != null ? args.Length : 0; + switch (argc) + { + case 1: + return DateTime.Parse((string)args[0]); + case 2: + return DateTime.ParseExact((string)args[0], (string)args[1], CultureInfo.InvariantCulture); + default: + throw new ArgumentException("date( [,]) expects 1 or 2 arguments"); + } + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Core/Expressions/Processors/IMethodCallProcessor.cs b/src/Spring/Spring.Core/Expressions/Processors/IMethodCallProcessor.cs new file mode 100644 index 00000000..86e68a5f --- /dev/null +++ b/src/Spring/Spring.Core/Expressions/Processors/IMethodCallProcessor.cs @@ -0,0 +1,32 @@ +#region License + +/* + * Copyright 2002-2009 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; + +namespace Spring.Expressions.Processors +{ + /// + /// + /// Erich Eichinger + public interface IMethodCallProcessor + { + object Process(object context, object[] args); + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Core/Spring.Core.2008.csproj b/src/Spring/Spring.Core/Spring.Core.2008.csproj index c6024a6b..dda1bb0d 100644 --- a/src/Spring/Spring.Core/Spring.Core.2008.csproj +++ b/src/Spring/Spring.Core/Spring.Core.2008.csproj @@ -461,6 +461,8 @@ + + @@ -512,9 +514,6 @@ - - Code - Code diff --git a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs index db8af40f..811eadba 100644 --- a/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs +++ b/test/Spring/Spring.Core.Tests/Expressions/ExpressionEvaluatorTests.cs @@ -293,8 +293,17 @@ namespace Spring.Expressions Assert.AreEqual("date", dateLiteral); } - [Test(Description = "http://jira.springframework.org/browse/SPRNET-1155")] + [Test(Description = "http://jira.springframework.org/browse/SPRNET-944")] public void TestDateVariableExpression() + { + Hashtable vars = new Hashtable(); + vars["date"] = "2008-05-15"; + object value = ExpressionEvaluator.GetValue(null, "#date", vars); + Assert.That(value, Is.EqualTo("2008-05-15")); + } + + [Test(Description = "http://jira.springframework.org/browse/SPRNET-1155")] + public void TestDateVariableExpressionCamelCased() { Hashtable vars = new Hashtable(); vars["Date"] = "2008-05-15"; @@ -466,17 +475,14 @@ namespace Spring.Expressions public void TestDateLiterals() { IExpression exp = Expression.Parse("date('1974/08/24')"); - Assert.AreEqual(exp.GetValue(), new DateTime(1974, 8, 24)); - Assert.AreEqual(exp.GetValue(), new DateTime(1974, 8, 24)); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('1974-08-24')"), new DateTime(1974, 8, 24)); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('08-24-1974', 'MM-dd-yyyy')"), - new DateTime(1974, 8, 24)); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('08/24/1974', 'MM/dd/yyyy')"), - new DateTime(1974, 8, 24)); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('1974-08-24 12:35:06Z', 'u')"), - new DateTime(1974, 8, 24, 12, 35, 6)); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('1974/08/24').Year"), 1974); - Assert.AreEqual(ExpressionEvaluator.GetValue(null, "date('1974/08/24').AddYears(31).Year"), 2005); + Assert.AreEqual(new DateTime(1974, 8, 24), exp.GetValue()); + Assert.AreEqual(new DateTime(1974, 8, 24), exp.GetValue()); + Assert.AreEqual(new DateTime(1974, 8, 24), ExpressionEvaluator.GetValue(null, "date('1974-08-24')")); + Assert.AreEqual(new DateTime(1974, 8, 24), ExpressionEvaluator.GetValue(null, "date('08-24-1974', 'MM-dd-yyyy')")); + Assert.AreEqual(new DateTime(1974, 8, 24), ExpressionEvaluator.GetValue(null, "date('08/24/1974', 'MM/dd/yyyy')")); + Assert.AreEqual(new DateTime(1974, 8, 24, 12, 35, 6), ExpressionEvaluator.GetValue(null, "date('1974-08-24 12:35:06Z', 'u')")); + Assert.AreEqual(1974, ExpressionEvaluator.GetValue(null, "date('1974/08/24').Year")); + Assert.AreEqual(2005, ExpressionEvaluator.GetValue(null, "date('1974/08/24').AddYears(31).Year")); } ///