xenadmin/XenModel/XenSearch/Sort.cs

174 lines
6.1 KiB
C#
Raw Normal View History

/* Copyright (c) Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml;
using XenAdmin.Core;
using XenAdmin.CustomFields;
using XenAPI;
namespace XenAdmin.XenSearch
{
public class Sort
{
private readonly string column;
private readonly bool ascending;
private readonly PropertyAccessor property;
public string Column
{
get { return column; }
}
public bool Ascending
{
get { return ascending; }
}
public Sort(string column, bool ascending)
{
this.column = column;
this.ascending = ascending;
this.property = CalcProperty();
}
private PropertyAccessor CalcProperty()
{
if (column.StartsWith(CustomFieldsManager.CUSTOM_FIELD))
{
string fieldName = column.Substring(CustomFieldsManager.CUSTOM_FIELD.Length);
CustomFieldDefinition customFieldDefinition = CustomFieldsManager.GetCustomFieldDefinition(fieldName);
if (customFieldDefinition == null) // a custom field that existed at the time the search was created but no longer exists
return (o => null);
if (customFieldDefinition.Type == CustomFieldDefinition.Types.Date)
{
return delegate(IXenObject o)
{
object val = CustomFieldsManager.GetCustomFieldValue(o, customFieldDefinition);
return (DateTime?)(val is DateTime ? val : null);
};
}
else
{
return delegate(IXenObject o)
{
object val = CustomFieldsManager.GetCustomFieldValue(o, customFieldDefinition);
return val == null ? null : val.ToString();
};
}
}
ColumnNames c;
try
{
c = (ColumnNames)Enum.Parse(typeof(ColumnNames), column);
}
catch (ArgumentException)
{
return null;
}
PropertyNames propertyName = PropertyAccessors.GetSortPropertyName(c);
return PropertyAccessors.Get(propertyName);
}
public Sort(XmlNode node)
: this(node.Attributes["column"].Value, SearchMarshalling.ParseBool(node.Attributes["ascending"].Value))
{
}
public XmlNode ToXmlNode(XmlDocument doc)
{
XmlNode node = doc.CreateElement("sort");
SearchMarshalling.AddAttribute(doc, node, "column", column);
SearchMarshalling.AddAttribute(doc, node, "ascending", ascending);
return node;
}
public int Compare(Object _1, Object _2)
{
// Comparison for the name column. If we need any other special cases,
// it would be better to subclass Sort, but that involved too much
// disruption especially in serializing and deserializing for this one case.
bool nameSort = (column == "name");
IXenObject i1 = _1 as IXenObject;
IXenObject i2 = _2 as IXenObject;
IComparable c1, c2;
if (i1 != null)
c1 = property(i1);
else if (nameSort)
c1 = (_1 is DateTime ? ((DateTime)_1).ToString("u", CultureInfo.InvariantCulture) : _1.ToString()); // CP-2036, CA-67113
else
c1 = null;
if (i2 != null)
c2 = property(i2);
else if (nameSort)
c2 = (_2 is DateTime ? ((DateTime)_2).ToString("u", CultureInfo.InvariantCulture) : _2.ToString());
else
c2 = null;
if (c1 == null || c2 == null)
return c1 == null && c2 == null ? 0 :
c1 == null ? 1 : -1;
int r = (nameSort ? StringUtility.NaturalCompare(c1.ToString(), c2.ToString()) : c1.CompareTo(c2));
if (!ascending)
r = -r;
return r;
}
public override bool Equals(object obj)
{
Sort other = obj as Sort;
if (other == null)
return false;
return column == other.column
&& ascending == other.ascending;
}
public override int GetHashCode()
{
return column.GetHashCode();
}
}
}