Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,69 @@
//
// AssociatedMetadataTypeTypeDescriptionProvider.cs
//
// Author:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2009 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !MOBILE
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
namespace System.ComponentModel.DataAnnotations
{
class AssociatedMetadataTypePropertyDescriptor : ReflectionPropertyDescriptor
{
MemberInfo metaTypeMember;
public AssociatedMetadataTypePropertyDescriptor (PropertyInfo typeProperty, MemberInfo metaTypeMember)
: base (typeProperty)
{
this.metaTypeMember = metaTypeMember;
}
protected override void FillAttributes (IList attributeList)
{
base.FillAttributes (attributeList);
if (metaTypeMember == null)
return;
object[] attributes = metaTypeMember.GetCustomAttributes (false);
if (attributes == null || attributes.Length == 0)
return;
foreach (object o in attributes) {
var attr = o as Attribute;
if (attr == null)
continue;
attributeList.Add (attr);
}
}
}
}
#endif

View File

@ -0,0 +1,66 @@
//
// AssociatedMetadataTypeTypeDescriptionProvider.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !MOBILE
using System;
using System.ComponentModel;
namespace System.ComponentModel.DataAnnotations
{
public class AssociatedMetadataTypeTypeDescriptionProvider : TypeDescriptionProvider
{
Type type;
Type associatedMetadataType;
public AssociatedMetadataTypeTypeDescriptionProvider (Type type)
{
if (type == null)
throw new ArgumentNullException ("type");
this.type = type;
}
public AssociatedMetadataTypeTypeDescriptionProvider (Type type, Type associatedMetadataType)
{
if (type == null)
throw new ArgumentNullException ("type");
if (associatedMetadataType == null)
throw new ArgumentNullException ("associatedMetadataType");
this.type = type;
this.associatedMetadataType = associatedMetadataType;
}
public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
{
return new AssociatedMetadataTypeTypeDescriptor (base.GetTypeDescriptor (objectType, instance), type, associatedMetadataType);
}
}
}
#endif

View File

@ -0,0 +1,170 @@
//
// AssociatedMetadataTypeTypeDescriptionProvider.cs
//
// Author:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2009 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !MOBILE
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
namespace System.ComponentModel.DataAnnotations
{
class AssociatedMetadataTypeTypeDescriptor : CustomTypeDescriptor
{
Type type;
Type associatedMetadataType;
bool associatedMetadataTypeChecked;
PropertyDescriptorCollection properties;
Type AssociatedMetadataType {
get {
if (!associatedMetadataTypeChecked && associatedMetadataType == null)
associatedMetadataType = FindMetadataType ();
return associatedMetadataType;
}
}
public AssociatedMetadataTypeTypeDescriptor (ICustomTypeDescriptor parent, Type type)
: this (parent, type, null)
{
}
public AssociatedMetadataTypeTypeDescriptor (ICustomTypeDescriptor parent, Type type, Type associatedMetadataType)
: base (parent)
{
this.type = type;
this.associatedMetadataType = associatedMetadataType;
}
void CopyAttributes (object[] from, List <Attribute> to)
{
foreach (object o in from) {
Attribute a = o as Attribute;
if (a == null)
continue;
to.Add (a);
}
}
public override AttributeCollection GetAttributes ()
{
var attributes = new List <Attribute> ();
CopyAttributes (type.GetCustomAttributes (true), attributes);
Type metaType = AssociatedMetadataType;
if (metaType != null)
CopyAttributes (metaType.GetCustomAttributes (true), attributes);
return new AttributeCollection (attributes.ToArray ());
}
public override PropertyDescriptorCollection GetProperties ()
{
// Code partially copied from TypeDescriptor.TypeInfo.GetProperties
if (properties != null)
return properties;
Dictionary <string, MemberInfo> metaMembers = null;
var propertiesHash = new Dictionary <string, bool> (); // name - null
var propertiesList = new List <AssociatedMetadataTypePropertyDescriptor> ();
Type currentType = type;
Type metaType = AssociatedMetadataType;
if (metaType != null) {
metaMembers = new Dictionary <string, MemberInfo> ();
MemberInfo[] members = metaType.GetMembers (BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (MemberInfo member in members) {
switch (member.MemberType) {
case MemberTypes.Field:
case MemberTypes.Property:
break;
default:
continue;
}
string name = member.Name;
if (metaMembers.ContainsKey (name))
continue;
metaMembers.Add (name, member);
}
}
// Getting properties type by type, because in the case of a property in the child type, where
// the "new" keyword is used and also the return type is changed Type.GetProperties returns
// also the parent property.
//
// Note that we also have to preserve the properties order here.
//
while (currentType != null && currentType != typeof (object)) {
PropertyInfo[] props = currentType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (PropertyInfo property in props) {
string propName = property.Name;
if (property.GetIndexParameters ().Length == 0 && property.CanRead && !propertiesHash.ContainsKey (propName)) {
MemberInfo metaMember;
if (metaMembers != null)
metaMembers.TryGetValue (propName, out metaMember);
else
metaMember = null;
propertiesList.Add (new AssociatedMetadataTypePropertyDescriptor (property, metaMember));
propertiesHash.Add (propName, true);
}
}
currentType = currentType.BaseType;
}
properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) propertiesList.ToArray (), true);
return properties;
}
Type FindMetadataType ()
{
associatedMetadataTypeChecked = true;
if (type == null)
return null;
object[] attrs = type.GetCustomAttributes (typeof (MetadataTypeAttribute), true);
if (attrs == null || attrs.Length == 0)
return null;
var attr = attrs [0] as MetadataTypeAttribute;
if (attr == null)
return null;
return attr.MetadataClassType;
}
}
}
#endif

