///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections.Generic;
using JetBrains.Build.Omea.Infra;
using Microsoft.Build.Framework;
namespace JetBrains.Build.Omea.Util
{
///
/// Implements a property bag that is marshalled by a reference.
///
public class Bag : MarshalByRefObject
{
#region Data
private readonly Dictionary myStore = new Dictionary();
#endregion
#region Attributes
///
/// Gets the underlying store.
///
public Dictionary Store
{
get
{
return myStore;
}
}
#endregion
#region Operations
///
/// Checks whether the value is present in the bag.
/// The type parameter checks the value type.
///
public bool Contains(AttributeName name)
{
#pragma warning disable CompareNonConstrainedGenericWithNull
return TryGet(name) != null;
#pragma warning restore CompareNonConstrainedGenericWithNull
}
///
/// Gets a value from the bag, throws on an error.
///
public T Get(AttributeName name)
{
object value;
if((!Store.TryGetValue(name, out value)) || (value == null))
throw new InvalidOperationException(string.Format("The “{0}” task input parameter must be specified.", name));
return DynamicCast(name, value);
}
///
/// Gets a value from the bag, or default if it's missing.
///
public T Get(AttributeName name, T defaultvalue)
{
object value;
if((Store.TryGetValue(name, out value)) || (value == null))
return DynamicCast(name, value);
return defaultvalue;
}
///
/// Gets a string value from the bag, throws on an error.
/// Has a special treatment for the TaskItem elements.
///
public string GetString(AttributeName attribute)
{
object value;
if((!Store.TryGetValue(attribute, out value)) || (value == null))
{
if(value == null)
throw new InvalidOperationException(string.Format("The “{0}” task input parameter must be specified.", attribute));
}
if(value is ITaskItem)
return ((ITaskItem)value).ItemSpec;
if(value is string)
return (string)value;
throw new InvalidOperationException(string.Format("The “{0}” task input parameter must be a string.", attribute));
}
///
/// Assigns a new value into the property bag.
///
public void Set(AttributeName name, T value)
{
TryGet(name); // This ensures the value type does not change in the cell
Store[name] = value;
}
///
/// Tries to get the value, returns a default value if not available.
/// Throws only on value type mismatch.
///
public T TryGet(AttributeName name)
{
object value;
return Store.TryGetValue(name, out value) ? DynamicCast(name, value) : default(T);
}
#endregion
#region Implementation
///
/// Casts the value to the given type.
/// Throws a detailed message if that is not possible.
///
private static T DynamicCast(AttributeName name, object value)
{
if(!(value is T))
throw new InvalidOperationException(string.Format("The “{0}” task input parameter must be of type “{1}”.", name, typeof(T).AssemblyQualifiedName));
return (T)value;
}
#endregion
}
}