Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Expressions/Processors
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv4517/src/Spring/Spring.Core/Expressions/Processors
Modified Files:
OrderByProcessor.cs SortProcessor.cs
Added Files:
ConversionProcessor.cs ReverseProcessor.cs
Log Message:
SPRNET-898
Index: SortProcessor.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Expressions/Processors/SortProcessor.cs,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** SortProcessor.cs 31 Jul 2007 08:18:30 -0000 1.3
--- SortProcessor.cs 20 Mar 2008 23:58:16 -0000 1.4
***************
*** 19,26 ****
#endregion
using System;
using System.Collections;
using Spring.Collections;
! using Spring.Util;
namespace Spring.Expressions.Processors
--- 19,29 ----
#endregion
+ #region Imports
+
using System;
using System.Collections;
using Spring.Collections;
!
! #endregion
namespace Spring.Expressions.Processors
***************
*** 59,101 ****
public object Process(ICollection source, object[] args)
{
! if (source == null)
{
! return null;
}
! if (source.Count == 0)
{
! return ObjectUtils.EmptyObjects;
}
! Type elementType = DetermineElementType(source);
! Array sortedArray = Array.CreateInstance(elementType, source.Count);
! source.CopyTo(sortedArray, 0);
! Array.Sort(sortedArray);
! return sortedArray;
}
! /// <summary>
! /// Tries to determine collection element type.
! /// </summary>
! /// <param name="source">Source collection.</param>
! /// <returns>A best possible element type match.</returns>
! /// <exception cref="ArgumentException">
! /// If <paramref name="source"/> is neither <see cref="IList"/>
! /// nor <see cref="ISet"/>.
! /// </exception>
! private Type DetermineElementType(ICollection source)
{
! if (source is IList)
! {
! return ((IList) source)[0].GetType();
! }
! else if (source is ISet)
! {
! return typeof(object);
! }
! else
{
! throw new ArgumentException("Sort processor can only be invoked on a list or a set.");
}
}
}
--- 62,95 ----
public object Process(ICollection source, object[] args)
{
! if (source == null || source.Count == 0)
{
! return source;
}
!
! bool sortAscending = true;
! if (args != null && args.Length == 1 && args[0] is bool)
{
! sortAscending = (bool) args[0];
}
! ArrayList list = new ArrayList(source);
! list.Sort();
! if (!sortAscending)
! {
! list.Reverse();
! }
!
! Type elementType = DetermineElementType(list);
! return list.ToArray(elementType);
}
! private Type DetermineElementType(IList list)
{
! for(int i=0;i<list.Count;i++)
{
! object element = list[i];
! if (element != null) return element.GetType();
}
+ return typeof (object);
}
}
Index: OrderByProcessor.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Expressions/Processors/OrderByProcessor.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** OrderByProcessor.cs 4 Dec 2006 08:58:33 -0000 1.1
--- OrderByProcessor.cs 20 Mar 2008 23:58:16 -0000 1.2
***************
*** 21,24 ****
--- 21,25 ----
using System;
using System.Collections;
+ using Spring.Util;
namespace Spring.Expressions.Processors
***************
*** 28,40 ****
/// </summary>
/// <author>Aleksandar Seovic</author>
/// <version>$Id$</version>
public class OrderByProcessor : ICollectionProcessor
{
/// <summary>
/// Sorts the source collection using custom sort criteria.
/// </summary>
/// <remarks>
! /// Please not that this aggregator requires that collection elements
! /// are of a uniform type.
/// </remarks>
/// <param name="source">
--- 29,113 ----
/// </summary>
/// <author>Aleksandar Seovic</author>
+ /// <author>Erich Eichinger</author>
/// <version>$Id$</version>
public class OrderByProcessor : ICollectionProcessor
{
+ #region Comparer Helper Implementations
+
+ private class SimpleExpressionComparer : IComparer
+ {
+ private readonly IExpression _expression;
+
+ public SimpleExpressionComparer(IExpression expression)
+ {
+ _expression = expression;
+ }
+
+ public int Compare(object x, object y)
+ {
+ x = _expression.GetValue(x);
+ y = _expression.GetValue(y);
+
+ if (x==y) return 0;
+
+ if (x != null) return ((IComparable) x).CompareTo(y);
+
+ return ((IComparable)y).CompareTo(x)*-1;
+ }
+ }
+
+ private class LambdaComparer : IComparer
+ {
+ private readonly Hashtable _variables;
+ private readonly IExpression _fn;
+
+ public LambdaComparer(LambdaExpressionNode lambdaExpression)
+ {
+ FunctionNode functionNode = new FunctionNode();
+ functionNode.Text = "compare";
+ VariableNode x = new VariableNode();
+ x.Text = "x";
+ VariableNode y = new VariableNode();
+ y.Text = "y";
+
+ functionNode.addChild(x);
+ functionNode.addChild(y);
+
+ _fn = functionNode;
+ _variables = new Hashtable();
+ _variables.Add( "compare", lambdaExpression );
+ }
+
+ public int Compare(object x, object y)
+ {
+ _variables["x"] = x;
+ _variables["y"] = y;
+ return (int) _fn.GetValue(null, _variables);
+ }
+ }
+
+ private class DelegateComparer : IComparer
+ {
+ private readonly Delegate _fnCompare;
+
+ public DelegateComparer(Delegate fnCompare)
+ {
+ _fnCompare = fnCompare;
+ }
+
+ public int Compare(object x, object y)
+ {
+ return (int)_fnCompare.DynamicInvoke(new object[] { x, y });
+ }
+ }
+
+ #endregion
+
/// <summary>
/// Sorts the source collection using custom sort criteria.
/// </summary>
/// <remarks>
! /// Please not that your compare function needs to take care about
! /// proper conversion of types to be comparable!
/// </remarks>
/// <param name="source">
***************
*** 49,58 ****
public object Process(ICollection source, object[] args)
{
! if (source == null)
{
! return null;
}
! throw new NotImplementedException("To be implemented...");
}
}
--- 122,165 ----
public object Process(ICollection source, object[] args)
{
! if (source == null || source.Count == 0)
{
! return source;
}
! if (args == null || args.Length != 1)
! {
! throw new ArgumentException("compare expression is a required argument for orderBy");
! }
!
! object arg = args[0];
! IComparer comparer = null;
! if (arg is string)
! {
! IExpression expCompare = Expression.Parse((string) arg);
! comparer = new SimpleExpressionComparer(expCompare);
! }
! else if (arg is IComparer)
! {
! comparer = (IComparer) arg;
! }
! else if (arg is LambdaExpressionNode)
! {
! LambdaExpressionNode fnCompare = (LambdaExpressionNode)arg;
! if (fnCompare.ArgumentNames.Length != 2)
! {
! throw new ArgumentException("compare function must accept 2 arguments");
! }
! comparer = new LambdaComparer(fnCompare);
! }
! else if (arg is Delegate)
! {
! comparer = new DelegateComparer((Delegate) arg);
! }
!
! AssertUtils.ArgumentNotNull(comparer, "comparer", "orderBy(comparer) argument 'comparer' does not evaluate to a supported type");
!
! ArrayList list = new ArrayList(source);
! list.Sort(comparer);
! return list;
}
}
--- NEW FILE: ConversionProcessor.cs ---
(This appears to be a binary file; contents omitted.)
--- NEW FILE: ReverseProcessor.cs ---
(This appears to be a binary file; contents omitted.)
|