View File

@ -0,0 +1,89 @@
//
// AssociationAttribute.cs
//
// Authors:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2010 Novell Inc. (http://novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
using System.Collections.Generic;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class AssociationAttribute : Attribute
{
static readonly char[] keySplitChars = { ',' };
IEnumerable <string> otherKeyMembers;
IEnumerable <string> thisKeyMembers;
public bool IsForeignKey { get; set; }
public string Name { get; private set; }
public string OtherKey { get; private set; }
public IEnumerable<string> OtherKeyMembers {
get {
if (otherKeyMembers == null)
otherKeyMembers = GetKeyMembers (OtherKey);
return otherKeyMembers;
}
}
public string ThisKey { get; private set; }
public IEnumerable<string> ThisKeyMembers {
get {
if (thisKeyMembers == null)
thisKeyMembers = GetKeyMembers (ThisKey);
return thisKeyMembers;
}
}
public AssociationAttribute (string name, string thisKey, string otherKey)
{
this.Name = name;
this.ThisKey = thisKey;
this.OtherKey = otherKey;
}
IEnumerable <string> GetKeyMembers (string key)
{
// .NET emulation
if (key == null)
throw new NullReferenceException (".NET emulation");
string nows = key.Replace (" ", String.Empty);
if (nows.Length == 0)
return new string[] { String.Empty };
return nows.Split (keySplitChars);
}
}
}
#endif

View File

@ -0,0 +1,64 @@
2010-05-26 Marek Habersack <mhabersack@novell.com>
* ValidationAttribute.cs: cope with null/empty ErrorMessageString
in FormatErrorMessage
2010-05-12 Marek Habersack <mhabersack@novell.com>
* ValidationException.cs: partially implemented
* ValidationAttribute.cs: implemented
* RequiredAttribute.cs: implemented. Fixes bug #604100
* AssociationAttribute.cs, ConcurrencyCheckAttribute.cs,
CustomValidationAttribute.cs, EditableAttribute.cs,
EnumDataTypeAttribute.cs, IValidatableObject.cs,
ValidationContext.cs, ValidationResult.cs: added
2009-09-15 Marek Habersack <mhabersack@novell.com>
* DataTypeAttribute.cs: implemented GetDataTypeName
2009-06-23 Marek Habersack <mhabersack@novell.com>
* ValidationAttribute.cs: error message must not ever be empty.
* UIHintAttribute.cs: do not throw NIEX from the constructor.
* DataTypeAttribute.cs: implemented correct DisplayFormat
intialization for DataType.Time.
* AssociatedMetadataTypeTypeDescriptor.cs: implemented retrieving
attributes of the associated metadata type, as well as merging of
attribute collections between metadata and main type properties.
* AssociatedMetadataTypePropertyDescriptor.cs: added. Helper class
which merges attributes from the metadata type (if any) with those
associated with property from the "main" type.
2009-04-23 Marek Habersack <mhabersack@novell.com>
* AssociatedMetadataTypeTypeDescriptor.cs: added - doesn't add any
real functionality yet.
* AssociatedMetadataTypeTypeDescriptionProvider.cs: implemented
all the methods.
2008-10-14 Atsushi Enomoto <atsushi@ximian.com>
* AssociatedMetadataTypeTypeDescriptionProvider.cs
DataType.cs
DataTypeAttribute.cs
DisplayColumnAttribute.cs
DisplayFormatAttribute.cs
MetadataTypeAttribute.cs
RangeAttribute.cs
RegularExpressionAttribute.cs
RequiredAttribute.cs
ScaffoldColumnAttribute.cs
ScaffoldTableAttribute.cs
StringLengthAttribute.cs
UIHintAttribute.cs
ValidationAttribute.cs
ValidationException.cs: initial checkin. mostly stubs.

