using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using System.Text.RegularExpressions; namespace HeuristicLab.OKB.Cockpit.Query.OKBQuery { public class TypeConverter { public static object Parse(object value, Type type) { if (value == null) return null; string s = value as string; if (s == null || type == null) return value; if (string.IsNullOrEmpty(s)) return null; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { type = type.GetGenericArguments()[0]; } try { if (type == typeof(string)) return value; if (type == typeof(int)) return int.Parse(s); if (type == typeof(double)) return double.Parse(s); if (type == typeof(DateTime)) return DateTime.Parse(s); if (type == typeof(Guid)) return new Guid(s); } catch (Exception x) { throw new ArgumentException(string.Format( "conversion of value '{0}' of type '{1}' to type '{2}' failed", value, value.GetType(), type), x); } throw new ArgumentException(string.Format( "conversion of value '{0}' of type '{1}' to type '{2}' is not supported", value, value.GetType(), type)); } public static List ParseList(IEnumerable values, Type type) { if (values == null) return null; return values .Select(v => Parse(v, type)) .ToList(); } } public partial class AttributeSelector { public AttributeSelector() { this.PropertyChanged += (s, a) => { switch (a.PropertyName) { case "IsValid": case "ValidationErrorString": break; case "DataTypeName": DataType = DataTypeName != null ? Type.GetType(DataTypeName) : null; goto default; case "TableName": case "FieldName": columnName = null; OnPropertyChanged("ColumnName"); goto default; default: Validate(); break; } }; ValidationErrors.CollectionChanged += (s, a) => { OnPropertyChanged("ValidationErrorString"); }; } public AttributeSelector(string tableName, string fieldName, Type type) : this() { TableName = tableName; FieldName = fieldName; DataTypeName = type.FullName; } private Type dataType; public Type DataType { get { return dataType; } private set { if (value == dataType) return; dataType = value; OnPropertyChanged("DataType"); } } protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } private string columnName; public string ColumnName { get { if (columnName == null) columnName = TableName + "_" + FieldName; return columnName; } set { if (value == columnName) return; columnName = value; OnPropertyChanged("ColumnName"); } } private bool isValid; public bool IsValid { get { return isValid; } set { if (isValid == value) return; isValid = value; OnPropertyChanged("IsValid"); } } private ObservableCollection ValidationErrors = new ObservableCollection(); public string ValidationErrorString { get { return string.Join("\n", ValidationErrors.ToArray()); } } protected bool validating = false; protected void Validate() { if (validating) return; object minValue = MinValue; object maxValue = MaxValue; List allowedValues = AllowedValues; ValidationErrors.Clear(); IsValid = ValidateNotNull(TableName, "table name") & ValidateNotNull(FieldName, "field name") & ValidateAndParse(ref minValue, "min value") & ValidateAndParse(ref maxValue, "max value") & ValidateAndParse(ref allowedValues, "allowed values"); if (IsValid) { validating = true; MinValue = minValue; MaxValue = maxValue; AllowedValues = allowedValues; validating = false; } } private bool ValidateNotNull(string value, string name) { if (value == null) { ValidationErrors.Add(String.Format("No {0}", name)); return false; } return true; } protected TypeNameConverter TypeNameConverter = new TypeNameConverter(); private bool ValidateAndParse(ref object value, string name) { try { value = TypeConverter.Parse(value, DataType); return true; } catch (Exception) { ValidationErrors.Add(string.Format("Cannot parse {0}: '{1}' as {2}", name, value, TypeNameConverter.FormatType(DataType))); return false; } } private bool ValidateAndParse(ref List values, string name) { try { if (values != null) values = values.Select(v => TypeConverter.Parse(v, DataType)).ToList(); return true; } catch (Exception) { ValidationErrors.Add(string.Format( "Cannot parse {0}: [{1}] as list of {2}", name, string.Join(", ", values.Select(v => v.ToString()).ToArray()), TypeNameConverter.FormatType(DataType))); return false; } } public override string ToString() { StringBuilder sb = new StringBuilder() .Append(TableName) .Append('.') .Append(FieldName); if (MinValue != null) sb.Append("\n >").Append(MinValue); if (MaxValue != null) sb.Append("\n <").Append(MaxValue); if (AllowedValues != null) sb.Append("\n in [") .Append(string.Join(", ", AllowedValues .Select(v => v.ToString()) .ToArray())) .Append(']'); if (IsHidden) return String.Format("({0})", sb.ToString()); else return sb.ToString(); } } public class AttributeSelectors : ObservableCollection { } }