SpEL API polishing

This commit is contained in:
eeichinger
2009-10-14 16:28:18 +00:00
parent 921cddbe2e
commit f00f3afcc3
55 changed files with 378 additions and 353 deletions

View File

@@ -54,7 +54,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (arrayType == null)
@@ -77,7 +77,7 @@ namespace Spring.Expressions
AST rankNode = rankRoot.getFirstChild();
while (rankNode != null)
{
ranks[i++] = (int)((BaseNode)rankNode).GetValueInternal(context, evalContext);
ranks[i++] = (int)GetValue((BaseNode)rankNode, context, evalContext);
rankNode = rankNode.getNextSibling();
}
return Array.CreateInstance(arrayType, ranks);
@@ -87,7 +87,7 @@ namespace Spring.Expressions
AST valuesRoot = getFirstChild().getNextSibling();
if (valuesRoot != null)
{
ArrayList values = (ArrayList)((BaseNode)valuesRoot).GetValueInternal(context, evalContext);
ArrayList values = (ArrayList)GetValue(((BaseNode)valuesRoot), context, evalContext);
return values.ToArray(arrayType);
}
}

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
AST left = getFirstChild();
@@ -69,10 +69,10 @@ namespace Spring.Expressions
}
else
{
result = ((BaseNode)right).GetValueInternal(context, evalContext);
result = GetValue(((BaseNode)right), context, evalContext);
}
((BaseNode)left).SetValueInternal( context, evalContext, result );
SetValue(((BaseNode)left), context, evalContext, result );
return result;
}

View File

@@ -31,12 +31,19 @@ namespace Spring.Expressions
//[Serializable]
public abstract class BaseNode : SpringAST, IExpression
{
protected class ArgumentMismatchException : Exception
{
public ArgumentMismatchException(string message)
: base(message)
{ }
}
#region EvaluationContext class
/// <summary>
/// Holds the state during evaluating an expression.
/// </summary>
public class EvaluationContext
protected class EvaluationContext
{
#region Holder classes
@@ -147,7 +154,7 @@ namespace Spring.Expressions
/// Returns node's value.
/// </summary>
/// <returns>Node's value.</returns>
object IExpression.GetValue()
public object GetValue()
{
return GetValue(null, null);
}
@@ -157,7 +164,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Object to evaluate node against.</param>
/// <returns>Node's value.</returns>
object IExpression.GetValue(object context)
public object GetValue(object context)
{
return GetValue(context, null);
}
@@ -168,43 +175,32 @@ namespace Spring.Expressions
/// <param name="context">Object to evaluate node against.</param>
/// <param name="variables">Expression variables map.</param>
/// <returns>Node's value.</returns>
object IExpression.GetValue(object context, IDictionary variables)
{
return GetValue(context, variables);
}
/// <summary>
/// This is the entrypoint into evaluating this expression.
/// </summary>
public object GetValue(object context, IDictionary variables)
{
EvaluationContext evalContext = new EvaluationContext(context, variables);
return Get(context, evalContext);
}
/// <summary>
/// Called internally during expression evaluation
/// </summary>
/// <param name="context">Object to evaluate node against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns></returns>
protected internal object GetValueInternal(object context, EvaluationContext evalContext)
{
return Get(context, evalContext);
}
/// <summary>
/// Returns node's value for the given context.
/// </summary>
/// <returns>Node's value.</returns>
protected abstract object Get(object context, EvaluationContext evalContext);
/// <summary>
/// Evaluates this node for the given context, switching local variables map to the ones specified in <paramref name="arguments"/>.
/// </summary>
protected virtual object Get(object context, EvaluationContext evalContext, object[] arguments)
{
throw new NotSupportedException("Node " + this.GetType() + " does not support evaluation with arguments");
}
/// <summary>
/// Sets node's value for the given context.
/// </summary>
/// <param name="context">Object to evaluate node against.</param>
/// <param name="newValue">New value for this node.</param>
void IExpression.SetValue(object context, object newValue)
public void SetValue(object context, object newValue)
{
SetValue(context, null, newValue);
}
@@ -215,28 +211,12 @@ namespace Spring.Expressions
/// <param name="context">Object to evaluate node against.</param>
/// <param name="variables">Expression variables map.</param>
/// <param name="newValue">New value for this node.</param>
void IExpression.SetValue(object context, IDictionary variables, object newValue)
{
SetValue( context,variables,newValue );
}
/// <summary>
/// This is the entrypoint into evaluating this expression.
/// </summary>
public void SetValue(object context, IDictionary variables, object newValue)
{
EvaluationContext evalContext = new EvaluationContext(context, variables);
Set(context, evalContext, newValue);
}
/// <summary>
/// Called internally during expression evaluation.
/// </summary>
protected internal void SetValueInternal(object context, EvaluationContext evalContext, object newValue)
{
Set(context, evalContext, newValue);
}
/// <summary>
/// Sets node's value for the given context.
/// </summary>
@@ -263,14 +243,22 @@ namespace Spring.Expressions
return string.Format("{0}[{1}]", this.GetType().Name, base.GetHashCode());
}
protected static object GetValueInternal(BaseNode node, object context, EvaluationContext evalContext)
/// <summary>
/// Evaluates this node, switching local variables map to the ones specified in <paramref name="arguments"/>.
/// </summary>
protected object GetValueWithArguments(BaseNode node, object context, EvaluationContext evalContext, object[] arguments)
{
return node.GetValueInternal(context, evalContext);
return node.Get(context, evalContext, arguments);
}
protected static void SetValueInternal(BaseNode node, object context, EvaluationContext evalContext, object newValue)
protected object GetValue(BaseNode node, object context, EvaluationContext evalContext)
{
node.SetValueInternal(context, evalContext, newValue);
return node.Get(context, evalContext);
}
protected void SetValue(BaseNode node, object context, EvaluationContext evalContext, object newValue)
{
node.Set(context, evalContext, newValue);
}
}
}