View File

@ -0,0 +1,118 @@
//
// CompareAttribute.cs
//
// Authors:
// Pablo Ruiz GarcĂ­a <pablo.ruiz@gmail.com>
//
// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
// Copyright (C) 2013 Pablo Ruiz GarcĂ­a
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_5
using System;
using System.Linq;
using System.Globalization;
using System.ComponentModel;
using System.Collections.Generic;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class CompareAttribute : ValidationAttribute
{
private const string DefaultErrorMessage = "'{0}' and '{1}' do not match.";
private const string NonExistingPropertyErrorMessage = "Could not find a property named {0}.";
private string _otherProperty;
private string _otherPropertyDisplayName;
public CompareAttribute (string otherProperty)
: base (() => DefaultErrorMessage)
{
if (string.IsNullOrEmpty (otherProperty))
throw new ArgumentNullException ("otherProperty");
_otherProperty = otherProperty;
}
public string OtherProperty { get { return _otherProperty; } }
public string OtherPropertyDisplayName { get { return _otherPropertyDisplayName; } }
public override bool RequiresValidationContext { get { return true; } }
private IEnumerable<Attribute> GetPropertyAttributes (Type type, string propertyName)
{
#if MOBILE
return TypeDescriptor.GetProperties (type).Find (propertyName, false).Attributes.OfType<Attribute> ();
#else
// Using AMTTDP seems the way to go to be able to relay on attributes declared
// by means of associated classes not directly decorating the property.
// See: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.associatedmetadatatypetypedescriptionprovider.aspx
return new AssociatedMetadataTypeTypeDescriptionProvider (type)
.GetTypeDescriptor (type)
.GetProperties ()
.Find (propertyName, false)
.Attributes.OfType<Attribute> ();
#endif
}
private void ResolveOtherPropertyDisplayName (ValidationContext context)
{
if (_otherPropertyDisplayName == null)
{
// NOTE: From my own tests, it seems MS.NET looksup displayName from various sources, what follows
// is a best guess from my on tests, however, I am probably missing some corner cases. (pruiz)
var attributes = GetPropertyAttributes (context.ObjectType, _otherProperty);
var displayAttr = attributes.FirstOrDefault (x => x is DisplayAttribute) as DisplayAttribute;
var displayNameAttr = attributes.FirstOrDefault (x => x is DisplayNameAttribute) as DisplayNameAttribute;
if (displayAttr != null) _otherPropertyDisplayName = displayAttr.GetName ();
else if (displayNameAttr != null) _otherPropertyDisplayName = displayNameAttr.DisplayName;
_otherPropertyDisplayName = _otherProperty;
}
}
public override string FormatErrorMessage (string name)
{
var oname = string.IsNullOrEmpty (_otherPropertyDisplayName) ? _otherProperty : _otherPropertyDisplayName;
return string.Format (ErrorMessageString, name, oname);
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var property = context.ObjectType.GetProperty (_otherProperty);
if (property == null) {
string message = string.Format (NonExistingPropertyErrorMessage, _otherProperty);
return new ValidationResult (message);
}
// XXX: Could not find a better place to call this, as this is
// the only place we have access to a ValidationContext. (pruiz)
ResolveOtherPropertyDisplayName (context);
return object.Equals (property.GetValue (context.ObjectInstance, null), value) ? null
: new ValidationResult (FormatErrorMessage (context.DisplayName));
}
}
}
#endif

View File

@ -0,0 +1,44 @@
//
// ConcurrencyCheckAttribute.cs
//
// Authors:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2010 Novell Inc. (http://novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
using System.Collections.Generic;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class ConcurrencyCheckAttribute : Attribute
{
public ConcurrencyCheckAttribute ()
{
}
}
}
#endif

View File

@ -0,0 +1,92 @@
//
// ControlParameters.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace System.ComponentModel.DataAnnotations
{
sealed class ControlParameters : IEquatable<ControlParameters>
{
Dictionary<string, object> dictionary;
readonly object[] parameters;
public ControlParameters (object[] parameters)
{
this.parameters = parameters;
}
public Dictionary<string, object> Dictionary {
get {
return dictionary ?? (dictionary = CreateDictionary ());
}
}
public bool Equals (ControlParameters other)
{
if (parameters == null || other.parameters == null)
return ReferenceEquals (parameters, other.parameters);
if (parameters.Length != other.parameters.Length)
return false;
try {
return Dictionary.OrderBy (l => l.Key).SequenceEqual (other.Dictionary.OrderBy (l => l.Key));
} catch (InvalidOperationException) {
return false;
}
}
Dictionary<string, object> CreateDictionary ()
{
if (parameters == null || parameters.Length == 0) {
return new Dictionary<string, object> (0);
}
if (parameters.Length % 2 != 0)
throw new InvalidOperationException ();
var dict = new Dictionary<string, object> ();
for (int i = 0; i < parameters.Length; ) {
var key = parameters [i++] as string;
if (key == null)
throw new InvalidOperationException ();
try {
dict.Add (key, parameters[i++]);
} catch (System.ArgumentException) {
throw new InvalidOperationException ();
}
}
return dict;
}
}
}

