Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@novell.com>2010-03-17 15:30:51 +0300
committerLluis Sanchez <lluis@novell.com>2010-03-17 15:30:51 +0300
commit3352c438c92957c57ce5818d2b410b9d761076f5 (patch)
tree0fdce565f42e17cbc1675f014da34527b99e0fa5 /main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs
parentde8a39a96737efd04aabafb4cc27c546061c90f5 (diff)
parent585086f0ea0a49166046bb8f48d2def87907d0e0 (diff)
Merged MD.Projects into MD.Core, and MD.Projects.Gui, MD.Core.Gui and MD.Components into MD.Ide.
svn path=/trunk/monodevelop/; revision=153728
Diffstat (limited to 'main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs287
1 files changed, 287 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs
new file mode 100644
index 0000000000..c5c778e8c1
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyContainer.cs
@@ -0,0 +1,287 @@
+//
+// PolicyContainer.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.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.Collections.Generic;
+
+namespace MonoDevelop.Projects.Policies
+{
+ /// <summary>
+ /// A set of policies. Policies are identified by type.
+ /// </summary>
+ public abstract class PolicyContainer
+ {
+ internal PolicyDictionary policies;
+
+ /// <summary>
+ /// Returns true if there isn't any policy defined.
+ /// </summary>
+ public bool IsEmpty {
+ get { return policies == null || policies.Count == 0; }
+ }
+
+ /// <summary>
+ /// The Get methods return policies taking into account inheritance. If a policy
+ /// can't be found it may return null, but never an 'undefined' policy.
+ /// </summary>
+ /// <returns>
+ /// The policy of the given type, or null if not found.
+ /// </returns>
+ public T Get<T> () where T : class, IEquatable<T>, new ()
+ {
+ if (policies != null) {
+ object policy;
+ if (policies.TryGetValue (typeof(T), null, out policy)) {
+ if (!PolicyService.IsUndefinedPolicy (policy))
+ return (T)policy;
+ else if (InheritDefaultPolicies)
+ return PolicyService.GetDefaultPolicy<T> ();
+ else
+ return null;
+ }
+ }
+ if (!InheritDefaultPolicies)
+ return null;
+ else if (IsRoot)
+ return PolicyService.GetDefaultPolicy<T> ();
+ else
+ return ParentPolicies.Get<T> ();
+ }
+
+ public T Get<T> (string scope) where T : class, IEquatable<T>, new ()
+ {
+ return Get<T> (new string[] { scope });
+ }
+
+ public T Get<T> (IEnumerable<string> scopes) where T : class, IEquatable<T>, new ()
+ {
+ // The search is done vertically, looking first at the parents
+ foreach (string scope in scopes) {
+ PolicyContainer currentBag = this;
+ while (currentBag != null) {
+ if (currentBag.DirectHas<T> (scope)) {
+ T pol = currentBag.DirectGet<T> (scope);
+ if (!PolicyService.IsUndefinedPolicy (pol))
+ return pol;
+ // If the bag has the policy (Has<> returns true) but the policy is undefined,
+ // then we have to keep looking using the base scopes.
+ // We start looking from the original bag, using the new scope.
+ break;
+ } else
+ currentBag = currentBag.ParentPolicies;
+ }
+ }
+ if (InheritDefaultPolicies)
+ return PolicyService.GetDefaultPolicy<T>(scopes);
+ else
+ return null;
+ }
+
+ public void Set<T> (T value) where T : class, IEquatable<T>, new ()
+ {
+ Set (value, null);
+ }
+
+ public void Set<T> (T value, string scope) where T : class, IEquatable<T>, new ()
+ {
+ CheckReadOnly ();
+ PolicyKey key = new PolicyKey (typeof(T), scope);
+ System.Diagnostics.Debug.Assert (key.Scope == scope);
+
+ if (policies == null) {
+ policies = new PolicyDictionary ();
+ } else if (value != null) {
+ object oldVal = null;
+ policies.TryGetValue (key, out oldVal);
+ if (oldVal != null && ((IEquatable<T>)oldVal).Equals (value))
+ return;
+ }
+
+ policies[key] = value;
+ OnPolicyChanged (key.PolicyType, key.Scope);
+ }
+
+ internal void InternalSet (Type t, string scope, object ob)
+ {
+ PolicyKey key = new PolicyKey (t, scope);
+ if (policies == null)
+ policies = new PolicyDictionary ();
+ policies[key] = ob;
+ OnPolicyChanged (key.PolicyType, key.Scope);
+ }
+
+ public bool Remove<T> () where T : class, IEquatable<T>, new ()
+ {
+ CheckReadOnly ();
+ return Remove<T> (null);
+ }
+
+ public bool Remove<T> (string scope) where T : class, IEquatable<T>, new ()
+ {
+ CheckReadOnly ();
+ return InternalRemove (typeof(T), scope);
+ }
+
+ internal bool InternalRemove (Type type, string scope)
+ {
+ if (policies != null) {
+ if (policies.Remove (new PolicyKey (type, scope))) {
+ OnPolicyChanged (type, scope);
+ if (policies.Count == 0)
+ policies = null;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public IEnumerable<string> GetScopes<T> ()
+ {
+ foreach (PolicyKey pk in policies.Keys) {
+ if (pk.PolicyType == typeof(T))
+ yield return pk.Scope;
+ }
+ }
+
+ public IEnumerable<ScopedPolicy<T>> GetScoped<T> () where T : class, IEquatable<T>, new ()
+ {
+ if (policies == null)
+ yield break;
+
+ foreach (KeyValuePair<PolicyKey,object> pinfo in policies) {
+ if (pinfo.Key.PolicyType == typeof(T))
+ yield return new ScopedPolicy<T> ((T)pinfo.Value, pinfo.Key.Scope);
+ }
+ T pol = Get<T> ();
+ if (pol != null && !PolicyService.IsUndefinedPolicy (pol))
+ yield return new ScopedPolicy<T> (pol, null);
+ }
+
+ internal IEnumerable<ScopedPolicy> GetScoped (Type t)
+ {
+ foreach (KeyValuePair<PolicyKey,object> pinfo in policies) {
+ if (pinfo.Key.PolicyType == t)
+ yield return new ScopedPolicy (t, pinfo.Value, pinfo.Key.Scope);
+ }
+ object pol = Get (t);
+ if (pol != null)
+ yield return new ScopedPolicy (t, pol, null);
+ }
+
+ internal object Get (Type type)
+ {
+ return Get (type, (string) null);
+ }
+
+ internal object Get (Type type, string scope)
+ {
+ if (policies == null)
+ return null;
+ object o;
+ if (policies.TryGetValue (type, scope, out o)) {
+ if (PolicyService.IsUndefinedPolicy (o))
+ return null;
+ }
+ return o;
+ }
+
+ public abstract bool IsRoot { get; }
+
+ public event EventHandler<PolicyChangedEventArgs> PolicyChanged;
+
+ #region Methods to be used for fine grained management of policies
+
+ // The DirectGet set of methods returns policies directly stored in the container,
+ // ignoring inherited policies. Those methods can return undefined policies,
+ // so return values have to be checked with PolicyService.IsUndefinedPolicy
+
+ internal PolicyDictionary Policies { get { return policies; } }
+
+ public T DirectGet<T> () where T : class, IEquatable<T>, new ()
+ {
+ return DirectGet<T> (null);
+ }
+
+ public T DirectGet<T> (string scope) where T : class, IEquatable<T>, new ()
+ {
+ if (policies != null) {
+ object policy;
+ if (policies.TryGetValue (typeof(T), scope, out policy))
+ return (T) policy;
+ }
+ return null;
+ }
+
+ public bool DirectHas<T> ()
+ {
+ return DirectHas<T> ((string)null);
+ }
+
+ public bool DirectHas<T> (string scope)
+ {
+ return policies != null && policies.ContainsKey (new PolicyKey (typeof(T), scope));
+ }
+
+ public bool DirectHas<T> (IEnumerable<string> scopes)
+ {
+ foreach (string scope in scopes) {
+ if (DirectHas<T> (scope))
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// The set of policies from which inherit policies when not found in this container
+ /// </summary>
+ public abstract PolicyContainer ParentPolicies { get; }
+
+ #endregion
+
+ /// <summary>
+ /// When set to true, the container will return a default policy when requesting a
+ /// policy object that is not defined in the container.
+ /// </summary>
+ protected abstract bool InheritDefaultPolicies { get; }
+
+ protected virtual void OnPolicyChanged (Type policyType, string scope)
+ {
+ if (PolicyChanged != null)
+ PolicyChanged (this, new PolicyChangedEventArgs (policyType, scope));
+ }
+
+ public virtual bool ReadOnly {
+ get;
+ internal set;
+ }
+
+ void CheckReadOnly ()
+ {
+ if (ReadOnly)
+ throw new InvalidOperationException ("This PolicyContainer can't be modified");
+ }
+ }
+}