View File

@@ -63,6 +63,13 @@ namespace Spring.Expressions
get { return (BaseNode) this.getFirstChild(); }
}
/// <summary>
/// Evaluate the left operand
/// </summary>
protected object GetLeftValue(object context, EvaluationContext evalContext)
{
return GetValue(Left, context, evalContext);
}
/// <summary>
/// Gets the right operand.
/// </summary>
@@ -70,6 +77,14 @@ namespace Spring.Expressions
public BaseNode Right
{
get { return (BaseNode) this.getFirstChild().getNextSibling(); }
}
/// <summary>
/// Evaluate the left operand
/// </summary>
protected object GetRightValue(object context, EvaluationContext evalContext)
{
return GetValue(Right, context, evalContext);
}
}
}

View File

@@ -61,7 +61,7 @@ namespace Spring.Expressions
/// <summary>
/// This is the entrypoint into evaluating this expression.
/// </summary>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (nodeValue == null)

View File

@@ -70,7 +70,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object[] argValues = ResolveArguments(evalContext);

View File

@@ -50,13 +50,13 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal(context, evalContext);
object right = Right.GetValueInternal(context, evalContext);
{
object leftVal = GetValue(Left, context, evalContext);
object rightVal = GetValue(Right, context, evalContext);
return (left != null ? left : right);
return (leftVal != null ? leftVal : rightVal);
}
}
}

View File