View File

@ -0,0 +1,75 @@
//
// CreditCardAttribute.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
// Pablo Ruiz GarcĂ­a <pablo.ruiz@gmail.com>
//
// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
// Copyright (C) 2013 Pablo Ruiz GarcĂ­a
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_5
using System;
using System.Linq;
using System.Globalization;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class CreditCardAttribute : DataTypeAttribute
{
private const string DefaultErrorMessage = "The {0} field is not a valid credit card number.";
public CreditCardAttribute ()
: base(DataType.CreditCard)
{
// XXX: There is no .ctor accepting Func<string> on DataTypeAttribute.. :?
base.ErrorMessage = DefaultErrorMessage;
}
public override bool IsValid(object value)
{
if (value == null)
return true;
if (string.IsNullOrEmpty(value as string))
return false;
// Remove any invalid characters..
var creditCardNumber = (value as string).Replace("-", "").Replace(" ", "");
if (creditCardNumber.Any (x => !Char.IsDigit (x)))
return false;
// Performan a Luhn-based check against credit card number.
//
// See: http://en.wikipedia.org/wiki/Luhn_algorithm
// See: http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers
return true;
}
}
}
#endif

View File

@ -0,0 +1,141 @@
//
// CustomValidationAttribute.cs
//
// Authors:
// Marek Habersack <grendel@twistedcode.net>
//
// Copyright (C) 2010-2011 Novell Inc. (http://novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
using System.Collections.Generic;
using System.Reflection;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true)]
public sealed class CustomValidationAttribute : ValidationAttribute
{
Tuple <string, Type> typeId;
MethodInfo validationMethod;
bool validationMethodChecked;
bool validationMethodSignatureValid;
int validationMethodParamCount;
public string Method { get; private set; }
public override object TypeId {
get { return typeId; }
}
public Type ValidatorType { get; private set; }
public CustomValidationAttribute (Type validatorType, string method)
{
this.ValidatorType = validatorType;
this.Method = method;
this.typeId = new Tuple <string, Type> (method, validatorType);
}
public override string FormatErrorMessage (string name)
{
ThrowIfAttributeNotWellFormed ();
return String.Format ("{0} is not valid.", name);
}
// LAMESPEC: MSDN doesn't document it at all, but corcompare shows it in the type
protected override ValidationResult IsValid (object value, ValidationContext validationContext)
{
ThrowIfAttributeNotWellFormed ();
object[] p;
if (validationMethodParamCount == 2)
p = new object [] {value, validationContext};
else
p = new object [] {value};
try {
return validationMethod.Invoke (null, p) as ValidationResult;
} catch (TargetInvocationException ex) {
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
void ThrowIfAttributeNotWellFormed ()
{
Type type = ValidatorType;
if (type == null)
throw new InvalidOperationException ("The CustomValidationAttribute.ValidatorType was not specified.");
if (type.IsNotPublic)
throw new InvalidOperationException (String.Format ("The custom validation type '{0}' must be public.", type.Name));
string method = Method;
if (String.IsNullOrEmpty (method))
throw new InvalidOperationException ("The CustomValidationAttribute.Method was not specified.");
if (validationMethod == null) {
if (!validationMethodChecked) {
validationMethod = type.GetMethod (method, BindingFlags.Public | BindingFlags.Static);
validationMethodChecked = true;
}
if (validationMethod == null)
throw new InvalidOperationException (
String.Format ("The CustomValidationAttribute method '{0}' does not exist in type '{1}' or is not public and static.",
method, type.Name));
if (!typeof (ValidationResult).IsAssignableFrom (validationMethod.ReturnType))
throw new InvalidOperationException (String.Format ("The CustomValidationAttribute method '{0}' in type '{1}' must return System.ComponentModel.DataAnnotations.ValidationResult. Use System.ComponentModel.DataAnnotations.ValidationResult.Success to represent success.", method, type.Name));
validationMethodSignatureValid = true;
ParameterInfo[] parameters = validationMethod.GetParameters ();
if (parameters == null)
validationMethodSignatureValid = false;
else {
validationMethodParamCount = parameters.Length;
switch (validationMethodParamCount) {
case 1:
break;
case 2:
if (parameters [1].ParameterType != typeof (ValidationContext))
validationMethodSignatureValid = false;
break;
default:
validationMethodSignatureValid = false;
break;
}
}
}
if (!validationMethodSignatureValid)
throw new InvalidOperationException (String.Format ("The CustomValidationAttribute method '{0}' in type '{1}' must match the expected signature: public static ValidationResult MethodTwo(object value, ValidationContext context). The value can be strongly typed. The ValidationContext parameter is optional.", method, type.Name));
}
}
}
#endif

View File

@ -0,0 +1,57 @@
//
// DataType.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008-2011 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.ComponentModel.DataAnnotations
{
public enum DataType
{
Custom,
DateTime,
Date,
Time,
Duration,
PhoneNumber,
Currency,
Text,
Html,
MultilineText,
EmailAddress,
Password,
Url,
#if NET_4_0
ImageUrl,
#endif
#if NET_4_5
CreditCard,
PostalCode,
Upload
#endif
}
}

View File

@ -0,0 +1,109 @@
//
// DataTypeAttribute.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
// Pablo Ruiz GarcĂ­a <pablo.ruiz@gmail.com>
//
// Copyright (C) 2008 Novell Inc. http://novell.com
// Copyright (C) 2013 Pablo Ruiz GarcĂ­a
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
namespace System.ComponentModel.DataAnnotations
{
#if NET_4_0
[AttributeUsage (AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
#else
[AttributeUsage (AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = false)]
#endif
public class DataTypeAttribute : ValidationAttribute
{
public DataTypeAttribute (DataType dataType)
{
DataType = dataType;
DisplayFormatAttribute displayFormat;
switch (dataType) {
case DataType.Time:
displayFormat = new DisplayFormatAttribute ();
displayFormat.ApplyFormatInEditMode = true;
displayFormat.ConvertEmptyStringToNull = true;
displayFormat.DataFormatString = "{0:t}";
#if NET_4_0
displayFormat.HtmlEncode = true;
#endif
break;
case DataType.Date:
displayFormat = new DisplayFormatAttribute ();
displayFormat.ApplyFormatInEditMode = true;
displayFormat.ConvertEmptyStringToNull = true;
displayFormat.DataFormatString = "{0:d}";
#if NET_4_0
displayFormat.HtmlEncode = true;
#endif
break;
case DataType.Currency:
displayFormat = new DisplayFormatAttribute ();
displayFormat.ApplyFormatInEditMode = false;
displayFormat.ConvertEmptyStringToNull = true;
displayFormat.DataFormatString = "{0:C}";
#if NET_4_0
displayFormat.HtmlEncode = true;
#endif
break;
default:
displayFormat = null;
break;
}
DisplayFormat = displayFormat;
}
public DataTypeAttribute (string customDataType)
{
CustomDataType = customDataType;
}
public string CustomDataType { get; private set; }
public DataType DataType { get; private set; }
public DisplayFormatAttribute DisplayFormat { get; protected set; }
public virtual string GetDataTypeName ()
{
DataType dt = DataType;
if (dt == DataType.Custom)
return CustomDataType;
return dt.ToString ();
}
public override bool IsValid (object value)
{
// Returns alwasy true
// See: http://msdn.microsoft.com/en-us/library/cc679235.aspx
return true;
}
}
}

View File

@ -0,0 +1,160 @@
//
// DisplayAttribute.cs
//
// Author:
// David Stone <david@gixug.com>
//
// Copyright (C) 2010 David Stone
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
namespace System.ComponentModel.DataAnnotations
{
#if NET_4_0
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = false)]
public sealed class DisplayAttribute : Attribute
{
public Type ResourceType { get; set; }
public string Description { get; set; }
public string GroupName { get; set; }
public string Name { get; set; }
public string ShortName { get; set; }
public string Prompt { get; set; }
const string property_not_set_message = "The {0} property has not been set. Use the Get{0} method to get the value.";
const string localization_failed_message = "Cannot retrieve property '{0}' because localization failed. Type '{1} is not public or does not contain a public static string property with the name '{2}'.";
bool? _autoGenerateField;
public bool AutoGenerateField {
get {
if (!_autoGenerateField.HasValue) {
throw new InvalidOperationException (string.Format (property_not_set_message, "AutoGenerateField"));
}
return _autoGenerateField.Value;
}
set { _autoGenerateField = value; }
}
bool? _autoGenerateFilter;
public bool AutoGenerateFilter {
get {
if (_autoGenerateFilter == null) {
throw new InvalidOperationException (string.Format (property_not_set_message, "AutoGenerateFilter"));
}
return _autoGenerateFilter.Value;
}
set { _autoGenerateFilter = value; }
}
int? _order;
public int Order {
get {
if (_order == null)
throw new InvalidOperationException (string.Format (property_not_set_message, "Order"));
return _order.Value;
}
set { _order = value; }
}
private string GetLocalizedString (string propertyName, string key)
{
// If we don't have a resource or a key, go ahead and fall back on the key
if (ResourceType == null || key == null)
return key;
var property = ResourceType.GetProperty (key);
// Strings are only valid if they are public static strings
var isValid = false;
if (ResourceType.IsVisible && property != null && property.PropertyType == typeof(string)) {
var getter = property.GetGetMethod ();
// Gotta have a public static getter on the property
if (getter != null && getter.IsStatic && getter.IsPublic) {
isValid = true;
}
}
// If it's not valid, go ahead and throw an InvalidOperationException
if (!isValid) {
var message = string.Format (localization_failed_message, propertyName, ResourceType.ToString (), key);
throw new InvalidOperationException (message);
}
return (string)property.GetValue (null, null);
}
#region Consumer Methods
public bool? GetAutoGenerateField ()
{
return _autoGenerateField;
}
public bool? GetAutoGenerateFilter ()
{
return _autoGenerateFilter;
}
public int? GetOrder ()
{
return _order;
}
public string GetName ()
{
return GetLocalizedString ("Name", Name);
}
public string GetShortName ()
{
// Short name falls back on Name if the short name isn't set
return GetLocalizedString ("ShortName", ShortName) ?? GetName ();
}
public string GetDescription ()
{
return GetLocalizedString ("Description", Description);
}
public string GetPrompt ()
{
return GetLocalizedString ("Prompt", Prompt);
}
public string GetGroupName ()
{
return GetLocalizedString ("GroupName", GroupName);
}
#endregion
}
#endif
}

View File

@ -0,0 +1,59 @@
//
// DisplayColumnAttribute.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class DisplayColumnAttribute : Attribute
{
public DisplayColumnAttribute (string displayColumn)
: this (displayColumn, null)
{
}
public DisplayColumnAttribute (string displayColumn, string sortColumn)
: this (displayColumn, sortColumn, false)
{
}
public DisplayColumnAttribute (string displayColumn, string sortColumn, bool sortDescending)
{
DisplayColumn = displayColumn;
SortColumn = sortColumn;
SortDescending = sortDescending;
}
public string DisplayColumn { get; private set; }
public string SortColumn { get; private set; }
public bool SortDescending { get; private set; }
}
}

