fixed SPRNET-1155 - removed dateLiteral from antlr grammar and replaced with IMethodCallProcessor strategy in MethodNode

This commit is contained in:
eeichinger
2009-09-04 21:42:55 +00:00
parent 33fbc05483
commit c6a5918c67
12 changed files with 541 additions and 612 deletions

View File

@@ -1,84 +0,0 @@
#region License
/*
* Copyright <20> 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
{
/// <summary>
/// Represents parsed node in the navigation expression.
/// </summary>
/// <author>Aleksandar Seovic</author>
[Serializable]
public class DateLiteralNode : BaseNode
{
private object nodeValue;
/// <summary>
/// Create a new instance
/// </summary>
public DateLiteralNode():base()
{
}
/// <summary>
/// Create a new instance from SerializationInfo
/// </summary>
protected DateLiteralNode(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
/// <summary>
/// Returns node's value for the given context.
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
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;
}
}
}

View File

@@ -154,7 +154,7 @@ node :
| firstSelection
| lastSelection
| exprList
| DOT!
| DOT!
)+
;
@@ -173,15 +173,17 @@ localFunctionOrVar
| localVar
;
localFunction : DOLLAR! ID^ <AST = Spring.Expressions.LocalFunctionNode> methodArgs
localFunction
: DOLLAR! ID^ <AST = Spring.Expressions.LocalFunctionNode> methodArgs
;
localVar : DOLLAR! ID^ <AST = Spring.Expressions.LocalVariableNode>;
localVar
: DOLLAR! ID^ <AST = Spring.Expressions.LocalVariableNode>
;
methodOrProperty
: (ID LPAREN)=>
ID^ <AST = Spring.Expressions.MethodNode> methodArgs
| property
: (ID LPAREN)=> ID^ <AST = Spring.Expressions.MethodNode> methodArgs
| property
;
methodArgs
@@ -301,7 +303,6 @@ literal
| REAL_LITERAL <AST = Spring.Expressions.RealLiteralNode>
| STRING_LITERAL <AST = Spring.Expressions.StringLiteralNode>
| boolLiteral
| dateLiteral
;
boolLiteral
@@ -309,11 +310,6 @@ boolLiteral
| FALSE <AST = Spring.Expressions.BooleanLiteralNode>
;
dateLiteral
: "date"^ <AST = Spring.Expressions.DateLiteralNode>
LPAREN! STRING_LITERAL (COMMA! STRING_LITERAL)? RPAREN!
;
relationalOperator
: EQUAL
| NOT_EQUAL
@@ -329,6 +325,7 @@ relationalOperator
;
class ExpressionLexer extends Lexer;
options {

View File

@@ -1,5 +1,5 @@
#region License
#region License
/*
* Copyright <20> 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
{
/// <summary>
/// Represents parsed method node in the navigation expression.
/// </summary>
/// <author>Aleksandar Seovic</author>
[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;
/// <summary>
/// Static constructor. Initializes a map of special collection processor methods.
/// </summary>
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());
}
/// <summary>
/// Create a new instance
/// </summary>
public MethodNode()
{
}
/// <summary>
/// Create a new instance from SerializationInfo
/// </summary>
protected MethodNode(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
/// <summary>
/// Returns node's value for the given context.
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
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);
}
}
/// <summary>
/// Gets the best method given the name, argument values, for a given type.
/// </summary>
/// <param name="type">The type on which to search for the method.</param>
/// <param name="methodName">Name of the method.</param>
/// <param name="bindingFlags">The binding flags.</param>
/// <param name="argValues">The arg values.</param>
/// <returns>Best matching method or null if none found.</returns>
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
{
/// <summary>
/// Represents parsed method node in the navigation expression.
/// </summary>
/// <author>Aleksandar Seovic</author>
[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;
/// <summary>
/// Static constructor. Initializes a map of special collection processor methods.
/// </summary>
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());
}
/// <summary>
/// Create a new instance
/// </summary>
public MethodNode()
{
}
/// <summary>
/// Create a new instance from SerializationInfo
/// </summary>
protected MethodNode(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
/// <summary>
/// Returns node's value for the given context.
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
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);
}
}
/// <summary>
/// Gets the best method given the name, argument values, for a given type.
/// </summary>
/// <param name="type">The type on which to search for the method.</param>
/// <param name="methodName">Name of the method.</param>
/// <param name="bindingFlags">The binding flags.</param>
/// <param name="argValues">The arg values.</param>
/// <returns>Best matching method or null if none found.</returns>
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
};
}
}
};
}
}

View File

@@ -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)))

View File

@@ -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_());

View File

@@ -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;
}
}

View File

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

View File

@@ -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)
{

View File

@@ -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
{
/// <summary>
/// Converts a string literal to a <see cref="DateTime"/> instance.
/// </summary>
/// <author>Erich Eichinger</author>
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(<date> [,<format>]) expects 1 or 2 arguments");
}
}
}
}

View File

@@ -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
{
/// <summary>
/// </summary>
/// <author>Erich Eichinger</author>
public interface IMethodCallProcessor
{
object Process(object context, object[] args);
}
}

View File

@@ -461,6 +461,8 @@
<Compile Include="Expressions\Parser\antlr\TokenWithIndex.cs" />
<Compile Include="Expressions\Parser\antlr\TreeParser.cs" />
<Compile Include="Expressions\Parser\antlr\TreeParserSharedInputState.cs" />
<Compile Include="Expressions\Processors\DateConversionProcessor.cs" />
<Compile Include="Expressions\Processors\IMethodCallProcessor.cs" />
<Compile Include="Expressions\SyntaxErrorException.cs" />
<Compile Include="Expressions\Parser\ExpressionLexer.cs" />
<Compile Include="Expressions\Parser\ExpressionParser.cs" />
@@ -512,9 +514,6 @@
<Compile Include="Expressions\OpIn.cs" />
<Compile Include="Expressions\QualifiedIdentifier.cs" />
<Compile Include="Expressions\NamedArgumentNode.cs" />
<Compile Include="Expressions\DateLiteralNode.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Expressions\Expression.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -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"));
}
/// <summary>