/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
/**************************************************************************\
Copyright Microsoft Corporation. All Rights Reserved.
\**************************************************************************/
// This file contains general utilities to aid in development.
// Classes here generally shouldn't be exposed publicly since
// they're not particular to any library functionality.
// Because the classes here are internal, it's likely this file
// might be included in multiple assemblies.
namespace Standard
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Threading;
///
/// A static class for retail validated assertions.
/// Instead of breaking into the debugger an exception is thrown.
///
internal static class Verify
{
///
/// Ensure that the current thread's apartment state is what's expected.
///
///
/// The required apartment state for the current thread.
///
///
/// The message string for the exception to be thrown if the state is invalid.
///
///
/// Thrown if the calling thread's apartment state is not the same as the requiredState.
///
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsApartmentState( ApartmentState requiredState, string message )
{
if( Thread.CurrentThread.GetApartmentState() != requiredState )
{
throw new InvalidOperationException( message );
}
}
///
/// Ensure that an argument is neither null nor empty.
///
/// The string to validate.
/// The name of the parameter that will be presented if an exception is thrown.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[SuppressMessage( "Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength" )]
[DebuggerStepThrough]
public static void IsNeitherNullNorEmpty( string value, string name )
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty( name );
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty.";
if( null == value )
{
throw new ArgumentNullException( name, errorMessage );
}
if( "" == value )
{
throw new ArgumentException( errorMessage, name );
}
}
///
/// Ensure that an argument is neither null nor does it consist only of whitespace.
///
/// The string to validate.
/// The name of the parameter that will be presented if an exception is thrown.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[SuppressMessage( "Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength" )]
[DebuggerStepThrough]
public static void IsNeitherNullNorWhitespace( string value, string name )
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty( name );
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters.";
if( null == value )
{
throw new ArgumentNullException( name, errorMessage );
}
if( "" == value.Trim() )
{
throw new ArgumentException( errorMessage, name );
}
}
/// Verifies that an argument is not null.
/// Type of the object to validate. Must be a class.
/// The object to validate.
/// The name of the parameter that will be presented if an exception is thrown.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsNotDefault( T obj, string name ) where T : struct
{
if( default( T ).Equals( obj ) )
{
throw new ArgumentException( "The parameter must not be the default value.", name );
}
}
/// Verifies that an argument is not null.
/// Type of the object to validate. Must be a class.
/// The object to validate.
/// The name of the parameter that will be presented if an exception is thrown.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsNotNull( T obj, string name ) where T : class
{
if( null == obj )
{
throw new ArgumentNullException( name );
}
}
/// Verifies that an argument is null.
/// Type of the object to validate. Must be a class.
/// The object to validate.
/// The name of the parameter that will be presented if an exception is thrown.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsNull( T obj, string name ) where T : class
{
if( null != obj )
{
throw new ArgumentException( "The parameter must be null.", name );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void PropertyIsNotNull( T obj, string name ) where T : class
{
if( null == obj )
{
throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, "The property {0} cannot be null at this time.", name ) );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void PropertyIsNull( T obj, string name ) where T : class
{
if( null != obj )
{
throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, "The property {0} must be null at this time.", name ) );
}
}
///
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
///
/// The statement to be verified as true.
/// Name of the parameter to include in the ArgumentException.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsTrue( bool statement, string name )
{
if( !statement )
{
throw new ArgumentException( "", name );
}
}
///
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
///
/// The statement to be verified as true.
/// Name of the parameter to include in the ArgumentException.
/// The message to include in the ArgumentException.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void IsTrue( bool statement, string name, string message )
{
if( !statement )
{
throw new ArgumentException( message, name );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void AreEqual( T expected, T actual, string parameterName, string message )
{
if( null == expected )
{
// Two nulls are considered equal, regardless of type semantics.
if( null != actual && !actual.Equals( expected ) )
{
throw new ArgumentException( message, parameterName );
}
}
else if( !expected.Equals( actual ) )
{
throw new ArgumentException( message, parameterName );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void AreNotEqual( T notExpected, T actual, string parameterName, string message )
{
if( null == notExpected )
{
// Two nulls are considered equal, regardless of type semantics.
if( null == actual || actual.Equals( notExpected ) )
{
throw new ArgumentException( message, parameterName );
}
}
else if( notExpected.Equals( actual ) )
{
throw new ArgumentException( message, parameterName );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void UriIsAbsolute( Uri uri, string parameterName )
{
Verify.IsNotNull( uri, parameterName );
if( !uri.IsAbsoluteUri )
{
throw new ArgumentException( "The URI must be absolute.", parameterName );
}
}
///
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
///
/// The lower bound inclusive value.
/// The value to verify.
/// The upper bound exclusive value.
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void BoundedInteger( int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName )
{
if( value < lowerBoundInclusive || value >= upperBoundExclusive )
{
throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The integer value must be bounded with [{0}, {1})", lowerBoundInclusive, upperBoundExclusive ), parameterName );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void BoundedDoubleInc( double lowerBoundInclusive, double value, double upperBoundInclusive, string message, string parameter )
{
if( value < lowerBoundInclusive || value > upperBoundInclusive )
{
throw new ArgumentException( message, parameter );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void TypeSupportsInterface( Type type, Type interfaceType, string parameterName )
{
Assert.IsNeitherNullNorEmpty( parameterName );
Verify.IsNotNull( type, "type" );
Verify.IsNotNull( interfaceType, "interfaceType" );
if( type.GetInterface( interfaceType.Name ) == null )
{
throw new ArgumentException( "The type of this parameter does not support a required interface", parameterName );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
public static void FileExists( string filePath, string parameterName )
{
Verify.IsNeitherNullNorEmpty( filePath, parameterName );
if( !File.Exists( filePath ) )
{
throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "No file exists at \"{0}\"", filePath ), parameterName );
}
}
[SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
[DebuggerStepThrough]
internal static void ImplementsInterface( object parameter, Type interfaceType, string parameterName )
{
Assert.IsNotNull( parameter );
Assert.IsNotNull( interfaceType );
Assert.IsTrue( interfaceType.IsInterface );
bool isImplemented = false;
foreach( var ifaceType in parameter.GetType().GetInterfaces() )
{
if( ifaceType == interfaceType )
{
isImplemented = true;
break;
}
}
if( !isImplemented )
{
throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString() ), parameterName );
}
}
}
}