1 // System.Security.Policy.CodeGroup
4 // Nick Drochak (ndrochak@gol.com)
6 // (C) 2001 Nick Drochak, All rights reserved.
8 using System.Security.Policy;
9 using System.Security.Permissions;
10 using System.Collections;
11 using System; // for MonoTODO attribute
13 namespace System.Security.Policy {
16 public abstract class CodeGroup {
17 PolicyStatement m_policy = null;
18 IMembershipCondition m_membershipCondition = null;
19 string m_description = null;
21 ArrayList m_children = new ArrayList();
24 public CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
26 if (null == membershipCondition)
27 throw new ArgumentNullException("Value cannot be null.");
30 m_membershipCondition = membershipCondition;
33 // for PolicyLevel (to avoid validation duplication)
34 internal CodeGroup (SecurityElement e)
41 public abstract CodeGroup Copy();
42 public abstract string MergeLogic {get;}
43 public abstract PolicyStatement Resolve (Evidence evidence);
44 public abstract CodeGroup ResolveMatchingCodeGroups(Evidence evidence);
46 public PolicyStatement PolicyStatement {
48 get { return m_policy; }
50 set { m_policy = value; }
53 public string Description {
55 get { return m_description; }
57 set { m_description = value; }
60 public IMembershipCondition MembershipCondition {
63 return m_membershipCondition;
68 throw new ArgumentException("Value cannot be null");
69 m_membershipCondition = value;
74 get { return m_name; }
75 set { m_name = value; }
78 public IList Children {
79 get { return m_children; }
82 throw new ArgumentNullException ("value");
83 m_children = new ArrayList(value);
87 public virtual string AttributeString {
90 return m_policy.AttributeString;
95 public virtual string PermissionSetName {
97 if (m_policy.PermissionSet is Security.NamedPermissionSet)
98 return ((NamedPermissionSet)(m_policy.PermissionSet)).Name;
103 public void AddChild(CodeGroup group)
106 throw new ArgumentNullException("The group parameter cannot be null");
107 m_children.Add(group);
110 public override bool Equals(object o)
112 if (!(o is CodeGroup))
115 return Equals((CodeGroup)o, false);
118 public bool Equals(CodeGroup cg, bool compareChildren)
120 if (cg.Name != this.Name)
123 if (cg.Description != this.Description)
126 // if (!cg.MembershipCondition.Equals ((IMembershipCondition)this.MembershipCondition))
129 if (compareChildren) {
130 int childCount = cg.Children.Count;
131 if (this.Children.Count != childCount)
134 for (int index = 0; index < childCount; index++) {
135 // LAMESPEC: are we supposed to check child equality recursively?
136 // The docs imply 'no' but it seems natural to do a 'deep' compare.
137 // Will check the children's children, and so-on unless we find out that
139 if (!((CodeGroup)(this.Children[index])).Equals((CodeGroup)(cg.Children[index]), true))
146 public void RemoveChild (CodeGroup group)
149 m_children.Remove (group);
152 public override int GetHashCode ()
154 int hashCode = m_membershipCondition.GetHashCode ();
155 if (m_policy != null)
156 hashCode += m_policy.GetHashCode ();
160 public void FromXml (SecurityElement e)
165 public void FromXml (SecurityElement e, PolicyLevel level)
168 throw new ArgumentNullException("e");
170 PermissionSet ps = null;
171 SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
173 ps = new NamedPermissionSet (pset);
176 ps = new NamedPermissionSet ("Nothing", new PermissionSet (PermissionState.None));
177 m_policy = new PolicyStatement (ps);
180 if ((e.Children != null) && (e.Children.Count > 0)) {
181 foreach (SecurityElement se in e.Children) {
182 if (se.Tag == "CodeGroup") {
183 this.AddChild (CodeGroup.CreateFromXml (se));
188 m_membershipCondition = null;
189 SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
191 string className = mc.Attribute ("class");
192 Type classType = Type.GetType (className);
193 if (classType == null)
194 classType = Type.GetType ("System.Security.Policy." + className);
195 m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType);
196 m_membershipCondition.FromXml (mc, level);
199 m_name = e.Attribute("Name");
200 m_description = e.Attribute("Description");
202 // seems like we might need this to Resolve() in subclasses
208 protected virtual void ParseXml(SecurityElement e, PolicyLevel level)
212 public SecurityElement ToXml()
217 public SecurityElement ToXml (PolicyLevel level)
219 SecurityElement e = new SecurityElement("CodeGroup");
220 e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
221 e.AddAttribute("version", "1");
224 e.AddAttribute("Name", Name);
226 if (null != Description)
227 e.AddAttribute("Description", Description);
229 if (null != MembershipCondition)
230 e.AddChild(MembershipCondition.ToXml());
232 if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
233 e.AddChild (PolicyStatement.PermissionSet.ToXml ());
235 foreach (CodeGroup child in Children)
236 e.AddChild(child.ToXml());
242 protected virtual void CreateXml(SecurityElement element, PolicyLevel level)
248 internal static CodeGroup CreateFromXml (SecurityElement se)
250 string fullClassName = se.Attribute ("class");
251 string className = fullClassName;
252 // many possible formats
253 // a. "FirstMatchCodeGroup"
254 // b. "System.Security.Policy.FirstMatchCodeGroup"
255 // c. "System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\n version=\"1\">\r\n <IMembershipCondition class=\"System.Security.Policy.AllMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
256 int n = className.IndexOf (",");
258 className = className.Substring (0, n);
260 n = className.LastIndexOf (".");
262 className = className.Substring (n + 1);
263 // much faster than calling Activator.CreateInstance
265 case "FileCodeGroup":
266 return new FileCodeGroup (se);
267 case "FirstMatchCodeGroup":
268 return new FirstMatchCodeGroup (se);
270 return new NetCodeGroup (se);
271 case "UnionCodeGroup":
272 return new UnionCodeGroup (se);
274 Type classType = Type.GetType (fullClassName);
275 return (CodeGroup) Activator.CreateInstance (classType, true);
278 } // public abstract class CodeGroup
279 } // namespace System.Security.Policy