View File

@ -0,0 +1,46 @@
//
// DisplayFormatAttribute.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell Inc. http://novell.com
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = false)]
public class DisplayFormatAttribute : Attribute
{
public bool ApplyFormatInEditMode { get; set; }
public bool ConvertEmptyStringToNull { get; set; }
public string DataFormatString { get; set; }
public string NullDisplayText { get; set; }
#if NET_4_0
public bool HtmlEncode { get; set; }
#endif
}
}

View File

@ -0,0 +1,48 @@
//
// EditableAttribute.cs
//
// Authors:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2010 Novell Inc. (http://novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
using System.Collections.Generic;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class EditableAttribute : Attribute
{
public bool AllowEdit { get; private set; }
public bool AllowInitialValue { get; set; }
public EditableAttribute (bool allowEdit)
{
this.AllowEdit = allowEdit;
}
}
}
#endif

View File

@ -0,0 +1,313 @@
//
// EmailAddressAttribute.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
// Pablo Ruiz GarcĂ­a <pablo.ruiz@gmail.com>
//
// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
// Copyright (C) 2013 Pablo Ruiz GarcĂ­a
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_5
using System;
using System.Globalization;
using System.Text.RegularExpressions;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class EmailAddressAttribute : DataTypeAttribute
{
private const string DefaultErrorMessage = "The {0} field is not a valid e-mail address.";
const string AtomCharacters = "!#$%&'*+-/=?^_`{|}~";
static bool IsLetterOrDigit (char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}
static bool IsAtom (char c)
{
return IsLetterOrDigit (c) || AtomCharacters.IndexOf (c) != -1;
}
static bool IsDomain (char c)
{
return IsLetterOrDigit (c) || c == '-';
}
static bool SkipAtom (string text, ref int index)
{
int startIndex = index;
while (index < text.Length && IsAtom (text[index]))
index++;
return index > startIndex;
}
static bool SkipSubDomain (string text, ref int index)
{
if (!IsDomain (text[index]) || text[index] == '-')
return false;
index++;
while (index < text.Length && IsDomain (text[index]))
index++;
return true;
}
static bool SkipDomain (string text, ref int index)
{
if (!SkipSubDomain (text, ref index))
return false;
while (index < text.Length && text[index] == '.') {
index++;
if (index == text.Length)
return false;
if (!SkipSubDomain (text, ref index))
return false;
}
return true;
}
static bool SkipQuoted (string text, ref int index)
{
bool escaped = false;
// skip over leading '"'
index++;
while (index < text.Length) {
if (text[index] == (byte) '\\') {
escaped = !escaped;
} else if (!escaped) {
if (text[index] == (byte) '"')
break;
} else {
escaped = false;
}
index++;
}
if (index >= text.Length || text[index] != (byte) '"')
return false;
index++;
return true;
}
static bool SkipWord (string text, ref int index)
{
if (text[index] == (byte) '"')
return SkipQuoted (text, ref index);
return SkipAtom (text, ref index);
}
static bool SkipIPv4Literal (string text, ref int index)
{
int groups = 0;
while (index < text.Length && groups < 4) {
int startIndex = index;
int value = 0;
while (index < text.Length && text[index] >= '0' && text[index] <= '9') {
value = (value * 10) + (text[index] - '0');
index++;
}
if (index == startIndex || index - startIndex > 3 || value > 255)
return false;
groups++;
if (groups < 4 && index < text.Length && text[index] == '.')
index++;
}
return groups == 4;
}
static bool IsHexDigit (char c)
{
return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
}
// This needs to handle the following forms:
//
// IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
// IPv6-hex = 1*4HEXDIG
// IPv6-full = IPv6-hex 7(":" IPv6-hex)
// IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::" [IPv6-hex *5(":" IPv6-hex)]
// ; The "::" represents at least 2 16-bit groups of zeros
// ; No more than 6 groups in addition to the "::" may be
// ; present
// IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
// IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
// [IPv6-hex *3(":" IPv6-hex) ":"] IPv4-address-literal
// ; The "::" represents at least 2 16-bit groups of zeros
// ; No more than 4 groups in addition to the "::" and
// ; IPv4-address-literal may be present
static bool SkipIPv6Literal (string text, ref int index)
{
bool compact = false;
int colons = 0;
while (index < text.Length) {
int startIndex = index;
while (index < text.Length && IsHexDigit (text[index]))
index++;
if (index >= text.Length)
break;
if (index > startIndex && colons > 2 && text[index] == '.') {
// IPv6v4
index = startIndex;
if (!SkipIPv4Literal (text, ref index))
return false;
break;
}
int count = index - startIndex;
if (count > 4)
return false;
if (text[index] != ':')
break;
startIndex = index;
while (index < text.Length && text[index] == ':')
index++;
count = index - startIndex;
if (count > 2)
return false;
if (count == 2) {
if (compact)
return false;
compact = true;
colons += 2;
} else {
colons++;
}
}
if (colons < 2)
return false;
if (compact)
return colons < 6;
return colons < 7;
}
static bool Validate (string email)
{
int index = 0;
if (email.Length == 0)
return false;
if (!SkipWord (email, ref index) || index >= email.Length)
return false;
while (index < email.Length && email[index] == '.') {
index++;
if (!SkipWord (email, ref index) || index >= email.Length)
return false;
}
if (index + 1 >= email.Length || email[index++] != '@')
return false;
if (email[index] != '[') {
// domain
if (!SkipDomain (email, ref index))
return false;
return index == email.Length;
}
// address literal
index++;
// we need at least 8 more characters
if (index + 8 >= email.Length)
return false;
var ipv6 = email.Substring (index, 5);
if (ipv6.ToLowerInvariant () == "ipv6:") {
index += "IPv6:".Length;
if (!SkipIPv6Literal (email, ref index))
return false;
} else {
if (!SkipIPv4Literal (email, ref index))
return false;
}
if (index >= email.Length || email[index++] != ']')
return false;
return index == email.Length;
}
public EmailAddressAttribute ()
: base(DataType.EmailAddress)
{
// XXX: There is no .ctor accepting Func<string> on DataTypeAttribute.. :?
base.ErrorMessage = DefaultErrorMessage;
}
public override bool IsValid(object value)
{
if (value == null)
return true;
string email = value as string;
if (email == null)
return false;
return Validate (email);
}
}
}
#endif