@@ -263,7 +263,7 @@ namespace Spring.Expressions
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Value of the last node.</returns>
protected override object Get( object context, EvaluationContext evalContext )
protected override object Get(object context, EvaluationContext evalContext)
{
object result = context;
@@ -272,7 +272,7 @@ namespace Spring.Expressions
AST node = this.getFirstChild();
while (node != null)
{
result = ((BaseNode)node).GetValueInternal( result, evalContext );
result = GetValue(((BaseNode)node), result, evalContext );
node = node.getNextSibling();
}
@@ -301,7 +301,7 @@ namespace Spring.Expressions
{
try
{
target = ((BaseNode)node).GetValueInternal( target, evalContext );
target = GetValue(((BaseNode)node), target, evalContext);
node = node.getNextSibling();
}
catch (NotReadablePropertyException e)
@@ -309,7 +309,7 @@ namespace Spring.Expressions
throw new NotWritablePropertyException( "Cannot read the value of '" + node.getText() + "' property in the expression.", e );
}
}
((BaseNode)node).SetValueInternal( target, evalContext, newValue );
SetValue(((BaseNode)node), target, evalContext, newValue);
}
else
{

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Result of the last expression in a list</returns>
/// <returns>Result of the last expression in a list</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object result = context;
@@ -59,7 +59,7 @@ namespace Spring.Expressions
AST node = this.getFirstChild();
while (node != null)
{
result = ((BaseNode) node).GetValueInternal(context, evalContext);
result = GetValue(((BaseNode) node), context, evalContext);
node = node.getNextSibling();
}
return result;

View File

@@ -56,36 +56,30 @@ namespace Spring.Expressions
protected override object Get(object context, EvaluationContext evalContext)
{
string name = this.getText();
object function = evalContext.Variables[name];
object[] argValues = ResolveArguments(evalContext);
object function = evalContext.Variables[name];
// delegate?
Delegate callback = function as Delegate;
if (callback != null)
{
return new SafeMethod(callback.Method).Invoke(callback.Target, argValues);
return InvokeDelegate(callback, argValues);
}
// lambda?
LambdaExpressionNode lambda = function as LambdaExpressionNode;
if (lambda != null)
{
string[] argNames = lambda.ArgumentNames;
if (argValues.Length != argNames.Length)
try
{
throw new InvalidOperationException(
"Function '" + name + "' requires " + argNames.Length + " arguments.");
return GetValueWithArguments(lambda, context, evalContext, argValues);
}
IDictionary arguments = new Hashtable();
for (int i = 0; i < argValues.Length; i++)
catch (ArgumentMismatchException ame)
{
arguments[argNames[i]] = argValues[i];
throw new InvalidOperationException( "Failed executing function " + name + ": " + ame.Message );
}
return lambda.GetValueInternal(context, evalContext, arguments);
}
if (function == null)
@@ -94,5 +88,10 @@ namespace Spring.Expressions
}
throw new InvalidOperationException("Function '" + name + "' is defined but of unknown type.");
}
private object InvokeDelegate(Delegate callback, object[] arguments)
{
return new SafeMethod(callback.Method).Invoke(callback.Target, arguments);
}
}
}

View File

@@ -53,7 +53,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (nodeValue == null)

View File

@@ -62,7 +62,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (context == null)

View File

@@ -60,7 +60,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (nodeValue == null)

View File

