/// /// 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 } }