View File

@ -0,0 +1,117 @@
//
// EnumDataTypeAttribute.cs
//
// Authors:
// Marek Habersack <mhabersack@novell.com>
//
// Copyright (C) 2010 Novell Inc. (http://novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class EnumDataTypeAttribute : DataTypeAttribute
{
public Type EnumType { get; private set; }
public EnumDataTypeAttribute (Type enumType)
: base (DataType.Custom)
{
this.EnumType = enumType;
}
public override bool IsValid (object value)
{
Type type = EnumType;
if (!type.IsEnum)
throw new InvalidOperationException (
String.Format ("The type '{0}' needs to represent an enumeration type.", type.FullName)
);
if (value == null)
return true;
Type valueType = value.GetType ();
if (valueType.IsEnum && valueType != type)
return false;
string s = value as string;
if (s != null && s.Length == 0)
return true;
if (s != null && (valueType == typeof (bool) || valueType == typeof (char) || valueType == typeof (float)))
return false;
object o;
if (s != null) {
try {
o = Enum.Parse (type, s);
} catch {
return false;
}
} else if (valueType.IsEnum)
o = value;
else {
try {
o = Enum.ToObject (type, value);
} catch {
return false;
}
}
object[] attrs = type.GetCustomAttributes (typeof (FlagsAttribute), true);
if (attrs != null && attrs.Length > 0) {
string sval = Convert.ChangeType (o, Enum.GetUnderlyingType (type), CultureInfo.InvariantCulture).ToString ();
// This looks weird, but what happens here is that if we have a
// mismatch, the above type change will make sval equal o.ToString
// () and if we have a match, then sval will be string
// representation of the enum member's value. So, if we have an
// enum:
//
// [Flags]
// enum Test
// {
// One = 1,
// Two = 2
// }
//
// And the passed value was 3, then o.ToString () == "One, Two" and
// sval == "3". If the passed value was 33, though, o.ToString () ==
// "33" and sval == "33" - thus we DON'T have a match.
return !sval.Equals (o.ToString ());
}
return Enum.IsDefined (type, o);
}
}
}
#endif