@@ -29,7 +29,7 @@ namespace Spring.Expressions
/// Represents lambda expression.
/// </summary>
/// <author>Aleksandar Seovic</author>
[Serializable]
[Serializable]
public class LambdaExpressionNode : BaseNode
{
/// <summary>
@@ -77,34 +77,44 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if(bodyExpression == null)
{
InitializeLambda();
}
object result = bodyExpression.GetValueInternal(context, evalContext);
}
object result = GetValue(bodyExpression, context, evalContext);
return result;
}
/// <summary>
/// Evaluates this node, switching local variables map to the ones specified in <paramref name="argValues"/>.
/// </summary>
protected override object Get(object context, EvaluationContext evalContext, object[] argValues)
{
string[] argNames = this.ArgumentNames;
if (argValues.Length != argNames.Length)
{
throw new ArgumentMismatchException(string.Format("Invalid number of arguments - expected {0} arguments, but was called with {1}", argNames.Length, argValues.Length));
}
IDictionary arguments = new Hashtable();
for (int i = 0; i < argValues.Length; i++)
{
arguments[argNames[i]] = argValues[i];
}
EvaluationContext ec = (EvaluationContext)evalContext;
using (ec.SwitchLocalVariables(arguments))
{
object result = Get(context, ec);
return result;
}
}
/// <summary>
/// Returns Lambda Expression's value for the given context.
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <param name="arguments">A dictionary containing argument map for this lambda expression.</param>
/// <returns>Node's value.</returns>
public object GetValueInternal(object context, EvaluationContext evalContext, IDictionary arguments)
{
using (evalContext.SwitchLocalVariables(arguments))
{
object result = base.GetValueInternal(context, evalContext);
return result;
}
}
private void InitializeLambda()
{
lock (this)

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object[] values = ResolveArguments(evalContext);

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Result of the function evaluation.</returns>
/// <returns>Result of the function evaluation.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
string name = this.getText();
@@ -64,21 +64,15 @@ namespace Spring.Expressions
}
object[] argValues = ResolveArguments(evalContext);
string[] argNames = lambda.ArgumentNames;
if (argValues.Length != argNames.Length)
{
throw new InvalidOperationException(
"Function '" + name + "' requires " + argNames.Length + " arguments.");
}
IDictionary arguments = new Hashtable();
for (int i = 0; i < argValues.Length; i++)
{
arguments[argNames[i]] = argValues[i];
}
return lambda.GetValueInternal(context, evalContext, arguments);
try
{
return GetValueWithArguments(lambda, context, evalContext, argValues);
}
catch (ArgumentMismatchException ame)
{
throw new InvalidOperationException("Failed executing function '" + name + "': " + ame.Message);
}
}
}
}

View File

@@ -53,7 +53,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
string varName = this.getText();

View File

@@ -50,11 +50,12 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object key = ((BaseNode)this.getFirstChild()).GetValueInternal(context, evalContext);
object value = ((BaseNode)this.getFirstChild().getNextSibling()).GetValueInternal(context, evalContext);
{
BaseNode firstChild = (BaseNode)this.getFirstChild();
object key = GetValue(firstChild, context, evalContext);
object value = GetValue((BaseNode) firstChild.getNextSibling(), context, evalContext);
return new DictionaryEntry(key, value);
}

View File

@@ -51,15 +51,14 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IDictionary entries = new Hashtable();
AST entryNode = this.getFirstChild();
while (entryNode != null)
{
DictionaryEntry entry = (DictionaryEntry)
((MapEntryNode)entryNode).GetValueInternal( evalContext.RootContext, evalContext );
DictionaryEntry entry = (DictionaryEntry) GetValue(((MapEntryNode)entryNode), evalContext.RootContext, evalContext );
entries[entry.Key] = entry.Value;
entryNode = entryNode.getNextSibling();
}

View File

@@ -50,10 +50,10 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
return ((BaseNode) this.getFirstChild()).GetValueInternal(evalContext.RootContext, evalContext);
return GetValue(((BaseNode) this.getFirstChild()), evalContext.RootContext, evalContext);
}
}
}

View File

@@ -72,36 +72,33 @@ namespace Spring.Expressions
/// </summary>
private void InitializeNode()
{
if (args == null)
lock (this)
{
lock (this)
if (args == null)
{
if (args == null)
ArrayList argList = new ArrayList();
namedArgs = new Hashtable();
AST node = this.getFirstChild();
while (node != null)
{
ArrayList argList = new ArrayList();
namedArgs = new Hashtable();
AST node = this.getFirstChild();
while (node != null)
if (node.getFirstChild() is LambdaExpressionNode)
{
if (node.getFirstChild() is LambdaExpressionNode)
{
argList.Add(node.getFirstChild());
}
else if (node is NamedArgumentNode)
{
namedArgs.Add(node.getText(), node);
}
else
{
argList.Add(node);
}
node = node.getNextSibling();
argList.Add(node.getFirstChild());
}
args = (BaseNode[])argList.ToArray(typeof(BaseNode));
else if (node is NamedArgumentNode)
{
namedArgs.Add(node.getText(), node);
}
else
{
argList.Add(node);
}
node = node.getNextSibling();
}
args = (BaseNode[]) argList.ToArray(typeof (BaseNode));
}
}
}
@@ -127,8 +124,12 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>An array of argument values</returns>
protected object[] ResolveArguments(EvaluationContext evalContext)
{
InitializeNode();
{
if (args == null)
{
InitializeNode();
}
int length = args.Length;
object[] values = new object[length];
for (int i = 0; i < length; i++)
@@ -144,8 +145,12 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>A dictionary of argument name to value mappings.</returns>
protected IDictionary ResolveNamedArguments(EvaluationContext evalContext)
{
InitializeNode();
{
if (args == null)
{
InitializeNode();
}
if (namedArgs.Count == 0)
{
return null;
@@ -166,8 +171,11 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Resolved argument value.</returns>
protected object ResolveArgument(int position, EvaluationContext evalContext)
{
InitializeNode();
{
if (args == null)
{
InitializeNode();
}
return ResolveArgumentInternal(position, evalContext);
}
@@ -184,7 +192,7 @@ namespace Spring.Expressions
{
return arg;
}
return arg.GetValueInternal(evalContext.ThisContext, evalContext);
return GetValue(arg, evalContext.ThisContext, evalContext);
}
/// <summary>
@@ -195,7 +203,7 @@ namespace Spring.Expressions
/// <returns>Resolved named argument value.</returns>
private object ResolveNamedArgument(string name, EvaluationContext evalContext)
{
return ((BaseNode)namedArgs[name]).GetValueInternal(evalContext.ThisContext, evalContext);
return GetValue(((BaseNode)namedArgs[name]), evalContext.ThisContext, evalContext);
}
}

View File

@@ -53,11 +53,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal(context, evalContext);
object right = Right.GetValueInternal(context, evalContext);
object left = GetLeftValue(context, evalContext);
object right = GetRightValue(context, evalContext);
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
{

View File

@@ -59,11 +59,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object l = Left.GetValueInternal(context, evalContext);
object r = Right.GetValueInternal(context, evalContext);
object l = GetLeftValue(context, evalContext);
object r = GetRightValue(context, evalContext);
if (NumberUtils.IsInteger(l) && NumberUtils.IsInteger(r))
{

View File

@@ -54,11 +54,11 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>
/// true if the left operand is contained within the right operand, false otherwise.
/// </returns>
/// </returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object value = Left.GetValueInternal(context, evalContext);
IList range = Right.GetValueInternal(context, evalContext) as IList;
object value = GetLeftValue(context, evalContext);
IList range = GetRightValue(context, evalContext) as IList;
if (range == null || range.Count != 2)
{

View File

@@ -52,11 +52,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal(context, evalContext);
object right = Right.GetValueInternal(context, evalContext);
object left = GetLeftValue(context, evalContext);
object right = GetRightValue(context, evalContext);
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
{

View File

@@ -1,5 +1,5 @@
#region License
#region License
/*
* Copyright <20> 2002-2005 the original author or authors.
*
@@ -14,80 +14,80 @@
* 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.Runtime.Serialization;
using Spring.Util;
namespace Spring.Expressions
{
/// <summary>
/// Represents logical equality operator.
/// </summary>
/// <author>Aleksandar Seovic</author>
[Serializable]
public class OpEqual : BinaryOperator
{
/// <summary>
/// Create a new instance
/// </summary>
public OpEqual()
{
}
/// <summary>
/// Create a new instance from SerializationInfo
/// </summary>
protected OpEqual(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
/// <summary>
/// Returns a value for the logical equality operator node.
/// </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 left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
if (left == null)
{
return (right == null);
}
else if (right == null)
{
return false;
}
else if (left.GetType() == right.GetType())
{
if (left is Array)
{
return ArrayUtils.AreEqual(left as Array, right as Array);
}
else
{
return left.Equals(right);
}
}
else if (left.GetType().IsEnum && right is string)
{
return left.Equals(Enum.Parse(left.GetType(), (string) right));
}
else if (right.GetType().IsEnum && left is string)
{
return right.Equals(Enum.Parse(right.GetType(), (string) left));
}
else
{
return CompareUtils.Compare(left, right) == 0;
}
}
}
*/
#endregion
using System;
using System.Runtime.Serialization;
using Spring.Util;
namespace Spring.Expressions
{
/// <summary>
/// Represents logical equality operator.
/// </summary>
/// <author>Aleksandar Seovic</author>
[Serializable]
public class OpEqual : BinaryOperator
{
/// <summary>
/// Create a new instance
/// </summary>
public OpEqual()
{
}
/// <summary>
/// Create a new instance from SerializationInfo
/// </summary>
protected OpEqual(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
/// <summary>
/// Returns a value for the logical equality operator node.
/// </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 left = GetLeftValue(context, evalContext);
object right = GetRightValue(context, evalContext);
if (left == null)
{
return (right == null);
}
else if (right == null)
{
return false;
}
else if (left.GetType() == right.GetType())
{
if (left is Array)
{
return ArrayUtils.AreEqual(left as Array, right as Array);
}
else
{
return left.Equals(right);
}
}
else if (left.GetType().IsEnum && right is string)
{
return left.Equals(Enum.Parse(left.GetType(), (string)right));
}
else if (right.GetType().IsEnum && left is string)
{
return right.Equals(Enum.Parse(right.GetType(), (string)left));
}
else
{
return CompareUtils.Compare(left, right) == 0;
}
}
}
}

View File

@@ -51,11 +51,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal(context, evalContext);
object right = Right.GetValueInternal(context, evalContext);
object left = GetLeftValue(context, evalContext);
object right = GetRightValue(context, evalContext);
return CompareUtils.Compare(left, right) > 0;
}

View File

@@ -51,11 +51,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
return CompareUtils.Compare(left, right) >= 0;
}

View File

@@ -53,11 +53,11 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>
/// true if the left operand is contained within the right operand, false otherwise.
/// </returns>
/// </returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
if (right == null)
{

View File

@@ -52,11 +52,11 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>
/// true if the left operand is contained within the right operand, false otherwise.
/// </returns>
/// </returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object instance = Left.GetValueInternal( context, evalContext );
Type type = Right.GetValueInternal( context, evalContext ) as Type;
object instance = GetLeftValue( context, evalContext );
Type type = GetRightValue( context, evalContext ) as Type;
if (instance == null || type == null)
{

View File

@@ -51,11 +51,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
return CompareUtils.Compare(left, right) < 0;
}

View File

@@ -52,11 +52,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
return CompareUtils.Compare(left, right) <= 0;
}

View File

@@ -56,12 +56,12 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>
/// true if the left operand matches the right operand, false otherwise.
/// </returns>
/// </returns>
protected override object Get(object context, EvaluationContext evalContext)
{
#if NET_2_0 && !MONO_2_0
string text = Left.GetValueInternal( context, evalContext ) as string;
string pattern = Right.GetValueInternal( context, evalContext ) as string;
string text = GetLeftValue( context, evalContext ) as string;
string pattern = GetRightValue( context, evalContext ) as string;
return LikeOperator.LikeString(text, pattern, CompareMethod.Text);
#else

View File

@@ -51,22 +51,22 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object leftVal = GetLeftValue(context, evalContext );
object rightVal = GetRightValue(context, evalContext );
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
if (NumberUtils.IsNumber(leftVal) && NumberUtils.IsNumber(rightVal))
{
return NumberUtils.Modulus(left, right);
return NumberUtils.Modulus(leftVal, rightVal);
}
else
{
throw new ArgumentException("Cannot calculate modulus for instances of '"
+ left.GetType().FullName
+ leftVal.GetType().FullName
+ "' and '"
+ right.GetType().FullName
+ rightVal.GetType().FullName
+ "'.");
}
}

View File

@@ -53,11 +53,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
{

View File

@@ -55,7 +55,7 @@ namespace Spring.Expressions
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>
/// true if the left operand matches the right operand, false otherwise.
/// </returns>
/// </returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (regex == null)
@@ -64,13 +64,13 @@ namespace Spring.Expressions
{
if (regex == null)
{
string pattern = Right.GetValueInternal( context, evalContext ) as string;
string pattern = GetRightValue( context, evalContext ) as string;
regex = new Regex(pattern, RegexOptions.Compiled);
}
}
}
string text = Left.GetValueInternal( context, evalContext ) as string;
string text = GetLeftValue( context, evalContext ) as string;
return regex.IsMatch(text);
}
}

View File

@@ -59,10 +59,10 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object operand = Operand.GetValueInternal(context, evalContext);
object operand = GetValue(Operand, context, evalContext);
if (NumberUtils.IsInteger(operand))
{
return NumberUtils.BitwiseNot(operand);

View File

@@ -51,34 +51,34 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object leftVal = GetLeftValue( context, evalContext );
object rightVal = GetRightValue( context, evalContext );
if (left == null)
if (leftVal == null)
{
return (right != null);
return (rightVal != null);
}
else if (right == null)
else if (rightVal == null)
{
return true;
}
else if (left.GetType() == right.GetType())
else if (leftVal.GetType() == rightVal.GetType())
{
if (left is Array)
if (leftVal is Array)
{
return !ArrayUtils.AreEqual(left as Array, right as Array);
return !ArrayUtils.AreEqual(leftVal as Array, rightVal as Array);
}
else
{
return !left.Equals(right);
return !leftVal.Equals(rightVal);
}
}
else
{
return CompareUtils.Compare(left, right) != 0;
return CompareUtils.Compare(leftVal, rightVal) != 0;
}
}
}

View File

@@ -59,11 +59,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object l = Left.GetValueInternal(context, evalContext);
object r = Right.GetValueInternal(context, evalContext);
object l = GetLeftValue(context, evalContext);
object r = GetRightValue(context, evalContext);
if (NumberUtils.IsInteger(l) && NumberUtils.IsInteger(r))
{

View File

@@ -51,11 +51,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
{

View File

@@ -53,11 +53,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object left = Left.GetValueInternal( context, evalContext );
object right = Right.GetValueInternal( context, evalContext );
object left = GetLeftValue( context, evalContext );
object right = GetRightValue( context, evalContext );
if (NumberUtils.IsNumber(left) && NumberUtils.IsNumber(right))
{

View File

@@ -51,10 +51,10 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object n = Operand.GetValueInternal( context, evalContext );
object n = GetValue(Operand, context, evalContext );
if (!NumberUtils.IsNumber(n))
{

View File

@@ -51,10 +51,10 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object n = Operand.GetValueInternal( context, evalContext );
{
object n = GetValue(Operand, context, evalContext);
if (!NumberUtils.IsNumber(n))
{

View File

@@ -57,11 +57,11 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
object l = Left.GetValueInternal(context, evalContext);
object r = Right.GetValueInternal(context, evalContext);
object l = GetLeftValue(context, evalContext);
object r = GetRightValue(context, evalContext);
if (NumberUtils.IsInteger(l) && NumberUtils.IsInteger(r))
{

View File

@@ -52,7 +52,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IEnumerable enumerable = context as IEnumerable;
@@ -68,8 +68,8 @@ namespace Spring.Expressions
{
foreach(object o in enumerable)
{
evalContext.ThisContext = o;
projectedList.Add(expression.GetValueInternal(o, evalContext));
evalContext.ThisContext = o;
projectedList.Add(GetValue(expression, o, evalContext));
}
}
return projectedList;

View File

@@ -211,7 +211,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
lock (this)

View File

@@ -53,7 +53,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (nodeValue == null)

View File

@@ -52,7 +52,7 @@ namespace Spring.Context.Support
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IApplicationContext ctx;

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IEnumerable enumerable = context as IEnumerable;
@@ -66,8 +66,8 @@ namespace Spring.Expressions
{
foreach (object o in enumerable)
{
evalContext.ThisContext = o;
bool isMatch = (bool) expression.GetValueInternal(o, evalContext);
evalContext.ThisContext = o;
bool isMatch = (bool)GetValue(expression, o, evalContext);
if (isMatch)
{
return o;

View File

@@ -51,7 +51,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IList list = context as IList;
@@ -69,7 +69,7 @@ namespace Spring.Expressions
{
object listItem = list[i];
evalContext.ThisContext = listItem;
bool isMatch = (bool)expression.GetValueInternal( listItem, evalContext );
bool isMatch = (bool)GetValue(expression, listItem, evalContext );
if (isMatch)
{
return listItem;

View File

@@ -53,7 +53,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
IEnumerable enumerable = context as IEnumerable;
@@ -68,11 +68,11 @@ namespace Spring.Expressions
BaseNode maxIndexExpression = (minIndexExpression == null) ? null : (BaseNode)minIndexExpression.getNextSibling();
int minIndex = (int)((minIndexExpression == null)
? Int32.MinValue
: minIndexExpression.GetValueInternal(context, evalContext));
? Int32.MinValue
: GetValue(minIndexExpression, context, evalContext));
int maxIndex = (int)((maxIndexExpression == null)
? Int32.MaxValue
: maxIndexExpression.GetValueInternal(context, evalContext));
? Int32.MaxValue
: GetValue(maxIndexExpression, context, evalContext));
IList selectionList = new ArrayList();
@@ -81,8 +81,8 @@ namespace Spring.Expressions
int found = 0;
foreach (object o in enumerable)
{
evalContext.ThisContext = o;
bool isMatch = (bool)expression.GetValueInternal(o, evalContext);
evalContext.ThisContext = o;
bool isMatch = (bool)GetValue(expression, o, evalContext);
if (isMatch)
{
if (minIndex <= found && found <= maxIndex)

View File

@@ -58,7 +58,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
return this.getText();

View File

@@ -56,7 +56,7 @@ namespace Spring.Expressions
/// </summary>
/// <param name="context">Context to evaluate expressions against.</param>
/// <param name="evalContext">Current expression evaluation context.</param>
/// <returns>Node's value.</returns>
/// <returns>Node's value.</returns>
protected override object Get(object context, EvaluationContext evalContext)
{
if (!initialized)
@@ -75,15 +75,15 @@ namespace Spring.Expressions
initialized = true;
}
}
}
if (Convert.ToBoolean(condition.GetValueInternal(context, evalContext)))
{
return trueExp.GetValueInternal(context, evalContext);
}
if (Convert.ToBoolean(GetValue(condition, context, evalContext)))
{
return GetValue(trueExp, context, evalContext);
}
else
{
return falseExp.GetValueInternal(context, evalContext);
{
return GetValue(falseExp, context, evalContext);
}
}
}

View File

@@ -89,7 +89,23 @@ namespace Spring.Reflection.Dynamic
}
}
private static readonly IDictionary stateCache = new HybridDictionary();
private class IdentityTable : Hashtable
{
public IdentityTable()
{}
protected override int GetHash(object key)
{
return key.GetHashCode();
}
protected override bool KeyEquals(object item, object key)
{
return ReferenceEquals(item, key);
}
}
private static readonly Hashtable stateCache = new IdentityTable();
#endregion

View File

@@ -97,27 +97,22 @@ namespace Spring.Expressions
str.Text = "theArg";
fn.addChild(str);
IExpression exp = fn;
string result = str.Text;
// string result = string.Format("{0},{1},{2}", this.GetHashCode(), str.Text, str2.Text);
int ITERATIONS = 1000000;
int ITERATIONS = 10000000;
StopWatch watch = new StopWatch();
// using (watch.Start("Duration Direct: {0}"))
// {
// for (int i = 0; i < ITERATIONS; i++)
// {
// noop(str.getText());
// }
// }
using (watch.Start("Duration Direct: {0}"))
{
for (int i = 0; i < ITERATIONS; i++)
{
((WaitCallback)vars["noop"])(str.getText());
}
}
using (watch.Start("Duration SpEL: {0}"))
{
for (int i = 0; i < ITERATIONS; i++)
{
exp.GetValue(null, vars);
fn.GetValue(null, vars);
}
}
}