View File

@ -0,0 +1,92 @@
//
// FileExtensionAttribute.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
// Pablo Ruiz GarcĂ­a <pablo.ruiz@gmail.com>
//
// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
// Copyright (C) 2013 Pablo Ruiz GarcĂ­a
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_5
using System;
using System.Linq;
using System.Globalization;
using System.Text.RegularExpressions;
namespace System.ComponentModel.DataAnnotations
{
// See: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.fileextensionsattribute.aspx
[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class FileExtensionsAttribute : DataTypeAttribute
{
private const string DefaultErrorMessage = "The {0} field only accepts files with the following extensions: {1}.";
private const string DefaultExtensions = "png,jpg,jpeg,gif";
public FileExtensionsAttribute ()
: base (DataType.Upload)
{
// XXX: There is no .ctor accepting Func<string> on DataTypeAttribute.. :?
base.ErrorMessage = DefaultErrorMessage;
this.Extensions = DefaultExtensions;
}
public string Extensions { get; set; }
private string[] GetExtensionList ()
{
return (Extensions ?? "").Split (',');
}
private string GetExtension (string filename)
{
var parts = filename.Split ('.');
return parts.Length > 0 ? parts [parts.Length - 1] : "";
}
public override string FormatErrorMessage (string name)
{
var extensions = GetExtensionList().Aggregate ((cur, next) => cur + ", " + next);
return string.Format (ErrorMessageString, name, extensions);
}
public override bool IsValid(object value)
{
if (value == null)
return true;
if (value is string)
{
var str = value as string;
var ext = GetExtension (str);
return GetExtensionList ().Any (x => string.Equals (x, ext, StringComparison.InvariantCultureIgnoreCase));
}
return false;
}
}
}
#endif

View File

@ -0,0 +1,93 @@
//
// FilterUIHintAttribute.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System.Runtime.CompilerServices;
using System.Collections.Generic;
namespace System.ComponentModel.DataAnnotations
{
[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class FilterUIHintAttribute : Attribute
{
readonly ControlParameters controlParameters;
public FilterUIHintAttribute (string filterUIHint)
: this (filterUIHint, null, null)
{
}
public FilterUIHintAttribute (string filterUIHint, string presentationLayer)
: this (filterUIHint, presentationLayer, null)
{
}
public FilterUIHintAttribute (string filterUIHint, string presentationLayer, params object[] controlParameters)
{
FilterUIHint = filterUIHint;
PresentationLayer = presentationLayer;
this.controlParameters = new ControlParameters (controlParameters);
}
public IDictionary<string, object> ControlParameters {
get {
return controlParameters.Dictionary;
}
}
public string FilterUIHint { get; private set; }
public string PresentationLayer { get; private set; }
public override object TypeId {
get {
return this;
}
}
public override int GetHashCode ()
{
return RuntimeHelpers.GetHashCode (FilterUIHint) ^
RuntimeHelpers.GetHashCode (PresentationLayer);
}
public override bool Equals (object obj)
{
var fha = obj as FilterUIHintAttribute;
if (fha == null)
return false;
return fha.FilterUIHint == FilterUIHint &&
fha.PresentationLayer == PresentationLayer &&
fha.controlParameters.Equals (controlParameters);
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More